From 999078b0bfa409138ec9aca3265e3d1ad787184b Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Fri, 13 Aug 2010 14:22:16 +0200 Subject: [PATCH] Implement MathJax support * lisp/org-exp.el (org-export-with-LaTeX-fragments): New default t, which now means to use MathJax processing for HTML. Also allow new value `dvipng' to force the old image processing. (org-infile-export-plist): Parse for MATHJAX setup line. * lisp/org-html.el (org-export-html-mathjax-options): New option. (org-export-html-mathjax-config): New function. (org-export-html-mathjax-template): New option. (org-export-html-preprocess): Call the LaTeX snippet processor with an additional argument to declare special ways of processing. (org-export-as-html): Bind the dynamical variable `org-export-have-math'. Insert the MathJax script template when it is needed by the document. * lisp/org.el (org-preview-latex-fragment): Call `org-format-latex' with the additional processing argument. (org-export-have-math): New variable, for dynamic scoping. (org-format-latex): Implement specific ways of processing. New function argument for processing type. (org-org-menu): Remove the entry to configure LaTeX snippet processing. MathJax is now the default for displaying math in a browser. --- doc/org.texi | 144 +++++++++++++++++++++++++++++++---------------- lisp/org-exp.el | 37 +++++++++--- lisp/org-html.el | 127 ++++++++++++++++++++++++++++++++++++++++- lisp/org.el | 39 ++++++++----- 4 files changed, 275 insertions(+), 72 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index ac52c70de..942da00e6 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -363,6 +363,7 @@ HTML export * Links in HTML export:: How links will be interpreted and formatted * Tables in HTML export:: How to modify the formatting of tables * Images in HTML export:: How to insert figures into HTML output +* Math formatting in HTML export:: Beautiful math also on the web * Text areas in HTML export:: An alternative way to show an example * CSS support:: Changing the appearance of the output * JavaScript support:: Info and Folding in a web browser @@ -439,12 +440,17 @@ Using header arguments Specific header arguments * var:: Pass arguments to code blocks -* results:: Specify the type of results and how they will be collected and handled +* results:: Specify the type of results and how they will + be collected and handled * file:: Specify a path for file output -* dir:: Specify the default directory for code block execution +* dir:: Specify the default (possibly remote) + directory for code block execution * exports:: Export code and/or results * tangle:: Toggle tangling and specify file name -* no-expand:: Turn off variable assignment and noweb expansion during tangling +* comments:: Toggle insertion of comments in tangled + code files +* no-expand:: Turn off variable assignment and noweb + expansion during tangling * session:: Preserve the state of code evaluation * noweb:: Toggle expansion of noweb references * cache:: Avoid re-evaluating unchanged code blocks @@ -452,6 +458,7 @@ Specific header arguments * colnames:: Handle column names in tables * rownames:: Handle row names in tables * shebang:: Make tangled files executable +* eval:: Limit evaluation of specific code blocks Miscellaneous @@ -8818,12 +8825,9 @@ is a macro system based on Donald E. Knuth's @TeX{} system. Many of the features described here as ``La@TeX{}'' are really from @TeX{}, but for simplicity I am blurring this distinction.} is widely used to typeset scientific documents. Org-mode supports embedding La@TeX{} code into its -files, because many academics are used to reading La@TeX{} source code, and -because it can be readily processed into images for HTML production. - -It is not necessary to mark La@TeX{} macros and code in any special way. -If you observe a few conventions, Org-mode knows how to find it and what -to do with it. +files, because many academics are used to writing and reading La@TeX{} source +code, and because it can be readily processed to produce pretty output for a +number of export backends. @menu * Special symbols:: Greek letters and other symbols @@ -8867,7 +8871,7 @@ La@TeX{}, see the variable @code{org-entities} for the complete list. @samp{...} are all converted into special commands creating hyphens of different lengths or a compact set of dots. -If you would like to see entities displayed as utf8 characters, use the +If you would like to see entities displayed as UTF8 characters, use the following command@footnote{You can turn this on by default by setting the variable @code{org-pretty-entities}, or on a per-file base with the @code{#+STARTUP} option @code{entitiespretty}.}: @@ -8908,6 +8912,9 @@ convention, or use, on a per-file basis: #+OPTIONS: ^:@{@} @end example +@noindent With this setting, @samp{a_b} will not be interpreted as a +subscript, but @samp{a_@{b@}} will. + @table @kbd @kindex C-c C-x \ @item C-c C-x \ @@ -8920,31 +8927,31 @@ format sub- and superscripts in a WYSIWYM way. @cindex La@TeX{} fragments @vindex org-format-latex-header -With symbols, sub- and superscripts, HTML is pretty much at its end when -it comes to representing mathematical formulas@footnote{Yes, there is -MathML, but that is not yet fully supported by many browsers, and there -is no decent converter for turning La@TeX{} or ASCII representations of -formulas into MathML. So for the time being, converting formulas into -images seems the way to go.}. More complex expressions need a dedicated -formula processor. To this end, Org-mode can contain arbitrary La@TeX{} -fragments. It provides commands to preview the typeset result of these -fragments, and upon export to HTML, all fragments will be converted to -images and inlined into the HTML document@footnote{The La@TeX{} export -will not use images for displaying La@TeX{} fragments but include these -fragments directly into the La@TeX{} code.}. For this to work you -need to be on a system with a working La@TeX{} installation. You also -need the @file{dvipng} program, available at -@url{http://sourceforge.net/projects/dvipng/}. The La@TeX{} header that -will be used when processing a fragment can be configured with the -variable @code{org-format-latex-header}. +Going beyond symbols and sub- and superscripts, a full formula language is +needed. Org-mode can contain La@TeX{} math fragments, and it supports ways +to process these for several export backends. When exporting to La@TeX{}, +the code is obviously left as it is. When exporting to HTML, Org invokes the +@uref{http://www.mathjax.org, MathJax library} (@pxref{Math formatting in +HTML export}) to process and display the math@footnote{If you plan to use +this regularly or on pages with significant page views, you should install +@file{MathJax} on your own server in order to limit the load of our server.}. +Finally, it can also process the mathematical expressions into +images@footnote{For this to work you need to be on a system with a working +La@TeX{} installation. You also need the @file{dvipng} program, available at +@url{http://sourceforge.net/projects/dvipng/}. The La@TeX{} header that will +be used when processing a fragment can be configured with the variable +@code{org-format-latex-header}.} that can be displayed in a browser or in +DocBook documents. La@TeX{} fragments don't need any special marking at all. The following snippets will be identified as La@TeX{} source code: @itemize @bullet @item -Environments of any kind. The only requirement is that the -@code{\begin} statement appears on a new line, preceded by only -whitespace. +Environments of any kind@footnote{When @file{MathJax} is used, only the +environment recognized by @file{MathJax} will be processed. When dvipng is +used to create images, any La@TeX{} environments will be handled.}. The only +requirement is that the @code{\begin} statement appears on a new line, +preceded by only whitespace. @item Text within the usual La@TeX{} math delimiters. To avoid conflicts with currency specifications, single @samp{$} characters are only recognized as @@ -8972,12 +8979,26 @@ If you need any of the delimiter ASCII sequences for other purposes, you can configure the option @code{org-format-latex-options} to deselect the ones you do not wish to have interpreted by the La@TeX{} converter. +@vindex org-export-with-LaTeX-fragments +LaTeX processing can be configured with the variable +@code{org-export-with-LaTeX-fragments}. The default setting is @code{t} +which means @file{MathJax} for HTML, and no processing for DocBook, ASCII and +LaTeX backends. You can also set this variable on a per-file basis using one +of these lines: + +@example +#+OPTIONS: LaTeX:t @r{Do the right thing automatically (MathJax)} +#+OPTIONS: LaTeX:dvipng @r{Force using dvipng images} +#+OPTIONS: LaTeX:nil @r{Do not process La@TeX{} fragments at all} +#+OPTIONS: LaTeX:verbatim @r{Verbatim export, for jsMath or so} +@end example + @node Previewing LaTeX fragments, CDLaTeX mode, LaTeX fragments, Embedded LaTeX @subsection Previewing LaTeX fragments @cindex LaTeX fragments, preview -La@TeX{} fragments can be processed to produce preview images of the -typeset expressions: +If you have @file{dvipng} installed, La@TeX{} fragments can be processed to +produce preview images of the typeset expressions: @table @kbd @kindex C-c C-x C-l @@ -8999,14 +9020,6 @@ some aspects of the preview. In particular, the @code{:scale} (and for HTML export, @code{:html-scale}) property can be used to adjust the size of the preview images. -During HTML export (@pxref{HTML export}), all La@TeX{} fragments are -converted into images and inlined into the document if the following -setting is active: - -@lisp -(setq org-export-with-LaTeX-fragments t) -@end lisp - @node CDLaTeX mode, , Previewing LaTeX fragments, Embedded LaTeX @subsection Using CDLa@TeX{} to enter math @cindex CDLa@TeX{} @@ -9224,7 +9237,7 @@ tags: @r{turn on/off inclusion of tags, may also be @code{not-in-toc}} <: @r{turn on/off inclusion of any time/date stamps like DEADLINES} *: @r{turn on/off emphasized text (bold, italic, underlined)} TeX: @r{turn on/off simple @TeX{} macros in plain text} -LaTeX: @r{turn on/off La@TeX{} fragments} +LaTeX: @r{configure export of La@TeX{} fragments. Default @code{auto}} skip: @r{turn on/off skipping the text before the first heading} author: @r{turn on/off inclusion of author name/email into exported file} email: @r{turn on/off inclusion of author email into exported file} @@ -9357,6 +9370,7 @@ language, but with additional support for tables. * Links in HTML export:: How links will be interpreted and formatted * Tables in HTML export:: How to modify the formatting of tables * Images in HTML export:: How to insert figures into HTML output +* Math formatting in HTML export:: Beautiful math also on the web * Text areas in HTML export:: An alternative way to show an example * CSS support:: Changing the appearance of the output * JavaScript support:: Info and Folding in a web browser @@ -9492,7 +9506,7 @@ tables, place something like the following before the table: #+ATTR_HTML: border="2" rules="all" frame="all" @end example -@node Images in HTML export, Text areas in HTML export, Tables in HTML export, HTML export +@node Images in HTML export, Math formatting in HTML export, Tables in HTML export, HTML export @subsection Images in HTML export @cindex images, inline in HTML @@ -9529,7 +9543,41 @@ support text viewers and accessibility, and align it to the right. @noindent and you could use @code{http} addresses just as well. -@node Text areas in HTML export, CSS support, Images in HTML export, HTML export +@node Math formatting in HTML export, Text areas in HTML export, Images in HTML export, HTML export +@subsection Math formatting in HTML export +@cindex MathJax +@cindex dvipng + +La@TeX{} math snippets (@pxref{LaTeX fragments}) can be displayed in two +different ways on HTML pages. The default is to use the +@uref{http://www.mathjax.org, MathJax system} which should work out of the +box with Org mode installation because @code{http://orgmode.org} serves +@file{MathJax} for Org-mode users for small applications and for testing +purposes. @b{If you plan to use this regularly or on pages with significant +page views, you should install MathJax on your own server in order to limit +the load of our server.} To configure @file{MathJax}, use the variable +@code{org-export-html-mathjax-options} or insert something like the following +into the buffer: + +@example +#+MATHJAX: align:"left" mathml:t path:"/MathJax/MathJax.js" +@end example + +@noindent See the docstring of the variable +@code{org-export-html-mathjax-options} for the meaning of the parameters in +this line. + +If you prefer, you can also request that La@TeX{} are processed into small +images that will be inserted into the browser page. Before the availability +of MathJax, this was the default method for Org files. This method requires +that the @file{dvipng} program is available on your system. You can still +get this processing with + +@example +#+OPTIONS: LaTeX:dvipng +@end example + +@node Text areas in HTML export, CSS support, Math formatting in HTML export, HTML export @subsection Text areas in HTML export @cindex text areas, in HTML @@ -11451,14 +11499,14 @@ The following header arguments are defined: * results:: Specify the type of results and how they will be collected and handled * file:: Specify a path for file output -* dir:: Specify the default (possibly remote) +* dir:: Specify the default (possibly remote) directory for code block execution * exports:: Export code and/or results * tangle:: Toggle tangling and specify file name +* comments:: Toggle insertion of comments in tangled + code files * no-expand:: Turn off variable assignment and noweb expansion during tangling -* comments:: Toggle insertion of comments in tangled - code files * session:: Preserve the state of code evaluation * noweb:: Toggle expansion of noweb references * cache:: Avoid re-evaluating unchanged code blocks @@ -11466,7 +11514,7 @@ The following header arguments are defined: * colnames:: Handle column names in tables * rownames:: Handle row names in tables * shebang:: Make tangled files executable -* eval:: Limit evaluation of specific code blocks +* eval:: Limit evaluation of specific code blocks @end menu @node var, results, Specific header arguments, Specific header arguments @@ -12094,7 +12142,7 @@ Setting the @code{:shebang} header argument to a string value first line of any tangled file holding the code block, and the file permissions of the tangled file are set to make it executable. -@node eval, , shebang, Specific header arguments +@node eval, , shebang, Specific header arguments @subsubsection @code{:eval} The @code{:eval} header argument can be used to limit the evaluation of specific code blocks. @code{:eval} accepts two arguments ``never'' and diff --git a/lisp/org-exp.el b/lisp/org-exp.el index cd0a1050a..c52f38f57 100644 --- a/lisp/org-exp.el +++ b/lisp/org-exp.el @@ -471,20 +471,34 @@ This option can also be set with the +OPTIONS line, e.g. \"TeX:nil\"." :group 'org-export-latex :type 'boolean) -(defcustom org-export-with-LaTeX-fragments nil - "Non-nil means convert LaTeX fragments to images when exporting to HTML. -When set, the exporter will find LaTeX environments if the \\begin line is -the first non-white thing on a line. It will also find the math delimiters -like $a=b$ and \\( a=b \\) for inline math, $$a=b$$ and \\[ a=b \\] for -display math. +(defcustom org-export-with-LaTeX-fragments t + "Non-nil means process LaTeX math fragments for HTML display. +When set, the exporter will find and process LaTeX environments if the +\\begin line is the first non-white thing on a line. It will also find +and process the math delimiters like $a=b$ and \\( a=b \\) for inline math, +$$a=b$$ and \\[ a=b \\] for display math. -This option can also be set with the +OPTIONS line, e.g. \"LaTeX:t\". +This option can also be set with the +OPTIONS line, e.g. \"LaTeX:mathjax\". + +Allowed values are: + +nil Don't do anything. +verbatim Keep eveything in verbatim +dvipng Process the LaTeX fragments to images. + This will also include processing of non-math environments. +t Do MathJax preprocessing if there is at least on math snippet, + and arrange for MathJax.js to be loaded. The default is nil, because this option needs the `dvipng' program which is not available on all systems." :group 'org-export-translation :group 'org-export-latex - :type 'boolean) + :type '(choice + (const :tag "Do not process math in any way" nil) + (const :tag "Obsolete, use dvipng setting" t) + (const :tag "Use dvipng to make images" dvipng) + (const :tag "Use MathJax to display math" mathjax) + (const :tag "Leave math verbatim" verbatim))) (defcustom org-export-with-fixed-width t "Non-nil means lines starting with \":\" will be in fixed width font. @@ -675,12 +689,13 @@ modified) list.") (let ((re (org-make-options-regexp (append '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE" + "MATHJAX" "LINK_UP" "LINK_HOME" "SETUPFILE" "STYLE" "LATEX_HEADER" "LATEX_CLASS" "EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS" "KEYWORDS" "DESCRIPTION" "MACRO" "BIND" "XSLT") (mapcar 'car org-export-inbuffer-options-extra)))) - p key val text options a pr style + p key val text options mathjax a pr style latex-header latex-class macros letbind ext-setup-or-nil setup-contents (start 0)) (while (or (and ext-setup-or-nil @@ -712,6 +727,8 @@ modified) list.") (setq text (if text (concat text "\n" val) val))) ((string-equal key "OPTIONS") (setq options (concat val " " options))) + ((string-equal key "MATHJAX") + (setq mathjax (concat val " " mathjax))) ((string-equal key "BIND") (push (read (concat "(" val ")")) letbind)) ((string-equal key "XSLT") @@ -748,6 +765,8 @@ modified) list.") (setq p (plist-put p :latex-class latex-class))) (when options (setq p (org-export-add-options-to-plist p options))) + (when mathjax + (setq p (plist-put p :mathjax mathjax))) ;; Add macro definitions (setq p (plist-put p :macro-date "(eval (format-time-string \"$1\"))")) (setq p (plist-put p :macro-time "(eval (format-time-string \"$1\"))")) diff --git a/lisp/org-html.el b/lisp/org-html.el index a12141f44..450a9de9d 100644 --- a/lisp/org-html.el +++ b/lisp/org-html.el @@ -209,6 +209,112 @@ settings with tags." ;;;###autoload (put 'org-export-html-style-extra 'safe-local-variable 'stringp) +(defcustom org-export-html-mathjax-options + '((path "http://orgmode.org/mathjax/MathJax.js") + (scale "100") + (align "center") + (indent "2em") + (mathml nil)) + "Options for MathJax setup. + +path The path where to find MathJax +scale Scaling for the HTML-CSS backend, usually between 100 and 133 +align How to align display math: left, center, or right +indent If align is not center, how far from the left/right side? +mathml Should a MathML player be used if available? + This is faster and reduces bandwidth use, but currently + sometimes has lower spacing quality. Therefore, the default is + nil. When browsers get better, this switch can be flipped. + +You can also customize this for each buffer, using something like + +#+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\"" + :group 'org-export-html + :type '(list :greedy t + (list :tag "path (the path from where to load MathJax.js)" + (const :format " " path) (string)) + (list :tag "scale (scaling for the displayed math)" + (const :format " " scale) (string)) + (list :tag "align (alignment of displayed equations)" + (const :format " " align) (string)) + (list :tag "indent (indentation with left or right alignment)" + (const :format " " indent) (string)) + (list :tag "mathml (should MathML display be used is possible)" + (const :format " " mathml) (boolean)))) + +(defun org-export-html-mathjax-config (template options in-buffer) + "Insert the user setup into the matchjax template." + (let (name val (yes " ") (no "// ") x) + (mapc + (lambda (e) + (setq name (car e) val (nth 1 e)) + (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer) + (setq val (car (read-from-string + (substring in-buffer (match-end 0)))))) + (if (not (stringp val)) (setq val (format "%s" val))) + (if (string-match (concat "%" (upcase (symbol-name name))) template) + (setq template (replace-match val t t template)))) + options) + (setq val (nth 1 (assq 'mathml options))) + (if (string-match (concat "\\ + +" + "The MathJax setup for XHTML files." + :group 'org-export-html + :type 'string) + (defcustom org-export-html-tag-class-prefix "" "Prefix to class names for TODO keywords. Each tag gets a class given by the tag itself, with this prefix. @@ -439,7 +545,13 @@ This may also be a function, building and inserting the postamble.") (file-name-nondirectory org-current-export-file))) org-current-export-dir nil "Creating LaTeX image %s" - nil nil (eq (plist-get parameters :LaTeX-fragments) 'verbatim))) + nil nil + (cond + ((eq (plist-get parameters :LaTeX-fragments) 'verbatim) 'verbatim) + ((eq (plist-get parameters :LaTeX-fragments) 'mathjax ) 'mathjax) + ((eq (plist-get parameters :LaTeX-fragments) t ) 'mathjax) + ((eq (plist-get parameters :LaTeX-fragments) 'dvipng ) 'dvipng) + (t nil)))) (goto-char (point-min)) (let (label l1) (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t) @@ -812,6 +924,7 @@ PUB-DIR is set, use this as the publishing directory." (buffer-substring (if region-p (region-beginning) (point-min)) (if region-p (region-end) (point-max)))) + (org-export-have-math nil) (lines (org-split-string (org-export-preprocess-string @@ -835,6 +948,16 @@ PUB-DIR is set, use this as the publishing directory." :LaTeX-fragments (plist-get opt-plist :LaTeX-fragments)) "[\r\n]")) + (mathjax + (if (or (eq (plist-get opt-plist :LaTeX-fragments) 'mathjax) + (and org-export-have-math + (eq (plist-get opt-plist :LaTeX-fragments) t))) + + (org-export-html-mathjax-config + org-export-html-mathjax-template + org-export-html-mathjax-options + (or (plist-get opt-plist :mathjax) "")) + "")) table-open type table-buffer table-orig-buffer ind item-type starter didclose @@ -904,6 +1027,7 @@ lang=\"%s\" xml:lang=\"%s\"> %s +%s
@@ -922,6 +1046,7 @@ lang=\"%s\" xml:lang=\"%s\"> (or charset "iso-8859-1") date author description keywords style + mathjax (if (or link-up link-home) (concat (format org-export-html-home/up-format diff --git a/lisp/org.el b/lisp/org.el index 31d241104..a05f2bfcc 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -15880,7 +15880,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (concat "ltxpng/" (file-name-sans-extension (file-name-nondirectory buffer-file-name))) - default-directory 'overlays msg at 'forbuffer) + default-directory 'overlays msg at 'forbuffer 'dvipng) (message msg "done. Use `C-c C-c' to remove images."))))) (defvar org-latex-regexps @@ -15894,8 +15894,9 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." ("$$" "\\$\\$[^\000]*?\\$\\$" 0 nil)) "Regular expressions for matching embedded LaTeX.") +(defvar org-export-have-math nil) ;; dynamic scoping (defun org-format-latex (prefix &optional dir overlays msg at - forbuffer protect-only) + forbuffer processing-type) "Replace LaTeX fragments with links to an image, and produce images. Some of the options can be changed using the variable `org-format-latex-options'." @@ -15909,7 +15910,7 @@ Some of the options can be changed using the variable (org-format-latex-header-extra (plist-get (org-infile-export-plist) :latex-header-extra)) (cnt 0) txt hash link beg end re e checkdir - executables-checked + executables-checked string m n block linkfile movefile ov) ;; Check the different regular expressions (while (setq e (pop re-list)) @@ -15925,9 +15926,26 @@ Some of the options can be changed using the variable (not (eq (get-char-property (match-beginning n) 'org-overlay-type) 'org-latex-overlay)))) - (if protect-only + (setq org-export-have-math t) + (cond + ((eq processing-type 'verbatim) + ;; Leave the text verbatim, just protect it + (add-text-properties (match-beginning n) (match-end n) + '(org-protected t))) + ((eq processing-type 'mathjax) + ;; Prepare for MathJax processing + (setq string (match-string n)) + (if (equal m "$") + (save-excursion + (delete-region (match-beginning n) (match-end n)) + (goto-char (match-beginning n)) + (insert (org-add-props (concat "\\(" (substring string 1 -1) + "\\)") + '(org-protected t)))) (add-text-properties (match-beginning n) (match-end n) - '(org-protected t)) + '(org-protected t)))) + ((or (eq processing-type 'dvipng) t) + ;; Process to an image (setq txt (match-string n) beg (match-beginning n) end (match-end n) cnt (1+ cnt)) @@ -15981,7 +15999,8 @@ Some of the options can be changed using the variable (delete-region beg end) (insert (org-add-props link (list 'org-latex-src - (replace-regexp-in-string "\"" "" txt)))))))))))) + (replace-regexp-in-string + "\"" "" txt))))))))))))) ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image (string tofile options buffer) @@ -17650,14 +17669,6 @@ See the individual commands for more information." (org-inside-LaTeX-fragment-p)] ["Insert citation" org-reftex-citation t] "--" - ["Export LaTeX fragments as images" - (if (featurep 'org-exp) - (setq org-export-with-LaTeX-fragments - (not org-export-with-LaTeX-fragments)) - (require 'org-exp)) - :style toggle :selected (and (boundp 'org-export-with-LaTeX-fragments) - org-export-with-LaTeX-fragments)] - "--" ["Template for BEAMER" org-insert-beamer-options-template t]) "--" ("MobileOrg"