emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[O] [PATCH] EPS generation from latex source block


From: Thibault Marin
Subject: [O] [PATCH] EPS generation from latex source block
Date: Sun, 14 Feb 2016 03:14:52 -0600

Here is a small patch I use to produce TikZ EPS files from LaTeX source
blocks.

>From d750c26cabc87e4917974df8080714d5d7e2c9a8 Mon Sep 17 00:00:00 2001
From: thibault
Date: Sun, 14 Feb 2016 03:07:20 -0600
Subject: [PATCH] Add eps output to ob-latex (without imagemagick)
To: address@hidden

* ob-latex: Accept output file with EPS extension without requiring the
  imagemagick option.  This can be used to generate EPS files from TikZ
  in LaTeX source blocks.
* ox-latex: Add `org-latex-eps-process' based on
  `org-latex-pdf-process'.  Default build uses dvips and ghostscript to
  produce an EPS file with correct bounding box.  Add an extra optional
  argument to `org-latex-compile' to pass the output file type (pdf or
  eps)
---
 lisp/ob-latex.el | 18 +++++++++++----
 lisp/ox-latex.el | 67 +++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/lisp/ob-latex.el b/lisp/ob-latex.el
index a8fbe29..416e5be 100644
--- a/lisp/ob-latex.el
+++ b/lisp/ob-latex.el
@@ -158,7 +158,7 @@ This function is called by `org-babel-execute-src-block'."
                                       ".html")
                               out-file)
              (error "HTML file produced but SVG file requested")))))
-        ((or (string-match "\\.pdf$" out-file) imagemagick)
+        ((or (string-match "\\.pdf$" out-file) (string-match "\\.eps$" 
out-file) imagemagick)
          (with-temp-file tex-file
            (require 'ox-latex)
            (insert
@@ -189,9 +189,14 @@ This function is called by `org-babel-execute-src-block'."
                         "\n\\end{preview}\n\\end{document}\n")
               (concat "\n\\begin{document}\n" body "\n\\end{document}\n"))))
           (when (file-exists-p out-file) (delete-file out-file))
-         (let ((transient-pdf-file (org-babel-latex-tex-to-pdf tex-file)))
+         (let ((transient-pdf-file
+                (cond ((string-match "\\.pdf$" out-file)
+                       (org-babel-latex-tex-to-pdf tex-file))
+                      ((and (not imagemagick) (string-match "\\.eps$" 
out-file))
+                       (org-babel-latex-tex-to-eps tex-file)))))
            (cond
-            ((string-match "\\.pdf$" out-file)
+            ((or (string-match "\\.pdf$" out-file)
+                 (and (not imagemagick) (string-match "\\.eps$" out-file)))
              (rename-file transient-pdf-file out-file))
             (imagemagick
              (org-babel-latex-convert-pdf
@@ -199,7 +204,7 @@ This function is called by `org-babel-execute-src-block'."
              (when (file-exists-p transient-pdf-file)
                (delete-file transient-pdf-file))))))
          ((string-match "\\.\\([^\\.]+\\)$" out-file)
-          (error "Can not create %s files, please specify a .png or .pdf file 
or try the :imagemagick header argument"
+          (error "Can not create %s files, please specify a .png, .pdf or .eps 
file or try the :imagemagick header argument"
                 (match-string 1 out-file))))
         nil) ;; signal that output has already been written to file
     body))
