emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
@ 2021-11-10 16:16 Stewart Thomas
  2021-11-13 14:57 ` Max Nikulin
  0 siblings, 1 reply; 7+ messages in thread
From: Stewart Thomas @ 2021-11-10 16:16 UTC (permalink / raw)
  To: emacs-orgmode

(Apologies for sending this from gmail, my mail setup was not working
with the -Q option in emacs.)

A table in which a first column begins with square brackets is not
compiling. The square bracket is interpreted by latex as an argument
to the preceding line break.

Example org table:
  | Input  | Output |
  |--------+--------|
  | [1, 2] | {3, 4} |
  | [5, 6] | null   |

When exported to a PDF ( C-c C-e l o), I expect that the PDF to be rendered
with the brackets in the table as shown in org.

Instead, the result is a latex compilation error. The brackets are being
interpreted as length arguments to the preceding line break.

This is a relevant Stack Exchange issue (for pure latex) which suggests
some possible solutions.

[[https://tex.stackexchange.com/questions/34466/error-with-square-bracket-in-table][Error
with square bracket in table]]

To test, emacs was started with =emacs -q= to not load an init file.


Emacs  : GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.22.30, cairo version 1.15.12)
 of 2021-10-27
Package: Org mode version 9.5 (release_9.5-59-g52e6f1 @
/home/sjt015/repo/emacs/lisp/org/)

current state:
==============
(setq
 org-link-elisp-confirm-function 'yes-or-no-p
 org-bibtex-headline-format-function #[257 "\300%1\236A\207" [:title]
3 "\n\n(fn ENTRY)"]
 org-export-before-parsing-hook '(org-attach-expand-links)
 org-archive-hook '(org-attach-archive-delete-maybe)
 org-odt-format-inlinetask-function 'org-odt-format-inlinetask-default-function
 org-ascii-format-drawer-function #[771 "%1\207" [] 4 "\n\n(fn NAME
CONTENTS WIDTH)"]
 org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers
          org-cycle-show-empty-lines
          org-optimize-window-after-visibility-change)
 org-mode-hook '(#[0 "\300\301\302\303\304$\207"
           [add-hook change-major-mode-hook org-show-all append local]
           5]
         #[0 "\300\301\302\303\304$\207"
           [add-hook change-major-mode-hook org-babel-show-result-all
            append local]
           5]
         org-babel-result-hide-spec org-babel-hide-all-hashes)
 org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ CONTENTS)"]
 org-latex-format-headline-function 'org-latex-format-headline-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
 outline-isearch-open-invisible-function 'outline-isearch-open-invisible
 org-odt-format-headline-function 'org-odt-format-headline-default-function
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
             org-src-mode-configure-edit-buffer)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-speed-command-hook '(org-speed-command-activate
              org-babel-speed-command-activate)
 org-html-format-inlinetask-function
'org-html-format-inlinetask-default-function
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
 org-latex-format-inlinetask-function
'org-latex-format-inlinetask-default-function
 org-tab-first-hook '(org-babel-hide-result-toggle-maybe
              org-babel-header-arg-expand)
 org-link-shell-confirm-function 'yes-or-no-p
 org-babel-pre-tangle-hook '(save-buffer)
 org-agenda-loop-over-headlines-in-active-region nil
 org-occur-hook '(org-first-headline-recenter)
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-link-parameters '(("attachment" :follow org-attach-follow :complete
            org-attach-complete-link)
               ("id" :follow org-id-open)
               ("eww" :follow org-eww-open :store org-eww-store-link)
               ("rmail" :follow org-rmail-open :store
            org-rmail-store-link)
               ("mhe" :follow org-mhe-open :store org-mhe-store-link)
               ("irc" :follow org-irc-visit :store org-irc-store-link
            :export org-irc-export)
               ("info" :follow org-info-open :export org-info-export
            :store org-info-store-link)
               ("gnus" :follow org-gnus-open :store
            org-gnus-store-link)
               ("docview" :follow org-docview-open :export
            org-docview-export :store org-docview-store-link)
               ("bibtex" :follow org-bibtex-open :store
            org-bibtex-store-link)
               ("bbdb" :follow org-bbdb-open :export org-bbdb-export
            :complete org-bbdb-complete-link :store
            org-bbdb-store-link)
               ("w3m" :store org-w3m-store-link)
               ("doi" :follow org-link-doi-open :export
            org-link-doi-export)
               ("file+sys") ("file+emacs")
               ("shell" :follow org-link--open-shell)
               ("news" :follow
            #[514 "\301\300\302%4Q%2\"\207"
              ["news" browse-url ":"] 6 "\n\n(fn URL ARG)"]
            )
               ("mailto" :follow
            #[514 "\301\300\302%4Q%2\"\207"
              ["mailto" browse-url ":"] 6 "\n\n(fn URL ARG)"]
            )
               ("https" :follow
            #[514 "\301\300\302%4Q%2\"\207"
              ["https" browse-url ":"] 6 "\n\n(fn URL ARG)"]
            )
               ("http" :follow
            #[514 "\301\300\302%4Q%2\"\207"
              ["http" browse-url ":"] 6 "\n\n(fn URL ARG)"]
            )
               ("ftp" :follow
            #[514 "\301\300\302%4Q%2\"\207" ["ftp" browse-url ":"]
              6 "\n\n(fn URL ARG)"]
            )
               ("help" :follow org-link--open-help :store
            org-link--store-help)
               ("file" :complete org-link-complete-file)
               ("elisp" :follow org-link--open-elisp))
 org-html-format-headline-function 'org-html-format-headline-default-function
 org-metaup-hook '(org-babel-load-in-session-maybe)
 )


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2021-11-10 16:16 [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)] Stewart Thomas
@ 2021-11-13 14:57 ` Max Nikulin
  2022-10-07  8:31   ` [PATCH] " Ihor Radchenko
  0 siblings, 1 reply; 7+ messages in thread
From: Max Nikulin @ 2021-11-13 14:57 UTC (permalink / raw)
  To: Stewart Thomas, emacs-orgmode

On 10/11/2021 23:16, Stewart Thomas wrote:
> 
> A table in which a first column begins with square brackets is not
> compiling. The square bracket is interpreted by latex as an argument
> to the preceding line break.

Confirmed

Thank you for reporting the issue. Example of a workaround

---- >8 ----
#+macro: tr @@latex:\relax @@

| one |
| {{{tr}}}[2] |

Ref \\
{{{tr}}} [2]
---- 8< -----

To fix the bug newline (in tables and paragraphs) should be exported as 
"\\\relax" or "\\{}". I do not suggest curly brackets in the beginning 
of line to avoid issues with spurious spaces. Percent character 
(comment) at the end of line should be considered for a fix since it is 
usually used in the opposite way: to suppress newline character and 
spaces at the beginning of next source line.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2021-11-13 14:57 ` Max Nikulin
@ 2022-10-07  8:31   ` Ihor Radchenko
  2022-10-07 11:34     ` Max Nikulin
  0 siblings, 1 reply; 7+ messages in thread
