forked from mirrors/org-mode
org.el: Relocate LaTeX preview code to new file
* lisp/org.el (org-format-latex-options, org-format-latex-signal-error, org-latex-to-mathml-jar-file, org-latex-to-mathml-convert-command, org-latex-to-html-convert-command, org-preview-latex-default-process, org-preview-latex-process-alist, org-preview-latex-image-directory, org-format-latex-header, org-format-latex-mathml-available-p, org--make-preview-overlay, org-clear-latex-preview, org--latex-preview-region, org-latex-preview, org-format-latex, org-place-formula-image, org-create-math-formula, org-format-latex-as-mathml, org-format-latex-as-html, org--get-display-dpi, org-create-formula-image, org-dvipng-color, org-dvipng-color-format, org-latex-color, org-latex-color-format, org-normalize-color): Move to org-latex-preview.el. * lisp/org-latex-preview.el: A new home for code related to the generated of in-buffer previews of LaTeX fragments.
This commit is contained in:
parent
72ba4116eb
commit
c591dda62a
|
@ -0,0 +1,747 @@
|
|||
;;; org-latex-preview.el --- LaTeX previews for Org -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
;; Keywords: tex, extensions, tools
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; LaTeX previews for Org
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defgroup org-latex nil
|
||||
"Options for embedding LaTeX code into Org mode."
|
||||
:tag "Org LaTeX"
|
||||
:group 'org)
|
||||
|
||||
(defcustom org-format-latex-options
|
||||
'(:foreground default :background default :scale 1.0
|
||||
:html-foreground "Black" :html-background "Transparent"
|
||||
:html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))
|
||||
"Options for creating images from LaTeX fragments.
|
||||
This is a property list with the following properties:
|
||||
:foreground the foreground color for images embedded in Emacs, e.g. \"Black\".
|
||||
`default' means use the foreground of the default face.
|
||||
`auto' means use the foreground from the text face.
|
||||
:background the background color, or \"Transparent\".
|
||||
`default' means use the background of the default face.
|
||||
`auto' means use the background from the text face.
|
||||
:scale a scaling factor for the size of the images, to get more pixels
|
||||
:html-foreground, :html-background, :html-scale
|
||||
the same numbers for HTML export.
|
||||
:matchers a list indicating which matchers should be used to
|
||||
find LaTeX fragments. Valid members of this list are:
|
||||
\"begin\" find environments
|
||||
\"$1\" find single characters surrounded by $.$
|
||||
\"$\" find math expressions surrounded by $...$
|
||||
\"$$\" find math expressions surrounded by $$....$$
|
||||
\"\\(\" find math expressions surrounded by \\(...\\)
|
||||
\"\\=\\[\" find math expressions surrounded by \\=\\[...\\]"
|
||||
:group 'org-latex
|
||||
:type 'plist)
|
||||
|
||||
(defcustom org-format-latex-signal-error t
|
||||
"Non-nil means signal an error when image creation of LaTeX snippets fails.
|
||||
When nil, just push out a message."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom org-latex-to-mathml-jar-file nil
|
||||
"Value of\"%j\" in `org-latex-to-mathml-convert-command'.
|
||||
Use this to specify additional executable file say a jar file.
|
||||
|
||||
When using MathToWeb as the converter, specify the full-path to
|
||||
your mathtoweb.jar file."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(file :tag "JAR file" :must-match t)))
|
||||
|
||||
(defcustom org-latex-to-mathml-convert-command nil
|
||||
"Command to convert LaTeX fragments to MathML.
|
||||
Replace format-specifiers in the command as noted below and use
|
||||
`shell-command' to convert LaTeX to MathML.
|
||||
%j: Executable file in fully expanded form as specified by
|
||||
`org-latex-to-mathml-jar-file'.
|
||||
%I: Input LaTeX file in fully expanded form.
|
||||
%i: Shell-escaped LaTeX fragment to be converted.
|
||||
It must not be used inside a quoted argument, the result of %i
|
||||
expansion inside a quoted argument is undefined.
|
||||
%o: Output MathML file.
|
||||
|
||||
This command is used by `org-create-math-formula'.
|
||||
|
||||
When using MathToWeb as the converter, set this option to
|
||||
\"java -jar %j -unicode -force -df %o %I\".
|
||||
|
||||
When using LaTeXML set this option to
|
||||
\"latexmlmath %i --presentationmathml=%o\"."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(string :tag "\nShell command")))
|
||||
|
||||
(defcustom org-latex-to-html-convert-command nil
|
||||
"Shell command to convert LaTeX fragments to HTML.
|
||||
This command is very open-ended: the output of the command will
|
||||
directly replace the LaTeX fragment in the resulting HTML.
|
||||
Replace format-specifiers in the command as noted below and use
|
||||
`shell-command' to convert LaTeX to HTML.
|
||||
%i: The LaTeX fragment to be converted (shell-escaped).
|
||||
It must not be used inside a quoted argument, the result of %i
|
||||
expansion inside a quoted argument is undefined.
|
||||
|
||||
For example, this could be used with LaTeXML as
|
||||
\"latexmlc literal:%i --profile=math --preload=siunitx.sty 2>/dev/null\"."
|
||||
:group 'org-latex
|
||||
:package-version '(Org . "9.4")
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(string :tag "Shell command")))
|
||||
|
||||
(defcustom org-preview-latex-default-process 'dvipng
|
||||
"The default process to convert LaTeX fragments to image files.
|
||||
All available processes and theirs documents can be found in
|
||||
`org-preview-latex-process-alist', which see."
|
||||
:group 'org-latex
|
||||
:version "26.1"
|
||||
:package-version '(Org . "9.0")
|
||||
:type 'symbol)
|
||||
|
||||
(defcustom org-preview-latex-process-alist
|
||||
'((dvipng
|
||||
:programs ("latex" "dvipng")
|
||||
:description "dvi > png"
|
||||
:message "you need to install the programs: latex and dvipng."
|
||||
:image-input-type "dvi"
|
||||
:image-output-type "png"
|
||||
:image-size-adjust (1.0 . 1.0)
|
||||
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter ("dvipng -D %D -T tight -o %O %f")
|
||||
:transparent-image-converter
|
||||
("dvipng -D %D -T tight -bg Transparent -o %O %f"))
|
||||
(dvisvgm
|
||||
:programs ("latex" "dvisvgm")
|
||||
:description "dvi > svg"
|
||||
:message "you need to install the programs: latex and dvisvgm."
|
||||
:image-input-type "dvi"
|
||||
:image-output-type "svg"
|
||||
:image-size-adjust (1.7 . 1.5)
|
||||
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter ("dvisvgm %f --no-fonts --exact-bbox --scale=%S --output=%O"))
|
||||
(imagemagick
|
||||
:programs ("latex" "convert")
|
||||
:description "pdf > png"
|
||||
:message "you need to install the programs: latex and imagemagick."
|
||||
:image-input-type "pdf"
|
||||
:image-output-type "png"
|
||||
:image-size-adjust (1.0 . 1.0)
|
||||
:latex-compiler ("pdflatex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter
|
||||
("convert -density %D -trim -antialias %f -quality 100 %O")))
|
||||
"Definitions of external processes for LaTeX previewing.
|
||||
Org mode can use some external commands to generate TeX snippet's images for
|
||||
previewing or inserting into HTML files, e.g., \"dvipng\". This variable tells
|
||||
`org-create-formula-image' how to call them.
|
||||
|
||||
The value is an alist with the pattern (NAME . PROPERTIES). NAME is a symbol.
|
||||
PROPERTIES accepts the following attributes:
|
||||
|
||||
:programs list of strings, required programs.
|
||||
:description string, describe the process.
|
||||
:message string, message it when required programs cannot be found.
|
||||
:image-input-type string, input file type of image converter (e.g., \"dvi\").
|
||||
:image-output-type string, output file type of image converter (e.g., \"png\").
|
||||
: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 process
|
||||
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. When 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 strings, the LaTeX header of the snippet file.
|
||||
When nil, the fallback value is used instead, which is
|
||||
controlled by `org-format-latex-header',
|
||||
`org-latex-default-packages-alist' and
|
||||
`org-latex-packages-alist', which see.
|
||||
:latex-compiler list of LaTeX commands, as strings. Each of them is given
|
||||
to the shell. Place-holders \"%t\", \"%b\" and \"%o\" are
|
||||
replaced with values defined below.
|
||||
:image-converter list of image converter commands strings. Each of them is
|
||||
given to the shell and supports any of the following
|
||||
place-holders defined below.
|
||||
|
||||
If set, :transparent-image-converter is used instead of :image-converter to
|
||||
convert an image when the background color is nil or \"Transparent\".
|
||||
|
||||
Place-holders used by `:image-converter' and `:latex-compiler':
|
||||
|
||||
%f input file name
|
||||
%b base name of input file
|
||||
%o base directory of input file
|
||||
%O absolute output file name
|
||||
|
||||
Place-holders only used by `:image-converter':
|
||||
|
||||
%D dpi, which is used to adjust image size by some processing commands.
|
||||
%S the image size scale ratio, which is used to adjust image size by some
|
||||
processing commands."
|
||||
:group 'org-latex
|
||||
:package-version '(Org . "9.6")
|
||||
:type '(alist :tag "LaTeX to image backends"
|
||||
:value-type (plist)))
|
||||
|
||||
(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
|
||||
images at the same place."
|
||||
:group 'org-latex
|
||||
:version "26.1"
|
||||
:package-version '(Org . "9.0")
|
||||
:type 'string)
|
||||
|
||||
(defun org-format-latex-mathml-available-p ()
|
||||
"Return t if `org-latex-to-mathml-convert-command' is usable."
|
||||
(save-match-data
|
||||
(when (and (boundp 'org-latex-to-mathml-convert-command)
|
||||
org-latex-to-mathml-convert-command)
|
||||
(let ((executable (car (split-string
|
||||
org-latex-to-mathml-convert-command))))
|
||||
(when (executable-find executable)
|
||||
(if (string-match
|
||||
"%j" org-latex-to-mathml-convert-command)
|
||||
(file-readable-p org-latex-to-mathml-jar-file)
|
||||
t))))))
|
||||
|
||||
(defcustom org-format-latex-header "\\documentclass{article}
|
||||
\\usepackage[usenames]{color}
|
||||
\[DEFAULT-PACKAGES]
|
||||
\[PACKAGES]
|
||||
\\pagestyle{empty} % do not remove
|
||||
% The settings below are copied from fullpage.sty
|
||||
\\setlength{\\textwidth}{\\paperwidth}
|
||||
\\addtolength{\\textwidth}{-3cm}
|
||||
\\setlength{\\oddsidemargin}{1.5cm}
|
||||
\\addtolength{\\oddsidemargin}{-2.54cm}
|
||||
\\setlength{\\evensidemargin}{\\oddsidemargin}
|
||||
\\setlength{\\textheight}{\\paperheight}
|
||||
\\addtolength{\\textheight}{-\\headheight}
|
||||
\\addtolength{\\textheight}{-\\headsep}
|
||||
\\addtolength{\\textheight}{-\\footskip}
|
||||
\\addtolength{\\textheight}{-3cm}
|
||||
\\setlength{\\topmargin}{1.5cm}
|
||||
\\addtolength{\\topmargin}{-2.54cm}"
|
||||
"The document header used for processing LaTeX fragments.
|
||||
It is imperative that this header make sure that no page number
|
||||
appears on the page. The package defined in the variables
|
||||
`org-latex-default-packages-alist' and `org-latex-packages-alist'
|
||||
will either replace the placeholder \"[PACKAGES]\" in this
|
||||
header, or they will be appended."
|
||||
:group 'org-latex
|
||||
:type 'string)
|
||||
|
||||
(defun org--make-preview-overlay (beg end image &optional imagetype)
|
||||
"Build an overlay between BEG and END using IMAGE file.
|
||||
Argument IMAGETYPE is the extension of the displayed image,
|
||||
as a string. It defaults to \"png\"."
|
||||
(let ((ov (make-overlay beg end))
|
||||
(imagetype (or (intern imagetype) 'png)))
|
||||
(overlay-put ov 'org-overlay-type 'org-latex-overlay)
|
||||
(overlay-put ov 'evaporate t)
|
||||
(overlay-put ov
|
||||
'modification-hooks
|
||||
(list (lambda (o _flag _beg _end &optional _l)
|
||||
(delete-overlay o))))
|
||||
(overlay-put ov
|
||||
'display
|
||||
(list 'image :type imagetype :file image :ascent 'center))))
|
||||
|
||||
(defun org-clear-latex-preview (&optional beg end)
|
||||
"Remove all overlays with LaTeX fragment images in current buffer.
|
||||
When optional arguments BEG and END are non-nil, remove all
|
||||
overlays between them instead. Return a non-nil value when some
|
||||
overlays were removed, nil otherwise."
|
||||
(let ((overlays
|
||||
(cl-remove-if-not
|
||||
(lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay))
|
||||
(overlays-in (or beg (point-min)) (or end (point-max))))))
|
||||
(mapc #'delete-overlay overlays)
|
||||
overlays))
|
||||
|
||||
(defun org--latex-preview-region (beg end)
|
||||
"Preview LaTeX fragments between BEG and END.
|
||||
BEG and END are buffer positions."
|
||||
(let ((file (buffer-file-name (buffer-base-buffer))))
|
||||
(save-excursion
|
||||
(org-format-latex
|
||||
(concat org-preview-latex-image-directory "org-ltximg")
|
||||
beg end
|
||||
;; Emacs cannot overlay images from remote hosts. Create it in
|
||||
;; `temporary-file-directory' instead.
|
||||
(if (or (not file) (file-remote-p file))
|
||||
temporary-file-directory
|
||||
default-directory)
|
||||
'overlays nil 'forbuffer org-preview-latex-default-process))))
|
||||
|
||||
(defun org-latex-preview (&optional arg)
|
||||
"Toggle preview of the LaTeX fragment at point.
|
||||
|
||||
If the cursor is on a LaTeX fragment, create the image and
|
||||
overlay it over the source code, if there is none. Remove it
|
||||
otherwise. If there is no fragment at point, display images for
|
||||
all fragments in the current section. With an active region,
|
||||
display images for all fragments in the region.
|
||||
|
||||
With a `\\[universal-argument]' prefix argument ARG, clear images \
|
||||
for all fragments
|
||||
in the current section.
|
||||
|
||||
With a `\\[universal-argument] \\[universal-argument]' prefix \
|
||||
argument ARG, display image for all
|
||||
fragments in the buffer.
|
||||
|
||||
With a `\\[universal-argument] \\[universal-argument] \
|
||||
\\[universal-argument]' prefix argument ARG, clear image for all
|
||||
fragments in the buffer."
|
||||
(interactive "P")
|
||||
(cond
|
||||
((not (display-graphic-p)) nil)
|
||||
;; Clear whole buffer.
|
||||
((equal arg '(64))
|
||||
(org-clear-latex-preview (point-min) (point-max))
|
||||
(message "LaTeX previews removed from buffer"))
|
||||
;; Preview whole buffer.
|
||||
((equal arg '(16))
|
||||
(message "Creating LaTeX previews in buffer...")
|
||||
(org--latex-preview-region (point-min) (point-max))
|
||||
(message "Creating LaTeX previews in buffer... done."))
|
||||
;; Clear current section.
|
||||
((equal arg '(4))
|
||||
(org-clear-latex-preview
|
||||
(if (use-region-p)
|
||||
(region-beginning)
|
||||
(if (org-before-first-heading-p) (point-min)
|
||||
(save-excursion
|
||||
(org-with-limited-levels (org-back-to-heading t) (point)))))
|
||||
(if (use-region-p)
|
||||
(region-end)
|
||||
(org-with-limited-levels (org-entry-end-position)))))
|
||||
((use-region-p)
|
||||
(message "Creating LaTeX previews in region...")
|
||||
(org--latex-preview-region (region-beginning) (region-end))
|
||||
(message "Creating LaTeX previews in region... done."))
|
||||
;; Toggle preview on LaTeX code at point.
|
||||
((let ((datum (org-element-context)))
|
||||
(and (memq (org-element-type datum) '(latex-environment latex-fragment))
|
||||
(let ((beg (org-element-property :begin datum))
|
||||
(end (org-element-property :end datum)))
|
||||
(if (org-clear-latex-preview beg end)
|
||||
(message "LaTeX preview removed")
|
||||
(message "Creating LaTeX preview...")
|
||||
(org--latex-preview-region beg end)
|
||||
(message "Creating LaTeX preview... done."))
|
||||
t))))
|
||||
;; Preview current section.
|
||||
(t
|
||||
(let ((beg (if (org-before-first-heading-p) (point-min)
|
||||
(save-excursion
|
||||
(org-with-limited-levels (org-back-to-heading t) (point)))))
|
||||
(end (org-with-limited-levels (org-entry-end-position))))
|
||||
(message "Creating LaTeX previews in section...")
|
||||
(org--latex-preview-region beg end)
|
||||
(message "Creating LaTeX previews in section... done.")))))
|
||||
|
||||
(defun org-format-latex
|
||||
(prefix &optional beg end dir overlays msg forbuffer processing-type)
|
||||
"Replace LaTeX fragments with links to an image.
|
||||
|
||||
The function takes care of creating the replacement image.
|
||||
|
||||
Only consider fragments between BEG and END when those are
|
||||
provided.
|
||||
|
||||
When optional argument OVERLAYS is non-nil, display the image on
|
||||
top of the fragment instead of replacing it.
|
||||
|
||||
PROCESSING-TYPE is the conversion method to use, as a symbol.
|
||||
|
||||
Some of the options can be changed using the variable
|
||||
`org-format-latex-options', which see."
|
||||
(when (and overlays (fboundp 'clear-image-cache)) (clear-image-cache))
|
||||
(unless (eq processing-type 'verbatim)
|
||||
(let* ((math-regexp "\\$\\|\\\\[([]\\|^[ \t]*\\\\begin{[A-Za-z0-9*]+}")
|
||||
(cnt 0)
|
||||
checkdir-flag)
|
||||
(goto-char (or beg (point-min)))
|
||||
;; Optimize overlay creation: (info "(elisp) Managing Overlays").
|
||||
(when (and overlays (memq processing-type '(dvipng imagemagick)))
|
||||
(overlay-recenter (or end (point-max))))
|
||||
(while (re-search-forward math-regexp end t)
|
||||
(unless (and overlays
|
||||
(eq (get-char-property (point) 'org-overlay-type)
|
||||
'org-latex-overlay))
|
||||
(let* ((context (org-element-context))
|
||||
(type (org-element-type context)))
|
||||
(when (memq type '(latex-environment latex-fragment))
|
||||
(let ((block-type (eq type 'latex-environment))
|
||||
(value (org-element-property :value context))
|
||||
(beg (org-element-property :begin context))
|
||||
(end (save-excursion
|
||||
(goto-char (org-element-property :end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point))))
|
||||
(cond
|
||||
((eq processing-type 'mathjax)
|
||||
;; Prepare for MathJax processing.
|
||||
(if (not (string-match "\\`\\$\\$?" value))
|
||||
(goto-char end)
|
||||
(delete-region beg end)
|
||||
(if (string= (match-string 0 value) "$$")
|
||||
(insert "\\[" (substring value 2 -2) "\\]")
|
||||
(insert "\\(" (substring value 1 -1) "\\)"))))
|
||||
((eq processing-type 'html)
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-html value)))
|
||||
((assq processing-type org-preview-latex-process-alist)
|
||||
;; Process to an image.
|
||||
(cl-incf cnt)
|
||||
(goto-char beg)
|
||||
(let* ((processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(face (face-at-point))
|
||||
;; Get the colors from the face at point.
|
||||
(fg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:foreground)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :foreground nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :foreground nil))
|
||||
(t color))
|
||||
color)))
|
||||
(bg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:background)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :background nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :background nil))
|
||||
(t color))
|
||||
color)))
|
||||
(hash (sha1 (prin1-to-string
|
||||
(list org-format-latex-header
|
||||
org-latex-default-packages-alist
|
||||
org-latex-packages-alist
|
||||
org-format-latex-options
|
||||
forbuffer value fg bg))))
|
||||
(imagetype (or (plist-get processing-info :image-output-type) "png"))
|
||||
(absprefix (expand-file-name prefix dir))
|
||||
(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
|
||||
(org-combine-plists
|
||||
org-format-latex-options
|
||||
`(:foreground ,fg :background ,bg))))
|
||||
(when msg (message msg cnt))
|
||||
(unless checkdir-flag ; Ensure the directory exists.
|
||||
(setq checkdir-flag t)
|
||||
(let ((todir (file-name-directory absprefix)))
|
||||
(unless (file-directory-p todir)
|
||||
(make-directory todir t))))
|
||||
(unless (file-exists-p movefile)
|
||||
(org-create-formula-image
|
||||
value movefile options forbuffer processing-type))
|
||||
(org-place-formula-image link block-type beg end value overlays movefile imagetype)))
|
||||
((eq processing-type 'mathml)
|
||||
;; Process to MathML.
|
||||
(unless (org-format-latex-mathml-available-p)
|
||||
(user-error "LaTeX to MathML converter not configured"))
|
||||
(cl-incf cnt)
|
||||
(when msg (message msg cnt))
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-mathml
|
||||
value block-type prefix dir)))
|
||||
(t
|
||||
(error "Unknown conversion process %s for LaTeX fragments"
|
||||
processing-type)))))))))))
|
||||
|
||||
(defun org-place-formula-image (link block-type beg end value overlays movefile imagetype)
|
||||
"Place an overlay from BEG to END showing MOVEFILE.
|
||||
The overlay will be above BEG if OVERLAYS is non-nil."
|
||||
(if overlays
|
||||
(progn
|
||||
(dolist (o (overlays-in beg end))
|
||||
(when (eq (overlay-get o 'org-overlay-type)
|
||||
'org-latex-overlay)
|
||||
(delete-overlay o)))
|
||||
(org--make-preview-overlay beg end movefile imagetype)
|
||||
(goto-char end))
|
||||
(delete-region beg end)
|
||||
(insert
|
||||
(org-add-props link
|
||||
(list 'org-latex-src
|
||||
(replace-regexp-in-string "\"" "" value)
|
||||
'org-latex-src-embed-type
|
||||
(if block-type 'paragraph 'character))))))
|
||||
|
||||
(defun org-create-math-formula (latex-frag &optional mathml-file)
|
||||
"Convert LATEX-FRAG to MathML and store it in MATHML-FILE.
|
||||
Use `org-latex-to-mathml-convert-command'. If the conversion is
|
||||
successful, return the portion between \"<math...> </math>\"
|
||||
elements otherwise return nil. When MATHML-FILE is specified,
|
||||
write the results in to that file. When invoked as an
|
||||
interactive command, prompt for LATEX-FRAG, with initial value
|
||||
set to the current active region and echo the results for user
|
||||
inspection."
|
||||
(interactive (list (let ((frag (when (org-region-active-p)
|
||||
(buffer-substring-no-properties
|
||||
(region-beginning) (region-end)))))
|
||||
(read-string "LaTeX Fragment: " frag nil frag))))
|
||||
(unless latex-frag (user-error "Invalid LaTeX fragment"))
|
||||
(let* ((tmp-in-file
|
||||
(let ((file (file-relative-name
|
||||
(make-temp-name (expand-file-name "ltxmathml-in")))))
|
||||
(write-region latex-frag nil file)
|
||||
file))
|
||||
(tmp-out-file (file-relative-name
|
||||
(make-temp-name (expand-file-name "ltxmathml-out"))))
|
||||
(cmd (format-spec
|
||||
org-latex-to-mathml-convert-command
|
||||
`((?j . ,(and org-latex-to-mathml-jar-file
|
||||
(shell-quote-argument
|
||||
(expand-file-name
|
||||
org-latex-to-mathml-jar-file))))
|
||||
(?I . ,(shell-quote-argument tmp-in-file))
|
||||
(?i . ,latex-frag)
|
||||
(?o . ,(shell-quote-argument tmp-out-file)))))
|
||||
mathml shell-command-output)
|
||||
(when (called-interactively-p 'any)
|
||||
(unless (org-format-latex-mathml-available-p)
|
||||
(user-error "LaTeX to MathML converter not configured")))
|
||||
(message "Running %s" cmd)
|
||||
(setq shell-command-output (shell-command-to-string cmd))
|
||||
(setq mathml
|
||||
(when (file-readable-p tmp-out-file)
|
||||
(with-current-buffer (find-file-noselect tmp-out-file t)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "<math[^>]*?%s[^>]*?>\\(.\\|\n\\)*</math>"
|
||||
(regexp-quote
|
||||
"xmlns=\"http://www.w3.org/1998/Math/MathML\""))
|
||||
nil t)
|
||||
(prog1 (match-string 0) (kill-buffer))))))
|
||||
(cond
|
||||
(mathml
|
||||
(setq mathml
|
||||
(concat "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" mathml))
|
||||
(when mathml-file
|
||||
(write-region mathml nil mathml-file))
|
||||
(when (called-interactively-p 'any)
|
||||
(message mathml)))
|
||||
((warn "LaTeX to MathML conversion failed")
|
||||
(message shell-command-output)))
|
||||
(delete-file tmp-in-file)
|
||||
(when (file-exists-p tmp-out-file)
|
||||
(delete-file tmp-out-file))
|
||||
mathml))
|
||||
|
||||
(defun org-format-latex-as-mathml (latex-frag latex-frag-type
|
||||
prefix &optional dir)
|
||||
"Use `org-create-math-formula' but check local cache first."
|
||||
(let* ((absprefix (expand-file-name prefix dir))
|
||||
(print-length nil) (print-level nil)
|
||||
(formula-id (concat
|
||||
"formula-"
|
||||
(sha1
|
||||
(prin1-to-string
|
||||
(list latex-frag
|
||||
org-latex-to-mathml-convert-command)))))
|
||||
(formula-cache (format "%s-%s.mathml" absprefix formula-id))
|
||||
(formula-cache-dir (file-name-directory formula-cache)))
|
||||
|
||||
(unless (file-directory-p formula-cache-dir)
|
||||
(make-directory formula-cache-dir t))
|
||||
|
||||
(unless (file-exists-p formula-cache)
|
||||
(org-create-math-formula latex-frag formula-cache))
|
||||
|
||||
(if (file-exists-p formula-cache)
|
||||
;; Successful conversion. Return the link to MathML file.
|
||||
(org-add-props
|
||||
(format "[[file:%s]]" (file-relative-name formula-cache dir))
|
||||
(list 'org-latex-src (replace-regexp-in-string "\"" "" latex-frag)
|
||||
'org-latex-src-embed-type (if latex-frag-type
|
||||
'paragraph 'character)))
|
||||
;; Failed conversion. Return the LaTeX fragment verbatim
|
||||
latex-frag)))
|
||||
|
||||
(defun org-format-latex-as-html (latex-fragment)
|
||||
"Convert LATEX-FRAGMENT to HTML.
|
||||
This uses `org-latex-to-html-convert-command', which see."
|
||||
(let ((cmd (format-spec org-latex-to-html-convert-command
|
||||
`((?i . ,latex-fragment)))))
|
||||
(message "Running %s" cmd)
|
||||
(shell-command-to-string cmd)))
|
||||
|
||||
(defun org--get-display-dpi ()
|
||||
"Get the DPI of the display.
|
||||
The function assumes that the display has the same pixel width in
|
||||
the horizontal and vertical directions."
|
||||
(if (display-graphic-p)
|
||||
(round (/ (display-pixel-height)
|
||||
(/ (display-mm-height) 25.4)))
|
||||
(error "Attempt to calculate the dpi of a non-graphic display")))
|
||||
|
||||
(defun org-create-formula-image
|
||||
(string tofile options buffer &optional processing-type)
|
||||
"Create an image from LaTeX source using external processes.
|
||||
|
||||
The LaTeX STRING is saved to a temporary LaTeX file, then
|
||||
converted to an image file by process PROCESSING-TYPE defined in
|
||||
`org-preview-latex-process-alist'. A nil value defaults to
|
||||
`org-preview-latex-default-process'.
|
||||
|
||||
The generated image file is eventually moved to TOFILE.
|
||||
|
||||
The OPTIONS argument controls the size, foreground color and
|
||||
background color of the generated image.
|
||||
|
||||
When BUFFER non-nil, this function is used for LaTeX previewing.
|
||||
Otherwise, it is used to deal with LaTeX snippets showed in
|
||||
a HTML file."
|
||||
(let* ((processing-type (or processing-type
|
||||
org-preview-latex-default-process))
|
||||
(processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(programs (plist-get processing-info :programs))
|
||||
(error-message (or (plist-get processing-info :message) ""))
|
||||
(image-input-type (plist-get processing-info :image-input-type))
|
||||
(image-output-type (plist-get processing-info :image-output-type))
|
||||
(post-clean (or (plist-get processing-info :post-clean)
|
||||
'(".dvi" ".xdv" ".pdf" ".tex" ".aux" ".log"
|
||||
".svg" ".png" ".jpg" ".jpeg" ".out")))
|
||||
(latex-header
|
||||
(or (plist-get processing-info :latex-header)
|
||||
(org-latex-make-preamble
|
||||
(org-export-get-environment (org-export-get-backend 'latex))
|
||||
org-format-latex-header
|
||||
'snippet)))
|
||||
(latex-compiler (plist-get processing-info :latex-compiler))
|
||||
(tmpdir temporary-file-directory)
|
||||
(texfilebase (make-temp-name
|
||||
(expand-file-name "orgtex" tmpdir)))
|
||||
(texfile (concat texfilebase ".tex"))
|
||||
(image-size-adjust (or (plist-get 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 (if (and buffer (display-graphic-p)) (org--get-display-dpi) 140.0)))
|
||||
(fg (or (plist-get options (if buffer :foreground :html-foreground))
|
||||
"Black"))
|
||||
(bg (or (plist-get options (if buffer :background :html-background))
|
||||
"Transparent"))
|
||||
(image-converter
|
||||
(or (and (string= bg "Transparent")
|
||||
(plist-get processing-info :transparent-image-converter))
|
||||
(plist-get processing-info :image-converter)))
|
||||
(log-buf (get-buffer-create "*Org Preview LaTeX Output*"))
|
||||
(resize-mini-windows nil)) ;Fix Emacs flicker when creating image.
|
||||
(dolist (program programs)
|
||||
(org-check-external-command program error-message))
|
||||
(if (eq fg 'default)
|
||||
(setq fg (org-latex-color :foreground))
|
||||
(setq fg (org-latex-color-format fg)))
|
||||
(setq bg (cond
|
||||
((eq bg 'default) (org-latex-color :background))
|
||||
((string= bg "Transparent") nil)
|
||||
(t (org-latex-color-format bg))))
|
||||
;; Remove TeX \par at end of snippet to avoid trailing space.
|
||||
(if (string-suffix-p string "\n")
|
||||
(aset string (1- (length string)) ?%)
|
||||
(setq string (concat string "%")))
|
||||
(with-temp-file texfile
|
||||
(insert latex-header)
|
||||
(insert "\n\\begin{document}\n"
|
||||
"\\definecolor{fg}{rgb}{" fg "}%\n"
|
||||
(if bg
|
||||
(concat "\\definecolor{bg}{rgb}{" bg "}%\n"
|
||||
"\n\\pagecolor{bg}%\n")
|
||||
"")
|
||||
"\n{\\color{fg}\n"
|
||||
string
|
||||
"\n}\n"
|
||||
"\n\\end{document}\n"))
|
||||
(let* ((err-msg (format "Please adjust `%s' part of \
|
||||
`org-preview-latex-process-alist'."
|
||||
processing-type))
|
||||
(image-input-file
|
||||
(org-compile-file
|
||||
texfile latex-compiler image-input-type err-msg log-buf))
|
||||
(image-output-file
|
||||
(org-compile-file
|
||||
image-input-file image-converter image-output-type err-msg log-buf
|
||||
`((?D . ,(shell-quote-argument (format "%s" dpi)))
|
||||
(?S . ,(shell-quote-argument (format "%s" (/ dpi 140.0))))))))
|
||||
(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-dvipng-color (attr)
|
||||
"Return a RGB color specification for dvipng."
|
||||
(org-dvipng-color-format (face-attribute 'default attr nil)))
|
||||
|
||||
(defun org-dvipng-color-format (color-name)
|
||||
"Convert COLOR-NAME to a RGB color value for dvipng."
|
||||
(apply #'format "rgb %s %s %s"
|
||||
(mapcar 'org-normalize-color
|
||||
(color-values color-name))))
|
||||
|
||||
(defun org-latex-color (attr)
|
||||
"Return a RGB color for the LaTeX color package."
|
||||
(org-latex-color-format (face-attribute 'default attr nil)))
|
||||
|
||||
(defun org-latex-color-format (color-name)
|
||||
"Convert COLOR-NAME to a RGB color value."
|
||||
(apply #'format "%s,%s,%s"
|
||||
(mapcar 'org-normalize-color
|
||||
(color-values color-name))))
|
||||
|
||||
(defun org-normalize-color (value)
|
||||
"Return string to be used as color value for an RGB component."
|
||||
(format "%g" (/ value 65535.0)))
|
||||
|
||||
(provide 'org-latex-preview)
|
||||
;;; org-latex-preview.el ends here
|
724
lisp/org.el
724
lisp/org.el
|
@ -3209,244 +3209,6 @@ A nil value means to remove them, after a query, from the list."
|
|||
:group 'org-agenda
|
||||
:type 'boolean)
|
||||
|
||||
(defgroup org-latex nil
|
||||
"Options for embedding LaTeX code into Org mode."
|
||||
:tag "Org LaTeX"
|
||||
:group 'org)
|
||||
|
||||
(defcustom org-format-latex-options
|
||||
'(:foreground default :background default :scale 1.0
|
||||
:html-foreground "Black" :html-background "Transparent"
|
||||
:html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))
|
||||
"Options for creating images from LaTeX fragments.
|
||||
This is a property list with the following properties:
|
||||
:foreground the foreground color for images embedded in Emacs, e.g. \"Black\".
|
||||
`default' means use the foreground of the default face.
|
||||
`auto' means use the foreground from the text face.
|
||||
:background the background color, or \"Transparent\".
|
||||
`default' means use the background of the default face.
|
||||
`auto' means use the background from the text face.
|
||||
:scale a scaling factor for the size of the images, to get more pixels
|
||||
:html-foreground, :html-background, :html-scale
|
||||
the same numbers for HTML export.
|
||||
:matchers a list indicating which matchers should be used to
|
||||
find LaTeX fragments. Valid members of this list are:
|
||||
\"begin\" find environments
|
||||
\"$1\" find single characters surrounded by $.$
|
||||
\"$\" find math expressions surrounded by $...$
|
||||
\"$$\" find math expressions surrounded by $$....$$
|
||||
\"\\(\" find math expressions surrounded by \\(...\\)
|
||||
\"\\=\\[\" find math expressions surrounded by \\=\\[...\\]"
|
||||
:group 'org-latex
|
||||
:type 'plist)
|
||||
|
||||
(defcustom org-format-latex-signal-error t
|
||||
"Non-nil means signal an error when image creation of LaTeX snippets fails.
|
||||
When nil, just push out a message."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom org-latex-to-mathml-jar-file nil
|
||||
"Value of\"%j\" in `org-latex-to-mathml-convert-command'.
|
||||
Use this to specify additional executable file say a jar file.
|
||||
|
||||
When using MathToWeb as the converter, specify the full-path to
|
||||
your mathtoweb.jar file."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(file :tag "JAR file" :must-match t)))
|
||||
|
||||
(defcustom org-latex-to-mathml-convert-command nil
|
||||
"Command to convert LaTeX fragments to MathML.
|
||||
Replace format-specifiers in the command as noted below and use
|
||||
`shell-command' to convert LaTeX to MathML.
|
||||
%j: Executable file in fully expanded form as specified by
|
||||
`org-latex-to-mathml-jar-file'.
|
||||
%I: Input LaTeX file in fully expanded form.
|
||||
%i: Shell-escaped LaTeX fragment to be converted.
|
||||
It must not be used inside a quoted argument, the result of %i
|
||||
expansion inside a quoted argument is undefined.
|
||||
%o: Output MathML file.
|
||||
|
||||
This command is used by `org-create-math-formula'.
|
||||
|
||||
When using MathToWeb as the converter, set this option to
|
||||
\"java -jar %j -unicode -force -df %o %I\".
|
||||
|
||||
When using LaTeXML set this option to
|
||||
\"latexmlmath %i --presentationmathml=%o\"."
|
||||
:group 'org-latex
|
||||
:version "24.1"
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(string :tag "\nShell command")))
|
||||
|
||||
(defcustom org-latex-to-html-convert-command nil
|
||||
"Shell command to convert LaTeX fragments to HTML.
|
||||
This command is very open-ended: the output of the command will
|
||||
directly replace the LaTeX fragment in the resulting HTML.
|
||||
Replace format-specifiers in the command as noted below and use
|
||||
`shell-command' to convert LaTeX to HTML.
|
||||
%i: The LaTeX fragment to be converted (shell-escaped).
|
||||
It must not be used inside a quoted argument, the result of %i
|
||||
expansion inside a quoted argument is undefined.
|
||||
|
||||
For example, this could be used with LaTeXML as
|
||||
\"latexmlc literal:%i --profile=math --preload=siunitx.sty 2>/dev/null\"."
|
||||
:group 'org-latex
|
||||
:package-version '(Org . "9.4")
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(string :tag "Shell command")))
|
||||
|
||||
(defcustom org-preview-latex-default-process 'dvipng
|
||||
"The default process to convert LaTeX fragments to image files.
|
||||
All available processes and theirs documents can be found in
|
||||
`org-preview-latex-process-alist', which see."
|
||||
:group 'org-latex
|
||||
:version "26.1"
|
||||
:package-version '(Org . "9.0")
|
||||
:type 'symbol)
|
||||
|
||||
(defcustom org-preview-latex-process-alist
|
||||
'((dvipng
|
||||
:programs ("latex" "dvipng")
|
||||
:description "dvi > png"
|
||||
:message "you need to install the programs: latex and dvipng."
|
||||
:image-input-type "dvi"
|
||||
:image-output-type "png"
|
||||
:image-size-adjust (1.0 . 1.0)
|
||||
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter ("dvipng -D %D -T tight -o %O %f")
|
||||
:transparent-image-converter
|
||||
("dvipng -D %D -T tight -bg Transparent -o %O %f"))
|
||||
(dvisvgm
|
||||
:programs ("latex" "dvisvgm")
|
||||
:description "dvi > svg"
|
||||
:message "you need to install the programs: latex and dvisvgm."
|
||||
:image-input-type "dvi"
|
||||
:image-output-type "svg"
|
||||
:image-size-adjust (1.7 . 1.5)
|
||||
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter ("dvisvgm %f --no-fonts --exact-bbox --scale=%S --output=%O"))
|
||||
(imagemagick
|
||||
:programs ("latex" "convert")
|
||||
:description "pdf > png"
|
||||
:message "you need to install the programs: latex and imagemagick."
|
||||
:image-input-type "pdf"
|
||||
:image-output-type "png"
|
||||
:image-size-adjust (1.0 . 1.0)
|
||||
:latex-compiler ("pdflatex -interaction nonstopmode -output-directory %o %f")
|
||||
:image-converter
|
||||
("convert -density %D -trim -antialias %f -quality 100 %O")))
|
||||
"Definitions of external processes for LaTeX previewing.
|
||||
Org mode can use some external commands to generate TeX snippet's images for
|
||||
previewing or inserting into HTML files, e.g., \"dvipng\". This variable tells
|
||||
`org-create-formula-image' how to call them.
|
||||
|
||||
The value is an alist with the pattern (NAME . PROPERTIES). NAME is a symbol.
|
||||
PROPERTIES accepts the following attributes:
|
||||
|
||||
:programs list of strings, required programs.
|
||||
:description string, describe the process.
|
||||
:message string, message it when required programs cannot be found.
|
||||
:image-input-type string, input file type of image converter (e.g., \"dvi\").
|
||||
:image-output-type string, output file type of image converter (e.g., \"png\").
|
||||
: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 process
|
||||
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. When 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 strings, the LaTeX header of the snippet file.
|
||||
When nil, the fallback value is used instead, which is
|
||||
controlled by `org-format-latex-header',
|
||||
`org-latex-default-packages-alist' and
|
||||
`org-latex-packages-alist', which see.
|
||||
:latex-compiler list of LaTeX commands, as strings. Each of them is given
|
||||
to the shell. Place-holders \"%t\", \"%b\" and \"%o\" are
|
||||
replaced with values defined below.
|
||||
:image-converter list of image converter commands strings. Each of them is
|
||||
given to the shell and supports any of the following
|
||||
place-holders defined below.
|
||||
|
||||
If set, :transparent-image-converter is used instead of :image-converter to
|
||||
convert an image when the background color is nil or \"Transparent\".
|
||||
|
||||
Place-holders used by `:image-converter' and `:latex-compiler':
|
||||
|
||||
%f input file name
|
||||
%b base name of input file
|
||||
%o base directory of input file
|
||||
%O absolute output file name
|
||||
|
||||
Place-holders only used by `:image-converter':
|
||||
|
||||
%D dpi, which is used to adjust image size by some processing commands.
|
||||
%S the image size scale ratio, which is used to adjust image size by some
|
||||
processing commands."
|
||||
:group 'org-latex
|
||||
:package-version '(Org . "9.6")
|
||||
:type '(alist :tag "LaTeX to image backends"
|
||||
:value-type (plist)))
|
||||
|
||||
(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
|
||||
images at the same place."
|
||||
:group 'org-latex
|
||||
:version "26.1"
|
||||
:package-version '(Org . "9.0")
|
||||
:type 'string)
|
||||
|
||||
(defun org-format-latex-mathml-available-p ()
|
||||
"Return t if `org-latex-to-mathml-convert-command' is usable."
|
||||
(save-match-data
|
||||
(when (and (boundp 'org-latex-to-mathml-convert-command)
|
||||
org-latex-to-mathml-convert-command)
|
||||
(let ((executable (car (split-string
|
||||
org-latex-to-mathml-convert-command))))
|
||||
(when (executable-find executable)
|
||||
(if (string-match
|
||||
"%j" org-latex-to-mathml-convert-command)
|
||||
(file-readable-p org-latex-to-mathml-jar-file)
|
||||
t))))))
|
||||
|
||||
(defcustom org-format-latex-header "\\documentclass{article}
|
||||
\\usepackage[usenames]{color}
|
||||
\[DEFAULT-PACKAGES]
|
||||
\[PACKAGES]
|
||||
\\pagestyle{empty} % do not remove
|
||||
% The settings below are copied from fullpage.sty
|
||||
\\setlength{\\textwidth}{\\paperwidth}
|
||||
\\addtolength{\\textwidth}{-3cm}
|
||||
\\setlength{\\oddsidemargin}{1.5cm}
|
||||
\\addtolength{\\oddsidemargin}{-2.54cm}
|
||||
\\setlength{\\evensidemargin}{\\oddsidemargin}
|
||||
\\setlength{\\textheight}{\\paperheight}
|
||||
\\addtolength{\\textheight}{-\\headheight}
|
||||
\\addtolength{\\textheight}{-\\headsep}
|
||||
\\addtolength{\\textheight}{-\\footskip}
|
||||
\\addtolength{\\textheight}{-3cm}
|
||||
\\setlength{\\topmargin}{1.5cm}
|
||||
\\addtolength{\\topmargin}{-2.54cm}"
|
||||
"The document header used for processing LaTeX fragments.
|
||||
It is imperative that this header make sure that no page number
|
||||
appears on the page. The package defined in the variables
|
||||
`org-latex-default-packages-alist' and `org-latex-packages-alist'
|
||||
will either replace the placeholder \"[PACKAGES]\" in this
|
||||
header, or they will be appended."
|
||||
:group 'org-latex
|
||||
:type 'string)
|
||||
|
||||
(defun org-set-packages-alist (var val)
|
||||
"Set the packages alist and make sure it has 3 elements per entry."
|
||||
(set-default-toplevel-value var (mapcar (lambda (x)
|
||||
|
@ -16046,6 +15808,8 @@ environment remains unintended."
|
|||
|
||||
;;;; LaTeX fragments
|
||||
|
||||
(require 'org-latex-preview)
|
||||
|
||||
(defun org-inside-LaTeX-fragment-p (&optional element)
|
||||
"Test if point is inside a LaTeX fragment or environment.
|
||||
|
||||
|
@ -16061,466 +15825,6 @@ at point."
|
|||
(org-in-regexp
|
||||
"\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*")))
|
||||
|
||||
(defun org--make-preview-overlay (beg end image &optional imagetype)
|
||||
"Build an overlay between BEG and END using IMAGE file.
|
||||
Argument IMAGETYPE is the extension of the displayed image,
|
||||
as a string. It defaults to \"png\"."
|
||||
(let ((ov (make-overlay beg end))
|
||||
(imagetype (or (intern imagetype) 'png)))
|
||||
(overlay-put ov 'org-overlay-type 'org-latex-overlay)
|
||||
(overlay-put ov 'evaporate t)
|
||||
(overlay-put ov
|
||||
'modification-hooks
|
||||
(list (lambda (o _flag _beg _end &optional _l)
|
||||
(delete-overlay o))))
|
||||
(overlay-put ov
|
||||
'display
|
||||
(list 'image :type imagetype :file image :ascent 'center))))
|
||||
|
||||
(defun org-clear-latex-preview (&optional beg end)
|
||||
"Remove all overlays with LaTeX fragment images in current buffer.
|
||||
When optional arguments BEG and END are non-nil, remove all
|
||||
overlays between them instead. Return a non-nil value when some
|
||||
overlays were removed, nil otherwise."
|
||||
(let ((overlays
|
||||
(cl-remove-if-not
|
||||
(lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay))
|
||||
(overlays-in (or beg (point-min)) (or end (point-max))))))
|
||||
(mapc #'delete-overlay overlays)
|
||||
overlays))
|
||||
|
||||
(defun org--latex-preview-region (beg end)
|
||||
"Preview LaTeX fragments between BEG and END.
|
||||
BEG and END are buffer positions."
|
||||
(let ((file (buffer-file-name (buffer-base-buffer))))
|
||||
(save-excursion
|
||||
(org-format-latex
|
||||
(concat org-preview-latex-image-directory "org-ltximg")
|
||||
beg end
|
||||
;; Emacs cannot overlay images from remote hosts. Create it in
|
||||
;; `temporary-file-directory' instead.
|
||||
(if (or (not file) (file-remote-p file))
|
||||
temporary-file-directory
|
||||
default-directory)
|
||||
'overlays nil 'forbuffer org-preview-latex-default-process))))
|
||||
|
||||
(defun org-latex-preview (&optional arg)
|
||||
"Toggle preview of the LaTeX fragment at point.
|
||||
|
||||
If the cursor is on a LaTeX fragment, create the image and
|
||||
overlay it over the source code, if there is none. Remove it
|
||||
otherwise. If there is no fragment at point, display images for
|
||||
all fragments in the current section. With an active region,
|
||||
display images for all fragments in the region.
|
||||
|
||||
With a `\\[universal-argument]' prefix argument ARG, clear images \
|
||||
for all fragments
|
||||
in the current section.
|
||||
|
||||
With a `\\[universal-argument] \\[universal-argument]' prefix \
|
||||
argument ARG, display image for all
|
||||
fragments in the buffer.
|
||||
|
||||
With a `\\[universal-argument] \\[universal-argument] \
|
||||
\\[universal-argument]' prefix argument ARG, clear image for all
|
||||
fragments in the buffer."
|
||||
(interactive "P")
|
||||
(cond
|
||||
((not (display-graphic-p)) nil)
|
||||
((and untrusted-content (not org--latex-preview-when-risky)) nil)
|
||||
;; Clear whole buffer.
|
||||
((equal arg '(64))
|
||||
(org-clear-latex-preview (point-min) (point-max))
|
||||
(message "LaTeX previews removed from buffer"))
|
||||
;; Preview whole buffer.
|
||||
((equal arg '(16))
|
||||
(message "Creating LaTeX previews in buffer...")
|
||||
(org--latex-preview-region (point-min) (point-max))
|
||||
(message "Creating LaTeX previews in buffer... done."))
|
||||
;; Clear current section.
|
||||
((equal arg '(4))
|
||||
(org-clear-latex-preview
|
||||
(if (use-region-p)
|
||||
(region-beginning)
|
||||
(if (org-before-first-heading-p) (point-min)
|
||||
(save-excursion
|
||||
(org-with-limited-levels (org-back-to-heading t) (point)))))
|
||||
(if (use-region-p)
|
||||
(region-end)
|
||||
(org-with-limited-levels (org-entry-end-position)))))
|
||||
((use-region-p)
|
||||
(message "Creating LaTeX previews in region...")
|
||||
(org--latex-preview-region (region-beginning) (region-end))
|
||||
(message "Creating LaTeX previews in region... done."))
|
||||
;; Toggle preview on LaTeX code at point.
|
||||
((let ((datum (org-element-context)))
|
||||
(and (org-element-type-p datum '(latex-environment latex-fragment))
|
||||
(let ((beg (org-element-begin datum))
|
||||
(end (org-element-end datum)))
|
||||
(if (org-clear-latex-preview beg end)
|
||||
(message "LaTeX preview removed")
|
||||
(message "Creating LaTeX preview...")
|
||||
(org--latex-preview-region beg end)
|
||||
(message "Creating LaTeX preview... done."))
|
||||
t))))
|
||||
;; Preview current section.
|
||||
(t
|
||||
(let ((beg (if (org-before-first-heading-p) (point-min)
|
||||
(save-excursion
|
||||
(org-with-limited-levels (org-back-to-heading t) (point)))))
|
||||
(end (org-with-limited-levels (org-entry-end-position))))
|
||||
(message "Creating LaTeX previews in section...")
|
||||
(org--latex-preview-region beg end)
|
||||
(message "Creating LaTeX previews in section... done.")))))
|
||||
|
||||
(defun org-format-latex
|
||||
(prefix &optional beg end dir overlays msg forbuffer processing-type)
|
||||
"Replace LaTeX fragments with links to an image.
|
||||
|
||||
The function takes care of creating the replacement image.
|
||||
|
||||
Only consider fragments between BEG and END when those are
|
||||
provided.
|
||||
|
||||
When optional argument OVERLAYS is non-nil, display the image on
|
||||
top of the fragment instead of replacing it.
|
||||
|
||||
PROCESSING-TYPE is the conversion method to use, as a symbol.
|
||||
|
||||
Some of the options can be changed using the variable
|
||||
`org-format-latex-options', which see."
|
||||
(when (and overlays (fboundp 'clear-image-cache)) (clear-image-cache))
|
||||
(unless (eq processing-type 'verbatim)
|
||||
(let* ((math-regexp "\\$\\|\\\\[([]\\|^[ \t]*\\\\begin{[A-Za-z0-9*]+}")
|
||||
(cnt 0)
|
||||
checkdir-flag)
|
||||
(goto-char (or beg (point-min)))
|
||||
;; FIXME: `overlay-recenter' is not needed (and has no effect)
|
||||
;; since Emacs 29.
|
||||
;; Optimize overlay creation: (info "(elisp) Managing Overlays").
|
||||
(when (and overlays (memq processing-type '(dvipng imagemagick)))
|
||||
(overlay-recenter (or end (point-max))))
|
||||
(while (re-search-forward math-regexp end t)
|
||||
(unless (and overlays
|
||||
(eq (get-char-property (point) 'org-overlay-type)
|
||||
'org-latex-overlay))
|
||||
(let* ((context (org-element-context))
|
||||
(type (org-element-type context)))
|
||||
(when (memq type '(latex-environment latex-fragment))
|
||||
(let ((block-type (eq type 'latex-environment))
|
||||
(value (org-element-property :value context))
|
||||
(beg (org-element-begin context))
|
||||
(end (save-excursion
|
||||
(goto-char (org-element-end context))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point))))
|
||||
(cond
|
||||
((eq processing-type 'mathjax)
|
||||
;; Prepare for MathJax processing.
|
||||
(if (not (string-match "\\`\\$\\$?" value))
|
||||
(goto-char end)
|
||||
(delete-region beg end)
|
||||
(if (string= (match-string 0 value) "$$")
|
||||
(insert "\\[" (substring value 2 -2) "\\]")
|
||||
(insert "\\(" (substring value 1 -1) "\\)"))))
|
||||
((eq processing-type 'html)
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-html value)))
|
||||
((assq processing-type org-preview-latex-process-alist)
|
||||
;; Process to an image.
|
||||
(cl-incf cnt)
|
||||
(goto-char beg)
|
||||
(let* ((processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(face (face-at-point))
|
||||
;; Get the colors from the face at point.
|
||||
(fg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:foreground)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :foreground nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :foreground nil))
|
||||
(t color))
|
||||
color)))
|
||||
(bg
|
||||
(let ((color (plist-get org-format-latex-options
|
||||
:background)))
|
||||
(if forbuffer
|
||||
(cond
|
||||
((eq color 'auto)
|
||||
(face-attribute face :background nil 'default))
|
||||
((eq color 'default)
|
||||
(face-attribute 'default :background nil))
|
||||
(t color))
|
||||
color)))
|
||||
(hash (sha1 (prin1-to-string
|
||||
(list org-format-latex-header
|
||||
org-latex-default-packages-alist
|
||||
org-latex-packages-alist
|
||||
org-format-latex-options
|
||||
forbuffer value fg bg))))
|
||||
(imagetype (or (plist-get processing-info :image-output-type) "png"))
|
||||
(absprefix (expand-file-name prefix dir))
|
||||
(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
|
||||
(org-combine-plists
|
||||
org-format-latex-options
|
||||
`(:foreground ,fg :background ,bg))))
|
||||
(when msg (message msg cnt))
|
||||
(unless checkdir-flag ; Ensure the directory exists.
|
||||
(setq checkdir-flag t)
|
||||
(let ((todir (file-name-directory absprefix)))
|
||||
(unless (file-directory-p todir)
|
||||
(make-directory todir t))))
|
||||
(unless (file-exists-p movefile)
|
||||
(org-create-formula-image
|
||||
value movefile options forbuffer processing-type))
|
||||
(org-place-formula-image link block-type beg end value overlays movefile imagetype)))
|
||||
((eq processing-type 'mathml)
|
||||
;; Process to MathML.
|
||||
(unless (org-format-latex-mathml-available-p)
|
||||
(user-error "LaTeX to MathML converter not configured"))
|
||||
(cl-incf cnt)
|
||||
(when msg (message msg cnt))
|
||||
(goto-char beg)
|
||||
(delete-region beg end)
|
||||
(insert (org-format-latex-as-mathml
|
||||
value block-type prefix dir)))
|
||||
(t
|
||||
(error "Unknown conversion process %s for LaTeX fragments"
|
||||
processing-type)))))))))))
|
||||
|
||||
(defun org-place-formula-image (link block-type beg end value overlays movefile imagetype)
|
||||
"Place an overlay from BEG to END showing MOVEFILE.
|
||||
The overlay will be above BEG if OVERLAYS is non-nil."
|
||||
(if overlays
|
||||
(progn
|
||||
(dolist (o (overlays-in beg end))
|
||||
(when (eq (overlay-get o 'org-overlay-type)
|
||||
'org-latex-overlay)
|
||||
(delete-overlay o)))
|
||||
(org--make-preview-overlay beg end movefile imagetype)
|
||||
(goto-char end))
|
||||
(delete-region beg end)
|
||||
(insert
|
||||
(org-add-props link
|
||||
(list 'org-latex-src
|
||||
(replace-regexp-in-string "\"" "" value)
|
||||
'org-latex-src-embed-type
|
||||
(if block-type 'paragraph 'character))))))
|
||||
|
||||
(defun org-create-math-formula (latex-frag &optional mathml-file)
|
||||
"Convert LATEX-FRAG to MathML and store it in MATHML-FILE.
|
||||
Use `org-latex-to-mathml-convert-command'. If the conversion is
|
||||
successful, return the portion between \"<math...> </math>\"
|
||||
elements otherwise return nil. When MATHML-FILE is specified,
|
||||
write the results in to that file. When invoked as an
|
||||
interactive command, prompt for LATEX-FRAG, with initial value
|
||||
set to the current active region and echo the results for user
|
||||
inspection."
|
||||
(interactive (list (let ((frag (when (org-region-active-p)
|
||||
(buffer-substring-no-properties
|
||||
(region-beginning) (region-end)))))
|
||||
(read-string "LaTeX Fragment: " frag nil frag))))
|
||||
(unless latex-frag (user-error "Invalid LaTeX fragment"))
|
||||
(let* ((tmp-in-file
|
||||
(let ((file (file-relative-name
|
||||
(make-temp-name (expand-file-name "ltxmathml-in")))))
|
||||
(write-region latex-frag nil file)
|
||||
file))
|
||||
(tmp-out-file (file-relative-name
|
||||
(make-temp-name (expand-file-name "ltxmathml-out"))))
|
||||
(cmd (format-spec
|
||||
org-latex-to-mathml-convert-command
|
||||
`((?j . ,(and org-latex-to-mathml-jar-file
|
||||
(shell-quote-argument
|
||||
(expand-file-name
|
||||
org-latex-to-mathml-jar-file))))
|
||||
(?I . ,(shell-quote-argument tmp-in-file))
|
||||
(?i . ,(shell-quote-argument latex-frag))
|
||||
(?o . ,(shell-quote-argument tmp-out-file)))))
|
||||
mathml shell-command-output)
|
||||
(when (called-interactively-p 'any)
|
||||
(unless (org-format-latex-mathml-available-p)
|
||||
(user-error "LaTeX to MathML converter not configured")))
|
||||
(message "Running %s" cmd)
|
||||
(setq shell-command-output (shell-command-to-string cmd))
|
||||
(setq mathml
|
||||
(when (file-readable-p tmp-out-file)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents tmp-out-file)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "<math[^>]*?%s[^>]*?>\\(.\\|\n\\)*</math>"
|
||||
(regexp-quote
|
||||
"xmlns=\"http://www.w3.org/1998/Math/MathML\""))
|
||||
nil t)
|
||||
(match-string 0)))))
|
||||
(cond
|
||||
(mathml
|
||||
(setq mathml
|
||||
(concat "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" mathml))
|
||||
(when mathml-file
|
||||
(write-region mathml nil mathml-file))
|
||||
(when (called-interactively-p 'any)
|
||||
(message mathml)))
|
||||
((warn "LaTeX to MathML conversion failed")
|
||||
(message shell-command-output)))
|
||||
(delete-file tmp-in-file)
|
||||
(when (file-exists-p tmp-out-file)
|
||||
(delete-file tmp-out-file))
|
||||
mathml))
|
||||
|
||||
(defun org-format-latex-as-mathml (latex-frag latex-frag-type
|
||||
prefix &optional dir)
|
||||
"Use `org-create-math-formula' but check local cache first."
|
||||
(let* ((absprefix (expand-file-name prefix dir))
|
||||
(print-length nil) (print-level nil)
|
||||
(formula-id (concat
|
||||
"formula-"
|
||||
(sha1
|
||||
(prin1-to-string
|
||||
(list latex-frag
|
||||
org-latex-to-mathml-convert-command)))))
|
||||
(formula-cache (format "%s-%s.mathml" absprefix formula-id))
|
||||
(formula-cache-dir (file-name-directory formula-cache)))
|
||||
|
||||
(unless (file-directory-p formula-cache-dir)
|
||||
(make-directory formula-cache-dir t))
|
||||
|
||||
(unless (file-exists-p formula-cache)
|
||||
(org-create-math-formula latex-frag formula-cache))
|
||||
|
||||
(if (file-exists-p formula-cache)
|
||||
;; Successful conversion. Return the link to MathML file.
|
||||
(org-add-props
|
||||
(format "[[file:%s]]" (file-relative-name formula-cache dir))
|
||||
(list 'org-latex-src (replace-regexp-in-string "\"" "" latex-frag)
|
||||
'org-latex-src-embed-type (if latex-frag-type
|
||||
'paragraph 'character)))
|
||||
;; Failed conversion. Return the LaTeX fragment verbatim
|
||||
latex-frag)))
|
||||
|
||||
(defun org-format-latex-as-html (latex-fragment)
|
||||
"Convert LATEX-FRAGMENT to HTML.
|
||||
This uses `org-latex-to-html-convert-command', which see."
|
||||
(let ((cmd (format-spec org-latex-to-html-convert-command
|
||||
`((?i . ,(shell-quote-argument latex-fragment))))))
|
||||
(message "Running %s" cmd)
|
||||
(shell-command-to-string cmd)))
|
||||
|
||||
(defun org--get-display-dpi ()
|
||||
"Get the DPI of the display.
|
||||
The function assumes that the display has the same pixel width in
|
||||
the horizontal and vertical directions."
|
||||
(if (display-graphic-p)
|
||||
(round (/ (display-pixel-height)
|
||||
(/ (display-mm-height) 25.4)))
|
||||
(error "Attempt to calculate the dpi of a non-graphic display")))
|
||||
|
||||
(defun org-create-formula-image
|
||||
(string tofile options buffer &optional processing-type)
|
||||
"Create an image from LaTeX source using external processes.
|
||||
|
||||
The LaTeX STRING is saved to a temporary LaTeX file, then
|
||||
converted to an image file by process PROCESSING-TYPE defined in
|
||||
`org-preview-latex-process-alist'. A nil value defaults to
|
||||
`org-preview-latex-default-process'.
|
||||
|
||||
The generated image file is eventually moved to TOFILE.
|
||||
|
||||
The OPTIONS argument controls the size, foreground color and
|
||||
background color of the generated image.
|
||||
|
||||
When BUFFER non-nil, this function is used for LaTeX previewing.
|
||||
Otherwise, it is used to deal with LaTeX snippets showed in
|
||||
a HTML file."
|
||||
(let* ((processing-type (or processing-type
|
||||
org-preview-latex-default-process))
|
||||
(processing-info
|
||||
(cdr (assq processing-type org-preview-latex-process-alist)))
|
||||
(programs (plist-get processing-info :programs))
|
||||
(error-message (or (plist-get processing-info :message) ""))
|
||||
(image-input-type (plist-get processing-info :image-input-type))
|
||||
(image-output-type (plist-get processing-info :image-output-type))
|
||||
(post-clean (or (plist-get processing-info :post-clean)
|
||||
'(".dvi" ".xdv" ".pdf" ".tex" ".aux" ".log"
|
||||
".svg" ".png" ".jpg" ".jpeg" ".out")))
|
||||
(latex-header
|
||||
(or (plist-get processing-info :latex-header)
|
||||
(org-latex-make-preamble
|
||||
(org-export-get-environment (org-export-get-backend 'latex))
|
||||
org-format-latex-header
|
||||
'snippet)))
|
||||
(latex-compiler (plist-get processing-info :latex-compiler))
|
||||
(tmpdir temporary-file-directory)
|
||||
(texfilebase (make-temp-name
|
||||
(expand-file-name "orgtex" tmpdir)))
|
||||
(texfile (concat texfilebase ".tex"))
|
||||
(image-size-adjust (or (plist-get 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 (if (and buffer (display-graphic-p)) (org--get-display-dpi) 140.0)))
|
||||
(fg (or (plist-get options (if buffer :foreground :html-foreground))
|
||||
"Black"))
|
||||
(bg (or (plist-get options (if buffer :background :html-background))
|
||||
"Transparent"))
|
||||
(image-converter
|
||||
(or (and (string= bg "Transparent")
|
||||
(plist-get processing-info :transparent-image-converter))
|
||||
(plist-get processing-info :image-converter)))
|
||||
(log-buf (get-buffer-create "*Org Preview LaTeX Output*"))
|
||||
(resize-mini-windows nil)) ;Fix Emacs flicker when creating image.
|
||||
(dolist (program programs)
|
||||
(org-check-external-command program error-message))
|
||||
(if (eq fg 'default)
|
||||
(setq fg (org-latex-color :foreground))
|
||||
(setq fg (org-latex-color-format fg)))
|
||||
(setq bg (cond
|
||||
((eq bg 'default) (org-latex-color :background))
|
||||
((string= bg "Transparent") nil)
|
||||
(t (org-latex-color-format bg))))
|
||||
;; Remove TeX \par at end of snippet to avoid trailing space.
|
||||
(if (string-suffix-p string "\n")
|
||||
(aset string (1- (length string)) ?%)
|
||||
(setq string (concat string "%")))
|
||||
(with-temp-file texfile
|
||||
(insert latex-header)
|
||||
(insert "\n\\begin{document}\n"
|
||||
"\\definecolor{fg}{rgb}{" fg "}%\n"
|
||||
(if bg
|
||||
(concat "\\definecolor{bg}{rgb}{" bg "}%\n"
|
||||
"\n\\pagecolor{bg}%\n")
|
||||
"")
|
||||
"\n{\\color{fg}\n"
|
||||
string
|
||||
"\n}\n"
|
||||
"\n\\end{document}\n"))
|
||||
(let* ((err-msg (format "Please adjust `%s' part of \
|
||||
`org-preview-latex-process-alist'."
|
||||
processing-type))
|
||||
(image-input-file
|
||||
(org-compile-file
|
||||
texfile latex-compiler image-input-type err-msg log-buf))
|
||||
(image-output-file
|
||||
(org-compile-file
|
||||
image-input-file image-converter image-output-type err-msg log-buf
|
||||
`((?D . ,(shell-quote-argument (format "%s" dpi)))
|
||||
(?S . ,(shell-quote-argument (format "%s" (/ dpi 140.0))))))))
|
||||
(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-splice-latex-header (tpl def-pkg pkg snippets-p &optional extra)
|
||||
"Fill a LaTeX header template TPL.
|
||||
In the template, the following place holders will be recognized:
|
||||
|
@ -16580,30 +15884,6 @@ SNIPPETS-P indicates if this is run to create snippet images for HTML."
|
|||
"\n"))
|
||||
(if newline (concat pkg "\n") pkg))
|
||||
|
||||
(defun org-dvipng-color (attr)
|
||||
"Return a RGB color specification for dvipng."
|
||||
(org-dvipng-color-format (face-attribute 'default attr nil)))
|
||||
|
||||
(defun org-dvipng-color-format (color-name)
|
||||
"Convert COLOR-NAME to a RGB color value for dvipng."
|
||||
(apply #'format "rgb %s %s %s"
|
||||
(mapcar 'org-normalize-color
|
||||
(color-values color-name))))
|
||||
|
||||
(defun org-latex-color (attr)
|
||||
"Return a RGB color for the LaTeX color package."
|
||||
(org-latex-color-format (face-attribute 'default attr nil)))
|
||||
|
||||
(defun org-latex-color-format (color-name)
|
||||
"Convert COLOR-NAME to a RGB color value."
|
||||
(apply #'format "%s,%s,%s"
|
||||
(mapcar 'org-normalize-color
|
||||
(color-values color-name))))
|
||||
|
||||
(defun org-normalize-color (value)
|
||||
"Return string to be used as color value for an RGB component."
|
||||
(format "%g" (/ value 65535.0)))
|
||||
|
||||
|
||||
;; Image display
|
||||
|
||||
|
|
Loading…
Reference in New Issue