@@ -216,6 +221,11 @@ This function is called by `org-babel-execute-src-block'."
   (require 'ox-latex)
   (org-latex-compile file))
 
+(defun org-babel-latex-tex-to-eps (file)
+  "Generate a pdf file according to the contents FILE."
+  (require 'ox-latex)
+  (org-latex-compile file nil "eps"))
+
 (defun org-babel-prep-session:latex (_session _params)
   "Return an error because LaTeX doesn't support sessions."
   (error "LaTeX does not support sessions"))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 9285aac..eb0c883 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1166,6 +1166,36 @@ file name as its single argument."
                 ("latexmk -g -pdflatex=\"%latex\" %f"))
          (function)))
 
+(defcustom org-latex-eps-dpi 300
+  "Resolution for EPS image generation.
+This is passed to the ghostscript command when adjusting the bounding
+box."
+  :group 'org-export-latex
+  :type 'integer
+  :version "25.1"
+  :package-version '(Org . "9.0"))
+
+(defcustom org-latex-eps-process
+  '("latex -interaction nonstopmode %f"
+    "dvips -R -K0 -E %b.dvi -o %b_t.eps"
+    "gs -dNOPAUSE -dBATCH -sDEVICE=eps2write -r600 -sOutputFile=%b.eps 
%b_t.eps")
+  "Commands to process a LaTeX file to an EPS file.
+This is a list of commands built similarly to
+`org-latex-pdf-process'.  %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), %o by the base directory of the
+file.
+
+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."
+  :group 'org-export-pdf
+  :type '((string)
+         (function))
+  :version "25.1"
+  :package-version '(Org . "9.0"))
+
 (defcustom org-latex-logfiles-extensions
   '("aux" "bcf" "blg" "fdb_latexmk" "fls" "figlist" "idx" "log" "nav" "out"
     "ptc" "run.xml" "snm" "toc" "vrb" "xdv")
@@ -3515,18 +3545,27 @@ 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 output-type)
   "Compile a TeX file.
 
 TEXFILE is the name of the file being compiled.  Processing is
-done through the command specified in `org-latex-pdf-process'.
+done through the command specified in ORG-LATEX-PROCESS.
+ORG-LATEX-PROCESS defaults to `org-latex-pdf-process'.  An alternative
+to produce EPS output instead of PDF is to use
+`org-latex-eps-process'.
 
 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.
 
 Return PDF file name or an error if it couldn't be produced."
-  (let* ((base-name (file-name-sans-extension (file-name-nondirectory 
texfile)))
+  (unless output-type (setq output-type "pdf"))
+  (let* ((org-latex-process
+         (cond ((string= output-type "pdf") org-latex-pdf-process)
+               ((string= output-type "eps") org-latex-eps-process)
+               (t nil)))
+        (output-type-str (upcase output-type))
+        (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))
@@ -3547,23 +3586,24 @@ Return PDF file name or an error if it couldn't be 
produced."
     (save-window-excursion
       (cond
        ;; A function is provided: Apply it.
-       ((functionp org-latex-pdf-process)
-       (funcall org-latex-pdf-process (shell-quote-argument texfile)))
+       ((functionp org-latex-process)
+       (funcall org-latex-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',
+       ;; "%latex" and "%bibtex" is used in `org-latex-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)
+       ((consp org-latex-process)
        (let ((outbuf (and (not snippet)
-                          (get-buffer-create "*Org PDF LaTeX Output*")))
+                          (get-buffer-create
+                           (format "*Org %s LaTeX Output*" output-type-str))))
              (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)
+         (dolist (command org-latex-process)
            (let ((c (replace-regexp-in-string
                      "%\\(latex\\|bibtex\\)\\>"
                      (lambda (str) (upcase (substring str 0 2)))
@@ -3572,8 +3612,8 @@ Return PDF file name or an error if it couldn't be 
produced."
          ;; 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")))
+       (t (error (format "No valid command to process to %s" 
output-type-str))))
+      (let ((pdffile (concat out-dir base-name "." output-type)))
        ;; Check for process failure.  Provide collected errors if
        ;; possible.
        (if (or (not (file-exists-p pdffile))
@@ -3581,7 +3621,8 @@ Return PDF file name or an error if it couldn't be 
produced."
                ;; (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))
+           (error (format "%s file %s wasn't produced"
+                          output-type-str pdffile))
          ;; Else remove log files, when specified, and signal end of
          ;; process to user, along with any error encountered.
          (unless snippet
@@ -3593,7 +3634,7 @@ Return PDF file name or an error if it couldn't be 
produced."
                                     "\\."
                                     (regexp-opt 
org-latex-logfiles-extensions))))
                (delete-file file)))
-           (message (concat "PDF file produced"
+           (message (concat output-type-str "file produced"
                             (cond
                              ((eq warnings 'error) " with errors.")
                              (warnings (concat " with warnings: " warnings))
-- 
2.7.0.rc3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]