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 9 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 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}

+ 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
 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~.

+ 2 - 2
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)

+ 90 - 48
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)