emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Thibault Marin <thibault.marin@gmx.com>
To: Nicolas Goaziou <mail@nicolasgoaziou.fr>
Cc: emacs-org list <emacs-orgmode@gnu.org>
Subject: Re: Equation references in HTML export
Date: Wed, 10 Jan 2018 22:04:59 -0600	[thread overview]
Message-ID: <87h8rtf3bo.fsf@dell-desktop.WORKGROUP> (raw)
In-Reply-To: <87h8ru3eq8.fsf@nicolasgoaziou.fr>

[-- Attachment #1: Type: text/plain, Size: 3657 bytes --]


Hi,


> You may be right. In this case, we may use \eqref if MathJax is
> going to be used (like your initial patch did), and do the above
> otherwise.

OK, I think that would work.  To summarize, here are the different
outputs under MathJax and the other modes:

- MathJax mode:
  - Environment:
    ,----
    | \begin{align}
    | \label{eq:org19c7f92}
    | 1 + 1 = 0
    | \end{align}
    `----
  - Link:
    ,----
    | link to \eqref{eq:org19c7f92}
    `----
- other modes, e.g. verbatim: (it is similar for the rest: dvipng,
  imagemagick, etc).:
  - Environment
    ,----
    | <div id="org19c7f92" class="equation-container">
    | <span class="equation">
    | \begin{align}
    | 1 + 1 = 0
    | \end{align}
    | 
    | </span>
    | <span class="equation-label">
    | 1
    | </span>
    | </div>
    `----
  - Link:
    ,----
    | link to equation <a href="#org19c7f92">1</a>
    `----

The attached patch produces this on my test cases.

About the CSS caption:
> I'm not sure. Have you checked how captions in other parts of
> "ox-html.el"?

I looked at other structures:
- for figures, the caption is in a `figcaption' tag if HTML5 is used or
  in a paragraph, both under the figure,
- for tables, the caption is in a `caption' tag, at the top or bottom of
  the environment depending on `:html-table-caption-above',
- As far as I can tell, source blocks get no caption.

Since there does not appear to have a common convention, I think the
proposed output (see above with "equation-container", "equation" and
"equation-label" tags) would be fine, if nobody objects.  Some CSS puts
the label on the right side, as with LaTeX export or MathJax.  This only
applies to the non-MathJax modes.


> Do we need to rely on `org-latex-caption-above', which is LaTeX
> specific? We could instead extend `org-html-table-caption-above' to
> handle LaTeX environments, and rename it `org-html-caption-above'.

I think I misunderstood what the caption does in ox-latex.  Here, in the
MathJax case, just I need to insert the `\label' inside the latex
environment, e.g. `\begin{equation}\label{org21321}' similar to what
`org-latex-latex-environment' does.  The caption itself (the equation
number) is always on the right of the equation, regardless of the mode
(MathJax or other), so this is variable is not needed anymore.


I hope the patch looks better now.  I have a few remaining questions:

- The `org-html--is-math-environment' function relies on
  `org-latex-math-environments-re' from ox-latex for the numbering
  (numbering only equations, ignoring other environments).  Is it
  acceptable?
- In non-MathJax modes, I currently pre-process the latex environment to
  change equation environments to their * version,
  e.g. "\begin{equation}" -> "\begin{equation*}".  This is to prevent
  the latex environment from adding its own labeling to the rendered
  image.  This feels like a hack.  Is there a better way to achieve
  this?
- The `org-html--insert-latex-environment-label' (the function that
  inserts `\label' inside the environment also feels like a hack.  I
  originally wanted to re-use the equivalent latex code, but maybe this
  is simpler.  Do you think we can do better?
- In the image modes (e.g. dvipng), I removed the following comment: ";;
  Do not provide a caption or a name to be consistent with `mathjax'
  handling."  I am not sure what it means and whether I should be
  concerned about it.
- I think I have been with messing this file enough now that I should
  add tests.  I didn't see any tests for ox-latex or ox-html.  Is there
  a reason for that?


Please let me know if you have any comment.

Thanks,

thibault

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-html.el-Add-label-and-number-to-equations-in-HTML.patch --]
[-- Type: text/x-diff, Size: 9156 bytes --]

From 70f6e350615922007e08eec7deecdcdeadd0dc04 Mon Sep 17 00:00:00 2001
From: thibault <thibault.marin@gmx.com>
Date: Sun, 7 Jan 2018 03:04:39 -0600
Subject: [PATCH] ox-html.el: Add label and number to equations in HTML export

