I am writting a LaTeX document using org-mode, and there is a section where I want to include a proof, which has the following code.

#+LaTeX_HEADER: \newcommand{\dem}[1]{\textcolor{gris}{\small{Demostración. #1}}}

If I write

\dem{(1) Esto es una demostración}

There is nothing wrong when exporting to LaTeX, and the text appears formated correctly. However, if I add an equation with some braces in it, like

\dem{Esto es una demostración con ecuación: \(x = x^{-2}\)}

then, the document is exported as

\dem\{Esto es una demostración con ecuación: \(x = x^{-2}\)\}

and the format is not correct. Is there any way I can "escape" those curly braces in my org-mode text to format the text correctly?

  • The effect is not reproducable with the built in org-mode of Emacs 26.2 and Emacs 27.0.50. I tested with the text from your question up to "Then, the document is exported as".
    – Tobias
    Sep 5 '19 at 7:42
  • @Tobias That is, the LaTeX document does not have the curly braces escaped? I have Emacs 26.2 with spacemacs 0.2. Sep 5 '19 at 16:22
  • @Tobias Can you reproduce it using \dem{Esto es una demostración con ecuación: \(x = x^{-2}\)} ? I've realized the error happens when adding other braces within the dem part. Sep 5 '19 at 16:38
  • The problem is reproducible with the new equation. I've edited the question accordingly.
    – Tobias
    Sep 5 '19 at 21:27
  • Thank you for the edit. Do you come up with any reason why this might happen? Sep 6 '19 at 7:34

I don't know the reason why this happens. I've found a quick fix for the problem though.

\dem{Esto es una demostración con ecuación: \(x = x^{-2}\)}

Works fine


org-element-latex-fragment-parser is too simple to scope with nested brace-delimited lists as arguments of latex macros.

The following advice for org-element-latex-fragment-parser replaces the LaTeX macro parsing with a version that parses LaTeX arguments as sexps.

(require 'tex-mode)

(defun bugfix-org-forward-latex-sexp (&optional start count)
  "Scan forward COUNT sexps starting with character START.
COUNT defaults to 1.
Skip over any sexp if START is not given.
Scanning stops at the end of the current line."
  (let ((line-end (line-end-position))
    state pos)
    (unless count (setq count 1))
    (while (and
        (> count 0)
        (or (null start)
        (eq (char-after) start))
        (setq state (parse-partial-sexp (point) ;; from
                        line-end ;; to
                        0 ;; targetdepth for forward-sexp
                        nil ;; stopbefore
                        state ;; oldstate
              pos (point))
        (null (> (nth 0 state) 0) ;; depth
      (goto-char pos)
      (cl-decf count))

(defun bugfix-org-element-latex-fragment-parser (fun)
  "See `org-element-latex-fragment-parser'.
This bugfix parses arguments of LaTeX macros as sexps."
  (let ((begin (point))
    (latex-macro (looking-at "\\\\[a-zA-Z]+\\*?")))
    (if latex-macro
      (goto-char (match-end 0))
      ;; scan optional arguments
      (bugfix-org-forward-latex-sexp ?\[ (buffer-size))
      ;; scan brace-delimited argument
      (bugfix-org-forward-latex-sexp ?\{)
      (let ((fragment (buffer-substring-no-properties begin (point)))
        (post-blank (skip-chars-forward " \t")))
        (list 'latex-fragment
          (list :value fragment
            :begin begin
            :end (point)
            :post-blank post-blank))))
      (funcall fun))))

(advice-add 'org-element-latex-fragment-parser :around #'bugfix-org-element-latex-fragment-parser)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.