|
@@ -0,0 +1,171 @@
|
|
|
+;;; org-static-mathjax.el --- Muse-like tags in Org-mode
|
|
|
+;;
|
|
|
+;; Author: Jan Böker <jan dot boecker at jboecker dot de>
|
|
|
+
|
|
|
+;; This elisp code integrates Static MathJax into the
|
|
|
+;; HTML export process of Org-mode.
|
|
|
+;;
|
|
|
+;; The supporting files for this package are in contrib/scripts/staticmathjax
|
|
|
+;; Please read the README.org file in that directory for more information.
|
|
|
+
|
|
|
+;; To use it, evaluate it on startup, add the following to your .emacs:
|
|
|
+
|
|
|
+;; (require 'org-static-mathjax)
|
|
|
+;;
|
|
|
+;; You will then have to customize the following two variables:
|
|
|
+;; - org-static-mathjax-app-ini-path
|
|
|
+;; - org-static-mathjax-local-mathjax-path
|
|
|
+;;
|
|
|
+;; If xulrunner is not in your $PATH, you will also need to customize
|
|
|
+;; org-static-mathjax-xulrunner-path.
|
|
|
+;;
|
|
|
+;; If everything is setup correctly, you can trigger Static MathJax on
|
|
|
+;; export to HTML by adding the following line to your Org file:
|
|
|
+;; #+StaticMathJax: embed-fonts:nil output-file-name:"embedded-math.html"
|
|
|
+;;
|
|
|
+;; You can omit either argument.
|
|
|
+;; embed-fonts defaults to nil. If you do not specify output-file-name,
|
|
|
+;; the exported file is overwritten with the static version.
|
|
|
+;;
|
|
|
+;; If embed-fonts is non-nil, the fonts are embedded directly into the
|
|
|
+;; output file using data: URIs.
|
|
|
+;;
|
|
|
+;; output-file-name specifies the file name of the static version. You
|
|
|
+;; can use any arbitrary lisp form here, for example:
|
|
|
+;; output-file-name:(concat (file-name-sans-extension buffer-file-name) "-static.html")
|
|
|
+;;
|
|
|
+;; The StaticMathJax XULRunner application expects a UTF-8 encoded
|
|
|
+;; input file. If the static version displays random characters instead
|
|
|
+;; of your math, add the following line at the top of your Org file:
|
|
|
+;; -*- coding: utf-8; -*-
|
|
|
+;;
|
|
|
+;; License: GPL v2 or later
|
|
|
+
|
|
|
+(defcustom org-static-mathjax-app-ini-path
|
|
|
+ (or (expand-file-name
|
|
|
+ "../scripts/staticmatchjax/application.ini"
|
|
|
+ (file-name-directory (or load-file-name buffer-file-name)))
|
|
|
+ "")
|
|
|
+ "Path to \"application.ini\" of the Static MathJax XULRunner application.
|
|
|
+If you have extracted StaticMathJax to e.g. ~/.local/staticmathjax, set
|
|
|
+this to ~/.local/staticmathjax/application.ini"
|
|
|
+ :type 'string)
|
|
|
+
|
|
|
+(defcustom org-static-mathjax-xulrunner-path
|
|
|
+ "xulrunner"
|
|
|
+ "Path to your xulrunner binary"
|
|
|
+ :type 'string)
|
|
|
+
|
|
|
+(defcustom org-static-mathjax-local-mathjax-path
|
|
|
+ ""
|
|
|
+ "Extract the MathJax zip file somewhere on your local
|
|
|
+hard drive and specify the path here.
|
|
|
+
|
|
|
+The directory has to be writeable, as org-static-mathjax
|
|
|
+creates a temporary file there during export."
|
|
|
+ :type 'string)
|
|
|
+
|
|
|
+(defvar org-static-mathjax-debug
|
|
|
+ nil
|
|
|
+ "If non-nil, org-static-mathjax will print some debug messages")
|
|
|
+
|
|
|
+(defun org-static-mathjax-hook-installer ()
|
|
|
+ "Installs org-static-mathjax-process in after-save-hook.
|
|
|
+
|
|
|
+Sets the following buffer-local variables for org-static-mathjax-process to pick up:
|
|
|
+org-static-mathjax-mathjax-path: The path to MathJax.js as used by Org HTML export
|
|
|
+org-static-mathjax-options: The string given with #+STATICMATHJAX: in the file"
|
|
|
+ (let ((static-mathjax-option-string (plist-get opt-plist :static-mathjax)))
|
|
|
+ (if static-mathjax-option-string
|
|
|
+ (progn (set (make-local-variable 'org-static-mathjax-options) static-mathjax-option-string)
|
|
|
+ (set (make-local-variable 'org-static-mathjax-mathjax-path)
|
|
|
+ (nth 1 (assq 'path org-export-html-mathjax-options)))
|
|
|
+ (let ((mathjax-options (plist-get opt-plist :mathjax)))
|
|
|
+ (if mathjax-options
|
|
|
+ (if (string-match "\\<path:" mathjax-options)
|
|
|
+ (set 'org-static-mathjax-mathjax-path
|
|
|
+ (car (read-from-string
|
|
|
+ (substring mathjax-options (match-end 0))))))))
|
|
|
+ (add-hook 'after-save-hook
|
|
|
+ 'org-static-mathjax-process
|
|
|
+ nil t)))))
|
|
|
+
|
|
|
+
|
|
|
+(defun org-static-mathjax-process ()
|
|
|
+ (save-excursion
|
|
|
+ ; some sanity checking
|
|
|
+ (if (or (string= org-static-mathjax-app-ini-path "")
|
|
|
+ (not (file-exists-p org-static-mathjax-app-ini-path)))
|
|
|
+ (error "Static MathJax: You must customize org-static-mathjax-app-ini-path!"))
|
|
|
+ (if (or (string= org-static-mathjax-local-mathjax-path "")
|
|
|
+ (not (file-exists-p org-static-mathjax-local-mathjax-path)))
|
|
|
+ (error "Static MathJax: You must customize org-static-mathjax-local-mathjax-path!"))
|
|
|
+
|
|
|
+ ; define variables
|
|
|
+ (let* ((options org-static-mathjax-options)
|
|
|
+ (output-file-name buffer-file-name)
|
|
|
+ (input-file-name (let ((temporary-file-directory (file-name-directory org-static-mathjax-local-mathjax-path)))
|
|
|
+ (make-temp-file "org-static-mathjax-" nil ".html")))
|
|
|
+ (html-code (buffer-string))
|
|
|
+ (mathjax-oldpath (concat "src=\"" org-static-mathjax-mathjax-path))
|
|
|
+ (mathjax-newpath (concat "src=\"" org-static-mathjax-local-mathjax-path))
|
|
|
+ embed-fonts)
|
|
|
+ ; read file-local options
|
|
|
+ (mapc
|
|
|
+ (lambda (symbol)
|
|
|
+ (if (string-match (concat "\\<" (symbol-name symbol) ":") options)
|
|
|
+ (set symbol (eval (car (read-from-string
|
|
|
+ (substring options (match-end 0))))))))
|
|
|
+ '(embed-fonts output-file-name))
|
|
|
+
|
|
|
+ ; debug
|
|
|
+ (when org-static-mathjax-debug
|
|
|
+ (message "output file name, embed-fonts")
|
|
|
+ (print output-file-name)
|
|
|
+ (print embed-fonts))
|
|
|
+
|
|
|
+ ; open (temporary) input file, copy contents there, replace MathJax path with local installation
|
|
|
+ (with-temp-buffer
|
|
|
+ (insert html-code)
|
|
|
+ (goto-char 1)
|
|
|
+ (replace-regexp mathjax-oldpath mathjax-newpath)
|
|
|
+ (write-file input-file-name))
|
|
|
+
|
|
|
+ ; prepare argument list for call-process
|
|
|
+ (let ((call-process-args (list org-static-mathjax-xulrunner-path
|
|
|
+ nil nil nil
|
|
|
+ org-static-mathjax-app-ini-path
|
|
|
+ input-file-name
|
|
|
+ output-file-name)))
|
|
|
+ ; if fonts are embedded, just append the --embed-fonts flag
|
|
|
+ (if embed-fonts
|
|
|
+ (add-to-list 'call-process-args "--embed-fonts" t))
|
|
|
+ ; if fonts are not embedded, the XULRunner app must replace all references
|
|
|
+ ; to the font files with the real location (Firefox inserts file:// URLs there,
|
|
|
+ ; because we are using a local MathJax installation here)
|
|
|
+ (if (not embed-fonts)
|
|
|
+ (progn
|
|
|
+ (add-to-list 'call-process-args "--final-mathjax-url" t)
|
|
|
+ (add-to-list 'call-process-args
|
|
|
+ (file-name-directory org-static-mathjax-mathjax-path)
|
|
|
+ t)))
|
|
|
+
|
|
|
+ ; debug
|
|
|
+ (when org-static-mathjax-debug
|
|
|
+ (print call-process-args))
|
|
|
+ ; call it
|
|
|
+ (apply 'call-process call-process-args)
|
|
|
+ ; delete our temporary input file
|
|
|
+ (kill-buffer)
|
|
|
+ (delete-file input-file-name)
|
|
|
+ (let ((backup-file (concat input-file-name "~")))
|
|
|
+ (if (file-exists-p backup-file)
|
|
|
+ (delete-file backup-file)))))))
|
|
|
+
|
|
|
+(add-to-list 'org-export-inbuffer-options-extra
|
|
|
+'("STATICMATHJAX" :static-mathjax))
|
|
|
+
|
|
|
+(add-hook 'org-export-html-final-hook 'org-static-mathjax-hook-installer)
|
|
|
+
|
|
|
+
|
|
|
+(provide 'org-static-mathjax)
|