emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Jambunathan K <kjambunathan@gmail.com>
To: emacs-orgmode@gnu.org
Subject: [PATCH] org.el: Add support for LaTeX to MathML conversion
Date: Fri, 09 Sep 2011 01:27:57 +0530	[thread overview]
Message-ID: <81obyuolh6.fsf@gmail.com> (raw)
In-Reply-To: <814o0n3uzi.fsf@gmail.com> (Jambunathan K.'s message of "Thu, 08 Sep 2011 21:08:09 +0530")

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

> IMPORTANT: I am following this mail with a patch to org.el which will
> add support for LaTeX-to-MathML conversion using an external
> converter.

MathToWeb is available from

Your .emacs should look something like this.

 '(org-latex-to-mathml-convert-command "java -jar %j -unicode -force -df %o %I")
 '(org-latex-to-mathml-jar-file "~/tmp-odt/mathtoweb.jar"))

I am attaching odt files used with both dvipng and mathml options. The
latex-mathml.odt reports an error on one of the $$ $$ equations.

Note to reviewers: Can someone enhance the patch so that
`org-latex-src-embed-type can take all the various anchors that a latex
equation could use - inline, display-unnumbered, display-numbered, what

Note to the users:
1. You need to not only apply this patch but also pull from the repo for
   full support.
2. Currently there is NO support for numbered and displayed equations
   which go like this

   x = y             (1)
   y = z             (2)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org.el-Add-support-for-LaTeX-to-MathML-conversion.patch --]
[-- Type: text/x-patch, Size: 8309 bytes --]

From 762bffe1fc11d28502d6842c9b7d0049442ee2ef Mon Sep 17 00:00:00 2001
From: Jambunathan K <kjambunathan@gmail.com>
Date: Fri, 9 Sep 2011 00:14:59 +0530
Subject: [PATCH] org.el: Add support for LaTeX to MathML conversion

* lisp/org.el (org-latex-to-mathml-jar-file)
(org-latex-to-mathml-convert-command): New user-customizable
(org-format-latex-mathml-available-p, org-create-math-formula)
(org-format-latex-as-mathml): New functions.
(org-format-latex): Add a new local variable block-type that
notes the nature of the equation - inline or display.
Associate it's value to `org-latex-src-embed-type' property of
dvipng links.  Add mathml as new processing type.
 lisp/org.el |  159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 154 insertions(+), 5 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index d63b854..b907338 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -16507,11 +16507,11 @@ Some of the options can be changed using the variable
 	  (plist-get (org-infile-export-plist) :latex-header-extra))
 	 (cnt 0) txt hash link beg end re e checkdir
 	 executables-checked string