From: Ihor Radchenko @ 2022-10-07  8:31 UTC (permalink / raw)
  To: Max Nikulin, Daniel Fleischer; +Cc: Stewart Thomas, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 845 bytes --]

Max Nikulin <manikulin@gmail.com> writes:

> On 10/11/2021 23:16, Stewart Thomas wrote:
>> 
>> A table in which a first column begins with square brackets is not
>> compiling. The square bracket is interpreted by latex as an argument
>> to the preceding line break.
>
> Confirmed
>
> To fix the bug newline (in tables and paragraphs) should be exported as 
> "\\\relax" or "\\{}". I do not suggest curly brackets in the beginning 
> of line to avoid issues with spurious spaces. Percent character 
> (comment) at the end of line should be considered for a fix since it is 
> usually used in the opposite way: to suppress newline character and 
> spaces at the beginning of next source line.

I am attaching a tentative patch to fix this.
However, I am not sure if I replaced \\ with \\\relax in the right
places.

Daniel, can you please check?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Protect-.-after-to-be-interpreted-as-LaTeX-.patch --]
[-- Type: text/x-patch, Size: 6875 bytes --]

From 43d643197883e10a6c6551489d37053c2c89b4dd Mon Sep 17 00:00:00 2001
Message-Id: <43d643197883e10a6c6551489d37053c2c89b4dd.1665131437.git.yantar92@gmail.com>
From: Ihor Radchenko <yantar92@gmail.com>
Date: Fri, 7 Oct 2022 16:24:32 +0800
Subject: [PATCH] ox-latex: Protect [...] after \\ to be interpreted as LaTeX
 argument

