diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index a8171ade7..ad5a0684f 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -13,6 +13,16 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org. * Version 9.7 (not released yet) ** Important announcements and breaking changes +*** =ox-latex=: ~org-latex-line-break-safe~ is deprecated + +~org-latex-line-break-safe~ constant was previously introduced to deal +with edge cases when LaTeX interprets [...] as LaTeX command +argument. However, it caused a number of other issues and proved +itself not to be as "safe" as it supposed to be. + +We now use a Pandoc's approach to deal with the same problem, +utilizing ={[}= to escape =[...]= instances where needed. + *** ob-python now sets ~python-shell-buffer-name~ in Org edit buffers When editing a Python src block, the editing buffer is now associated diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 5b2256687..44632ebc0 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -629,6 +629,24 @@ Counting starts at 1." (define-obsolete-function-alias 'org-file-url-p 'org-url-p "9.6") (define-obsolete-variable-alias 'org-plantuml-executable-args 'org-plantuml-args "Org 9.6") + +(defconst org-latex-line-break-safe "\\\\[0pt]" + "Linebreak protecting the following [...]. + +Without \"[0pt]\" it would be interpreted as an optional argument to +the \\\\. + +This constant, for example, makes the below code not err: + +\\begin{tabular}{c|c} + [t] & s\\\\[0pt] + [I] & A\\\\[0pt] + [m] & kg +\\end{tabular}") +(make-obsolete 'org-latex-line-break-safe + "should not be used - it is not safe in all the scenarios." + "9.7") + (defun org-in-fixed-width-region-p () "Non-nil if point in a fixed-width region." (save-match-data diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index a64dd5a87..d6e74cb45 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -298,23 +298,10 @@ cdr is a property list. Valid keywords for this list can be: - `:script-tag' the script otf tag.") -(defconst org-latex-line-break-safe "\\\\[0pt]" - "Linebreak protecting the following [...]. -Without \"[0pt]\" it would be interpreted as an optional argument to -the \\\\. - -This constant, for example, makes the below code not err: - -\\begin{tabular}{c|c} - [t] & s\\\\[0pt] - [I] & A\\\\[0pt] - [m] & kg -\\end{tabular}") - -(defconst org-latex-table-matrix-macros `(("bordermatrix" . "\\cr") +(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr") ("qbordermatrix" . "\\cr") - ("kbordermatrix" . ,org-latex-line-break-safe)) + ("kbordermatrix" . "\\\\")) "Alist between matrix macros and their row ending.") (defconst org-latex-math-environments-re @@ -2124,7 +2111,7 @@ information." (concat (org-timestamp-translate (org-element-property :value clock)) (let ((time (org-element-property :duration clock))) (and time (format " (%s)" time))))) - org-latex-line-break-safe)) + "\\\\")) ;;;; Code @@ -2722,7 +2709,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-latex-line-break (_line-break _contents _info) "Transcode a LINE-BREAK object from Org to LaTeX. CONTENTS is nil. INFO is a plist holding contextual information." - (concat org-latex-line-break-safe "\n")) + "\\\\\n") ;;;; Link @@ -3092,9 +3079,7 @@ contextual information." ;; Handle break preservation if required. (when (plist-get info :preserve-breaks) (setq output (replace-regexp-in-string - "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" - (concat org-latex-line-break-safe "\n") - output nil t))) + "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t))) ;; Protect [foo] at the beginning of lines / beginning of the ;; plain-text object. This prevents LaTeX from unexpectedly ;; interpreting @@latex:\pagebreak@@ [foo] as a command with @@ -3139,7 +3124,7 @@ information." (format (plist-get info :latex-active-timestamp-format) (org-timestamp-translate scheduled))))))) " ") - org-latex-line-break-safe)) + "\\\\")) ;;;; Property Drawer @@ -3919,11 +3904,11 @@ This function assumes TABLE has `org' as its `:type' property and (format "\\begin{%s}%s{%s}\n" table-env width alignment) (and above? (org-string-nw-p caption) - (concat caption org-latex-line-break-safe "\n")) + (concat caption "\\\\\n")) contents (and (not above?) (org-string-nw-p caption) - (concat caption org-latex-line-break-safe "\n")) + (concat caption "\\\\\n")) (format "\\end{%s}" table-env) (and fontsize "}")))) (t @@ -4008,7 +3993,7 @@ This function assumes TABLE has `org' as its `:type' property and (lambda (cell) (substring (org-element-interpret-data cell) 0 -1)) (org-element-map row 'table-cell #'identity info) "&") - (or (cdr (assoc env org-latex-table-matrix-macros)) org-latex-line-break-safe) + (or (cdr (assoc env org-latex-table-matrix-macros)) "\\\\") "\n"))) (org-element-map table 'table-row #'identity info) ""))) (concat @@ -4083,7 +4068,7 @@ a communication channel." (setq table-head-cache (make-hash-table :test #'eq)) (plist-put info :org-latex-table-head-cache table-head-cache)) (if-let ((head-contents (gethash (org-element-parent table-row) table-head-cache))) - (puthash (org-element-parent table-row) (concat head-contents org-latex-line-break-safe "\n" contents) + (puthash (org-element-parent table-row) (concat head-contents "\\\\\n" contents) table-head-cache) (puthash (org-element-parent table-row) contents table-head-cache)))) ;; Return LaTeX string as the transcoder. @@ -4092,7 +4077,7 @@ a communication channel." ;; hline was specifically marked. (and booktabsp (not (org-export-get-previous-element table-row info)) "\\toprule\n") - contents org-latex-line-break-safe "\n" + contents "\\\\\n" (cond ;; Special case for long tables. Define header and footers. ((and longtablep (org-export-table-row-ends-header-p table-row info)) @@ -4100,9 +4085,9 @@ a communication channel." (org-element-lineage table-row 'table) info)))) (format "%s \\endfirsthead -\\multicolumn{%d}{l}{%s} \\\\[0pt] +\\multicolumn{%d}{l}{%s} \\\\ %s -%s \\\\[0pt]\n +%s \\\\\n %s \\endhead %s\\multicolumn{%d}{r}{%s} \\\\ @@ -4211,15 +4196,15 @@ contextual information." (replace-regexp-in-string (if (not lit) (rx-to-string - `(seq (group ,org-latex-line-break-safe "\n") - (1+ (group line-start (0+ space) ,org-latex-line-break-safe "\n")))) - (concat "^[ \t]*" (regexp-quote org-latex-line-break-safe) "$")) + `(seq (group "\\\\\n") + (1+ (group line-start (0+ space) "\\\\\n")))) + "^[ \t]*\\\\$") (if (not lit) (if lin "\\\\!\n\n" "\n\n") "\\vspace*{\\baselineskip}") (replace-regexp-in-string "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" - (concat org-latex-line-break-safe "\n") + "\\\\\n" (if (not lit) (concat (org-trim contents t) "\n") contents) diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el index 92ccd2a05..6ee790894 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -1633,11 +1633,11 @@ See also `test-org-table/copy-field'." (ert-deftest test-org-table/to-latex () "Test `orgtbl-to-latex' specifications." (should - (equal "\\begin{tabular}{l}\na\\\\[0pt]\n\\end{tabular}" + (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}" (orgtbl-to-latex (org-table-to-lisp "| a |") nil))) ;; Test :environment parameter. (should - (equal "\\begin{tabularx}{l}\na\\\\[0pt]\n\\end{tabularx}" + (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:environment "tabularx")))) ;; Test :booktabs parameter. @@ -1646,7 +1646,7 @@ See also `test-org-table/copy-field'." "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t)))) ;; Handle LaTeX snippets. (should - (equal "\\begin{tabular}{l}\n\\(x\\)\\\\[0pt]\n\\end{tabular}" + (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}" (orgtbl-to-latex (org-table-to-lisp "| $x$ |") nil))) ;; Test pseudo objects and :raw parameter. (should diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el index 237ad97ec..d0be4e5a4 100644 --- a/testing/lisp/test-ox-latex.el +++ b/testing/lisp/test-ox-latex.el @@ -71,14 +71,14 @@ lorem ipsum dolor (should (search-forward "\\begin{verse} -lorem ipsum dolor\\\\[0pt] +lorem ipsum dolor\\\\ lorem ipsum dolor -lorem ipsum dolor\\\\[0pt] +lorem ipsum dolor\\\\ lorem ipsum dolor -lorem ipsum dolor\\\\[0pt] -lorem ipsum dolor\\\\[0pt] +lorem ipsum dolor\\\\ +lorem ipsum dolor\\\\ \\end{verse}")))) (ert-deftest test-ox-latex/longtable () @@ -98,15 +98,15 @@ lorem ipsum dolor\\\\[0pt] (should (search-forward "\\begin{longtable}{lr} -First & Second\\\\[0pt] -Column & Column\\\\[0pt] +First & Second\\\\ +Column & Column\\\\ \\hline \\endfirsthead")) (goto-char (point-min)) (should (search-forward - "First & Second\\\\[0pt] -Column & Column \\\\[0pt] + "First & Second\\\\ +Column & Column \\\\ \\hline \\endhead"))