Commit | Line | Data |
---|---|---|
86fbb8ca CD |
1 | ;;; ob-latex.el --- org-babel functions for latex "evaluation" |
2 | ||
ba318903 | 3 | ;; Copyright (C) 2009-2014 Free Software Foundation, Inc. |
86fbb8ca CD |
4 | |
5 | ;; Author: Eric Schulte | |
6 | ;; Keywords: literate programming, reproducible research | |
7 | ;; Homepage: http://orgmode.org | |
86fbb8ca CD |
8 | |
9 | ;; This file is part of GNU Emacs. | |
10 | ||
11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation, either version 3 of the License, or | |
14 | ;; (at your option) any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | ||
24 | ;;; Commentary: | |
25 | ||
26 | ;; Org-Babel support for evaluating LaTeX source code. | |
27 | ;; | |
28 | ;; Currently on evaluation this returns raw LaTeX code, unless a :file | |
29 | ;; header argument is given in which case small png or pdf files will | |
30 | ;; be created directly form the latex source code. | |
31 | ||
32 | ;;; Code: | |
33 | (require 'ob) | |
34 | ||
35 | (declare-function org-create-formula-image "org" (string tofile options buffer)) | |
36 | (declare-function org-splice-latex-header "org" | |
37 | (tpl def-pkg pkg snippets-p &optional extra)) | |
271672fa BG |
38 | (declare-function org-latex-guess-inputenc "ox-latex" (header)) |
39 | (declare-function org-latex-compile "ox-latex" (file)) | |
40 | ||
3ab2c837 | 41 | (defvar org-babel-tangle-lang-exts) |
86fbb8ca CD |
42 | (add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex")) |
43 | ||
271672fa BG |
44 | (defvar org-format-latex-header) ; From org.el |
45 | (defvar org-format-latex-options) ; From org.el | |
46 | (defvar org-latex-default-packages-alist) ; From org.el | |
47 | (defvar org-latex-packages-alist) ; From org.el | |
afe98dfa | 48 | |
86fbb8ca CD |
49 | (defvar org-babel-default-header-args:latex |
50 | '((:results . "latex") (:exports . "results")) | |
51 | "Default arguments to use when evaluating a LaTeX source block.") | |
52 | ||
73d3db82 | 53 | (defcustom org-babel-latex-htlatex "" |
271672fa BG |
54 | "The htlatex command to enable conversion of latex to SVG or HTML." |
55 | :group 'org-babel | |
56 | :type 'string) | |
57 | ||
58 | (defcustom org-babel-latex-htlatex-packages | |
59 | '("[usenames]{color}" "{tikz}" "{color}" "{listings}" "{amsmath}") | |
60 | "Packages to use for htlatex export." | |
61 | :group 'org-babel | |
3c8b09ca | 62 | :type '(repeat (string))) |
271672fa | 63 | |
afe98dfa | 64 | (defun org-babel-expand-body:latex (body params) |
86fbb8ca CD |
65 | "Expand BODY according to PARAMS, return the expanded body." |
66 | (mapc (lambda (pair) ;; replace variables | |
67 | (setq body | |
68 | (replace-regexp-in-string | |
69 | (regexp-quote (format "%S" (car pair))) | |
70 | (if (stringp (cdr pair)) | |
71 | (cdr pair) (format "%S" (cdr pair))) | |
afe98dfa CD |
72 | body))) (mapcar #'cdr (org-babel-get-header params :var))) |
73 | (org-babel-trim body)) | |
86fbb8ca | 74 | |
86fbb8ca CD |
75 | (defun org-babel-execute:latex (body params) |
76 | "Execute a block of Latex code with Babel. | |
77 | This function is called by `org-babel-execute-src-block'." | |
78 | (setq body (org-babel-expand-body:latex body params)) | |
79 | (if (cdr (assoc :file params)) | |
afe98dfa CD |
80 | (let* ((out-file (cdr (assoc :file params))) |
81 | (tex-file (org-babel-temp-file "latex-" ".tex")) | |
82 | (border (cdr (assoc :border params))) | |
e66ba1df BG |
83 | (imagemagick (cdr (assoc :imagemagick params))) |
84 | (im-in-options (cdr (assoc :iminoptions params))) | |
85 | (im-out-options (cdr (assoc :imoutoptions params))) | |
86 | (pdfpng (cdr (assoc :pdfpng params))) | |
afe98dfa CD |
87 | (fit (or (cdr (assoc :fit params)) border)) |
88 | (height (and fit (cdr (assoc :pdfheight params)))) | |
89 | (width (and fit (cdr (assoc :pdfwidth params)))) | |
90 | (headers (cdr (assoc :headers params))) | |
91 | (in-buffer (not (string= "no" (cdr (assoc :buffer params))))) | |
271672fa BG |
92 | (org-latex-packages-alist |
93 | (append (cdr (assoc :packages params)) org-latex-packages-alist))) | |
86fbb8ca | 94 | (cond |
e66ba1df | 95 | ((and (string-match "\\.png$" out-file) (not imagemagick)) |
86fbb8ca CD |
96 | (org-create-formula-image |
97 | body out-file org-format-latex-options in-buffer)) | |
271672fa BG |
98 | ((string-match "\\.tikz$" out-file) |
99 | (when (file-exists-p out-file) (delete-file out-file)) | |
100 | (with-temp-file out-file | |
101 | (insert body))) | |
102 | ((or (string-match "\\.pdf$" out-file) imagemagick) | |
afe98dfa | 103 | (with-temp-file tex-file |
271672fa | 104 | (require 'ox-latex) |
afe98dfa | 105 | (insert |
271672fa BG |
106 | (org-latex-guess-inputenc |
107 | (org-splice-latex-header | |
108 | org-format-latex-header | |
109 | (delq | |
110 | nil | |
111 | (mapcar | |
112 | (lambda (el) | |
113 | (unless (and (listp el) (string= "hyperref" (cadr el))) | |
114 | el)) | |
115 | org-latex-default-packages-alist)) | |
116 | org-latex-packages-alist | |
117 | nil)) | |
afe98dfa CD |
118 | (if fit "\n\\usepackage[active, tightpage]{preview}\n" "") |
119 | (if border (format "\\setlength{\\PreviewBorder}{%s}" border) "") | |
120 | (if height (concat "\n" (format "\\pdfpageheight %s" height)) "") | |
121 | (if width (concat "\n" (format "\\pdfpagewidth %s" width)) "") | |
122 | (if headers | |
123 | (concat "\n" | |
124 | (if (listp headers) | |
125 | (mapconcat #'identity headers "\n") | |
126 | headers) "\n") | |
127 | "") | |
afe98dfa CD |
128 | (if fit |
129 | (concat "\n\\begin{document}\n\\begin{preview}\n" body | |
130 | "\n\\end{preview}\n\\end{document}\n") | |
271672fa | 131 | (concat "\n\\begin{document}\n" body "\n\\end{document}\n")))) |
86fbb8ca | 132 | (when (file-exists-p out-file) (delete-file out-file)) |
e66ba1df BG |
133 | (let ((transient-pdf-file (org-babel-latex-tex-to-pdf tex-file))) |
134 | (cond | |
135 | ((string-match "\\.pdf$" out-file) | |
136 | (rename-file transient-pdf-file out-file)) | |
137 | (imagemagick | |
138 | (convert-pdf | |
139 | transient-pdf-file out-file im-in-options im-out-options) | |
140 | (when (file-exists-p transient-pdf-file) | |
141 | (delete-file transient-pdf-file)))))) | |
271672fa BG |
142 | ((and (or (string-match "\\.svg$" out-file) |
143 | (string-match "\\.html$" out-file)) | |
73d3db82 | 144 | (not (string= "" org-babel-latex-htlatex))) |
271672fa BG |
145 | (with-temp-file tex-file |
146 | (insert (concat | |
147 | "\\documentclass[preview]{standalone} | |
148 | \\def\\pgfsysdriver{pgfsys-tex4ht.def} | |
149 | " | |
150 | (mapconcat (lambda (pkg) | |
151 | (concat "\\usepackage" pkg)) | |
152 | org-babel-latex-htlatex-packages | |
153 | "\n") | |
154 | "\\begin{document}" | |
155 | body | |
156 | "\\end{document}"))) | |
157 | (when (file-exists-p out-file) (delete-file out-file)) | |
158 | (let ((default-directory (file-name-directory tex-file))) | |
159 | (shell-command (format "%s %s" org-babel-latex-htlatex tex-file))) | |
160 | (cond | |
161 | ((file-exists-p (concat (file-name-sans-extension tex-file) "-1.svg")) | |
162 | (if (string-match "\\.svg$" out-file) | |
163 | (progn | |
164 | (shell-command "pwd") | |
165 | (shell-command (format "mv %s %s" | |
166 | (concat (file-name-sans-extension tex-file) "-1.svg") | |
167 | out-file))) | |
168 | (error "SVG file produced but HTML file requested."))) | |
169 | ((file-exists-p (concat (file-name-sans-extension tex-file) ".html")) | |
170 | (if (string-match "\\.html$" out-file) | |
171 | (shell-command "mv %s %s" | |
172 | (concat (file-name-sans-extension tex-file) | |
173 | ".html") | |
174 | out-file) | |
175 | (error "HTML file produced but SVG file requested."))))) | |
86fbb8ca | 176 | ((string-match "\\.\\([^\\.]+\\)$" out-file) |
8223b1d2 | 177 | (error "Can not create %s files, please specify a .png or .pdf file or try the :imagemagick header argument" |
86fbb8ca | 178 | (match-string 1 out-file)))) |
3ab2c837 | 179 | nil) ;; signal that output has already been written to file |
86fbb8ca CD |
180 | body)) |
181 | ||
e66ba1df BG |
182 | (defun convert-pdf (pdffile out-file im-in-options im-out-options) |
183 | "Generate a file from a pdf file using imagemagick." | |
184 | (let ((cmd (concat "convert " im-in-options " " pdffile " " | |
185 | im-out-options " " out-file))) | |
186 | (message (concat "Converting pdffile file " cmd "...")) | |
187 | (shell-command cmd))) | |
188 | ||
afe98dfa | 189 | (defun org-babel-latex-tex-to-pdf (file) |
271672fa BG |
190 | "Generate a pdf file according to the contents FILE." |
191 | (require 'ox-latex) | |
192 | (org-latex-compile file)) | |
86fbb8ca CD |
193 | |
194 | (defun org-babel-prep-session:latex (session params) | |
9858f6c3 | 195 | "Return an error because LaTeX doesn't support sessions." |
86fbb8ca CD |
196 | (error "LaTeX does not support sessions")) |
197 | ||
86fbb8ca | 198 | |
271672fa | 199 | (provide 'ob-latex) |
86fbb8ca | 200 | ;;; ob-latex.el ends here |