* lisp/ox-latex.el (org-latex-linebreak-safe): New constant holding
safe version of LaTeX line break.
(org-latex-table-matrix-macros):
(org-latex-clock):
(org-latex-line-break):
(org-latex-plain-text):
(org-latex-planning):
(org-latex--org-table):
(org-latex--math-table):
(org-latex-table-row):
(org-latex-verse-block): Use the new constant.

* testing/lisp/test-org-table.el (test-org-table/to-latex): Update
tests.

Reported-by: Stewart Thomas <sjt015@bucknell.edu>
Link: https://orgmode.org/list/ce760fc3-5aae-144d-2d02-7dea215f73fc@gmail.com
---
 lisp/ox-latex.el               | 47 ++++++++++++++++++++++++----------
 testing/lisp/test-org-table.el |  6 ++---
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 34ff52b81..127637ccf 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -278,10 +278,23 @@ (defconst org-latex-language-alist
 
 - `:lang-name' the actual name of the language.")
 
+(defconst org-latex-linebreak-safe "\\\\\\relax"
+  "Linebreak protecting the following [...].
 
-(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
+Without \"\\relax\" 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\\\\\\relax
+    [I] & A\\\\\\relax
+    [m] & kg
+\\end{tabular}")
+
+(defconst org-latex-table-matrix-macros `(("bordermatrix" . "\\cr")
 					  ("qbordermatrix" . "\\cr")
-					  ("kbordermatrix" . "\\\\"))
+					  ("kbordermatrix" . ,org-latex-linebreak-safe))
   "Alist between matrix macros and their row ending.")
 
 (defconst org-latex-math-environments-re
@@ -2062,7 +2075,7 @@ (defun org-latex-clock (clock _contents info)
 	   (concat (org-timestamp-translate (org-element-property :value clock))
 		   (let ((time (org-element-property :duration clock)))
 		     (and time (format " (%s)" time)))))
-   "\\\\"))
+   org-latex-linebreak-safe))
 
 
 ;;;; Code
@@ -2659,7 +2672,7 @@ ;;;; Line Break
 (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."
-  "\\\\\n")
+  (concat org-latex-linebreak-safe "\n"))
 
 
 ;;;; Link
@@ -3005,7 +3018,9 @@ (defun org-latex-plain-text (text info)
     ;; Handle break preservation if required.
     (when (plist-get info :preserve-breaks)
       (setq output (replace-regexp-in-string
-		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t)))
+		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n"
+                    (concat org-latex-linebreak-safe "\n")
+                    output nil t)))
     ;; Return value.
     output))
 
@@ -3041,7 +3056,7 @@ (defun org-latex-planning (planning _contents info)
 		(format (plist-get info :latex-active-timestamp-format)
 			(org-timestamp-translate scheduled)))))))
     " ")
-   "\\\\"))
+   org-latex-linebreak-safe))
 
 
 ;;;; Property Drawer
