emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Equation references in HTML export
@ 2018-01-05  5:30 Thibault Marin
  2018-01-06 10:41 ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Thibault Marin @ 2018-01-05  5:30 UTC (permalink / raw)
  To: emacs-org list

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: 0001-ox-html.el-Add-MathJax-label-and-reference-to-equati.patch --]
[-- Type: text/x-diff, Size: 9608 bytes --]

From 094df613ec5fd05b6d2124bc45e6f9a8cbef92e5 Mon Sep 17 00:00:00 2001
From: thibault <thibault.marin@gmx.com>
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)))
 
 \f
 ;;; 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


[-- Attachment #2: Type: text/plain, Size: 1142 bytes --]


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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-01-19 17:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-05  5:30 Equation references in HTML export Thibault Marin
2018-01-06 10:41 ` Nicolas Goaziou
2018-01-07  9:11   ` Thibault Marin
2018-01-09 21:27     ` Nicolas Goaziou
2018-01-11  4:04       ` Thibault Marin
2018-01-16 18:09         ` Nicolas Goaziou
2018-01-17  4:39           ` Thibault Marin
2018-01-17 21:27             ` Nicolas Goaziou
2018-01-18  3:25               ` Thibault Marin
2018-01-19 17:39                 ` Nicolas Goaziou
2018-01-17  7:35           ` Eric S Fraga
2018-01-19  4:09             ` Thibault Marin
2018-01-19  7:39               ` Eric S Fraga

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).