From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Feng Shu" Subject: Re: [PATCH] New feature: Use dvisvgm to preview latex formular Date: Sun, 15 May 2016 10:27:00 +0800 Message-ID: <87mvnsm4y3.fsf@163.com> References: <87lh3dxibp.fsf@163.com> <87lh3chenz.fsf@163.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:33818) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2McQ-0007Fi-P6 for emacs-orgmode@gnu.org; Mon, 16 May 2016 13:47:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2McJ-00073t-1m for emacs-orgmode@gnu.org; Mon, 16 May 2016 13:47:49 -0400 Received: from plane.gmane.org ([80.91.229.3]:36491) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2McI-00072R-Ih for emacs-orgmode@gnu.org; Mon, 16 May 2016 13:47:43 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1b1sbi-0006i0-7X for emacs-orgmode@gnu.org; Sun, 15 May 2016 11:45:06 +0200 Received: from 183.206.77.37 ([183.206.77.37]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 15 May 2016 11:45:06 +0200 Received: from tumashu by 183.206.77.37 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 15 May 2016 11:45:06 +0200 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org "Feng Shu" writes: I will refactor the latex previewing code, this patch should be delay reviewd. > "Feng Shu" writes: > > This is version 2, make diff more easy read. > > From 66804cf5642256a38beb0b84ad8194562f34bfce Mon Sep 17 00:00:00 2001 > From: Feng Shu > Date: Sat, 14 May 2016 22:42:53 +0800 > Subject: [PATCH] New feature: Use dvisvgm to preview latex formular > > Tester should set like below: > > (setq org-latex-create-formula-image-program 'dvisvgm) > (setq org-latex-pdf-process > '(:fetcher my-org-latex-pdf-process-format)) > (defun my-org-latex-pdf-process-format (&optional texfile snippet caller-info) > (cond > (snippet '("latex -interaction nonstopmode -output-directory %o %f")) > (t '("%latex -interaction nonstopmode -output-directory %o %f" > "%latex -interaction nonstopmode -output-directory %o %f" > "%latex -interaction nonstopmode -output-directory %o %f")))) > > * ox-latex.el (org-latex-pdf-process): Add a new config method, :fetcher. > (org-latex-compile): Add a new optional argument: caller-info, > which used to record the caller's info > > * ox-html.el (org-html-with-latex): Add dvisvgm support. > (org-html-with-latex): Add dvisvgm support. > (org-html-format-latex): "ltxpng" -> "ltximg". > (org-html-latex-environment): Add dvisvgm support. > (org-html-latex-fragment): Add dvisvgm support. > > * org.el (org-latex-create-formula-image-program): Add dvisvgm. > (org-latex-preview-ltximg-directory): Rename from `org-latex-preview-ltximg-directory'. > (org--format-latex-make-overlay): Add optional image-type, which used to deal with svg. > (org-toggle-latex-fragment): "org-ltxpng" -> "org-ltximg". > (org-format-latex): Add dvisvgm support. > (org-create-formula-image): Add dvisvgm case. > (org-create-formula-image-with-dvisvgm): New function, deal with latex formula with dvisvgm command. > > * org.texi (@LaTeX{} fragments): Add dvisvgm information. > (Previewing @LaTeX{} fragments): Add dvisvgm information. > (Math formatting in HTML export): Add dvisvgm information. > (Working with @LaTeX{} math snippets): Add dvisvgm information. > --- > doc/org.texi | 39 +++++++++----- > lisp/org.el | 101 ++++++++++++++++++++++++++++------ > lisp/ox-html.el | 19 ++++--- > lisp/ox-latex.el | 161 +++++++++++++++++++++++++++++++++++-------------------- > 4 files changed, 225 insertions(+), 95 deletions(-) > > diff --git a/doc/org.texi b/doc/org.texi > index 17b01c2..286fabb 100644 > --- a/doc/org.texi > +++ b/doc/org.texi > @@ -10393,10 +10393,10 @@ snippets will be identified as @LaTeX{} source code: > @item > Environments of any kind@footnote{When MathJax is used, only the > environments recognized by MathJax will be processed. When > -@file{dvipng} program or @file{imagemagick} suite is used to create images, > -any @LaTeX{} environment will be handled.}. The only requirement is that the > -@code{\begin} statement appears on a new line, at the beginning of the line > -or after whitespaces only. > +@file{dvipng} program, @file{dvisvgm} program or @file{imagemagick} suite is > +used to create images, any @LaTeX{} environment will be handled.}. The only > +requirement is that the @code{\begin} statement appears on a new line, at the > +beginning of the line or after whitespaces only. > @item > Text within the usual @LaTeX{} math delimiters. To avoid conflicts with > currency specifications, single @samp{$} characters are only recognized as > @@ -10444,10 +10444,10 @@ lines: > @cindex @LaTeX{} fragments, preview > > @vindex org-latex-create-formula-image-program > -If you have a working @LaTeX{} installation and either @file{dvipng} or > -@file{convert} installed@footnote{These are respectively available at > -@url{http://sourceforge.net/projects/dvipng/} and from the @file{imagemagick} > -suite. Choose the converter by setting the variable > +If you have a working @LaTeX{} installation and @file{dvipng}, @file{dvisvgm} > +or @file{convert} installed@footnote{These are respectively available at > +@url{http://sourceforge.net/projects/dvipng/}, @url{http://dvisvgm.bplaced.net/} > +and from the @file{imagemagick} suite. Choose the converter by setting the variable > @code{org-latex-create-formula-image-program} accordingly.}, @LaTeX{} > fragments can be processed to produce images of the typeset expressions to be > used for inclusion while exporting to HTML (see @pxref{@LaTeX{} fragments}), > @@ -11713,6 +11713,7 @@ You could use @code{http} addresses just as well. > @subsection Math formatting in HTML export > @cindex MathJax > @cindex dvipng > +@cindex dvisvgm > @cindex imagemagick > > @LaTeX{} math snippets (@pxref{@LaTeX{} fragments}) can be displayed in two > @@ -11737,13 +11738,18 @@ template can be configure via @code{org-html-mathjax-template}. > If you prefer, you can also request that @LaTeX{} fragments are processed > into small images that will be inserted into the browser page. Before the > availability of MathJax, this was the default method for Org files. This > -method requires that the @file{dvipng} program or @file{imagemagick} suite is > -available on your system. You can still get this processing with > +method requires that the @file{dvipng} program, @file{dvisvgm} or > +@file{imagemagick} suite is available on your system. You can still get > +this processing with > > @example > #+OPTIONS: tex:dvipng > @end example > > +@example > +#+OPTIONS: tex:dvisvgm > +@end example > + > or: > > @example > @@ -12908,6 +12914,7 @@ and open the formula file with the system-registered application. > @end table > > @cindex dvipng > +@cindex dvisvgm > @cindex imagemagick > @item PNG images > > @@ -12917,16 +12924,20 @@ This option is activated on a per-file basis with > #+OPTIONS: tex:dvipng > @end example > > +@example > +#+OPTIONS: tex:dvisvgm > +@end example > + > or: > > @example > #+OPTIONS: tex:imagemagick > @end example > > -With this option, @LaTeX{} fragments are processed into PNG images and the > -resulting images are embedded in the exported document. This method requires > -that the @file{dvipng} program or @file{imagemagick} suite be available on > -your system. > +With this option, @LaTeX{} fragments are processed into PNG or SVG images and > +the resulting images are embedded in the exported document. This method requires > +that the @file{dvipng} program, @file{dvisvgm} or @file{imagemagick} suite be > +available on your system. > @end enumerate > > @node Working with MathML or OpenDocument formula files > diff --git a/lisp/org.el b/lisp/org.el > index f45d5d0..d86042c 100644 > --- a/lisp/org.el > +++ b/lisp/org.el > @@ -3985,15 +3985,22 @@ When using LaTeXML set this option to > dvipng Process the LaTeX fragments to dvi file, then convert > dvi files to png files using dvipng. > This will also include processing of non-math environments. > +dvisvgm Process the LaTeX fragments to dvi/xdv file, then convert > + dvi/xdv files to svg files using dvipng. > + This will also include processing of non-math environments. > imagemagick Convert the LaTeX fragments to pdf files and use imagemagick > to convert pdf files to png files" > :group 'org-latex > :version "24.1" > :type '(choice > (const :tag "dvipng" dvipng) > + (const :tag "dvisvgm" dvisvgm) > (const :tag "imagemagick" imagemagick))) > > -(defcustom org-latex-preview-ltxpng-directory "ltxpng/" > +(defalias 'org-latex-preview-ltxpng-directory 'org-latex-preview-ltximg-directory) > +(make-obsolete 'org-latex-preview-ltxpng-directory 'org-latex-preview-ltximg-directory > + "Org mode version 9.0") > +(defcustom org-latex-preview-ltximg-directory "ltximg/" > "Path to store latex preview images. > A relative path here creates many directories relative to the > processed org files paths. An absolute path puts all preview > @@ -18996,9 +19003,10 @@ looks only before point, not after." > (org-in-regexp > "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*"))) > > -(defun org--format-latex-make-overlay (beg end image) > +(defun org--format-latex-make-overlay (beg end image &optional imagetype) > "Build an overlay between BEG and END using IMAGE file." > - (let ((ov (make-overlay beg end))) > + (let ((ov (make-overlay beg end)) > + (imagetype (or imagetype 'png))) > (overlay-put ov 'org-overlay-type 'org-latex-overlay) > (overlay-put ov 'evaporate t) > (overlay-put ov > @@ -19008,10 +19016,10 @@ looks only before point, not after." > (if (featurep 'xemacs) > (progn > (overlay-put ov 'invisible t) > - (overlay-put ov 'end-glyph (make-glyph (vector 'png :file image)))) > + (overlay-put ov 'end-glyph (make-glyph (vector imagetype :file image)))) > (overlay-put ov > 'display > - (list 'image :type 'png :file image :ascent 'center))))) > + (list 'image :type imagetype :file image :ascent 'center))))) > > (defun org--list-latex-overlays (&optional beg end) > "List all Org LaTeX overlays in current buffer. > @@ -19092,7 +19100,7 @@ for all fragments in the buffer." > (narrow-to-region beg end)))))) > (let ((file (buffer-file-name (buffer-base-buffer)))) > (org-format-latex > - (concat org-latex-preview-ltxpng-directory "org-ltxpng") > + (concat org-latex-preview-ltximg-directory "org-ltximg") > ;; Emacs cannot overlay images from remote hosts. > ;; Create it in `temporary-file-directory' instead. > (if (or (not file) (file-remote-p file)) > @@ -19123,7 +19131,7 @@ Some of the options can be changed using the variable > checkdir-flag) > (goto-char (point-min)) > ;; Optimize overlay creation: (info "(elisp) Managing Overlays"). > - (when (and overlays (memq processing-type '(dvipng imagemagick))) > + (when (and overlays (memq processing-type '(dvipng dvisvgm imagemagick))) > (overlay-recenter (point-max))) > (while (re-search-forward math-regexp nil t) > (unless (and overlays > @@ -19148,7 +19156,7 @@ Some of the options can be changed using the variable > (if (string= (match-string 0 value) "$$") > (insert "\\[" (substring value 2 -2) "\\]") > (insert "\\(" (substring value 1 -1) "\\)")))) > - ((dvipng imagemagick) > + ((dvipng dvisvgm imagemagick) > ;; Process to an image. > (cl-incf cnt) > (goto-char beg) > @@ -19172,9 +19180,10 @@ Some of the options can be changed using the variable > org-latex-packages-alist > org-format-latex-options > forbuffer value fg bg)))) > + (imagetype (if (eq processing-type 'dvisvgm) 'svg 'png)) > (absprefix (expand-file-name prefix dir)) > - (linkfile (format "%s_%s.png" prefix hash)) > - (movefile (format "%s_%s.png" absprefix hash)) > + (linkfile (format "%s_%s.%s" prefix hash imagetype)) > + (movefile (format "%s_%s.%s" absprefix hash imagetype)) > (sep (and block-type "\n\n")) > (link (concat sep "[[file:" linkfile "]]" sep)) > (options > @@ -19196,7 +19205,7 @@ Some of the options can be changed using the variable > (when (eq (overlay-get o 'org-overlay-type) > 'org-latex-overlay) > (delete-overlay o))) > - (org--format-latex-make-overlay beg end movefile) > + (org--format-latex-make-overlay beg end movefile imagetype) > (goto-char end)) > (delete-region beg end) > (insert > @@ -19315,10 +19324,10 @@ inspection." > > (defun org-create-formula-image (string tofile options buffer &optional type) > "Create an image from LaTeX source using dvipng or convert. > -This function calls either `org-create-formula-image-with-dvipng' > -or `org-create-formula-image-with-imagemagick' depending on the > -value of `org-latex-create-formula-image-program' or on the value > -of the optional TYPE variable. > +This function calls `org-create-formula-image-with-dvipng' > +`org-create-formula-image-with-dvisvgm' or `org-create-formula-image-with-imagemagick' > +depending on the value of `org-latex-create-formula-image-program' or > +on the value of the optional TYPE variable. > > Note: ultimately these two function should be combined as they > share a good deal of logic." > @@ -19330,6 +19339,10 @@ share a good deal of logic." > (org-check-external-command > "dvipng" "needed to convert LaTeX fragments to images") > #'org-create-formula-image-with-dvipng) > + (dvisvgm > + (org-check-external-command > + "dvisvgm" "needed to convert LaTeX fragments to images") > + #'org-create-formula-image-with-dvisvgm) > (imagemagick > (org-check-external-command > "convert" "you need to install imagemagick") > @@ -19429,6 +19442,64 @@ horizontal and vertical directions." > (delete-file (concat texfilebase e)))) > pngfile)))) > > +(defun org-create-formula-image-with-dvisvgm (string tofile options buffer) > + "This calls dvisvgm." > + (require 'ox-latex) > + (let* ((tmpdir (if (featurep 'xemacs) > + (temp-directory) > + temporary-file-directory)) > + (texfilebase (make-temp-name > + (expand-file-name "orgtex" tmpdir))) > + (texfile (concat texfilebase ".tex")) > + (dvifile (concat texfilebase ".dvi")) > + (xdvfile (concat texfilebase ".xdv")) > + (svgfile (concat texfilebase ".svg")) > + (scale (number-to-string (or (plist-get options (if buffer :scale :html-scale)) 2.0))) > + (fg (or (plist-get options (if buffer :foreground :html-foreground)) > + "Black")) > + (bg (or (plist-get options (if buffer :background :html-background)) > + "Transparent"))) > + (if (eq fg 'default) (setq fg (org-latex-color :foreground)) > + (setq fg (org-latex-color-format fg))) > + (if (eq bg 'default) (setq bg (org-latex-color :background)) > + (setq bg (org-latex-color-format > + (if (string= bg "Transparent") "white" bg)))) > + (let ((latex-header (org-create-formula--latex-header))) > + (with-temp-file texfile > + (insert latex-header) > + (insert "\n\\begin{document}\n" > + "\\definecolor{fg}{rgb}{" fg "}\n" > + "\\definecolor{bg}{rgb}{" bg "}\n" > + "\n\\pagecolor{bg}\n" > + "\n{\\color{fg}\n" > + string > + "\n}\n" > + "\n\\end{document}\n"))) > + (org-latex-compile texfile t '(:name dvisvgm :need dvi)) > + (if (not (or (file-exists-p dvifile) > + (file-exists-p xdvfile))) > + (progn (message "Failed to create dvi or xdv file from %s" texfile) nil) > + (ignore-errors > + (call-process "dvisvgm" nil nil nil > + (if (file-exists-p dvifile) > + dvifile > + xdvfile) > + "-n" > + "-b" "min" > + "-c" scale > + "-o" svgfile)) > + (if (not (file-exists-p svgfile)) > + (if org-format-latex-signal-error > + (error "Failed to create svg file from %s" texfile) > + (message "Failed to create svg file from %s" texfile) > + nil) > + ;; Use the requested file name and clean up > + (copy-file svgfile tofile 'replace) > + (dolist (e '(".dvi" ".xdv" ".tex" ".aux" ".log" ".svg" ".out")) > + (when (file-exists-p (concat texfilebase e)) > + (delete-file (concat texfilebase e)))) > + svgfile)))) > + > (declare-function org-latex-compile "ox-latex" (texfile &optional snippet)) > (defun org-create-formula-image-with-imagemagick (string tofile options buffer) > "This calls convert, which is included into imagemagick." > diff --git a/lisp/ox-html.el b/lisp/ox-html.el > index b188c38..2c1fa4a 100644 > --- a/lisp/ox-html.el > +++ b/lisp/ox-html.el > @@ -818,7 +818,9 @@ e.g. \"tex:mathjax\". Allowed values are: > > nil Ignore math snippets. > `verbatim' Keep everything in verbatim > -`dvipng' Process the LaTeX fragments to images. This will also > +`dvipng' Process the LaTeX fragments to png images. This will also > + include processing of non-math environments. > +`dvisvgm' Process the LaTeX fragments to svg images. This will also > include processing of non-math environments. > `imagemagick' Convert the LaTeX fragments to pdf files and use > imagemagick to convert pdf files to png files. > @@ -830,7 +832,8 @@ t Synonym for `mathjax'." > :package-version '(Org . "8.0") > :type '(choice > (const :tag "Do not process math in any way" nil) > - (const :tag "Use dvipng to make images" dvipng) > + (const :tag "Use dvipng to make png images" dvipng) > + (const :tag "Use dvisvgm to make svg images" dvisvgm) > (const :tag "Use imagemagick to make images" imagemagick) > (const :tag "Use MathJax to display math" mathjax) > (const :tag "Leave math verbatim" verbatim))) > @@ -2760,9 +2763,9 @@ CONTENTS is nil. INFO is a plist holding contextual information." > (defun org-html-format-latex (latex-frag processing-type info) > "Format a LaTeX fragment LATEX-FRAG into HTML. > PROCESSING-TYPE designates the tool used for conversion. It is > -a symbol among `mathjax', `dvipng', `imagemagick', `verbatim' nil > -and t. See `org-html-with-latex' for more information. INFO is > -a plist containing export properties." > +a symbol among `mathjax', `dvipng', `dvisvgm', `imagemagick', > +`verbatim' nil and t. See `org-html-with-latex' for more information. > +INFO is a plist containing export properties." > (let ((cache-relpath "") (cache-dir "")) > (unless (eq processing-type 'mathjax) > (let ((bfn (or (buffer-file-name) > @@ -2777,7 +2780,7 @@ a plist containing export properties." > "\n") > "\n"))))) > (setq cache-relpath > - (concat "ltxpng/" > + (concat "ltximg/" > (file-name-sans-extension > (file-name-nondirectory bfn))) > cache-dir (file-name-directory bfn)) > @@ -2801,7 +2804,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." > (case processing-type > ((t mathjax) > (org-html-format-latex latex-frag 'mathjax info)) > - ((dvipng imagemagick) > + ((dvipng dvisvgm imagemagick) > (let ((formula-link > (org-html-format-latex latex-frag processing-type info))) > (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) > @@ -2822,7 +2825,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." > (case processing-type > ((t mathjax) > (org-html-format-latex latex-frag 'mathjax info)) > - ((dvipng imagemagick) > + ((dvipng dvisvgm imagemagick) > (let ((formula-link > (org-html-format-latex latex-frag processing-type info))) > (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) > diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el > index 7fa68c5..ccbd348 100644 > --- a/lisp/ox-latex.el > +++ b/lisp/ox-latex.el > @@ -1143,7 +1143,32 @@ 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 > AUCTeX or the Emacs LaTeX mode. This function should accept the > -file name as its single argument." > +file name as its single argument. > + > +User can set this variable to a plist, the first element of the > +plist is :fetcher and the second is a function, for example: > + > + (setq org-latex-pdf-process > + '(:fetcher my-org-latex-pdf-process-format)) > + > + (defun my-org-late-pdf-process-formt (&optional texfile snippet caller-info) > + (cond > + (snippet '(\"latex -interaction nonstopmode -output-directory %o %f\")) > + (t '(\"%latex -interaction nonstopmode -output-directory %o %f\" > + \"%latex -interaction nonstopmode -output-directory %o %f\" > + \"%latex -interaction nonstopmode -output-directory %o %f\")))) > + > +`org-latex-compile' will call the second function, then use the > +returned command list. > + > +the function has three optional arguments: texfile, snippet and > +caller-info, when `org-latex-compile' compile a tex snippet for > +previewing, snippet will set to t and client-info argument will > +record the infomation of org-latex-compile's caller, for example: > + > + (:name dvisvgm :need dvi) > + > +This information can be used to select tex command." > :group 'org-export-pdf > :type '(choice > (repeat :tag "Shell command sequence" > @@ -3515,7 +3540,7 @@ Return PDF file's name." > async subtreep visible-only body-only ext-plist > (lambda (file) (org-latex-compile file))))) > > -(defun org-latex-compile (texfile &optional snippet) > +(defun org-latex-compile (texfile &optional snippet caller-info) > "Compile a TeX file. > > TEXFILE is the name of the file being compiled. Processing is > @@ -3525,6 +3550,16 @@ When optional argument SNIPPET is non-nil, TEXFILE is a temporary > file used to preview a LaTeX snippet. In this case, do not > create a log buffer and do not bother removing log files. > > +By default, `org-latex-compile' will compile `texfile' to a pdf > +file, but when we compile a tex snippet, the desired output may > +dvi or xdv file instead of pdf file, snippet-generate-function > +can tell `org-latex-compile' the infomation with the argument > +CALLER-INFO, then org-latex-compile can find proper commands > +with this infomation, this argument is a property list, for > +example: > + > + (:caller dvisvgm :need dvi) > + > 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)) > @@ -3544,62 +3579,72 @@ Return PDF file name or an error if it couldn't be produced." > (time (current-time)) > warnings) > (unless snippet (message "Processing LaTeX file %s..." texfile)) > - (save-window-excursion > - (cond > - ;; A function is provided: Apply it. > - ((functionp org-latex-pdf-process) > - (funcall org-latex-pdf-process (shell-quote-argument texfile))) > - ;; A list is provided: Replace %b, %f and %o with appropriate > - ;; values in each command before applying it. Note that while > - ;; "%latex" and "%bibtex" is used in `org-latex-pdf-process', > - ;; they are replaced with "%L" and "%B" to adhere to > - ;; format-spec. Output is redirected to "*Org PDF LaTeX > - ;; Output*" buffer. > - ((consp org-latex-pdf-process) > - (let ((outbuf (and (not snippet) > - (get-buffer-create "*Org PDF LaTeX Output*"))) > - (spec (list (cons ?B (shell-quote-argument org-latex-bib-compiler)) > - (cons ?L (shell-quote-argument compiler)) > - (cons ?b (shell-quote-argument base-name)) > - (cons ?f (shell-quote-argument full-name)) > - (cons ?o (shell-quote-argument out-dir))))) > - (dolist (command org-latex-pdf-process) > - (let ((c (replace-regexp-in-string > - "%\\(latex\\|bibtex\\)\\>" > - (lambda (str) (upcase (substring str 0 2))) > - command))) > - (shell-command (format-spec c spec) outbuf))) > - ;; Collect standard errors from output buffer. > - (setq warnings (and (not snippet) > - (org-latex--collect-warnings outbuf))))) > - (t (error "No valid command to process to PDF"))) > - (let ((pdffile (concat out-dir base-name ".pdf"))) > - ;; Check for process failure. Provide collected errors if > - ;; possible. > - (if (or (not (file-exists-p pdffile)) > - ;; Only compare times up to whole seconds as some filesystems > - ;; (e.g. HFS+) do not retain any finer granularity. > - (time-less-p (cl-subseq (nth 5 (file-attributes pdffile)) 0 2) > - (cl-subseq time 0 2))) > - (error (format "PDF file %s wasn't produced" pdffile)) > - ;; Else remove log files, when specified, and signal end of > - ;; process to user, along with any error encountered. > - (unless snippet > - (when org-latex-remove-logfiles > - (dolist (file (directory-files > - out-dir t > - (concat (regexp-quote base-name) > - "\\(?:\\.[0-9]+\\)?" > - "\\." > - (regexp-opt org-latex-logfiles-extensions)))) > - (delete-file file))) > - (message (concat "PDF file produced" > - (cond > - ((eq warnings 'error) " with errors.") > - (warnings (concat " with warnings: " warnings)) > - (t ".")))))) > - ;; Return output file name. > - pdffile)))) > + (let* ((fetcher-function (plist-get org-latex-pdf-process :fetcher)) > + (latex-pdf-process > + (if fetcher-function > + (if (functionp fetcher-function) > + (funcall fetcher-function > + (shell-quote-argument texfile) snippet caller-info) > + (error "`org-latex-pdf-process' set an invalid fetcher function.")) > + org-latex-pdf-process))) > + (save-window-excursion > + (cond > + ;; A function is provided: Apply it. > + ((functionp latex-pdf-process) > + (funcall latex-pdf-process (shell-quote-argument texfile))) > + ;; A list is provided: Replace %b, %f and %o with appropriate > + ;; values in each command before applying it. Note that while > + ;; "%latex" and "%bibtex" is used in `org-latex-pdf-process', > + ;; they are replaced with "%L" and "%B" to adhere to > + ;; format-spec. Output is redirected to "*Org PDF LaTeX > + ;; Output*" buffer. > + ((consp latex-pdf-process) > + (let ((outbuf (and (not snippet) > + (get-buffer-create "*Org PDF LaTeX Output*"))) > + (spec (list (cons ?B (shell-quote-argument org-latex-bib-compiler)) > + (cons ?L (shell-quote-argument compiler)) > + (cons ?b (shell-quote-argument base-name)) > + (cons ?f (shell-quote-argument full-name)) > + (cons ?o (shell-quote-argument out-dir))))) > + (dolist (command latex-pdf-process) > + (let ((c (replace-regexp-in-string > + "%\\(latex\\|bibtex\\)\\>" > + (lambda (str) (upcase (substring str 0 2))) > + command))) > + (shell-command (format-spec c spec) outbuf))) > + ;; Collect standard errors from output buffer. > + (setq warnings (and (not snippet) > + (org-latex--collect-warnings outbuf))))) > + (t (error "No valid command to process to PDF"))) > + (let ((pdffile (concat out-dir base-name ".pdf"))) > + ;; Check for process failure. Provide collected errors if > + ;; possible. > + (if (or (not (file-exists-p pdffile)) > + ;; Only compare times up to whole seconds as some filesystems > + ;; (e.g. HFS+) do not retain any finer granularity. > + (time-less-p (cl-subseq (nth 5 (file-attributes pdffile)) 0 2) > + (cl-subseq time 0 2))) > + ;; When compile a tex snippet, we may only need dvi file > + (unless snippet > + (error (format "PDF file %s wasn't produced" pdffile))) > + ;; Else remove log files, when specified, and signal end of > + ;; process to user, along with any error encountered. > + (unless snippet > + (when org-latex-remove-logfiles > + (dolist (file (directory-files > + out-dir t > + (concat (regexp-quote base-name) > + "\\(?:\\.[0-9]+\\)?" > + "\\." > + (regexp-opt org-latex-logfiles-extensions)))) > + (delete-file file))) > + (message (concat "PDF file produced" > + (cond > + ((eq warnings 'error) " with errors.") > + (warnings (concat " with warnings: " warnings)) > + (t ".")))))) > + ;; Return output file name. > + pdffile))))) > > (defun org-latex--collect-warnings (buffer) > "Collect some warnings from \"pdflatex\" command output. > -- > 2.1.4 --