Hello,

Following an exchange with Ihor on the Matrix room, here is a full report.

# Summary

When `org-html-with-latex` is set to a value listed in `org-preview-latex-
process-alist` (dvisvgm, dvipng, imagemagick), HTML export of a `latex-
environment` element unconditionally appends `*` to the environment name 
before compiling the .tex fragment.

This works fine for environments that have a starred form (`equation`, `align`, 
...), but breaks every environment that does not have one. A typical example 
is `tikzcd` from tikz-cd: `\begin{tikzcd}` becomes `\begin{tikzcd*}`, which is 
undefined. LaTeX reports the error but proceeds, and only the body of the 
environment ends up rendered (as math), producing nonsense output such as `F [ 
r ] E [ d , pi ] M` in place of a commutative diagram.

The in-buffer pipeline (`M-x org-latex-preview`) does NOT perform this rewrite, 
so the same fragment previews correctly. The difference between the two 
pipelines is what motivated the investigation.

# Reproducer

Minimal init (`/tmp/min-init.el`):

  (require 'org)
  (require 'ox-html)
  (require 'ox-publish)
  (setq org-html-with-latex 'dvisvgm)
  (add-to-list 'org-latex-packages-alist '("" "tikz" t))
  (add-to-list 'org-latex-packages-alist '("" "tikz-cd" t))

Test file (`/tmp/repro.org`):

  #+TITLE: tikzcd export repro

  \begin{tikzcd}
  F \arrow[r] & E \arrow[d, "\pi"] \\
              & M
  \end{tikzcd}

Steps:

  $ emacs -Q -l /tmp/min-init.el /tmp/repro.org
  M-x org-html-export-to-html

Observed: the resulting HTML embeds an SVG whose contents are the body of the 
env typeset as math, not a diagram.

# How to demonstrate

To inspect the .tex actually fed to latex, disable cleanup:

  (setf (plist-get (cdr (assq 'dvisvgm org-preview-latex-process-alist))
                   :post-clean)
        '(".keep-me-for-debug"))

Then re-export and look at /tmp/orgtex*.tex:

  \begin{document}
  \definecolor{fg}{rgb}{0,0,0}%
  {\color{fg}
  \begin{tikzcd*}                       <-- starred, undefined
  F \arrow[r] & E \arrow[d, "\pi"] \\
              & M
  \end{tikzcd*}
  %
  }
  \end{document}

For comparison, `M-x org-latex-preview` on the same fragment produces a .tex 
containing `\begin{tikzcd}...\end{tikzcd}` verbatim and renders correctly.

# Underlying cause (very likely)

`lisp/ox-html.el`, function `org-html-latex-environment`, in the branch 
handling image-based processing types:

  ((assq processing-type org-preview-latex-process-alist)
   (let ((formula-link
          (org-html-format-latex
           (org-html--unlabel-latex-environment latex-frag)   ;; <--
           processing-type info)))
     ...))

And `org-html--unlabel-latex-environment` itself:

  (defun org-html--unlabel-latex-environment (latex-frag)
    "Change environment in LATEX-FRAG string to an unnumbered one.
  For instance, change an `equation` environment to `equation*`."
    (replace-regexp-in-string
     "\\`[ \t]*\\\\begin{\\([^*]+?\\)}"
     "\\1*"
     (replace-regexp-in-string "^[ \t]*\\\\end{\\([^*]+?\\)}[ \r\t\n]*\\'"
                               "\\1*"
                               latex-frag nil nil 1)
     nil nil 1))

The rewrite has no whitelist and no check for whether a starred form exists 
for the environment in question.

# Workaround

Restrict the rewrite to math environments (which are the ones that have a 
starred form in practice):

  (defun my/org-html--unlabel-latex-environment (orig latex-frag)
    "Only star environments known to have a starred form."
    (if (string-match-p org-latex-math-environments-re latex-frag)
        (funcall orig latex-frag)
      latex-frag))

  (advice-add 'org-html--unlabel-latex-environment :around
              #'my/org-html--unlabel-latex-environment)

With this advice, the generated .tex preserves `\begin{tikzcd}` verbatim and 
HTML export produces the expected diagram. `align*`, `equation`, etc. continue 
to work as before.

# Suggested fix

The set of environments to star should be restricted to those that actually 
have a starred form. `org-latex-math-environments-re` in `ox-latex.el` is not 
designed for this purpose, but its current content happens to coincide with 
the math environments that have starred forms; using it as a gating regexp 
inside `org-html--unlabel-latex-environment` (or, possibly more cleanly, at 
the call site in `org-html-latex-environment`) fixes the issue.

A more involved fix would be a dedicated list (or defcustom) of environments 
eligible for unnumbering, decoupled from the `org-latex-math-environments-re` 
invariant.

# Versions

- Org: 9.8.4 (commit 004e0828b, 2026-05-10)
- Emacs: 30 (pgtk)
- OS: NixOS

Originally observed on 83a55c6fe (2025-05-12) and confirmed to still occur on 
current main 004e0828b.

# Related context

This came up while trying to render `tikz-cd` commutative diagrams inline in 
org-mode notes with `org-html-with-latex` set to `dvisvgm` (necessary because 
MathJax does not support tikz). The preview pipeline (`org-latex-preview`) 
works correctly out of the box; only the HTML export pipeline is affected.

Thanks,
Chris




Reply via email to