From 762bffe1fc11d28502d6842c9b7d0049442ee2ef Mon Sep 17 00:00:00 2001 From: Jambunathan K 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 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. --- 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 (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 \" \" +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 + "") + "\\(.\\|\n\\)*" + (regexp-quote "")) nil t) + (prog1 (match-string 0) (kill-buffer)))))) + (cond + (mathml + (setq mathml + (concat "\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) -- 1.7.2.3