dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

org-static-mathjax.el (7269B)


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