-	 m n block linkfile movefile ov)
+	 m n block-type block linkfile movefile ov)
     ;; Check the different regular expressions
     (while (setq e (pop re-list))
-      (setq m (car e) re (nth 1 e) n (nth 2 e)
-	    block (if (nth 3 e) "\n\n" ""))
+      (setq m (car e) re (nth 1 e) n (nth 2 e) block-type (nth 3 e)
+	    block (if block-type "\n\n" ""))
       (when (member m matchers)
 	(goto-char (point-min))
 	(while (re-search-forward re nil t)
@@ -16540,7 +16540,7 @@ Some of the options can be changed using the variable
 				'(org-protected t))))
 		(add-text-properties (match-beginning n) (match-end n)
 				     '(org-protected t))))
-	     ((or (eq processing-type 'dvipng) t)
+	     ((eq processing-type 'dvipng)
 	      ;; Process to an image
 	      (setq txt (match-string n)
 		    beg (match-beginning n) end (match-end n)
@@ -16596,7 +16596,156 @@ Some of the options can be changed using the variable
 		(insert (org-add-props link
 			    (list 'org-latex-src
-				   "\"" "" txt)))))))))))))
+				   "\"" "" txt)
+				  'org-latex-src-embed-type
+				  (if block-type 'paragraph 'character))))))
+	     ((eq processing-type 'mathml)
+	      ;; Process to MathML
+	      (unless executables-checked
+		(unless (save-match-data (org-format-latex-mathml-available-p))
+		  (error "LaTeX to MathML converter not configured"))
+		(setq executables-checked t))
+	      (setq txt (match-string n)
+		    beg (match-beginning n) end (match-end n)
+		    cnt (1+ cnt))
+	      (if msg (message msg cnt))
+	      (goto-char beg)
+	      (delete-region beg end)
+	      (insert (org-format-latex-as-mathml
+		       txt block-type prefix dir)))
+	     (t
+	      (error "Unknown conversion type %s for latex fragments"
+		     processing-type)))))))))
+(defcustom org-latex-to-mathml-jar-file nil
+  "Value of\"%j\" in `org-latex-to-mathml-convert-command'.
+Use this to specify additional executable file say a jar file.
+When using MathToWeb as the converter, specify the full-path to
+your mathtoweb.jar file."
+  :group 'org-latex
+  :type '(choice
+	  (const :tag "None" nil)
+	  (file :tag "JAR file" :must-match t)))
+(defcustom org-latex-to-mathml-convert-command nil
+  "Command to convert LaTeX fragments to MathML.
+Replace format-specifiers in the command as noted below and use
+`shell-command' to convert LaTeX to MathML.
+%j: 	Executable file in fully expanded form as specified by
+ 	`org-latex-to-mathml-jar-file'.
+%I:     Input LaTeX file in fully expanded form
+%o:     Output MathML file
+This command is used by `org-create-math-formula'.
+When using MathToWeb as the converter, set this to
+\"java -jar %j -unicode -force -df %o %I\"."
+  :group 'org-latex
+  :type '(choice
+	  (const :tag "None" nil)
+	  (string :tag "\nShell command")))
+(defun org-format-latex-mathml-available-p ()
+  "Return t if `org-latex-to-mathml-convert-command' is usable."
+  (save-match-data
+    (when (and (boundp 'org-latex-to-mathml-convert-command)
+	       org-latex-to-mathml-convert-command)
+      (let ((executable (car (split-string
+			      org-latex-to-mathml-convert-command))))
+	(when (executable-find executable)
+	  (if (string-match
+	       "%j" org-latex-to-mathml-convert-command)
+	      (file-readable-p org-latex-to-mathml-jar-file)
+	    t))))))
+(defun org-create-math-formula (latex-frag &optional mathml-file)
+  "Convert LATEX-FRAG to MathML and store it in MATHML-FILE.
+Use `org-latex-to-mathml-convert-command'.  If the conversion is
+sucessful, return the portion between \"<math...> </math>\"
+elements otherwise return nil.  When MATHML-FILE is specified,
+write the results in to that file.  When invoked as an
+interactive command, prompt for LATEX-FRAG, with initial value
+set to the current active region and echo the results for user
+  (interactive (list (let ((frag (when (region-active-p)
+				   (buffer-substring-no-properties
+				    (region-beginning) (region-end)))))
+		       (read-string "LaTeX Fragment: " frag nil frag))))
+  (unless latex-frag (error "Invalid latex-frag"))
+  (let* ((tmp-in-file (file-relative-name
+		       (make-temp-name (expand-file-name "ltxmathml-in"))))
+	 (ignore (write-region latex-frag nil tmp-in-file))
+	 (tmp-out-file (file-relative-name
+			(make-temp-name (expand-file-name  "ltxmathml-out"))))
+	 (cmd (format-spec
+	       org-latex-to-mathml-convert-command
+	       `((?j . ,(shell-quote-argument
+			 (expand-file-name org-latex-to-mathml-jar-file)))
+		 (?I . ,(shell-quote-argument tmp-in-file))
+		 (?o . ,(shell-quote-argument tmp-out-file)))))
+	 mathml shell-command-output)
+    (when (org-called-interactively-p 'any)
+      (unless (org-format-latex-mathml-available-p)
+	(error "LaTeX to MathML converter not configured")))
+    (message "Running %s" cmd)
+    (setq shell-command-output (shell-command-to-string cmd))
+    (setq mathml
+	  (when (file-readable-p tmp-out-file)
+	    (with-current-buffer (find-file-noselect tmp-out-file t)
+	      (goto-char (point-min))
+	      (when (re-search-forward
+		     (concat
+		      (regexp-quote
+		       "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">")
+		      "\\(.\\|\n\\)*"
+		      (regexp-quote "</math>")) nil t)
+		(prog1 (match-string 0) (kill-buffer))))))
+    (cond
+     (mathml
+      (setq mathml
+	    (concat "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" mathml))
+      (when mathml-file
+	(write-region mathml nil mathml-file))
+      (when (org-called-interactively-p 'any)
+	(message mathml)))
+     ((message "LaTeX to MathML conversion failed")
+      (message shell-command-output)))
+    (delete-file tmp-in-file)
+    (when (file-exists-p tmp-out-file)
+      (delete-file tmp-out-file))
+    mathml))
+(defun org-format-latex-as-mathml (latex-frag latex-frag-type
+					      prefix &optional dir)
+  "Use `org-create-math-formula' but check local cache first."
+  (let* ((absprefix (expand-file-name prefix dir))
+	 (print-length nil) (print-level nil)
+	 (formula-id (concat
+		      "formula-"
+		      (sha1
+		       (prin1-to-string
+			(list latex-frag
+			      org-latex-to-mathml-convert-command)))))
+	 (formula-cache (format "%s-%s.mathml" absprefix formula-id))
+	 (formula-cache-dir (file-name-directory formula-cache)))
+    (unless (file-directory-p formula-cache-dir)
+      (make-directory formula-cache-dir t))
+    (unless (file-exists-p formula-cache)
+      (org-create-math-formula latex-frag formula-cache))
+    (if (file-exists-p formula-cache)
+	;; Successful conversion.  Return the link to MathML file.
+	(org-add-props
+	    (format  "[[file:%s]]" (file-relative-name formula-cache dir))
+	    (list 'org-latex-src (replace-regexp-in-string "\"" "" latex-frag)
+		  'org-latex-src-embed-type (if latex-frag-type
+						'paragraph 'character)))
+      ;; Failed conversion.  Return the LaTeX fragment verbatim
+      (add-text-properties
+       0 (1- (length latex-frag)) '(org-protected t) latex-frag)
+      latex-frag)))
 ;; This function borrows from Ganesh Swami's latex2png.el
 (defun org-create-formula-image (string tofile options buffer)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: latex-mathml.org --]
[-- Type: text/x-org, Size: 795 bytes --]

#+TITLE:     latex-mathml.org
#+AUTHOR:    Jambunathan K
#+EMAIL:     kjambunathan@gmail.com
#+DATE:      2011-09-09 Fri
#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS:   TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc


* LaTeX Fragments

** LaTeX Fragment1
#   See org-format-latex-options

    There is a equation down below.

     e = \frac{1}{2}mv^2

** LaTeX Fragment2

#+CAPTION: Radicals
#+LABEL: Equation:1

   If $a^2=b$ and \( b=2 \), then the solution must be either $$
   a=+\sqrt{2} $$ or \[ a=-\sqrt{2} \].

[-- Attachment #4: latex-mathml.odt --]
[-- Type: application/vnd.oasis.opendocument.text, Size: 11436 bytes --]

[-- Attachment #5: latex-dvipng.odt --]
[-- Type: application/vnd.oasis.opendocument.text, Size: 12342 bytes --]

  reply	other threads:[~2011-09-08 19:58 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-08 15:38 [odt][ANN] Embed links to mathml files as ODF formula Jambunathan K
2011-09-08 19:57 ` Jambunathan K [this message]
2011-09-17 19:35   ` [PATCH] org.el: Add support for LaTeX to MathML conversion Jambunathan K

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:

  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=81obyuolh6.fsf@gmail.com \
    --to=kjambunathan@gmail.com \
    --cc=emacs-orgmode@gnu.org \


* 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


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).