>From 094df613ec5fd05b6d2124bc45e6f9a8cbef92e5 Mon Sep 17 00:00:00 2001
From: thibault <[email protected]>
Date: Thu, 4 Jan 2018 21:23:59 -0600
Subject: [PATCH] ox-html.el: Add MathJax label and reference to equations in
HTML export
* lisp/ox-html.el (org-html-format-latex): Add "\label" to latex
environment as done for latex export. Add optional input
`latex-environment' to trigger the insertion.
(org-html-latex-environment): Pass unprocessed latex-environment to
`org-html-format-latex' when using MathJax.
(org-html-link): Replace rendering of link from "<a href ...>" to
"\ref{}" for equations when using MathJax.
* lisp/ox-latex.el (org-latex--label): Abstract code constructing the
label id into new function.
(org-latex--label-id): New function to construct the label id (used when
inserting labels for latex or html export).
(org-latex--insert-environment-label): New function to insert label into
buffer containing latex environment string (for use in latex and html
export).
(org-latex-latex-environment): Use new function
`org-latex--insert-environment-label' to insert environment label.
---
lisp/ox-html.el | 66 +++++++++++++++++++++++++++++++++++-----------------
lisp/ox-latex.el | 70 ++++++++++++++++++++++++++++++++------------------------
2 files changed, 85 insertions(+), 51 deletions(-)
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 90a6cede0..b5257653c 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -180,7 +180,9 @@
(:creator "CREATOR" nil org-html-creator-string)
(:with-latex nil "tex" org-html-with-latex)
;; Retrieve LaTeX header for fragments.
- (:latex-header "LATEX_HEADER" nil nil newline)))
+ (:latex-header "LATEX_HEADER" nil nil newline)
+ ;; Options for LaTeX environments
+ (:latex-caption-above nil nil org-latex-caption-above)))
;;; Internal Variables
@@ -2788,14 +2790,23 @@ CONTENTS is nil. INFO is a plist holding contextual information."
;;;; Latex Environment
-(defun org-html-format-latex (latex-frag processing-type info)
+(defun org-html-format-latex (latex-frag processing-type info
+ &optional latex-environment)
"Format a LaTeX fragment LATEX-FRAG into HTML.
PROCESSING-TYPE designates the tool used for conversion. It can
be `mathjax', `verbatim', nil, t or symbols in
`org-preview-latex-process-alist', e.g., `dvipng', `dvisvgm' or
`imagemagick'. See `org-html-with-latex' for more information.
INFO is a plist containing export properties."
- (let ((cache-relpath "") (cache-dir ""))
+ (let* ((cache-relpath "")
+ (cache-dir "")
+ (type (when latex-environment
+ (org-latex--environment-type latex-environment)))
+ (caption-above-p
+ (memq type (append (plist-get info :latex-caption-above) '(math))))
+ (caption (when (and (eq type 'math)
+ (eq processing-type 'mathjax))
+ (org-latex--label latex-environment info nil t))))
(unless (eq processing-type 'mathjax)
(let ((bfn (or (buffer-file-name)
(make-temp-name
@@ -2819,6 +2830,8 @@ INFO is a plist containing export properties."
(setq latex-frag (concat latex-header latex-frag))))
(with-temp-buffer
(insert latex-frag)
+ (when (and latex-environment caption)
+ (org-latex--insert-environment-label caption caption-above-p))
(org-format-latex cache-relpath nil nil cache-dir nil
"Creating LaTeX Image..." nil processing-type)
(buffer-string))))
@@ -2832,7 +2845,8 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(attributes (org-export-read-attribute :attr_html latex-environment)))
(cond
((memq processing-type '(t mathjax))
- (org-html-format-latex latex-frag 'mathjax info))
+ (org-html-format-latex latex-frag 'mathjax info
+ latex-environment))
((assq processing-type org-preview-latex-process-alist)
(let ((formula-link
(org-html-format-latex latex-frag processing-type info)))
@@ -3062,23 +3076,33 @@ INFO is a plist holding contextual information. See
(format "<a href=\"#%s\"%s>%s</a>" href attributes desc)))
;; Fuzzy link points to a target or an element.
(_
- (let* ((ref (org-export-get-reference destination info))
- (org-html-standalone-image-predicate
- #'org-html--has-caption-p)
- (number (cond
- (desc nil)
- ((org-html-standalone-image-p destination info)
- (org-export-get-ordinal
- (org-element-map destination 'link
- #'identity info t)
- info 'link 'org-html-standalone-image-p))
- (t (org-export-get-ordinal
- destination info nil 'org-html--has-caption-p))))
- (desc (cond (desc)
- ((not number) "No description for this link")
- ((numberp number) (number-to-string number))
- (t (mapconcat #'number-to-string number ".")))))
- (format "<a href=\"#%s\"%s>%s</a>" ref attributes desc))))))
+ (let* ((processing-type (plist-get info :with-latex))
+ (latex-environment destination)
+ (env-type (when (and latex-environment
+ (string=
+ (car latex-environment)
+ "latex-environment"))
+ (org-latex--environment-type latex-environment))))
+ (if (and (eq env-type 'math) processing-type)
+ (let ((ref (org-latex--label-id latex-environment info nil)))
+ (format "\\eqref{%s}" ref))
+ (let* ((ref (org-export-get-reference destination info))
+ (org-html-standalone-image-predicate
+ #'org-html--has-caption-p)
+ (number (cond
+ (desc nil)
+ ((org-html-standalone-image-p destination info)
+ (org-export-get-ordinal
+ (org-element-map destination 'link
+ #'identity info t)
+ info 'link 'org-html-standalone-image-p))
+ (t (org-export-get-ordinal
+ destination info nil 'org-html--has-caption-p))))
+ (desc (cond (desc)
+ ((not number) "No description for this link")
+ ((numberp number) (number-to-string number))
+ (t (mapconcat #'number-to-string number ".")))))
+ (format "<a href=\"#%s\"%s>%s</a>" ref attributes desc))))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
((string= type "coderef")
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 603bae22f..a57380499 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1244,6 +1244,32 @@ INFO is a plist holding contextual information."
(let ((type (org-element-type element)))
(memq (if (eq type 'link) 'image type) above)))))
+(defun org-latex--label-id (datum info &optional force)
+ "Return label for DATUM without \label environment."
+ (let* ((type (org-element-type datum))
+ (user-label
+ (org-element-property
+ (cl-case type
+ ((headline inlinetask) :CUSTOM_ID)
+ (target :value)
+ (otherwise :name))
+ datum)))
+ (and (or user-label force)
+ (if (and user-label (plist-get info :latex-prefer-user-labels))
+ user-label
+ (concat (cl-case type
+ (headline "sec:")
+ (table "tab:")
+ (latex-environment
+ (and (string-match-p
+ org-latex-math-environments-re
+ (org-element-property :value datum))
+ "eq:"))
+ (paragraph
+ (and (org-element-property :caption datum)
+ "fig:")))
+ (org-export-get-reference datum info))))))
+
(defun org-latex--label (datum info &optional force full)
"Return an appropriate label for DATUM.
DATUM is an element or a `target' type object. INFO is the
@@ -1255,29 +1281,7 @@ this case always return a unique label.
Eventually, if FULL is non-nil, wrap label within \"\\label{}\"."
(let* ((type (org-element-type datum))
- (user-label
- (org-element-property
- (cl-case type
- ((headline inlinetask) :CUSTOM_ID)
- (target :value)
- (otherwise :name))
- datum))
- (label
- (and (or user-label force)
- (if (and user-label (plist-get info :latex-prefer-user-labels))
- user-label
- (concat (cl-case type
- (headline "sec:")
- (table "tab:")
- (latex-environment
- (and (string-match-p
- org-latex-math-environments-re
- (org-element-property :value datum))
- "eq:"))
- (paragraph
- (and (org-element-property :caption datum)
- "fig:")))
- (org-export-get-reference datum info))))))
+ (label (org-latex--label-id datum info force)))
(cond ((not full) label)
(label (format "\\label{%s}%s"
label
@@ -2280,6 +2284,18 @@ could be a member of `org-latex-caption-above' or `math'."
'src-block)
(t 'special-block))))
+(defun org-latex--insert-environment-label (label caption-above-p)
+ "Insert LaTeX label LABEL in buffer containing LaTeX environment.
+When CAPTION-ABOVE-P is non nil, the label is added at the
+beginning of the environment. Otherwise, it is added at the end."
+ (if caption-above-p
+ (progn
+ (goto-char (point-min))
+ (forward-line))
+ (goto-char (point-max))
+ (forward-line -1))
+ (insert label))
+
(defun org-latex-latex-environment (latex-environment _contents info)
"Transcode a LATEX-ENVIRONMENT element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
@@ -2301,13 +2317,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
;; is not a math environment.
(with-temp-buffer
(insert value)
- (if caption-above-p
- (progn
- (goto-char (point-min))
- (forward-line))
- (goto-char (point-max))
- (forward-line -1))
- (insert caption)
+ (org-latex--insert-environment-label caption caption-above-p)
(buffer-string))))))
;;;; Latex Fragment
--
2.15.1
Hi list,
I am trying to get links to equations to work with HTML export (with Org mode
version 9.1.6 (release_9.1.6-295-ge8cd52 @ /.../org-mode-git/lisp/)).
It currently does not seem to work, as demonstrated by the following example org
file:
#+begin_src org
,#+NAME: eq-test
\begin{align}
1 + 1 = 0
\end{align}
link to equation [[eq-test]]
#+end_src
The relevant part of the resulting HTML is:
#+begin_src html
\begin{align}
1 + 1 = 0
\end{align}
<p>
link to equation <a href="#org0b47727">1</a>
</p>
#+end_src
The =align= block does not have a =label=. The link could use =\ref= (or
=\eqref=) which is handled by MathJax. The attached patch attempts to fix
this. It produces the following (correct?) output:
#+begin_src html
\begin{align}
\label{eq:orgbfedefe}
1 + 1 = 0
\end{align}
<p>
link to equation \eqref{eq:orgbfedefe}
</p>
#+end_src
The patch attempts to re-use functionality from ox-latex.el to avoid code
duplication. Please let me know if there is a better way to achieve the
same result.
Does this look like something that could eventually be merged? Let me know if
any change is required.
Thanks,
thibault