Browse Source

ox-latex: Support changable TeX compilers

* org.el (org-latex-default-packages-alist): Only use inputenc
and fontenc in pdftex.
* ox-latex.el (latex): Add :latex-compiler.
(org-latex-compiler): New defcustom.
(org-latex-compilers): New defconst.
(org-latex--remove-packages): New function.
(org-latex-template): Use new function and variables.
(org-latex-pdf-process): Update to use %latex shorthand.
(org-latex-compile): Check and use intended compiler.
* org.texi (@LaTeX{} and PDF export): Document changes.
* ORG-NEWS: Add entry.

Adds #+latex_compiler: keyword.

Note, rubber is dropped from `org-latex-pdf-process' since it does not
allow arbitrary latex commands.

Suggested-by: Suvayu Ali <fatkasuvayu+linux@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/98921>
Rasmus 10 years ago
parent
commit
1e4b7e4bec
4 changed files with 122 additions and 61 deletions
  1. 27 10
      doc/org.texi
  2. 3 1
      etc/ORG-NEWS
  3. 2 2
      lisp/org.el
  4. 90 48
      lisp/ox-latex.el

+ 27 - 10
doc/org.texi

@@ -11899,16 +11899,14 @@ pages, configure the variable @code{org-html-use-infojs}.
 @cindex @LaTeX{} export
 @cindex @LaTeX{} export
 @cindex PDF 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
 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
 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.
 Export as @LaTeX{} and then process to PDF, then open the resulting PDF file.
 @end table
 @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
 @node @LaTeX{} specific export settings
 @subsection @LaTeX{} specific export settings
 @subsection @LaTeX{} specific export settings
 The @LaTeX{} exporter introduces a number of keywords, similar to the general
 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
 @cindex #+LATEX_CLASS_OPTIONS
 Options given to the @LaTeX{} document class.
 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
 @item LATEX_HEADER
 @cindex #+LATEX_HEADER
 @cindex #+LATEX_HEADER
 @vindex org-latex-classes
 @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-caption-above}              @tab @code{org-latex-caption-above}
 @item @code{:latex-classes}                    @tab @code{org-latex-classes}
 @item @code{:latex-classes}                    @tab @code{org-latex-classes}
 @item @code{:latex-class}                      @tab @code{org-latex-default-class}
 @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-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-environment}  @tab @code{org-latex-default-table-environment}
 @item @code{:latex-default-table-mode}         @tab @code{org-latex-default-table-mode}
 @item @code{:latex-default-table-mode}         @tab @code{org-latex-default-table-mode}

+ 3 - 1
etc/ORG-NEWS

@@ -37,7 +37,9 @@ Evaluating a Stan block can produce two different results.
 
 
 For more information and usage examples, visit
 For more information and usage examples, visit
 http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-stan.html
 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
 ** New functions
 ~org-show-children~ is a faster implementation of
 ~org-show-children~ is a faster implementation of
 ~outline-show-children~.
 ~outline-show-children~.

+ 2 - 2
lisp/org.el

@@ -4080,8 +4080,8 @@ header, or they will be appended."
 	  (default-value var)))
 	  (default-value var)))
 
 
 (defcustom org-latex-default-packages-alist
 (defcustom org-latex-default-packages-alist
-  '(("AUTO" "inputenc"  t)
-    ("T1"   "fontenc"   t)
+  '(("AUTO" "inputenc"  t ("pdflatex"))
+    ("T1"   "fontenc"   t ("pdflatex"))
     (""     "graphicx"  t)
     (""     "graphicx"  t)
     (""     "grffile"   t)
     (""     "grffile"   t)
     (""     "longtable" nil)
     (""     "longtable" nil)

+ 90 - 48
lisp/ox-latex.el

@@ -144,6 +144,7 @@
     (:latex-text-markup-alist nil nil org-latex-text-markup-alist)
     (:latex-text-markup-alist nil nil org-latex-text-markup-alist)
     (:latex-title-command nil nil org-latex-title-command)
     (:latex-title-command nil nil org-latex-title-command)
     (:latex-toc-command nil nil org-latex-toc-command)
     (:latex-toc-command nil nil org-latex-toc-command)
+    (:latex-compiler "LATEX_COMPILER" nil org-latex-compiler)
     ;; Redefine regular options.
     ;; Redefine regular options.
     (:date "DATE" nil "\\today" parse)))
     (:date "DATE" nil "\\today" parse)))
 
 
@@ -1039,15 +1040,40 @@ during latex export it will output
 
 
 ;;;; Compilation
 ;;;; 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
 (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.
   "Commands to process a LaTeX file to a PDF file.
 This is a list of strings, each of them will be given to the
 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
 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
 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
 The reason why this is a list is that it usually takes several
 runs of `pdflatex', maybe mixed with a call to `bibtex'.  Org
 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
 commands have to be run to get to a stable result, and it also
 does not do any error checking.
 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
 Alternatively, this may be a Lisp function that does the
 processing, so you could use this to apply the machinery of
 processing, so you could use this to apply the machinery of
