compatibility fixes for fda70440f4
[org-mode.git] / contrib / lisp / org-static-mathjax.el
blobac13ee2dd1ebb82e0a312242bf511e59526b6e0e
1 ;;; org-static-mathjax.el --- Muse-like tags in Org-mode
2 ;;
3 ;; Author: Jan Böker <jan dot boecker at jboecker dot de>
5 ;; This file is part of GNU Emacs.
7 ;; GNU Emacs is free software: you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; GNU Emacs is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Commentary:
21 ;; This elisp code integrates Static MathJax into the
22 ;; HTML export process of Org-mode.
24 ;; The supporting files for this package are in contrib/scripts/staticmathjax
25 ;; Please read the README.org file in that directory for more information.
27 ;; To use it, evaluate it on startup, add the following to your .emacs:
29 ;; (require 'org-static-mathjax)
31 ;; You will then have to customize the following two variables:
32 ;; - org-static-mathjax-app-ini-path
33 ;; - org-static-mathjax-local-mathjax-path
35 ;; If xulrunner is not in your $PATH, you will also need to customize
36 ;; org-static-mathjax-xulrunner-path.
38 ;; If everything is setup correctly, you can trigger Static MathJax on
39 ;; export to HTML by adding the following line to your Org file:
40 ;; #+StaticMathJax: embed-fonts:nil output-file-name:"embedded-math.html"
42 ;; You can omit either argument.
43 ;; embed-fonts defaults to nil. If you do not specify output-file-name,
44 ;; the exported file is overwritten with the static version.
46 ;; If embed-fonts is non-nil, the fonts are embedded directly into the
47 ;; output file using data: URIs.
49 ;; output-file-name specifies the file name of the static version. You
50 ;; can use any arbitrary lisp form here, for example:
51 ;; output-file-name:(concat (file-name-sans-extension buffer-file-name) "-static.html")
53 ;; The StaticMathJax XULRunner application expects a UTF-8 encoded
54 ;; input file. If the static version displays random characters instead
55 ;; of your math, add the following line at the top of your Org file:
56 ;; -*- coding: utf-8; -*-
58 ;;; Code:
60 (defcustom org-static-mathjax-app-ini-path
61 (or (expand-file-name
62 "../scripts/staticmatchjax/application.ini"
63 (file-name-directory (or load-file-name buffer-file-name)))
64 "")
65 "Path to \"application.ini\" of the Static MathJax XULRunner application.
66 If you have extracted StaticMathJax to e.g. ~/.local/staticmathjax, set
67 this to ~/.local/staticmathjax/application.ini"
68 :type 'string)
70 (defcustom org-static-mathjax-xulrunner-path
71 "xulrunner"
72 "Path to your xulrunner binary"
73 :type 'string)
75 (defcustom org-static-mathjax-local-mathjax-path
77 "Extract the MathJax zip file somewhere on your local
78 hard drive and specify the path here.
80 The directory has to be writeable, as org-static-mathjax
81 creates a temporary file there during export."
82 :type 'string)
84 (defvar org-static-mathjax-debug
85 nil
86 "If non-nil, org-static-mathjax will print some debug messages")
88 (defun org-static-mathjax-hook-installer ()
89 "Installs org-static-mathjax-process in after-save-hook.
91 Sets the following buffer-local variables for org-static-mathjax-process to pick up:
92 org-static-mathjax-mathjax-path: The path to MathJax.js as used by Org HTML export
93 org-static-mathjax-options: The string given with #+STATICMATHJAX: in the file"
94 (let ((static-mathjax-option-string (plist-get opt-plist :static-mathjax)))
95 (if static-mathjax-option-string
96 (progn (set (make-local-variable 'org-static-mathjax-options) static-mathjax-option-string)
97 (set (make-local-variable 'org-static-mathjax-mathjax-path)
98 (nth 1 (assq 'path org-export-html-mathjax-options)))
99 (let ((mathjax-options (plist-get opt-plist :mathjax)))
100 (if mathjax-options
101 (if (string-match "\\<path:" mathjax-options)
102 (set 'org-static-mathjax-mathjax-path
103 (car (read-from-string
104 (substring mathjax-options (match-end 0))))))))
105 (add-hook 'after-save-hook
106 'org-static-mathjax-process
107 nil t)))))
110 (defun org-static-mathjax-process ()
111 (save-excursion
112 ; some sanity checking
113 (if (or (string= org-static-mathjax-app-ini-path "")
114 (not (file-exists-p org-static-mathjax-app-ini-path)))
115 (error "Static MathJax: You must customize org-static-mathjax-app-ini-path!"))
116 (if (or (string= org-static-mathjax-local-mathjax-path "")
117 (not (file-exists-p org-static-mathjax-local-mathjax-path)))
118 (error "Static MathJax: You must customize org-static-mathjax-local-mathjax-path!"))
120 ; define variables
121 (let* ((options org-static-mathjax-options)
122 (output-file-name buffer-file-name)
123 (input-file-name (let ((temporary-file-directory (file-name-directory org-static-mathjax-local-mathjax-path)))
124 (make-temp-file "org-static-mathjax-" nil ".html")))
125 (html-code (buffer-string))
126 (mathjax-oldpath (concat "src=\"" org-static-mathjax-mathjax-path))
127 (mathjax-newpath (concat "src=\"" org-static-mathjax-local-mathjax-path))
128 embed-fonts)
129 ; read file-local options
130 (mapc
131 (lambda (symbol)
132 (if (string-match (concat "\\<" (symbol-name symbol) ":") options)
133 (set symbol (eval (car (read-from-string
134 (substring options (match-end 0))))))))
135 '(embed-fonts output-file-name))
137 ; debug
138 (when org-static-mathjax-debug
139 (message "output file name, embed-fonts")
140 (print output-file-name)
141 (print embed-fonts))
143 ; open (temporary) input file, copy contents there, replace MathJax path with local installation
144 (with-temp-buffer
145 (insert html-code)
146 (goto-char 1)
147 (replace-regexp mathjax-oldpath mathjax-newpath)
148 (write-file input-file-name))
150 ; prepare argument list for call-process
151 (let ((call-process-args (list org-static-mathjax-xulrunner-path
152 nil nil nil
153 org-static-mathjax-app-ini-path
154 input-file-name
155 output-file-name)))
156 ; if fonts are embedded, just append the --embed-fonts flag
157 (if embed-fonts
158 (add-to-list 'call-process-args "--embed-fonts" t))
159 ; if fonts are not embedded, the XULRunner app must replace all references
160 ; to the font files with the real location (Firefox inserts file:// URLs there,
161 ; because we are using a local MathJax installation here)
162 (if (not embed-fonts)
163 (progn
164 (add-to-list 'call-process-args "--final-mathjax-url" t)
165 (add-to-list 'call-process-args
166 (file-name-directory org-static-mathjax-mathjax-path)
167 t)))
169 ; debug
170 (when org-static-mathjax-debug
171 (print call-process-args))
172 ; call it
173 (apply 'call-process call-process-args)
174 ; delete our temporary input file
175 (kill-buffer)
176 (delete-file input-file-name)
177 (let ((backup-file (concat input-file-name "~")))
178 (if (file-exists-p backup-file)
179 (delete-file backup-file)))))))
181 (add-to-list 'org-export-inbuffer-options-extra
182 '("STATICMATHJAX" :static-mathjax))
184 (add-hook 'org-export-html-final-hook 'org-static-mathjax-hook-installer)
187 (provide 'org-static-mathjax)