I am writing a document that is specifying a language with associated grammar and semantics. For this I have written the specification in Latex, using a method very similar to the one presented here.

That is: it heavily uses Latex's \newcommand macros. However, the contents of the commands themselves are nothing fancy and falls within the subset of Latex that MathJax supports.

I am slowly rewriting my documentation to Org mode, partially because of the HTML backend, allowing me to not only generate the original-ish PDF, but also a HTML page containing the same.

Now my question is: how can I export my (big list of) Latex \newcommand macros to Org such that they get compiled back to their originals on the Latex backend, but to their MathJax equivalent when exporting with the HTML backend?

Bonus question: Is it possible to redefine macros in MathJax? My original version contains several iterations of the same things, and overloads the macros by simply calling \renewcommand. Ideally, I would replicate this in MathJax, but it is not a dealbreaker: I can "simply" append some version id to each new iteration of the command, i.e. \somecommandA, \somecommandB etc.

1 Answer 1


I ended up finding the following solution.

I found a base solution on reddit that adds a "fake" language to babel as follows:

(add-to-list 'org-src-lang-modes '("latex-macros" . latex))

(defvar org-babel-default-header-args:latex-macros
  '((:results . "raw")
    (:exports . "results")))

(defun prefix-all-lines (pre body)
    (insert body)
    (string-insert-rectangle (point-min) (point-max) pre)

(defun org-babel-execute:latex-macros (body _params)
   (prefix-all-lines "#+LATEX_HEADER: " body)
   "\n#+HTML_HEAD_EXTRA: <div style=\"display: none\"> \\(\n"
   (prefix-all-lines "#+HTML_HEAD_EXTRA: " body)
   "\n#+HTML_HEAD_EXTRA: \\)</div>\n"))

This lets you define a latex-macros block as follows:

#+BEGIN_SRC latex-macros

For the Latex output, because it uses #+LATEX_HEADER, the commands are put in the preamble. For the HTML output, because of the HTML_HEAD_EXTRA, it is also put somewhere in the top of the document.

This got near what I wanted, but not quite, as I wanted to be able to redefine commands. What I ended up doing was modifying the code to add a 2nd "fake" language latex-macros-inline that uses #+BEGIN_EXPORT latex and BEGIN_EXPORT html blocks like so:

(defvar org-babel-default-header-args:latex-macros-inline
  '((:results . "raw")
    (:exports . "results")))

(defun org-babel-execute:latex-macros-inline (body _params)
   "\n#+BEGIN_EXPORT latex\n"
   "\n#+BEGIN_EXPORT html\n"
   "<div style=\"display: none\"> \n\\(\n"

Because of these blocks, both the Latex and HMTL is outputted at the actual place the block is defined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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