@@ -1076,36 +1092,22 @@ file name as its single argument."
   :type '(choice
   :type '(choice
 	  (repeat :tag "Shell command sequence"
 	  (repeat :tag "Shell command sequence"
 		  (string :tag "Shell command"))
 		  (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"
 		  "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"
 	  (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"
 	  (const :tag "latexmk"
-		 ("latexmk -g -pdf %f"))
+		 ("latexmk -g -pdflatex=\"%latex\" %f"))
 	  (function)))
 	  (function)))
 
 
 (defcustom org-latex-logfiles-extensions
 (defcustom org-latex-logfiles-extensions
@@ -1346,6 +1348,30 @@ Return the new header."
 		  ""))
 		  ""))
 	 t t header 0)))))
 	 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)
 (defun org-latex--find-verb-separator (s)
   "Return a character not used in string S.
   "Return a character not used in string S.
 This is used to choose a separator for constructs like \\verb."
 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-element-normalize-string
 	     (org-splice-latex-header
 	     (org-splice-latex-header
 	      document-class-string
 	      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
 	      (concat (org-element-normalize-string
 		       (plist-get info :latex-header))
 		       (plist-get info :latex-header))
 		      (plist-get info :latex-header-extra)))))
 		      (plist-get info :latex-header-extra)))))
@@ -1516,6 +1543,11 @@ holding export options."
      ;; Time-stamp.
      ;; Time-stamp.
      (and (plist-get info :time-stamp-file)
      (and (plist-get info :time-stamp-file)
 	  (format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
 	  (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.
      ;; Document class and packages.
      (org-latex--make-header info)
      (org-latex--make-header info)
      ;; Possibly limit depth for headline numbering.
      ;; 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."
 Return PDF file name or an error if it couldn't be produced."
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile)))
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile)))
 	 (full-name (file-truename 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))
 	 (out-dir (file-name-directory texfile))
 	 ;; Properly set working directory for compilation.
 	 ;; Properly set working directory for compilation.
 	 (default-directory (if (file-name-absolute-p texfile)
 	 (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)
 	  (dolist (command org-latex-pdf-process)
 	    (shell-command
 	    (shell-command
 	     (replace-regexp-in-string
 	     (replace-regexp-in-string
-	      "%b" (shell-quote-argument base-name)
+	      "%latex" (shell-quote-argument compiler)
 	      (replace-regexp-in-string
 	      (replace-regexp-in-string
-	       "%f" (shell-quote-argument full-name)
+	       "%b" (shell-quote-argument base-name)
 	       (replace-regexp-in-string
 	       (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))
 	     outbuf))
 	  ;; Collect standard errors from output buffer.
 	  ;; Collect standard errors from output buffer.
 	  (setq warnings (and (not snippet)
 	  (setq warnings (and (not snippet)