From: "Feng Shu" <tumashu@163.com>
To: orgmode-devel <emacs-orgmode@gnu.org>
Cc: Feng Shu <tumashu@163.com>
Subject: Re: (V8) [PATCH] New feature: Use dvisvgm to preview latex formular
Date: Wed, 18 May 2016 14:30:29 +0800 [thread overview]
Message-ID: <87mvnnev3u.fsf_-_@163.com> (raw)
In-Reply-To: <87k2itu2h2.fsf@saiph.selenimh> (Nicolas Goaziou's message of "Mon, 16 May 2016 23:17:45 +0200")
[-- Attachment #1: Type: text/plain, Size: 692 bytes --]
> As discussed in another message, I don't think we should mess with
> `org-latex-compile'. Instead, we could factor out the needed part in
> `org-latex-compile' and make it a generic function. Then we can
> introduce a new function to specifically handle previewing related
> compilation.
>
> Note that I'm not asking you to implement the factoring out part in your
> patch, but to tell me if the following would fulfill your needs for
> `org-create-formula-image'. I'm sending its docstring again.
>
I have rebase my patch to new function org-compile-file, the v8 patch is
very different with the earlier version, it is more simpler i think,
please comment again, thanks for your help!
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-New-feature-Use-dvisvgm-to-preview-latex-formular.patch --]
[-- Type: text/x-diff, Size: 34672 bytes --]
From 61885684f4826b06de4bb72b6ef1f369960f268a Mon Sep 17 00:00:00 2001
From: Feng Shu <tumashu@163.com>
Date: Tue, 17 May 2016 21:24:35 +0800
Subject: [PATCH] New feature: Use dvisvgm to preview latex formular
* 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-preview-latex-image-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): Big refactor, merge dvipng and imagemagick backend's feature.
Add dvisvgm feature.
(org-preview-latex-process-alist): Add new variable, which used to set
latex preview processes.
(org-create-formula-image-with-dvipng): Useless, removed.
(org-create-formula-image-with-imagemagick): Useless, removed.
* 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 | 41 +++--
lisp/org.el | 462 +++++++++++++++++++++++++++++++++++++-------------------
lisp/ox-html.el | 27 ++--
3 files changed, 346 insertions(+), 184 deletions(-)
diff --git a/doc/org.texi b/doc/org.texi
index 17b01c2..ad75b5d 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,11 +10444,11 @@ 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
-@code{org-latex-create-formula-image-program} accordingly.}, @LaTeX{}
+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}),
or for inline previewing within Org mode.
@@ -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..d752cac 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3985,15 +3985,103 @@ 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 dvisvgm.
+ 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/"
+(defcustom org-preview-latex-process-alist
+ '((dvipng
+ :programs ("latex" "dvipng" "gs")
+ :message "you need to install latex, dvipng and ghostscript."
+ :image-input dvi
+ :image-output png
+ :image-size-adjust (1.0 . 1.0)
+ :latex-compiler ("latex -interaction nonstopmode -output-directory %o %t")
+ :image-converter ("dvipng -fg %F -bg %B -D %d -T tight -o %p %i"))
+ (dvisvgm
+ :programs ("latex" "dvisvgm" "gs")
+ :message "you needed to install latex, dvisvgm and ghostscript."
+ :use-xcolor t
+ :image-input (dvi xdv)
+ :image-output svg
+ :image-size-adjust (1.7 . 1.5)
+ :latex-compiler ("latex -interaction nonstopmode -output-directory %o %t")
+ :image-converter ("dvisvgm %i -n -b min -c %s -o %p"))
+ (imagemagick
+ :programs ("latex" "convert" "gs")
+ :message "you need to install latex, imagemagick and ghostscript."
+ :use-xcolor t
+ :image-input pdf
+ :image-output png
+ :image-size-adjust (1.0 . 1.0)
+ :latex-compiler ("latex -interaction nonstopmode -output-directory %o %t")
+ :image-converter ("convert -density %d -trim -antialias %i -quality 100 %p")))
+ "List definitions of external processes for LaTeX previewing.
+Org mode can use some external commands to generate TeX snippet's image for
+previewing or inserting into HTML files, e.g. dvipng, dvisvgm or imagemagick.
+This variable tells `org-create-formula-image' how to use external commands.
+
+ :name symbol, the process setting name.
+ :inherit symbol, inhert options from an exist process setting.
+ :programs list of strings, required programs.
+ :message string, message it when required programs can't be found.
+ :image-input symbol, input file type, for example: dvi.
+ :image-output symbol, output file type, for example: png.
+ :use-xcolor boolean, if set to `t', LaTeX \"xcolor\" macro is used
+ to deal with background and foreground color of image,
+ if set to `nil', dvipng style background and foregroud color
+ format are generated; you should used them in command options
+ with special string: \"%F\" and \"%B\".
+ :image-size-adjust cons of numbers, the car element is used to adjust latex image
+ size showed in buffer and the cdr element is for html file.
+ This option is only useful for backend developers, users
+ should use variable `org-format-latex-options' instead.
+ :post-clean list of strings, files matched are to be cleaned up once the
+ image is generated. If set to `nil', the files with dvi, xdv,
+ pdf, tex, aux, log, svg, png, jpg, jpeg or out extension will
+ be cleaned up.
+ :latex-header list of string, latex snippet file's header, if set to `nil',
+ the return value of `org-create-formula--latex-header' will be
+ used, which is controled `org-format-latex-header',
+ `org-latex-default-packages-alist' and `org-latex-packages-alist'.
+ :latex-compiler list of latex commands, each of them will be given to the shell
+ as a command. the special strings, %t, %b and %o, will be replaced
+ to according value before commands called.
+ :image-converter list of image converter command strings, each of them will be
+ given to the shell as a command. the following special strings,
+ will be replaced to according value before commands called.
+
+Special strings used by `:image-converter' and `:latex-compiler':
+
+1. %F foreground
+2. %B background
+3. %d dpi, which is used to adjust image size by
+ some backend's command.
+4. %s the image size scale ratio, which is used to
+ adjust image size by some backend's command.
+5. %t tex file name.
+6. %i input file name of image converter.
+7. %p output file name of image converter.
+8. %b base name of input file
+9. %o the base directory of input file."
+ :group 'org-latex
+ :version "25.1"
+ :type '(alist :tag "LaTeX to image backends"
+ :value-type (plist)))
+
+(define-obsolete-variable-alias
+ 'org-latex-preview-ltxpng-directory
+ 'org-preview-latex-image-directory "25.1")
+
+(defcustom org-preview-latex-image-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 +19084,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 +19097,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 +19181,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-preview-latex-image-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))
@@ -19139,8 +19228,8 @@ Some of the options can be changed using the variable
(goto-char (org-element-property :end context))
(skip-chars-backward " \r\t\n")
(point))))
- (cl-case processing-type
- (mathjax
+ (cond
+ ((eq processing-type 'mathjax)
;; Prepare for MathJax processing.
(if (not (string-match "\\`\\$\\$?" value))
(goto-char end)
@@ -19148,11 +19237,21 @@ 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)
+ ((assq processing-type org-preview-latex-process-alist)
;; Process to an image.
(cl-incf cnt)
(goto-char beg)
- (let* ((face (face-at-point))
+ (let* ((processing-info
+ (cdr (assq processing-type org-preview-latex-process-alist)))
+ (inherit-processing-info
+ (cdr (assq (plist-get processing-info :inherit)
+ org-preview-latex-process-alist)))
+ (inherit-processing-info
+ (if (or (plist-get inherit-processing-info :inherit)
+ (eq (plist-get processing-info :inherit) type))
+ (progn (error "'%s' inherit an invalid process setting." processing-type) nil)
+ inherit-processing-info))
+ (face (face-at-point))
;; Get the colors from the face at point.
(fg
(let ((color (plist-get org-format-latex-options
@@ -19172,9 +19271,12 @@ Some of the options can be changed using the variable
org-latex-packages-alist
org-format-latex-options
forbuffer value fg bg))))
+ (imagetype (or (plist-get processing-info :image-output)
+ (plist-get inherit-processing-info :image-output)
+ '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 +19298,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
@@ -19205,7 +19307,7 @@ Some of the options can be changed using the variable
(replace-regexp-in-string "\"" "" value)
'org-latex-src-embed-type
(if block-type 'paragraph 'character)))))))
- (mathml
+ ((eq processing-type 'mathml)
;; Process to MathML.
(unless (org-format-latex-mathml-available-p)
(user-error "LaTeX to MathML converter not configured"))
@@ -19215,7 +19317,7 @@ Some of the options can be changed using the variable
(delete-region beg end)
(insert (org-format-latex-as-mathml
value block-type prefix dir)))
- (otherwise
+ (t
(error "Unknown conversion type %s for LaTeX fragments"
processing-type)))))))))))
@@ -19313,31 +19415,6 @@ inspection."
;; Failed conversion. Return the LaTeX fragment verbatim
latex-frag)))
-(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.
-
-Note: ultimately these two function should be combined as they
-share a good deal of logic."
- (org-check-external-command
- "latex" "needed to convert LaTeX fragments to images")
- (funcall
- (cl-case (or type org-latex-create-formula-image-program)
- (dvipng
- (org-check-external-command
- "dvipng" "needed to convert LaTeX fragments to images")
- #'org-create-formula-image-with-dvipng)
- (imagemagick
- (org-check-external-command
- "convert" "you need to install imagemagick")
- #'org-create-formula-image-with-imagemagick)
- (t (error
- "Invalid value of `org-latex-create-formula-image-program'")))
- string tofile options buffer))
-
(declare-function org-export-get-backend "ox" (name))
(declare-function org-export--get-global-options "ox" (&optional backend))
(declare-function org-export--get-inbuffer-options "ox" (&optional backend))
@@ -19368,133 +19445,204 @@ horizontal and vertical directions."
(/ (display-mm-height) 25.4)))
(error "Attempt to calculate the dpi of a non-graphic display")))
-;; This function borrows from Ganesh Swami's latex2png.el
-(defun org-create-formula-image-with-dvipng (string tofile options buffer)
- "This calls dvipng."
+(defun org-create-formula-image (string tofile options buffer &optional type)
+ "Create an image from LaTeX source using external processes.
+
+The external processes are defined in `org-preview-latex-process-alist'."
(require 'ox-latex)
- (let* ((tmpdir (if (featurep 'xemacs)
- (temp-directory)
- temporary-file-directory))
+ (let* ((type (or type 'dvipng))
+ (processing-info
+ (cdr (assq type org-preview-latex-process-alist)))
+ (inherit-processing-info
+ (cdr (assq (plist-get processing-info :inherit)
+ org-preview-latex-process-alist)))
+ (inherit-processing-info
+ (if (or (plist-get inherit-processing-info :inherit)
+ (eq (plist-get processing-info :inherit) type))
+ (progn (error "'%s' inherit an invalid process setting." type) nil)
+ inherit-processing-info))
+ (programs
+ (or (plist-get processing-info :programs)
+ (plist-get inherit-processing-info :programs)))
+ (error-message
+ (or (plist-get processing-info :message)
+ (plist-get inherit-processing-info :message)))
+ (use-xcolor
+ (or (plist-get processing-info :use-xcolor)
+ (plist-get inherit-processing-info :use-xcolor)))
+ (image-input-types
+ (or (plist-get processing-info :image-input)
+ (plist-get inherit-processing-info :image-input)))
+ (image-output-type
+ (or (plist-get processing-info :image-output)
+ (plist-get inherit-processing-info :image-output)))
+ (post-clean (or (plist-get processing-info :post-clean)
+ (plist-get inherit-processing-info :post-clean)
+ '(".dvi" ".xdv" ".pdf" ".tex" ".aux" ".log"
+ ".svg" ".png" ".jpg" ".jpeg" ".out")))
+ (latex-header (or (plist-get processing-info :latex-header)
+ (plist-get inherit-processing-info :latex-header)
+ (org-create-formula--latex-header)))
+ (latex-compiler
+ (or (plist-get processing-info :latex-compiler)
+ (plist-get inherit-processing-info :latex-compiler)))
+ (image-converter
+ (or (plist-get processing-info :image-converter)
+ (plist-get inherit-processing-info :image-converter)))
+ (tmpdir temporary-file-directory)
(texfilebase (make-temp-name
(expand-file-name "orgtex" tmpdir)))
(texfile (concat texfilebase ".tex"))
- (dvifile (concat texfilebase ".dvi"))
- (pngfile (concat texfilebase ".png"))
- (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0))
- ;; This assumes that the display has the same pixel width in
- ;; the horizontal and vertical directions
- (dpi (number-to-string (* scale (if buffer (org--get-display-dpi) 120))))
+ (image-output-file
+ (format "%s.%s" texfilebase image-output-type))
+ (font-height (face-attribute 'default :height nil))
+ (image-size-adjust (or (plist-get processing-info :image-size-adjust)
+ (plist-get inherit-processing-info :image-size-adjust)
+ '(1.0 . 1.0)))
+ (scale (* (if buffer (car image-size-adjust) (cdr image-size-adjust))
+ (or (plist-get options (if buffer :scale :html-scale)) 1.0)))
+ (dpi (* scale (floor (if buffer font-height 140.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-dvipng-color :foreground))
- (unless (string= fg "Transparent") (setq fg (org-dvipng-color-format fg))))
- (if (eq bg 'default) (setq bg (org-dvipng-color :background))
- (unless (string= bg "Transparent") (setq bg (org-dvipng-color-format bg))))
- (let ((latex-header (org-create-formula--latex-header)))
+ "Transparent"))
+ (log-buf (get-buffer-create "*Org Preview LaTeX Output*"))
+ image-input-file)
+ (dolist (program programs)
+ (org-check-external-command program error-message))
+ (if use-xcolor
+ (progn (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))))
+ (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")))
+ (if (eq fg 'default)
+ (setq fg (org-dvipng-color :foreground))
+ (unless (string= fg "Transparent")
+ (setq fg (org-dvipng-color-format fg))))
+ (if (eq bg 'default)
+ (setq bg (org-dvipng-color :background))
+ (unless (string= bg "Transparent")
+ (setq bg (org-dvipng-color-format bg))))
(with-temp-file texfile
(insert latex-header)
(insert "\n\\begin{document}\n" string "\n\\end{document}\n")))
- (let ((dir default-directory))
- (ignore-errors
- (cd tmpdir)
- (call-process "latex" nil nil nil texfile))
- (cd dir))
- (if (not (file-exists-p dvifile))
- (progn (message "Failed to create dvi file from %s" texfile) nil)
- (ignore-errors
- (if (featurep 'xemacs)
- (call-process "dvipng" nil nil nil
- "-fg" fg "-bg" bg
- "-T" "tight"
- "-o" pngfile
- dvifile)
- (call-process "dvipng" nil nil nil
- "-fg" fg "-bg" bg
- "-D" dpi
- ;;"-x" scale "-y" scale
- "-T" "tight"
- "-o" pngfile
- dvifile)))
- (if (not (file-exists-p pngfile))
- (if org-format-latex-signal-error
- (error "Failed to create png file from %s" texfile)
- (message "Failed to create png file from %s" texfile)
- nil)
- ;; Use the requested file name and clean up
- (copy-file pngfile tofile 'replace)
- (dolist (e '(".dvi" ".tex" ".aux" ".log" ".png" ".out"))
- (when (file-exists-p (concat texfilebase e))
- (delete-file (concat texfilebase e))))
- pngfile))))
-
-(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."
- (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"))
- (pdffile (concat texfilebase ".pdf"))
- (pngfile (concat texfilebase ".png"))
- (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0))
- (dpi (number-to-string (* scale (if buffer (org--get-display-dpi) 120))))
- (fg (or (plist-get options (if buffer :foreground :html-foreground))
- "black"))
- (bg (or (plist-get options (if buffer :background :html-background))
- "white")))
- (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)
- (if (not (file-exists-p pdffile))
- (progn (message "Failed to create pdf file from %s" texfile) nil)
- (ignore-errors
- (if (featurep 'xemacs)
- (call-process "convert" nil nil nil
- "-density" "96"
- "-trim"
- "-antialias"
- pdffile
- "-quality" "100"
- ;; "-sharpen" "0x1.0"
- pngfile)
- (call-process "convert" nil nil nil
- "-density" dpi
- "-trim"
- "-antialias"
- pdffile
- "-quality" "100"
- ;; "-sharpen" "0x1.0"
- pngfile)))
- (if (not (file-exists-p pngfile))
- (if org-format-latex-signal-error
- (error "Failed to create png file from %s" texfile)
- (message "Failed to create png file from %s" texfile)
- nil)
- ;; Use the requested file name and clean up
- (copy-file pngfile tofile 'replace)
- (dolist (e '(".pdf" ".tex" ".aux" ".log" ".png"))
- (when (file-exists-p (concat texfilebase e))
- (delete-file (concat texfilebase e))))
- pngfile))))
+
+ (setq image-input-file
+ (org-compile-file
+ texfile image-input-types latex-compiler log-buf
+ (format "Please adjust '%s' part in `org-preview-latex-process-alist'." type)
+ `((?t . ,(shell-quote-argument texfile))
+ (?b . ,(shell-quote-argument texfilebase))
+ (?o . ,(shell-quote-argument tmpdir)))))
+
+ (setq image-output-file
+ (org-compile-file
+ image-input-file image-output-type image-converter log-buf
+ (format "Please adjust '%S' part in `org-preview-latex-process-alist'." type)
+ `((?F . ,(shell-quote-argument fg))
+ (?B . ,(shell-quote-argument bg))
+ (?d . ,(shell-quote-argument (format "%s" dpi)))
+ (?s . ,(shell-quote-argument (format "%s" (/ dpi 140.0))))
+ (?t . ,(shell-quote-argument texfile))
+ (?i . ,(shell-quote-argument image-input-file))
+ (?p . ,(shell-quote-argument image-output-file))
+ (?b . ,(shell-quote-argument texfilebase))
+ (?o . ,(shell-quote-argument tmpdir)))))
+
+ (when (file-exists-p image-output-file)
+ (copy-file image-output-file tofile 'replace)
+ (dolist (e post-clean)
+ (when (file-exists-p (concat texfilebase e))
+ (delete-file (concat texfilebase e))))
+ image-output-file)))
+
+(defun org-compile-file (source extensions process
+ &optional log-buffer message spec)
+ "Compile a SOURCE file using PROCESS.
+
+PROCESS is either a function or a list of shell commands, as
+strings.
+
+If PROCESS is a function, it is called with a single argument:
+SOURCE file. It must create a file with the same base name and
+directory as SOURCE, but using an extension belong EXTENSIONS.
+
+If it is a list of commands, each of them is called using
+`shell-command'. By default, in each command, %b, %f and %o are
+replaced, respectively, with SOURCE base name, SOURCE full name
+and SOURCE directory. It is possible, however, to use different
+place-holders by specifying them in optional argument SPEC. In
+this case, SPEC should be an alist (CHARACTER REPLACEMENT-STRING).
+
+When PROCESS is a list of commands, optional argument LOG-BUFFER
+can be set to a buffer or a buffer name. `shell-command' then
+uses it as an output buffer, which may be used for collecting
+errors.
+
+`default-directory' is set to SOURCE directory during the whole
+process.
+
+Return output file or raise suggest MESSAGE if it wasn't generated
+upon executing PROCESS."
+ (let* ((base-name (file-name-sans-extension (file-name-nondirectory source)))
+ (full-name (file-truename source))
+ (output-dir (file-name-directory source))
+ ;; Properly set working directory for compilation.
+ (default-directory (if (file-name-absolute-p source)
+ (file-name-directory full-name)
+ default-directory))
+ (extensions (if (consp extensions)
+ extensions
+ (list extensions)))
+ (time (current-time)))
+ (save-window-excursion
+ (pcase process
+ ((pred functionp)
+ (funcall process (shell-quote-argument source)))
+ ((pred consp)
+ (let ((resize-mini-windows nil)
+ (log-buffer (and log-buffer (get-buffer-create log-buffer)))
+ (spec (or spec `((?b ,(shell-quote-argument base-name))
+ (?f ,(shell-quote-argument full-name))
+ (?o ,(shell-quote-argument output-dir))))))
+ (dolist (command process)
+ (shell-command (format-spec command spec) log-buffer))))
+ (_ (error (format "No valid command to process %S. %s" source message))))
+
+ ;; Check for process failure.
+ (let* ((output-files
+ (mapcar (lambda (ext)
+ (format "%s%s.%s" output-dir base-name ext))
+ extensions))
+ (files-string
+ (format "%s%s.%s" output-dir base-name
+ (mapconcat #'symbol-name extensions "|")))
+ output-file)
+ (dolist (file output-files)
+ (when (file-exists-p file)
+ (setq output-file file)
+ (setq output-files nil)))
+ (when (or (not output-file)
+ ;; Only compare times up to whole seconds as some
+ ;; file-systems (e.g. HFS+) do not retain any finer
+ ;; granularity.
+ (time-less-p (cl-subseq (nth 5 (file-attributes output-file)) 0 2)
+ (cl-subseq time 0 2)))
+ (error (format "File %S wasn't produced. %s" files-string message)))
+ output-file))))
(defun org-splice-latex-header (tpl def-pkg pkg snippets-p &optional extra)
"Fill a LaTeX header template TPL.
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index b188c38..0e3d266 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 (file-name-as-directory org-preview-latex-image-directory)
(file-name-sans-extension
(file-name-nondirectory bfn)))
cache-dir (file-name-directory bfn))
@@ -2798,10 +2801,10 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(latex-frag (org-remove-indentation
(org-element-property :value latex-environment)))
(attributes (org-export-read-attribute :attr_html latex-environment)))
- (case processing-type
- ((t mathjax)
+ (cond
+ ((member processing-type '(t mathjax))
(org-html-format-latex latex-frag 'mathjax info))
- ((dvipng imagemagick)
+ ((assq processing-type org-preview-latex-process-alist)
(let ((formula-link
(org-html-format-latex latex-frag processing-type info)))
(when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
@@ -2819,10 +2822,10 @@ CONTENTS is nil. INFO is a plist holding contextual information."
CONTENTS is nil. INFO is a plist holding contextual information."
(let ((latex-frag (org-element-property :value latex-fragment))
(processing-type (plist-get info :with-latex)))
- (case processing-type
- ((t mathjax)
+ (cond
+ ((member processing-type '(t mathjax))
(org-html-format-latex latex-frag 'mathjax info))
- ((dvipng imagemagick)
+ ((assq processing-type org-preview-latex-process-alist)
(let ((formula-link
(org-html-format-latex latex-frag processing-type info)))
(when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
--
2.1.4
next prev parent reply other threads:[~2016-05-18 6:45 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-14 6:30 [PATCH] New feature: Use dvisvgm to preview latex formular Feng Shu
2016-05-14 8:47 ` numbchild
2016-05-14 14:56 ` Feng Shu
2016-05-15 2:27 ` Feng Shu
2016-05-15 6:02 ` (version 3) " Feng Shu
2016-05-15 12:14 ` Feng Shu
2016-05-15 22:32 ` Nicolas Goaziou
2016-05-16 5:32 ` Feng Shu
2016-05-16 13:18 ` Nicolas Goaziou
2016-05-16 15:06 ` tumashu
2016-05-16 5:33 ` Feng Shu
2016-05-16 13:19 ` Nicolas Goaziou
2016-05-16 12:05 ` (v6) " Feng Shu
2016-05-16 21:17 ` Nicolas Goaziou
2016-05-16 22:17 ` tumashu
2016-05-17 1:15 ` tumashu
2016-05-18 6:30 ` Feng Shu [this message]
2016-05-19 8:22 ` (V8) " Nicolas Goaziou
2016-05-19 9:18 ` tumashu
2016-05-19 10:32 ` Nicolas Goaziou
2016-05-19 14:01 ` (V9) " Feng Shu
2016-05-21 9:38 ` Nicolas Goaziou
2016-05-21 12:22 ` Feng Shu
2016-05-21 13:35 ` Rasmus
2016-05-15 12:16 ` (version 4) " Feng Shu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mvnnev3u.fsf_-_@163.com \
--to=tumashu@163.com \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.