Hey Ihor,
On 2025-08-10 04:06, Ihor Radchenko wrote:
> I was mostly talking about internals. If you mean something like "Use
> `LaTeX' as an intermediary" in your first message, then it is _not_ what
> I had in mind. What I had in mind is some kind of internal backend that
> will be used by html/odt/etc. The advantage of using a backend is that
> we can plug export customization system - filters, custom templates,
> in-buffer options, etc.
I misunderstood then, thanks for the explanation. I’ll study
'org-export-toc-entry-backend' to better understand how internal
backends are used.
> So, ox-odt now does support it.
> https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=8b900ae37
Thank you! I’ve attached a patch series that:
1. Fixes the description of 'org-odt-with-latex' to match the export
behaviour.
2. Allows any symbol from 'org-preview-latex-process-alist', just like
'org-html-with-latex'. This way, 'xelatex' and any future additions
are allowed, including user-defined symbols.
3. Replaces the hard-coded 'ltxmathml' directory with a variable.
Best,
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette
From 140afc20276690c059646e08814f84ae24589c29 Mon Sep 17 00:00:00 2001
From: "Jacob S. Gordon" <jacob.as.gor...@gmail.com>
Date: Sun, 10 Aug 2025 18:08:02 -0400
Subject: [PATCH v1 1/3] ox-odt: Align 'org-odt-with-latex' with export
behavior
* lisp/ox-odt.el (org-odt-with-latex): Remove 'mathjax', add missing
'mathml' and 'dvisvgm' options, and clarify when 'verbatim' is used as
a fallback.
(org-odt--translate-latex-fragments): Update comment.
---
lisp/ox-odt.el | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index 8fb026247..0c59d516f 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -722,26 +722,30 @@ When set, the exporter will process LaTeX environments and
fragments.
This option can also be set with the +OPTIONS line,
-e.g. \"tex:mathjax\". Allowed values are:
+e.g. \"tex:dvipng\". Allowed values are:
nil Ignore math snippets.
-`verbatim' Keep everything in verbatim
-`dvipng' Process the LaTeX fragments to images. This will also
- include processing of non-math environments.
+t, `mathml' Convert the LaTeX fragments to MathML if the
+ `org-latex-to-mathml-convert-command' is usable.
+`dvipng' Process the LaTeX fragments to PNG images. This will
+ also include processing of non-math environments.
`imagemagick' Convert the LaTeX fragments to pdf files and use
imagemagick to convert pdf files to png files.
-`mathjax' Do MathJax preprocessing and arrange for MathJax.js to
- be loaded.
+`dvisvgm' Process the LaTeX fragments to SVG images. This will
+ also include processing of non-math environments.
+`verbatim' Keep everything in verbatim.
-Any other symbol is a synonym for `mathjax'."
+If the desired converter is not available or any other symbol is
+provided, process as `verbatim'."
:version "24.4"
:package-version '(Org . "8.0")
:type '(choice
(const :tag "Do not process math in any way" nil)
- (const :tag "Leave math verbatim" verbatim)
+ (const :tag "Convert fragments to MathML" mathml)
(const :tag "Use dvipng to make images" dvipng)
(const :tag "Use imagemagick to make images" imagemagick)
- (other :tag "Use MathJax to display math" mathjax)))
+ (const :tag "Use dvisvgm to make images" dvisvgm)
+ (const :tag "Leave math verbatim" verbatim)))
;;;; Links
@@ -3779,9 +3783,9 @@ contextual information."
(let ((processing-type (plist-get info :with-latex))
(count 0)
(warning nil))
- ;; Normalize processing-type to one of dvipng, mathml or verbatim.
- ;; If the desired converter is not available, force verbatim
- ;; processing.
+ ;; Normalize processing-type to one of mathml, dvipng,
+ ;; imagemagick, dvisvgm, or verbatim. If the desired converter is
+ ;; not available, force verbatim processing.
(cl-case processing-type
((t mathml)
(if (and (fboundp 'org-format-latex-mathml-available-p)
base-commit: f90f6912afd17001006e9b1b30ad5af86342ebe8
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette
From f0130f09cb638a8e716caa1ae43b82cf04ab0c20 Mon Sep 17 00:00:00 2001
From: "Jacob S. Gordon" <jacob.as.gor...@gmail.com>
Date: Sun, 10 Aug 2025 21:23:56 -0400
Subject: [PATCH v1 2/3] ox-odt: Allow LaTeX fragment conversion from any
preview method
Previously, only 'dvipng', 'imagemagick' and 'dvisvgm' could be used
to convert LaTeX fragments to images. This missed 'xelatex' and any
user-defined symbols. Any symbol in 'org-preview-latex-process-alist'
can now be used.
* lisp/ox-odt.el (org-odt-with-latex): Replace specific conversion
methods with a generic symbol, mirroring 'org-html-with-latex'.
(org-odt--translate-latex-fragments): Replace hard-coded symbols with
those from 'org-preview-latex-process-alist', and check all external
commands from the same. Generalize comments.
---
lisp/ox-odt.el | 77 +++++++++++++++++++++++++-------------------------
1 file changed, 38 insertions(+), 39 deletions(-)
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index 0c59d516f..d0feb05c3 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -727,12 +727,9 @@ e.g. \"tex:dvipng\". Allowed values are:
nil Ignore math snippets.
t, `mathml' Convert the LaTeX fragments to MathML if the
`org-latex-to-mathml-convert-command' is usable.
-`dvipng' Process the LaTeX fragments to PNG images. This will
- also include processing of non-math environments.
-`imagemagick' Convert the LaTeX fragments to pdf files and use
- imagemagick to convert pdf files to png files.
-`dvisvgm' Process the LaTeX fragments to SVG images. This will
- also include processing of non-math environments.
+SYMBOL Convert the LaTeX fragments to images using any symbol
+ defined in `org-preview-latex-process-alist', e.g.,
+ `dvipng'.
`verbatim' Keep everything in verbatim.
If the desired converter is not available or any other symbol is
@@ -742,9 +739,7 @@ provided, process as `verbatim'."
:type '(choice
(const :tag "Do not process math in any way" nil)
(const :tag "Convert fragments to MathML" mathml)
- (const :tag "Use dvipng to make images" dvipng)
- (const :tag "Use imagemagick to make images" imagemagick)
- (const :tag "Use dvisvgm to make images" dvisvgm)
+ (symbol :tag "Convert fragments to images" :value dvipng)
(const :tag "Leave math verbatim" verbatim)))
@@ -3781,30 +3776,36 @@ contextual information."
(defun org-odt--translate-latex-fragments (tree _backend info)
(let ((processing-type (plist-get info :with-latex))
+ (preview-symbols (mapcar #'car org-preview-latex-process-alist))
(count 0)
(warning nil))
- ;; Normalize processing-type to one of mathml, dvipng,
- ;; imagemagick, dvisvgm, or verbatim. If the desired converter is
- ;; not available, force verbatim processing.
- (cl-case processing-type
- ((t mathml)
+ ;; Normalize processing-type to one of mathml, verbatim, or a
+ ;; symbol in org-preview-latex-process-alist. If the desired
+ ;; converter is not available, force verbatim processing.
+ (pcase processing-type
+ ((or 't 'mathml)
(if (and (fboundp 'org-format-latex-mathml-available-p)
(org-format-latex-mathml-available-p))
(setq processing-type 'mathml)
(setq warning "`org-odt-with-latex': LaTeX to MathML converter not available. Falling back to verbatim.")
(setq processing-type 'verbatim)))
- ((dvipng imagemagick dvisvgm)
- (unless (and (org-check-external-command "latex" "" t)
- (org-check-external-command
- (cl-case processing-type
- (dvipng "dvipng")
- (dvisvgm "dvisvgm")
- (imagemagick "convert"))
- "" t))
- (setq warning "`org-odt-with-latex': LaTeX to PNG converter not available. Falling back to verbatim.")
+ ((and s
+ (guard (memq s preview-symbols))
+ (let ext-commands
+ (plist-get
+ (cdr (assq s org-preview-latex-process-alist))
+ :programs))
+ (let ext-commands-check
+ (seq-reduce (lambda (result cmd)
+ (and result
+ (not (null
+ (org-check-external-command cmd "" t)))))
+ ext-commands t)))
+ (unless ext-commands-check
+ (setq warning "`org-odt-with-latex': LaTeX to image converter not available. Falling back to verbatim.")
(setq processing-type 'verbatim)))
- (verbatim) ;; nothing to do
- (otherwise
+ ('verbatim) ;; nothing to do
+ (_
(setq warning "`org-odt-with-latex': Unknown LaTeX option. Forcing verbatim.")
(setq processing-type 'verbatim)))
@@ -3821,34 +3822,32 @@ contextual information."
(message "Formatting LaTeX using %s" processing-type)
;; Convert `latex-fragment's and `latex-environment's.
- (when (memq processing-type '(mathml dvipng dvisvgm imagemagick))
+ (when (memq processing-type (append '(mathml) preview-symbols))
(org-element-map tree '(latex-fragment latex-environment)
(lambda (latex-*)
(cl-incf count)
(let* ((latex-frag (org-element-property :value latex-*))
(input-file (plist-get info :input-file))
+ (is-image (memq processing-type preview-symbols))
(cache-dir (file-name-directory input-file))
(cache-subdir (concat
- (cl-case processing-type
- ((dvipng dvisvgm imagemagick)
- org-preview-latex-image-directory)
- (mathml "ltxmathml/"))
+ (if is-image
+ org-preview-latex-image-directory
+ "ltxmathml/")
(file-name-sans-extension
(file-name-nondirectory input-file))))
(display-msg
- (cl-case processing-type
- ((dvipng dvisvgm imagemagick)
- (format "Creating LaTeX Image %d..." count))
- (mathml (format "Creating MathML snippet %d..." count))))
- ;; Get an Org-style link to PNG image or the MathML
- ;; file.
+ (if is-image
+ (format "Creating LaTeX image %d..." count)
+ (format "Creating MathML snippet %d..." count)))
+ ;; Get an Org-style link to image or the MathML file.
(link
(with-temp-buffer
(insert latex-frag)
(delay-mode-hooks (let ((org-inhibit-startup t)) (org-mode)))
- ;; When converting to a PNG image, make sure to
- ;; copy all LaTeX header specifications from the
- ;; Org source.
+ ;; When converting to an image, make sure to copy
+ ;; all LaTeX header specifications from the Org
+ ;; source.
(unless (eq processing-type 'mathml)
(let ((h (plist-get info :latex-header)))
(when h
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette
From 1709da8c3f8cb63bbb1976cf1daf1b3d5783d927 Mon Sep 17 00:00:00 2001
From: "Jacob S. Gordon" <jacob.as.gor...@gmail.com>
Date: Sun, 10 Aug 2025 21:41:24 -0400
Subject: [PATCH v1 3/3] ox-odt: Add variable to specify path of generated
MathML files
* lisp/org.el (org-latex-mathml-directory): Add custom variable.
* lisp/ox-odt.el (org-odt--translate-latex-fragments): Replace
hard-coded MathML directory with the new variable.
---
lisp/org.el | 9 +++++++++
lisp/ox-odt.el | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/lisp/org.el b/lisp/org.el
index 65abfbe1a..29143cafb 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3513,6 +3513,15 @@ images at the same place."
:package-version '(Org . "9.0")
:type 'string)
+(defcustom org-latex-mathml-directory "ltxmathml/"
+ "Path to store MathML files converted from LaTeX fragments.
+A relative path here creates many directories relative to the
+processed Org files paths. An absolute path puts all files
+in the same place."
+ :group 'org-latex
+ :version "31.1"
+ :type 'string)
+
(defun org-format-latex-mathml-available-p ()
"Return t if `org-latex-to-mathml-convert-command' is usable."
(save-match-data
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index d0feb05c3..8f3bb175a 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -3833,7 +3833,7 @@ contextual information."
(cache-subdir (concat
(if is-image
org-preview-latex-image-directory
- "ltxmathml/")
+ org-latex-mathml-directory)
(file-name-sans-extension
(file-name-nondirectory input-file))))
(display-msg
--
Jacob S. Gordon
jacob.as.gor...@gmail.com
Please avoid sending me HTML emails and MS Office documents.
https://useplaintext.email/#etiquette