diff --git a/doc/org.texi b/doc/org.texi index 8de8efc22..f743fade6 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -11899,16 +11899,14 @@ pages, configure the variable @code{org-html-use-infojs}. @cindex @LaTeX{} export @cindex PDF export -@LaTeX{} export can produce an arbitrarily complex LaTeX document of any -standard or custom document class. With further processing@footnote{The -default @LaTeX{} output is designed for processing with @code{pdftex} or -@code{latex}. The @LaTeX{} exporter can be configured to support alternative -TeX engines, see see @code{org-latex-pdf-process}, and alternative packages, -see @code{org-latex-default-packages-alist} and -@code{org-latex-packages-alist}.}, which the @LaTeX{} exporter is able to -control, this back-end is able to produce PDF output. Because the @LaTeX{} -exporter can be configured to use the @code{hyperref} package, the default -setup produces fully-linked PDF output. +The @LaTeX{} exporter can produce an arbitrarily complex @LaTeX{} document of +any standard or custom document class@footnote{The @LaTeX{} exporter can be +configured to support alternative @LaTeX{} engines (see +@code{org-latex-compiler}), build sequences (see +@code{org-latex-pdf-process}), and packages, (see +@code{org-latex-default-packages-alist} and +@code{org-latex-packages-alist}).}. The Org @LaTeX{} exporter is geared +towards producing fully-linked PDF output. As in @LaTeX{}, blank lines are meaningful for this back-end: a paragraph will not be started if two contiguous syntactical elements are not separated @@ -11942,6 +11940,19 @@ Export as @LaTeX{} and then process to PDF. Export as @LaTeX{} and then process to PDF, then open the resulting PDF file. @end table +@vindex org-latex-compiler +@vindex org-latex-bibtex-compiler +@vindex org-latex-default-packages-alist +The exporter supports several @LaTeX{} engines, namely @samp{pdflatex}, +@samp{xelatex} and @samp{lualatex}. The default @LaTeX{} compiler can be set +via @code{org-latex-compiler} or the @code{#+LATEX_COMPILER} keyword. It is +possible to only load some packages with certain compilers (see the docstring +of @code{org-latex-default-packages-alist}). The bibliography compiler may +also be set via @code{org-latex-bibtex-compiler}@footnote{You cannot set the +bibliography compiler on a file basis via a keyword. However, ``smart'' +@LaTeX{} compilation systems, such as @samp{latexmk}, are usually able to +select the correct bibliography compiler.}. + @node @LaTeX{} specific export settings @subsection @LaTeX{} specific export settings The @LaTeX{} exporter introduces a number of keywords, similar to the general @@ -11968,6 +11979,11 @@ The predefined preamble and headline level mapping to use @cindex #+LATEX_CLASS_OPTIONS Options given to the @LaTeX{} document class. +@item LATEX_COMPILER +@cindex #+LATEX_COMPILER +@vindex org-latex-compiler +The compiler used to produce the PDF (@code{org-latex-compiler}). + @item LATEX_HEADER @cindex #+LATEX_HEADER @vindex org-latex-classes @@ -14381,6 +14397,7 @@ however, override everything. @item @code{:latex-caption-above} @tab @code{org-latex-caption-above} @item @code{:latex-classes} @tab @code{org-latex-classes} @item @code{:latex-class} @tab @code{org-latex-default-class} +@item @code{:latex-compiler} @tab @code{org-latex-compiler} @item @code{:latex-default-figure-position} @tab @code{org-latex-default-figure-position} @item @code{:latex-default-table-environment} @tab @code{org-latex-default-table-environment} @item @code{:latex-default-table-mode} @tab @code{org-latex-default-table-mode} diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 50c5c0375..ba7761e9b 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -37,7 +37,9 @@ Evaluating a Stan block can produce two different results. For more information and usage examples, visit http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-stan.html - +*** New =#+latex_compiler= keyword to set LaTeX compiler. +PDFLaTeX, XeLaTeX, and LuaLaTeX are supported. See the manual for +details. ** New functions ~org-show-children~ is a faster implementation of ~outline-show-children~. diff --git a/lisp/org.el b/lisp/org.el index 1d2f175f6..cb555abb4 100755 --- a/lisp/org.el +++ b/lisp/org.el @@ -4080,8 +4080,8 @@ header, or they will be appended." (default-value var))) (defcustom org-latex-default-packages-alist - '(("AUTO" "inputenc" t) - ("T1" "fontenc" t) + '(("AUTO" "inputenc" t ("pdflatex")) + ("T1" "fontenc" t ("pdflatex")) ("" "graphicx" t) ("" "grffile" t) ("" "longtable" nil) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 1840a543a..951e62ac3 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -144,6 +144,7 @@ (:latex-text-markup-alist nil nil org-latex-text-markup-alist) (:latex-title-command nil nil org-latex-title-command) (:latex-toc-command nil nil org-latex-toc-command) + (:latex-compiler "LATEX_COMPILER" nil org-latex-compiler) ;; Redefine regular options. (:date "DATE" nil "\\today" parse))) @@ -1039,15 +1040,40 @@ during latex export it will output ;;;; Compilation +(defcustom org-latex-compiler-file-string "%% Indented LaTeX compiler: %s\n" + "LaTeX program format-string." + :group 'org-export-latex + :type '(choice + (const :tag "Comment" "%% Indented LaTeX compiler: %s\n") + (const :tag "latex-mode file variable" "%% -*- latex-run-command: %s -*-\n") + (const :tag "AUCTeX file variable" "%% -*- LaTeX-command: %s -*-\n") + (string :tag "custom format" "%% %s")) + :version "25.1" + :package-version '(Org . "9.0")) + +(defcustom org-latex-compiler "pdflatex" + "LaTeX program to use. Must be an element in `org-latex-compilers'." + :group 'org-export-latex + :type '(choice + (const :tag "pdfLaTeX" "pdflatex") + (const :tag "XeLaTeX" "xelatex") + (const :tag "LuaLaTeX" "lualatex")) + :version "25.1" + :package-version '(Org . "9.0")) + +(defconst org-latex-compilers '("pdflatex" "xelatex" "lualatex") + "Known LaTeX programs.") + (defcustom org-latex-pdf-process - '("pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f") + '("%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f") "Commands to process a LaTeX file to a PDF file. This is a list of strings, each of them will be given to the shell as a command. %f in the command will be replaced by the full file name, %b by the file base name (i.e. without directory -and extension parts) and %o by the base directory of the file. +and extension parts), %o by the base directory of the file, +and %latex is the LaTeX compiler (see `org-latex-compiler'). The reason why this is a list is that it usually takes several runs of `pdflatex', maybe mixed with a call to `bibtex'. Org @@ -1055,18 +1081,8 @@ does not have a clever mechanism to detect which of these commands have to be run to get to a stable result, and it also does not do any error checking. -By default, Org uses 3 runs of `pdflatex' to do the processing. -If you have texi2dvi on your system and if that does not cause -the infamous egrep/locale bug: - - http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html - -then `texi2dvi' is the superior choice as it automates the LaTeX -build process by calling the \"correct\" combinations of -auxiliary programs. Org does offer `texi2dvi' as one of the -customize options. Alternatively, `rubber' and `latexmk' also -provide similar functionality. The latter supports `biber' out -of the box. +Consider a smart LaTeX compiler such as `texi2dvi' or `latexmk', +which calls the \"correct\" combinations of auxiliary programs. Alternatively, this may be a Lisp function that does the processing, so you could use this to apply the machinery of @@ -1076,36 +1092,22 @@ file name as its single argument." :type '(choice (repeat :tag "Shell command sequence" (string :tag "Shell command")) - (const :tag "2 runs of pdflatex" - ("pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f")) - (const :tag "3 runs of pdflatex" - ("pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f")) - (const :tag "pdflatex,bibtex,pdflatex,pdflatex" - ("pdflatex -interaction nonstopmode -output-directory %o %f" - "bibtex %b" - "pdflatex -interaction nonstopmode -output-directory %o %f" - "pdflatex -interaction nonstopmode -output-directory %o %f")) - (const :tag "2 runs of xelatex" - ("xelatex -interaction nonstopmode -output-directory %o %f" - "xelatex -interaction nonstopmode -output-directory %o %f")) - (const :tag "3 runs of xelatex" - ("xelatex -interaction nonstopmode -output-directory %o %f" - "xelatex -interaction nonstopmode -output-directory %o %f" - "xelatex -interaction nonstopmode -output-directory %o %f")) - (const :tag "xelatex,bibtex,xelatex,xelatex" - ("xelatex -interaction nonstopmode -output-directory %o %f" + (const :tag "2 runs of latex" + ("%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f")) + (const :tag "3 runs of latex" + ("%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f")) + (const :tag "latex,bibtex,latex,latex" + ("%latex -interaction nonstopmode -output-directory %o %f" "bibtex %b" - "xelatex -interaction nonstopmode -output-directory %o %f" - "xelatex -interaction nonstopmode -output-directory %o %f")) + "%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f")) (const :tag "texi2dvi" - ("texi2dvi -p -b -V %f")) - (const :tag "rubber" - ("rubber -d --into %o %f")) + ("LATEX=\"%latex\" texi2dvi -p -b -V %f")) (const :tag "latexmk" - ("latexmk -g -pdf %f")) + ("latexmk -g -pdflatex=\"%latex\" %f")) (function))) (defcustom org-latex-logfiles-extensions @@ -1346,6 +1348,30 @@ Return the new header." "")) t t header 0))))) +(defun org-latex--remove-packages (pkg-alist info) + "Remove packages based on the current LaTeX program. + +If the fourth argument of an element is set in pkg-alist, and it +is not a member of the LaTeX program of the document, the packages +is removed. See also `org-latex-compiler'. + +Return modified pkg-alist." + (let ((compiler (or (plist-get info :latex-compiler) ""))) + (if (member-ignore-case compiler org-latex-compilers) + (delq nil + (mapcar + (lambda (pkg) + (unless (and + (listp pkg) + (let ((third (nth 3 pkg))) + (and third + (not (member-ignore-case + compile + (if (listp third) third (list third))))))) + pkg)) + pkg-alist)) + pkg-alist))) + (defun org-latex--find-verb-separator (s) "Return a character not used in string S. This is used to choose a separator for constructs like \\verb." @@ -1495,8 +1521,9 @@ INFO is a plist used as a communication channel." (org-element-normalize-string (org-splice-latex-header document-class-string - org-latex-default-packages-alist - org-latex-packages-alist nil + (org-latex--remove-packages org-latex-default-packages-alist info) + (org-latex--remove-packages org-latex-packages-alist info) + nil (concat (org-element-normalize-string (plist-get info :latex-header)) (plist-get info :latex-header-extra))))) @@ -1516,6 +1543,11 @@ holding export options." ;; Time-stamp. (and (plist-get info :time-stamp-file) (format-time-string "%% Created %Y-%m-%d %a %H:%M\n")) + ;; LaTeX program. + (let ((compiler (plist-get info :latex-compiler))) + (and (org-string-nw-p org-latex-compiler-file-string) + (string-match-p (regexp-opt org-latex-compilers) (or compiler "")) + (format org-latex-compiler-file-string compiler))) ;; Document class and packages. (org-latex--make-header info) ;; Possibly limit depth for headline numbering. @@ -3432,6 +3464,14 @@ create a log buffer and do not bother removing log files. Return PDF file name or an error if it couldn't be produced." (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile))) (full-name (file-truename texfile)) + (compiler (or (with-temp-buffer + (save-excursion (insert-file-contents full-name)) + (when (and (search-forward-regexp + (regexp-opt org-latex-compilers) (line-end-position 2) t) + (progn (beginning-of-line) + (looking-at-p "%"))) + (match-string 0))) + "pdflatex")) (out-dir (file-name-directory texfile)) ;; Properly set working directory for compilation. (default-directory (if (file-name-absolute-p texfile) @@ -3454,11 +3494,13 @@ Return PDF file name or an error if it couldn't be produced." (dolist (command org-latex-pdf-process) (shell-command (replace-regexp-in-string - "%b" (shell-quote-argument base-name) + "%latex" (shell-quote-argument compiler) (replace-regexp-in-string - "%f" (shell-quote-argument full-name) + "%b" (shell-quote-argument base-name) (replace-regexp-in-string - "%o" (shell-quote-argument out-dir) command t t) t t) t t) + "%f" (shell-quote-argument full-name) + (replace-regexp-in-string + "%o" (shell-quote-argument out-dir) command t t) t t) t t) t) outbuf)) ;; Collect standard errors from output buffer. (setq warnings (and (not snippet)