mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 76bbd07de7add0f9d13c6914f158d19630fe2f62
commit | author | age
76bbd0 1 ;;; ob-latex.el --- Babel Functions for LaTeX        -*- lexical-binding: t; -*-
C 2
3 ;; Copyright (C) 2009-2018 Free Software Foundation, Inc.
4
5 ;; Author: Eric Schulte
6 ;; Keywords: literate programming, reproducible research
7 ;; Homepage: https://orgmode.org
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 <https://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 &optional type))
36 (declare-function org-latex-compile "ox-latex" (texfile &optional snippet))
37 (declare-function org-latex-guess-inputenc "ox-latex" (header))
38 (declare-function org-splice-latex-header "org" (tpl def-pkg pkg snippets-p &optional extra))
39 (declare-function org-trim "org" (s &optional keep-lead))
40
41 (defvar org-babel-tangle-lang-exts)
42 (add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex"))
43
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
48
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
53 (defconst org-babel-header-args:latex
54   '((border      . :any)
55     (fit          . :any)
56     (imagemagick  . ((nil t)))
57     (iminoptions  . :any)
58     (imoutoptions . :any)
59     (packages     . :any)
60     (pdfheight    . :any)
61     (pdfpng       . :any)
62     (pdfwidth     . :any)
63     (headers      . :any)
64     (packages     . :any)
65     (buffer       . ((yes no))))
66   "LaTeX-specific header arguments.")
67
68 (defcustom org-babel-latex-htlatex "htlatex"
69   "The htlatex command to enable conversion of latex to SVG or HTML."
70   :group 'org-babel
71   :type 'string)
72
73 (defcustom org-babel-latex-htlatex-packages
74   '("[usenames]{color}" "{tikz}" "{color}" "{listings}" "{amsmath}")
75   "Packages to use for htlatex export."
76   :group 'org-babel
77   :type '(repeat (string)))
78
79 (defun org-babel-expand-body:latex (body params)
80   "Expand BODY according to PARAMS, return the expanded body."
81   (mapc (lambda (pair) ;; replace variables
82           (setq body
83                 (replace-regexp-in-string
84                  (regexp-quote (format "%S" (car pair)))
85                  (if (stringp (cdr pair))
86                      (cdr pair) (format "%S" (cdr pair)))
87                  body))) (org-babel--get-vars params))
88   (org-trim body))
89
90 (defun org-babel-execute:latex (body params)
91   "Execute a block of Latex code with Babel.
92 This function is called by `org-babel-execute-src-block'."
93   (setq body (org-babel-expand-body:latex body params))
94   (if (cdr (assq :file params))
95       (let* ((out-file (cdr (assq :file params)))
96          (extension (file-name-extension out-file))
97          (tex-file (org-babel-temp-file "latex-" ".tex"))
98          (border (cdr (assq :border params)))
99          (imagemagick (cdr (assq :imagemagick params)))
100          (im-in-options (cdr (assq :iminoptions params)))
101          (im-out-options (cdr (assq :imoutoptions params)))
102          (fit (or (cdr (assq :fit params)) border))
103          (height (and fit (cdr (assq :pdfheight params))))
104          (width (and fit (cdr (assq :pdfwidth params))))
105          (headers (cdr (assq :headers params)))
106          (in-buffer (not (string= "no" (cdr (assq :buffer params)))))
107          (org-latex-packages-alist
108           (append (cdr (assq :packages params)) org-latex-packages-alist)))
109         (cond
110          ((and (string-suffix-p ".png" out-file) (not imagemagick))
111           (org-create-formula-image
112            body out-file org-format-latex-options in-buffer))
113          ((string-suffix-p ".tikz" out-file)
114       (when (file-exists-p out-file) (delete-file out-file))
115       (with-temp-file out-file
116         (insert body)))
117      ((and (or (string= "svg" extension)
118            (string= "html" extension))
119            (executable-find org-babel-latex-htlatex))
120       ;; TODO: this is a very different way of generating the
121       ;; frame latex document than in the pdf case.  Ideally, both
122       ;; would be unified.  This would prevent bugs creeping in
123       ;; such as the one fixed on Aug 16 2014 whereby :headers was
124       ;; not included in the SVG/HTML case.
125       (with-temp-file tex-file
126         (insert (concat
127              "\\documentclass[preview]{standalone}
128 \\def\\pgfsysdriver{pgfsys-tex4ht.def}
129 "
130              (mapconcat (lambda (pkg)
131                   (concat "\\usepackage" pkg))
132                 org-babel-latex-htlatex-packages
133                 "\n")
134              (if headers
135              (concat "\n"
136                  (if (listp headers)
137                      (mapconcat #'identity headers "\n")
138                    headers) "\n")
139                "")
140              "\\begin{document}"
141              body
142              "\\end{document}")))
143       (when (file-exists-p out-file) (delete-file out-file))
144       (let ((default-directory (file-name-directory tex-file)))
145         (shell-command (format "%s %s" org-babel-latex-htlatex tex-file)))
146       (cond
147        ((file-exists-p (concat (file-name-sans-extension tex-file) "-1.svg"))
148         (if (string-suffix-p ".svg" out-file)
149         (progn
150           (shell-command "pwd")
151           (shell-command (format "mv %s %s"
152                      (concat (file-name-sans-extension tex-file) "-1.svg")
153                      out-file)))
154           (error "SVG file produced but HTML file requested")))
155        ((file-exists-p (concat (file-name-sans-extension tex-file) ".html"))
156         (if (string-suffix-p ".html" out-file)
157         (shell-command "mv %s %s"
158                    (concat (file-name-sans-extension tex-file)
159                        ".html")
160                    out-file)
161           (error "HTML file produced but SVG file requested")))))
162      ((or (string= "pdf" extension) imagemagick)
163       (with-temp-file tex-file
164         (require 'ox-latex)
165         (insert
166          (org-latex-guess-inputenc
167           (org-splice-latex-header
168            org-format-latex-header
169            (delq
170         nil
171         (mapcar
172          (lambda (el)
173            (unless (and (listp el) (string= "hyperref" (cadr el)))
174              el))
175          org-latex-default-packages-alist))
176            org-latex-packages-alist
177            nil))
178          (if fit "\n\\usepackage[active, tightpage]{preview}\n" "")
179          (if border (format "\\setlength{\\PreviewBorder}{%s}" border) "")
180          (if height (concat "\n" (format "\\pdfpageheight %s" height)) "")
181          (if width  (concat "\n" (format "\\pdfpagewidth %s" width))   "")
182          (if headers
183          (concat "\n"
184              (if (listp headers)
185                  (mapconcat #'identity headers "\n")
186                headers) "\n")
187            "")
188          (if fit
189          (concat "\n\\begin{document}\n\\begin{preview}\n" body
190              "\n\\end{preview}\n\\end{document}\n")
191            (concat "\n\\begin{document}\n" body "\n\\end{document}\n"))))
192           (when (file-exists-p out-file) (delete-file out-file))
193       (let ((transient-pdf-file (org-babel-latex-tex-to-pdf tex-file)))
194         (cond
195          ((string= "pdf" extension)
196           (rename-file transient-pdf-file out-file))
197          (imagemagick
198           (org-babel-latex-convert-pdf
199            transient-pdf-file out-file im-in-options im-out-options)
200           (when (file-exists-p transient-pdf-file)
201         (delete-file transient-pdf-file)))
202          (t
203           (error "Can not create %s files, please specify a .png or .pdf file or try the :imagemagick header argument"
204              extension))))))
205         nil) ;; signal that output has already been written to file
206     body))
207
208 (defun org-babel-latex-convert-pdf (pdffile out-file im-in-options im-out-options)
209   "Generate a file from a pdf file using imagemagick."
210   (let ((cmd (concat "convert " im-in-options " " pdffile " "
211              im-out-options " " out-file)))
212     (message "Converting pdffile file %s..." cmd)
213     (shell-command cmd)))
214
215 (defun org-babel-latex-tex-to-pdf (file)
216   "Generate a pdf file according to the contents FILE."
217   (require 'ox-latex)
218   (org-latex-compile file))
219
220 (defun org-babel-prep-session:latex (_session _params)
221   "Return an error because LaTeX doesn't support sessions."
222   (error "LaTeX does not support sessions"))
223
224
225 (provide 'ob-latex)
226 ;;; ob-latex.el ends here