forked from mirrors/org-mode
ox-latex: Precompile preamble for export
* lisp/ox-latex.el (org-latex-precompile, org-latex-make-preamble): Make use of "mylatexformat" to precompile the LaTeX preamble, for faster exports. (org-latex--remove-cached-preamble): Add a function to clear a cached preamble. * lisp/org-latex-preview.el (org-latex-preview-precompile, org-latex-preview--get-preamble): Relocate the precompilation functionality to ox-latex.el, and use the new ox-latex preamble precompilation API. (org-latex-preview-clear-cache): Use the new preamble cache clearing functionality in ox-latex.
This commit is contained in:
parent
688427138d
commit
3376423921
|
@ -1432,6 +1432,7 @@ previews."
|
||||||
(org-export--get-buffer-attributes)
|
(org-export--get-buffer-attributes)
|
||||||
'(:time-stamp-file nil)))
|
'(:time-stamp-file nil)))
|
||||||
org-export-use-babel
|
org-export-use-babel
|
||||||
|
org-latex-precompile
|
||||||
;; (org-latex-conditional-features
|
;; (org-latex-conditional-features
|
||||||
;; (cl-remove-if
|
;; (cl-remove-if
|
||||||
;; (lambda (feat)
|
;; (lambda (feat)
|
||||||
|
@ -1445,7 +1446,7 @@ previews."
|
||||||
(font-lock-mode -1)
|
(font-lock-mode -1)
|
||||||
(setq info
|
(setq info
|
||||||
(org-export--annotate-info (org-export-get-backend 'latex) info))
|
(org-export--annotate-info (org-export-get-backend 'latex) info))
|
||||||
(org-latex-make-preamble
|
(org-latex-make-preamble
|
||||||
(org-combine-plists
|
(org-combine-plists
|
||||||
(org-export-get-environment
|
(org-export-get-environment
|
||||||
(org-export-get-backend 'latex))
|
(org-export-get-backend 'latex))
|
||||||
|
@ -1994,6 +1995,13 @@ the *entire* preview cache will be cleared, and `org-persist-gc' run."
|
||||||
(list (org-element-property :begin context)
|
(list (org-element-property :begin context)
|
||||||
(org-element-property :end context)))
|
(org-element-property :end context)))
|
||||||
(t (list nil nil))))))
|
(t (list nil nil))))))
|
||||||
|
;; Clear the precompile cache if clearing the whole buffer or everything.
|
||||||
|
(when (or clear-entire-cache (not (or beg end)))
|
||||||
|
(dolist (compiler org-latex-compilers)
|
||||||
|
(org-latex--remove-cached-preamble
|
||||||
|
compiler org-latex-preview--preamble-content nil)
|
||||||
|
(org-latex--remove-cached-preamble
|
||||||
|
compiler org-latex-preview--preamble-content t)))
|
||||||
(org-latex-preview-clear-overlays beg end)
|
(org-latex-preview-clear-overlays beg end)
|
||||||
(if clear-entire-cache
|
(if clear-entire-cache
|
||||||
(let ((n 0))
|
(let ((n 0))
|
||||||
|
@ -2040,79 +2048,15 @@ according to PROCESSING-INFO and stored.
|
||||||
|
|
||||||
This is intended to speed up Org's LaTeX preview generation
|
This is intended to speed up Org's LaTeX preview generation
|
||||||
process."
|
process."
|
||||||
(let ((preamble-hash
|
(org-latex--precompile
|
||||||
(thread-first
|
(list :latex-compiler (plist-get processing-info :latex-processor)
|
||||||
preamble
|
:precompile-format-spec
|
||||||
(concat
|
|
||||||
(prin1-to-string
|
|
||||||
(car (plist-get processing-info :programs)))
|
|
||||||
(plist-get processing-info :latex-processor)
|
|
||||||
(and (string-match-p "\\(?:\\\\input{\\|\\\\include{\\)"
|
|
||||||
preamble)
|
|
||||||
default-directory))
|
|
||||||
(sha1))))
|
|
||||||
(or (cadr
|
|
||||||
(org-persist-read "LaTeX format file cache"
|
|
||||||
(list :key preamble-hash)
|
|
||||||
nil nil :read-related t))
|
|
||||||
(when-let ((dump-file
|
|
||||||
(org-latex-preview--precompile-preamble
|
|
||||||
processing-info preamble
|
|
||||||
(expand-file-name preamble-hash temporary-file-directory))))
|
|
||||||
(cadr
|
|
||||||
(org-persist-register `(,"LaTeX format file cache"
|
|
||||||
(file ,dump-file))
|
|
||||||
(list :key preamble-hash)
|
|
||||||
:write-immediately t))))))
|
|
||||||
|
|
||||||
(defun org-latex-preview--precompile-preamble (processing-info preamble basepath)
|
|
||||||
"Precompile PREAMBLE with \"mylatexformat\".
|
|
||||||
The PREAMBLE string is placed in BASEPATH.tex and compiled
|
|
||||||
according to PROCESSING-INFO. If compilation and dumping
|
|
||||||
succeeded, BASEPATH.fmt will be returned.
|
|
||||||
|
|
||||||
Should any errors occur during compilation, nil will be returned,
|
|
||||||
and appropriate warnings may be emitted."
|
|
||||||
(let ((dump-file (concat basepath ".fmt"))
|
|
||||||
(preamble-file (concat basepath ".tex"))
|
|
||||||
(precompile-buffer
|
|
||||||
(with-current-buffer
|
|
||||||
(get-buffer-create org-latex-preview--precompile-log)
|
|
||||||
(erase-buffer)
|
|
||||||
(current-buffer))))
|
|
||||||
(with-temp-file preamble-file
|
|
||||||
(insert preamble "\n\\endofdump\n"))
|
|
||||||
(message "Precompiling Org LaTeX Preview preamble...")
|
|
||||||
(condition-case nil
|
|
||||||
(org-compile-file
|
|
||||||
preamble-file (plist-get processing-info :latex-precompiler)
|
|
||||||
"fmt" nil precompile-buffer
|
|
||||||
(let ((org-tex-compiler
|
(let ((org-tex-compiler
|
||||||
(cdr (assoc (plist-get processing-info :latex-processor)
|
(cdr (assoc (plist-get processing-info :latex-processor)
|
||||||
org-latex-preview-compiler-command-map))))
|
org-latex-preview-compiler-command-map))))
|
||||||
`((?l . ,org-tex-compiler)
|
`((?l . ,org-tex-compiler)
|
||||||
(?L . ,(car (split-string org-tex-compiler))))))
|
(?L . ,(car (split-string org-tex-compiler))))))
|
||||||
(:success
|
preamble))
|
||||||
(kill-buffer precompile-buffer)
|
|
||||||
(delete-file preamble-file)
|
|
||||||
dump-file)
|
|
||||||
(error
|
|
||||||
(unless (= 0 (call-process "kpsewhich" nil nil nil "mylatexformat.ltx"))
|
|
||||||
(display-warning
|
|
||||||
'(org latex-preview preamble-precompilation)
|
|
||||||
"The LaTeX package \"mylatexformat\" is required for precompilation, but could not be found")
|
|
||||||
:warning)
|
|
||||||
(unless (= 0 (call-process "kpsewhich" nil nil nil "preview.sty"))
|
|
||||||
(display-warning
|
|
||||||
'(org latex-preview preamble-precompilation)
|
|
||||||
"The LaTeX package \"preview\" is required for precompilation, but could not be found")
|
|
||||||
:warning)
|
|
||||||
(display-warning
|
|
||||||
'(org latex-preview preamble-precompilation)
|
|
||||||
(format "Failed to precompile preamble (%s), see the \"%s\" buffer."
|
|
||||||
preamble-file precompile-buffer)
|
|
||||||
:warning)
|
|
||||||
nil))))
|
|
||||||
|
|
||||||
(defun org-latex-preview--tex-styled (processing-type value options &optional html-p)
|
(defun org-latex-preview--tex-styled (processing-type value options &optional html-p)
|
||||||
"Apply LaTeX style commands to VALUE based on OPTIONS.
|
"Apply LaTeX style commands to VALUE based on OPTIONS.
|
||||||
|
|
197
lisp/ox-latex.el
197
lisp/ox-latex.el
|
@ -1470,7 +1470,13 @@ default values of which are given by `org-latex-engraved-preamble' and
|
||||||
(bibliography-biblatex
|
(bibliography-biblatex
|
||||||
:condition (eq (org-cite-processor info) 'biblatex)
|
:condition (eq (org-cite-processor info) 'biblatex)
|
||||||
:when bibliography
|
:when bibliography
|
||||||
:snippet org-cite-biblatex--generate-latex-preamble)
|
:snippet org-cite-biblatex--generate-latex-usepackage)
|
||||||
|
(bibliography-biblatex-resources
|
||||||
|
:condition (eq (org-cite-processor info) 'biblatex)
|
||||||
|
:when bibliography
|
||||||
|
:snippet org-cite-biblatex--generate-latex-bibresources
|
||||||
|
:no-precompile t
|
||||||
|
:order 90)
|
||||||
(bibliography-natbib
|
(bibliography-natbib
|
||||||
:condition (eq (org-cite-processor info) 'natbib)
|
:condition (eq (org-cite-processor info) 'natbib)
|
||||||
:when bibliography
|
:when bibliography
|
||||||
|
@ -2070,7 +2076,13 @@ specified in `org-latex-default-packages-alist' or
|
||||||
"^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
|
"^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
|
||||||
class-options header t nil 1))))
|
class-options header t nil 1))))
|
||||||
(user-error "Unknown LaTeX class `%s'" class)))
|
(user-error "Unknown LaTeX class `%s'" class)))
|
||||||
generated-preamble)
|
(header-split (format "\n%%--org-latex-header-temp-split-%d--\n" (random 10000)))
|
||||||
|
(header (concat (org-element-normalize-string (plist-get info :latex-header))
|
||||||
|
header-split
|
||||||
|
(and (not snippet?)
|
||||||
|
(org-element-normalize-string
|
||||||
|
(plist-get info :latex-header-extra)))))
|
||||||
|
generated-preamble preamble-nonprecompilable)
|
||||||
(plist-put info :latex-full-header
|
(plist-put info :latex-full-header
|
||||||
(org-element-normalize-string
|
(org-element-normalize-string
|
||||||
(org-splice-latex-header
|
(org-splice-latex-header
|
||||||
|
@ -2078,32 +2090,66 @@ specified in `org-latex-default-packages-alist' or
|
||||||
(org-latex--remove-packages org-latex-default-packages-alist info)
|
(org-latex--remove-packages org-latex-default-packages-alist info)
|
||||||
(org-latex--remove-packages org-latex-packages-alist info)
|
(org-latex--remove-packages org-latex-packages-alist info)
|
||||||
snippet?
|
snippet?
|
||||||
(mapconcat #'org-element-normalize-string
|
header)))
|
||||||
(list (plist-get info :latex-header)
|
(if snippet?
|
||||||
(and (not snippet?)
|
(setq generated-preamble
|
||||||
(plist-get info :latex-header-extra)))
|
|
||||||
""))))
|
|
||||||
(setq generated-preamble
|
|
||||||
(if snippet?
|
|
||||||
(progn
|
(progn
|
||||||
(org-latex-guess-inputenc info)
|
(org-latex-guess-inputenc info)
|
||||||
(org-latex-guess-babel-language info)
|
(org-latex-guess-babel-language info)
|
||||||
(org-latex-guess-polyglossia-language info)
|
(org-latex-guess-polyglossia-language info)
|
||||||
"\n% Generated preamble omitted for snippets.")
|
"\n% Generated preamble omitted for snippets."))
|
||||||
|
(let (impl-precomp impl-noprecomp)
|
||||||
|
(dolist (impl (plist-get info :feature-implementations))
|
||||||
|
(message "LaTeX feature: %s" (car impl))
|
||||||
|
(if (or impl-noprecomp (plist-get (cdr impl) :no-precompile))
|
||||||
|
(push impl impl-noprecomp)
|
||||||
|
(push impl impl-precomp)))
|
||||||
|
(message "Precomp feats: %S" (reverse (mapcar #'car impl-precomp)))
|
||||||
|
(message "No precomp feats: %S" (reverse (mapcar #'car impl-noprecomp)))
|
||||||
|
(setq generated-preamble
|
||||||
|
(string-join
|
||||||
|
(org-export-expand-feature-snippets
|
||||||
|
info (nreverse impl-precomp))
|
||||||
|
"\n\n")
|
||||||
|
preamble-nonprecompilable
|
||||||
|
(string-join
|
||||||
|
(org-export-expand-feature-snippets
|
||||||
|
info (nreverse impl-noprecomp))
|
||||||
|
"\n\n"))))
|
||||||
|
(let* ((header-parts
|
||||||
|
(split-string (plist-get info :latex-full-header)
|
||||||
|
(regexp-quote header-split)))
|
||||||
|
(header-main (car header-parts))
|
||||||
|
(header-extra (cadr header-parts))
|
||||||
|
(preamble
|
||||||
(concat
|
(concat
|
||||||
|
(org-latex--insert-compiler info)
|
||||||
|
header-main
|
||||||
"\n"
|
"\n"
|
||||||
(string-join
|
generated-preamble
|
||||||
(org-export-expand-feature-snippets info)
|
"\n"))
|
||||||
"\n\n")
|
(format-file
|
||||||
"\n")))
|
(and org-latex-precompile
|
||||||
(concat
|
(org-latex--precompile info preamble))))
|
||||||
;; Time-stamp.
|
(when (and format-file (not snippet?))
|
||||||
(and (plist-get info :time-stamp-file)
|
(let ((preamble-parts (split-string preamble (regexp-quote header-split))))
|
||||||
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
(setq preamble (car preamble-parts)
|
||||||
;; LaTeX compiler.
|
preamble-nonprecompilable
|
||||||
(org-latex--insert-compiler info)
|
(concat preamble-nonprecompilable
|
||||||
(plist-get info :latex-full-header)
|
(cadr preamble-parts)))))
|
||||||
generated-preamble)))
|
(concat (and format-file
|
||||||
|
(concat "%& " (file-name-sans-extension format-file) "\n"))
|
||||||
|
(and (plist-get info :time-stamp-file)
|
||||||
|
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
||||||
|
preamble
|
||||||
|
(and format-file
|
||||||
|
"\n% end precompiled preamble\n\\ifcsname endofdump\\endcsname\\endofdump\\fi\n")
|
||||||
|
"\n"
|
||||||
|
preamble-nonprecompilable
|
||||||
|
(and preamble-nonprecompilable
|
||||||
|
(not (string-empty-p preamble-nonprecompilable))
|
||||||
|
"\n")
|
||||||
|
header-extra))))
|
||||||
|
|
||||||
(defun org-latex-template (contents info)
|
(defun org-latex-template (contents info)
|
||||||
"Return complete document string after LaTeX conversion.
|
"Return complete document string after LaTeX conversion.
|
||||||
|
@ -2176,6 +2222,113 @@ holding export options."
|
||||||
;; Document end.
|
;; Document end.
|
||||||
"\\end{document}")))
|
"\\end{document}")))
|
||||||
|
|
||||||
|
(defvar org-latex-precompile t
|
||||||
|
"Precompile the preamble during export.
|
||||||
|
This requires the LaTeX package \"mylatexformat\" to be installed.")
|
||||||
|
|
||||||
|
(defconst org-latex--precompile-log "*Org LaTeX Precompilation*")
|
||||||
|
|
||||||
|
(defvar org-latex-precompile-command
|
||||||
|
"%l -output-directory %o -ini -jobname=%b \"&%L\" mylatexformat.ltx %f")
|
||||||
|
|
||||||
|
(defvar org-latex-precompile-compiler-map
|
||||||
|
'(("pdflatex" . "latex")
|
||||||
|
("xelatex" . "xelatex -no-pdf")
|
||||||
|
("lualatex" . "dvilualatex")))
|
||||||
|
|
||||||
|
(defun org-latex--precompile (info preamble)
|
||||||
|
"Precompile/dump LaTeX PREAMBLE text.
|
||||||
|
|
||||||
|
The path to the format file (.fmt) is returned. If the format
|
||||||
|
file could not be found in the persist cache, it is generated
|
||||||
|
according to PROCESSING-INFO and stored.
|
||||||
|
|
||||||
|
This is intended to speed up Org's LaTeX preview generation
|
||||||
|
process."
|
||||||
|
(let ((preamble-hash
|
||||||
|
(thread-first
|
||||||
|
preamble
|
||||||
|
(concat
|
||||||
|
(plist-get info :latex-compiler)
|
||||||
|
(and (string-match-p "\\(?:\\\\input{\\|\\\\include{\\)"
|
||||||
|
preamble)
|
||||||
|
default-directory))
|
||||||
|
(sha1))))
|
||||||
|
(or (cadr
|
||||||
|
(org-persist-read "LaTeX format file cache"
|
||||||
|
(list :key preamble-hash)
|
||||||
|
nil nil :read-related t))
|
||||||
|
(when-let ((dump-file
|
||||||
|
(org-latex--precompile-preamble
|
||||||
|
info preamble (expand-file-name preamble-hash temporary-file-directory))))
|
||||||
|
(cadr
|
||||||
|
(org-persist-register `(,"LaTeX format file cache"
|
||||||
|
(file ,dump-file))
|
||||||
|
(list :key preamble-hash)
|
||||||
|
:write-immediately t))))))
|
||||||
|
|
||||||
|
(defun org-latex--remove-cached-preamble (latex-compiler preamble &optional tempfile-p)
|
||||||
|
"Remove the cached preamble file for PREAMBLE compiled with LATEX-COMPILER.
|
||||||
|
TEMPFILE-P should be set to mirror the caching `org-latex--precompile' call
|
||||||
|
which is intended to be evicted from the cache."
|
||||||
|
(let ((preamble-hash
|
||||||
|
(thread-first
|
||||||
|
preamble
|
||||||
|
(concat
|
||||||
|
latex-compiler
|
||||||
|
(if tempfile-p "-temp"
|
||||||
|
default-directory))
|
||||||
|
(sha1))))
|
||||||
|
(org-persist-unregister "LaTeX format file cache"
|
||||||
|
(list :key preamble-hash)
|
||||||
|
:remove-related t)))
|
||||||
|
|
||||||
|
(defun org-latex--precompile-preamble (info preamble basepath)
|
||||||
|
"Precompile PREAMBLE with \"mylatexformat\".
|
||||||
|
The PREAMBLE string is placed in BASEPATH.tex and compiled
|
||||||
|
according to PROCESSING-INFO. If compilation and dumping
|
||||||
|
succeeded, BASEPATH.fmt will be returned.
|
||||||
|
|
||||||
|
Should any errors occur during compilation, nil will be returned,
|
||||||
|
and appropriate warnings may be emitted."
|
||||||
|
(let ((dump-file (concat basepath ".fmt"))
|
||||||
|
(preamble-file (concat basepath ".tex"))
|
||||||
|
(precompile-buffer
|
||||||
|
(with-current-buffer
|
||||||
|
(get-buffer-create org-latex--precompile-log)
|
||||||
|
(erase-buffer)
|
||||||
|
(current-buffer))))
|
||||||
|
(with-temp-file preamble-file
|
||||||
|
(insert preamble "\n\\endofdump\n"))
|
||||||
|
(message "Precompiling Org LaTeX preamble...")
|
||||||
|
(condition-case nil
|
||||||
|
(org-compile-file
|
||||||
|
preamble-file (list org-latex-precompile-command)
|
||||||
|
"fmt" nil precompile-buffer
|
||||||
|
(or (plist-get info :precompile-format-spec)
|
||||||
|
`((?l . ,(plist-get info :latex-compiler))
|
||||||
|
(?L . ,(plist-get info :latex-compiler)))))
|
||||||
|
(:success
|
||||||
|
(kill-buffer precompile-buffer)
|
||||||
|
(delete-file preamble-file)
|
||||||
|
dump-file)
|
||||||
|
(error
|
||||||
|
(unless (= 0 (call-process "kpsewhich" nil nil nil "mylatexformat.ltx"))
|
||||||
|
(display-warning
|
||||||
|
'(org latex-preview preamble-precompilation)
|
||||||
|
"The LaTeX package \"mylatexformat\" is required for precompilation, but could not be found")
|
||||||
|
:warning)
|
||||||
|
(unless (= 0 (call-process "kpsewhich" nil nil nil "preview.sty"))
|
||||||
|
(display-warning
|
||||||
|
'(org latex-preview preamble-precompilation)
|
||||||
|
"The LaTeX package \"preview\" is required for precompilation, but could not be found")
|
||||||
|
:warning)
|
||||||
|
(display-warning
|
||||||
|
'(org latex-preview preamble-precompilation)
|
||||||
|
(format "Failed to precompile preamble (%s), see the \"%s\" buffer."
|
||||||
|
preamble-file precompile-buffer)
|
||||||
|
:warning)
|
||||||
|
nil))))
|
||||||
|
|
||||||
|
|
||||||
;;; Transcode Functions
|
;;; Transcode Functions
|
||||||
|
|
Loading…
Reference in New Issue