* lisp/ox-html.el (org-html--wrap-latex-environment): New function
wrapping the content of latex environments in HTML <div> tags, adding
"id" and equation number.
(org-html--is-math-environment): New function determining if a latex
environment is a math environment.
(org-html-latex-environment): Use `org-html--wrap-latex-environment' to
wrap equation in HTML container (non-MathJax modes).  Make latex
environment unnumbered when compiling equations to images.  Insert latex
label in environment in MathJax mode.
(org-html-link): Calculate equation number limiting counter to equation
environments.  Use eqref for link when using MathJax
(org-html--make-unlabelled-latex-environment): New function to convert
latex math environments to unnumbered versions (e.g. "equation" ->
"equation*").
(org-html--insert-latex-environment-label): Insert latex \label inside
environment.
---
 lisp/ox-html.el | 136 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 109 insertions(+), 27 deletions(-)

diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index a3a7c5f92..0bb3eff0e 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -430,6 +430,18 @@ for the JavaScript code in this tag.
   .footdef  { margin-bottom: 1em; }
   .figure { padding: 1em; }
   .figure p { text-align: center; }
+  .equation-container {
+    display: table;
+    text-align: center;
+    width: 100%;
+  }
+  .equation {
+    vertical-align: middle;
+  }
+  .equation-label {
+    display: table-cell;
+    text-align: right;
+  }
   .inlinetask {
     padding: 10px;
     border: 2px solid gray;
@@ -2823,26 +2835,84 @@ INFO is a plist containing export properties."
 			"Creating LaTeX Image..." nil processing-type)
       (buffer-string))))
 
+(defun org-html--wrap-latex-environment (contents info &optional caption label)
+  "Wrap CONTENTS string within appropriate environment for equations.
+INFO is a plist used as a communication channel.  When optional
+arguments CAPTION and LABEL are given, use them for caption and
+\"id\" attribute."
+  (format "\n<div%s class=\"equation-container\">\n%s%s\n</div>"
+          ;; ID.
+          (if (org-string-nw-p label) (format " id=\"%s\"" label) "")
+          ;; Contents.
+          (format "<span class=\"equation\">\n%s\n</span>" contents)
+          ;; Caption.
+          (if (not (org-string-nw-p caption)) ""
+            (format "\n<span class=\"equation-label\">\n%s\n</span>"
+                    caption))))
+
+(defun org-html--is-math-environment (element &optional info)
+  "Non-nil when ELEMENT is a LaTeX math environment.
+Math environments match the regular expression defined in
+`org-latex-math-environments-re'.
+INFO is a plist used as a communication channel.  This function
+is meant to be used as a predicate for `org-export-get-ordinal' or
+a value to `org-html-standalone-image-predicate'."
+  (string-match-p org-latex-math-environments-re
+                  (org-element-property :value element)))
+
+(defun org-html--make-unlabelled-latex-environment (latex-frag)
+  "Change environment in LATEX-FRAG to an unnumbered environment.
+For instance, change an 'equation' environment to 'equation*'."
+  (let* ((lines (split-string latex-frag "\n" t))
+         (last-idx (- (length lines) 1)))
+    (setf (nth 0 lines) (replace-regexp-in-string
+                         "^\\([\n\s]*\\)\\\\begin{\\([^*}]+\\)}"
+                         "\\1\\\\begin{\\2*}" (nth 0 lines)))
+    (setf (nth last-idx lines) (replace-regexp-in-string
+                                "\\\\end{\\([^*}]+\\)}\\([\n\s]*\\)$"
+                                "\\\\end{\\1*}\\2" (nth last-idx lines)))
+    (mapconcat #'identity lines "\n")))
+
+(defun org-html--insert-latex-environment-label (label latex-frag)
+  "Insert LABEL inside LATEX-FRAG."
+  (if (org-string-nw-p label)
+      (with-temp-buffer
+	(insert latex-frag)
+	(goto-char (point-min))
+	(forward-line)
+	(insert (format "\\label{%s}\n" label))
+	(buffer-string))
+    latex-frag))
+
 (defun org-html-latex-environment (latex-environment _contents info)
   "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
 CONTENTS is nil.  INFO is a plist holding contextual information."
   (let ((processing-type (plist-get info :with-latex))
 	(latex-frag (org-remove-indentation
 		     (org-element-property :value latex-environment)))
-	(attributes (org-export-read-attribute :attr_html latex-environment)))
+        (attributes (org-export-read-attribute :attr_html latex-environment))
+        (label (and (org-element-property :name latex-environment)
+                    (org-export-get-reference latex-environment info)))
+        (caption (number-to-string
+                  (org-export-get-ordinal
+                   latex-environment info nil
+                   #'org-html--is-math-environment))))
     (cond
      ((memq processing-type '(t mathjax))
-      (org-html-format-latex latex-frag 'mathjax info))
+      (org-html-format-latex
+       (org-html--insert-latex-environment-label label latex-frag)
+       'mathjax info))
      ((assq processing-type org-preview-latex-process-alist)
       (let ((formula-link
-	     (org-html-format-latex latex-frag processing-type info)))
-	(when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
-	  ;; Do not provide a caption or a name to be consistent with
-	  ;; `mathjax' handling.
-	  (org-html--wrap-image
-	   (org-html--format-image
-	    (match-string 1 formula-link) attributes info) info))))
-     (t latex-frag))))
+             (org-html-format-latex
+              (org-html--make-unlabelled-latex-environment latex-frag)
+              processing-type info)))
+        (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
+          (org-html--wrap-latex-environment
+           (org-html--format-image
+            (match-string 1 formula-link) attributes info)
+           info caption label))))
+     (t (org-html--wrap-latex-environment latex-frag info caption label)))))
 
 ;;;; Latex Fragment
 
@@ -3062,23 +3132,35 @@ 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))))))
+           (if (and destination
+                    (memq (plist-get info :with-latex) '(mathjax t))
+                    (eq 'latex-environment (org-element-type destination))
+                    (eq 'math (org-latex--environment-type destination)))
+               ;; Caption and labels are introduced within LaTeX environment. Use
+               ;; "eqref" macro to refer to those in the document.
+               (format "\\eqref{%s}"
+                       (org-export-get-reference destination info))
+             (let* ((ref (org-export-get-reference destination info))
+                    (org-html-standalone-image-predicate
+                     #'org-html--has-caption-p)
+                    (ordinal-counter-predicate
+                     (if (string= (car destination) "latex-environment")
+                         #'org-html--is-math-environment
+                       #'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 ordinal-counter-predicate))))
+                    (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")
-- 
2.15.1


  reply	other threads:[~2018-01-11  4:05 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87h8rtf3bo.fsf@dell-desktop.WORKGROUP \
    --to=thibault.marin@gmx.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=mail@nicolasgoaziou.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).