@@ -3821,11 +3836,11 @@ (defun org-latex--org-table (table contents info)
 		(format "\\begin{%s}%s{%s}\n" table-env width alignment)
 		(and above?
 		     (org-string-nw-p caption)
-		     (concat caption "\\\\\n"))
+		     (concat caption org-latex-linebreak-safe "\n"))
 		contents
 		(and (not above?)
 		     (org-string-nw-p caption)
-		     (concat caption "\\\\\n"))
+		     (concat caption org-latex-linebreak-safe "\n"))
 		(format "\\end{%s}" table-env)
 		(and fontsize "}"))))
      (t
@@ -3910,7 +3925,7 @@ (defun org-latex--math-table (table info)
 		 (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)) "\\\\")
+		(or (cdr (assoc env org-latex-table-matrix-macros)) org-latex-linebreak-safe)
 		"\n")))
 	   (org-element-map table 'table-row #'identity info) "")))
     (concat
@@ -3982,7 +3997,7 @@ (defun org-latex-table-row (table-row contents info)
        ;; hline was specifically marked.
        (and booktabsp (not (org-export-get-previous-element table-row info))
 	    "\\toprule\n")
-       contents "\\\\\n"
+       contents org-latex-linebreak-safe "\n"
        (cond
 	;; Special case for long tables.  Define header and footers.
 	((and longtablep (org-export-table-row-ends-header-p table-row info))
@@ -3990,9 +4005,9 @@ (defun org-latex-table-row (table-row contents info)
 			      (org-export-get-parent-table table-row) info))))
 	   (format "%s
 \\endfirsthead
-\\multicolumn{%d}{l}{%s} \\\\
+\\multicolumn{%d}{l}{%s} \\\\\\relax
 %s
-%s \\\\\n
+%s \\\\\\relax\n
 %s
 \\endhead
 %s\\multicolumn{%d}{r}{%s} \\\\
@@ -4092,8 +4107,12 @@ (defun org-latex-verse-block (verse-block contents info)
 	       (replace-regexp-in-string
 	        "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
 	        (replace-regexp-in-string
-	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
-	         contents nil t) nil t) nil t) linreset)
+	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n"
+                 (concat org-latex-linebreak-safe "\n")
+	         contents nil t)
+                nil t)
+               nil t)
+              linreset)
       info)
      ;; Insert footnote definitions, if any, after the environment, so
      ;; the special formatting above is not applied to them.
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 76fe41630..3e7f18a10 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -1635,11 +1635,11 @@ (ert-deftest test-org-table/to-generic ()
 (ert-deftest test-org-table/to-latex ()
   "Test `orgtbl-to-latex' specifications."
   (should
-   (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\na\\\\\\relax\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
   ;; Test :environment parameter.
   (should
-   (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}"
+   (equal "\\begin{tabularx}{l}\na\\\\\\relax\n\\end{tabularx}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |")
 			   '(:environment "tabularx"))))
   ;; Test :booktabs parameter.
@@ -1648,7 +1648,7 @@ (ert-deftest test-org-table/to-latex ()
     "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t))))
   ;; Handle LaTeX snippets.
   (should
-   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\relax\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| $x$ |") nil)))
   ;; Test pseudo objects and :raw parameter.
   (should
-- 
2.35.1


[-- Attachment #3: Type: text/plain, Size: 224 bytes --]


-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2022-10-07  8:31   ` [PATCH] " Ihor Radchenko
@ 2022-10-07 11:34     ` Max Nikulin
  2022-10-08  5:17       ` [PATCH v2] " Ihor Radchenko
  0 siblings, 1 reply; 7+ messages in thread
From: Max Nikulin @ 2022-10-07 11:34 UTC (permalink / raw)
  To: emacs-orgmode

On 07/10/2022 15:31, Ihor Radchenko wrote:
> 
> I am attaching a tentative patch to fix this.
> However, I am not sure if I replaced \\ with \\\relax in the right
> places.

Ihor, thank you for looking into this issue. I have not read your patch 
with enough attention to check that regular paragraphs, list entries and 
other elements are handled as well. Just a couple of notes:

> +(defconst org-latex-linebreak-safe "\\\\\\relax"

Is there a reason why you did not add \n at the end? It could help to 
avoid a lot of `concat' calls.

> -   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
> +   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\relax\n\\end{tabular}"

May be left as is since the line next to \\ does not start from square 
brackets.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2] Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2022-10-07 11:34     ` Max Nikulin
@ 2022-10-08  5:17       ` Ihor Radchenko
  2022-10-10 16:30         ` Max Nikulin
  0 siblings, 1 reply; 7+ messages in thread
From: Ihor Radchenko @ 2022-10-08  5:17 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 816 bytes --]

Max Nikulin <manikulin@gmail.com> writes:

>> +(defconst org-latex-linebreak-safe "\\\\\\relax"
>
> Is there a reason why you did not add \n at the end? It could help to 
> avoid a lot of `concat' calls.

Mostly because there are a couple of places where we need the version
without newline. I though that `concat' is better than
`replace-regexp-in-string' or introducing two constants with/without
newline.

I guess, we can introduce the two constants. It might be slightly more
optimal. See the updated version of the patch.

>> -   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
>> +   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\relax\n\\end{tabular}"
>
> May be left as is since the line next to \\ does not start from square 
> brackets.

Nope. It can't. These are ERT tests for the ox-latex output.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-ox-latex-Protect-.-after-to-be-interpreted-as-LaT.patch --]
[-- Type: text/x-patch, Size: 7074 bytes --]

From 14dceebeff73ff49e197f18b8235a40497bdbf55 Mon Sep 17 00:00:00 2001
Message-Id: <14dceebeff73ff49e197f18b8235a40497bdbf55.1665206183.git.yantar92@gmail.com>
From: Ihor Radchenko <yantar92@gmail.com>
Date: Fri, 7 Oct 2022 16:24:32 +0800
Subject: [PATCH v2] ox-latex: Protect [...] after \\ to be interpreted as
 LaTeX argument

* lisp/ox-latex.el (org-latex-linebreak-safe): New constant holding
safe version of LaTeX line break.
(org-latex-linebreak-safe-newline): New constant holding
`org-latex-linebreak-safe' with newline appended.
(org-latex-table-matrix-macros):
(org-latex-clock):
(org-latex-line-break):
(org-latex-plain-text):
(org-latex-planning):
(org-latex--org-table):
(org-latex--math-table):
(org-latex-table-row):
(org-latex-verse-block): Use the new constants.

* testing/lisp/test-org-table.el (test-org-table/to-latex): Update
tests.

Reported-by: Stewart Thomas <sjt015@bucknell.edu>
Link: https://orgmode.org/list/ce760fc3-5aae-144d-2d02-7dea215f73fc@gmail.com
---
 lisp/ox-latex.el               | 50 ++++++++++++++++++++++++----------
 testing/lisp/test-org-table.el |  6 ++--
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 34ff52b81..d340b9c95 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -278,10 +278,26 @@ (defconst org-latex-language-alist
 
 - `:lang-name' the actual name of the language.")
 
+(defconst org-latex-linebreak-safe "\\\\\\relax"
+  "Linebreak protecting the following [...].
 
-(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
+Without \"\\relax\" 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\\\\\\relax
+    [I] & A\\\\\\relax
+    [m] & kg
+\\end{tabular}")
+
+(defconst org-latex-linebreak-safe-newline (concat org-latex-linebreak-safe "\n")
+  "`org-latex-linebreak-safe' with newline.")
+
+(defconst org-latex-table-matrix-macros `(("bordermatrix" . "\\cr")
 					  ("qbordermatrix" . "\\cr")
-					  ("kbordermatrix" . "\\\\"))
+					  ("kbordermatrix" . ,org-latex-linebreak-safe))
   "Alist between matrix macros and their row ending.")
 
 (defconst org-latex-math-environments-re
@@ -2062,7 +2078,7 @@ (defun org-latex-clock (clock _contents info)
 	   (concat (org-timestamp-translate (org-element-property :value clock))
 		   (let ((time (org-element-property :duration clock)))
 		     (and time (format " (%s)" time)))))
-   "\\\\"))
+   org-latex-linebreak-safe))
 
 
 ;;;; Code
@@ -2659,7 +2675,7 @@ ;;;; Line Break
 (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."
-  "\\\\\n")
+  org-latex-linebreak-safe-newline)
 
 
 ;;;; Link
@@ -3005,7 +3021,9 @@ (defun org-latex-plain-text (text info)
     ;; Handle break preservation if required.
     (when (plist-get info :preserve-breaks)
       (setq output (replace-regexp-in-string
-		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t)))
+		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n"
+                    org-latex-linebreak-safe-newline
+                    output nil t)))
     ;; Return value.
     output))
 
@@ -3041,7 +3059,7 @@ (defun org-latex-planning (planning _contents info)
 		(format (plist-get info :latex-active-timestamp-format)
 			(org-timestamp-translate scheduled)))))))
     " ")
-   "\\\\"))
+   org-latex-linebreak-safe))
 
 
 ;;;; Property Drawer
@@ -3821,11 +3839,11 @@ (defun org-latex--org-table (table contents info)
 		(format "\\begin{%s}%s{%s}\n" table-env width alignment)
 		(and above?
 		     (org-string-nw-p caption)
-		     (concat caption "\\\\\n"))
+		     org-latex-linebreak-safe-newline)
 		contents
 		(and (not above?)
 		     (org-string-nw-p caption)
-		     (concat caption "\\\\\n"))
+		     org-latex-linebreak-safe-newline)
 		(format "\\end{%s}" table-env)
 		(and fontsize "}"))))
      (t
@@ -3910,7 +3928,7 @@ (defun org-latex--math-table (table info)
 		 (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)) "\\\\")
+		(or (cdr (assoc env org-latex-table-matrix-macros)) org-latex-linebreak-safe)
 		"\n")))
 	   (org-element-map table 'table-row #'identity info) "")))
     (concat
@@ -3982,7 +4000,7 @@ (defun org-latex-table-row (table-row contents info)
        ;; hline was specifically marked.
        (and booktabsp (not (org-export-get-previous-element table-row info))
 	    "\\toprule\n")
-       contents "\\\\\n"
+       contents org-latex-linebreak-safe-newline
        (cond
 	;; Special case for long tables.  Define header and footers.
 	((and longtablep (org-export-table-row-ends-header-p table-row info))
@@ -3990,9 +4008,9 @@ (defun org-latex-table-row (table-row contents info)
 			      (org-export-get-parent-table table-row) info))))
 	   (format "%s
 \\endfirsthead
-\\multicolumn{%d}{l}{%s} \\\\
+\\multicolumn{%d}{l}{%s} \\\\\\relax
 %s
-%s \\\\\n
+%s \\\\\\relax\n
 %s
 \\endhead
 %s\\multicolumn{%d}{r}{%s} \\\\
@@ -4092,8 +4110,12 @@ (defun org-latex-verse-block (verse-block contents info)
 	       (replace-regexp-in-string
 	        "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
 	        (replace-regexp-in-string
-	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
-	         contents nil t) nil t) nil t) linreset)
+	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n"
+                 org-latex-linebreak-safe-newline
+	         contents nil t)
+                nil t)
+               nil t)
+              linreset)
       info)
      ;; Insert footnote definitions, if any, after the environment, so
      ;; the special formatting above is not applied to them.
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 76fe41630..3e7f18a10 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -1635,11 +1635,11 @@ (ert-deftest test-org-table/to-generic ()
 (ert-deftest test-org-table/to-latex ()
   "Test `orgtbl-to-latex' specifications."
   (should
-   (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\na\\\\\\relax\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
   ;; Test :environment parameter.
   (should
-   (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}"
+   (equal "\\begin{tabularx}{l}\na\\\\\\relax\n\\end{tabularx}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |")
 			   '(:environment "tabularx"))))
   ;; Test :booktabs parameter.
@@ -1648,7 +1648,7 @@ (ert-deftest test-org-table/to-latex ()
     "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t))))
   ;; Handle LaTeX snippets.
   (should
-   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\relax\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| $x$ |") nil)))
   ;; Test pseudo objects and :raw parameter.
   (should
-- 
2.35.1


[-- Attachment #3: Type: text/plain, Size: 224 bytes --]


-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2022-10-08  5:17       ` [PATCH v2] " Ihor Radchenko
@ 2022-10-10 16:30         ` Max Nikulin
  2022-10-11  3:36           ` Ihor Radchenko
  0 siblings, 1 reply; 7+ messages in thread
From: Max Nikulin @ 2022-10-10 16:30 UTC (permalink / raw)
  To: emacs-orgmode

Ihor, I have tried your patch (v2). With a tiny test file it works as 
expected. I have not managed to add some text immediately after \relax 
to break this command.

On 08/10/2022 12:17, Ihor Radchenko wrote:
> Max Nikulin writes:
> 
>>> +(defconst org-latex-linebreak-safe "\\\\\\relax"
>>
>> Is there a reason why you did not add \n at the end? It could help to
>> avoid a lot of `concat' calls.
> 
> Mostly because there are a couple of places where we need the version
> without newline. I though that `concat' is better than
> `replace-regexp-in-string' or introducing two constants with/without
> newline.
> 
> I guess, we can introduce the two constants. It might be slightly more
> optimal. See the updated version of the patch.

Reading with more attention, I do not think that second constant really 
makes the code more clear. I had a hope that it is enough to introduce a 
single constant, but it seems it is not the case. I did not expect that 
newline should not be added e.g. planning export handler. Perhaps it is 
better to commit v1.

>>> -   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
>>> +   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\relax\n\\end{tabular}"
>>
>> May be left as is since the line next to \\ does not start from square
>> brackets.
> 
> Nope. It can't. These are ERT tests for the ox-latex output.

My bad. I am sorry.

> @@ -2659,7 +2675,7 @@ ;;;; Line Break
>  (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."
> -  "\\\\\n")
> +  org-latex-linebreak-safe-newline)

A minor naming inconsistency: "line-break" and "linebreak".




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Re: [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)]
  2022-10-10 16:30         ` Max Nikulin
@ 2022-10-11  3:36           ` Ihor Radchenko
  0 siblings, 0 replies; 7+ messages in thread
From: Ihor Radchenko @ 2022-10-11  3:36 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> Ihor, I have tried your patch (v2). With a tiny test file it works as 
> expected. I have not managed to add some text immediately after \relax 
> to break this command.
> ...
> Reading with more attention, I do not think that second constant really 
> makes the code more clear. I had a hope that it is enough to introduce a 
> single constant, but it seems it is not the case. I did not expect that 
> newline should not be added e.g. planning export handler. Perhaps it is 
> better to commit v1.
> ...
> A minor naming inconsistency: "line-break" and "linebreak".

Thanks for testing!
I applied the version 1 of the patch onto main changing the
org-latex-linebreak-safe to org-latex-line-break-safe.

https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=3f60acff7717e472d06833e9cf9fff6ca3d59337

Fixed.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-10-11  3:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-10 16:16 [BUG] Tables with square brackets do not compile in PDF (latex) export [9.5 (release_9.5-59-g52e6f1 @ /home/sjt015/repo/emacs/lisp/org/)] Stewart Thomas
2021-11-13 14:57 ` Max Nikulin
2022-10-07  8:31   ` [PATCH] " Ihor Radchenko
2022-10-07 11:34     ` Max Nikulin
2022-10-08  5:17       ` [PATCH v2] " Ihor Radchenko
2022-10-10 16:30         ` Max Nikulin
2022-10-11  3:36           ` Ihor Radchenko

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).