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
variables.
(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.

Patch by Jambunathan.
This commit is contained in:
Carsten Dominik 2011-10-16 10:52:32 +02:00
parent 05ead2de3b
commit 4f2f222c00
1 changed files with 154 additions and 5 deletions

View File

@ -16532,11 +16532,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)
@ -16565,7 +16565,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)
@ -16621,7 +16621,156 @@ Some of the options can be changed using the variable
(insert (org-add-props link
(list 'org-latex-src
(replace-regexp-in-string
"\"" "" 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
inspection."
(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)