forked from mirrors/org-mode
ox-html: Allow inlining svg tex as <svg> elements
* lisp/ox-html.el (org-html-latex-image--data, org-html-latex-image): Add support for inlining dvisvgm-exported svgs as <svg> elements, preserving the effect of the currentColor attribute. While making this change, we improve a few other aspects of the html LaTeX fragment export system, namely refactoring/code style improvements and the recognition of \[...\] and $$...$$ fragments as blocks not inline fragments.
This commit is contained in:
parent
fdaeb38609
commit
3019d930d6
103
lisp/ox-html.el
103
lisp/ox-html.el
|
@ -1181,13 +1181,12 @@ This is a HTML-specific counterpart to
|
||||||
|
|
||||||
This supports two extra properties,
|
This supports two extra properties,
|
||||||
:image-dir an html-export counterpart of `org-latex-preview-cache', and
|
:image-dir an html-export counterpart of `org-latex-preview-cache', and
|
||||||
:inline images that should not be saved according to :image-dir,
|
:inline a list of image formats (or single format symbol) that
|
||||||
but instead inlined in the generated HTML. This can be:
|
should not be saved according to :image-dir, but instead
|
||||||
- t, to inline all images
|
inlined in the generated HTML. Valid format symbols are:
|
||||||
- svg, to inline all images, using <svg> with SVGs
|
- png, to inline png images using <img> with a data URI
|
||||||
- nil, to never inline images
|
- svg, to inline svg images using <img> with a data URI
|
||||||
- an extension or list of extensions, for images that
|
- svg-embed, to inline svg images using an <svg> element"
|
||||||
should be inline (e.g. \"svg\")"
|
|
||||||
:group 'org-export-html
|
:group 'org-export-html
|
||||||
:package-version '(Org . "9.7")
|
:package-version '(Org . "9.7")
|
||||||
:type 'plist)
|
:type 'plist)
|
||||||
|
@ -3208,40 +3207,48 @@ that an image for ELEMENT already exists within it."
|
||||||
(path-info (or (org-latex-preview--get-cached hash)
|
(path-info (or (org-latex-preview--get-cached hash)
|
||||||
(error "Expected LaTeX preview %S to exist in the cache" hash)))
|
(error "Expected LaTeX preview %S to exist in the cache" hash)))
|
||||||
(image-options (plist-get info :html-latex-image-options))
|
(image-options (plist-get info :html-latex-image-options))
|
||||||
(rescale-factor (if (eq (plist-get (cdr path-info) :image-type) 'svg)
|
(block-p (memq (aref (org-element-property :value element) 1) '(?$ ?\[)))
|
||||||
(plist-get image-options :scale)
|
|
||||||
1))
|
|
||||||
(image-source
|
(image-source
|
||||||
(org-html-latex-image--data (car path-info) hash info)))
|
(org-html-latex-image--data path-info hash info block-p)))
|
||||||
(unless (and (plist-get (cdr path-info) :height)
|
(unless (and (plist-get (cdr path-info) :height)
|
||||||
(plist-get (cdr path-info) :depth))
|
(plist-get (cdr path-info) :depth))
|
||||||
(error "Something went wrong during image generation"))
|
(error "Something went wrong during image generation"))
|
||||||
(if (and (eq (plist-get image-options :inline) 'svg)
|
(if (and (eq (plist-get image-options :inline) 'svg-embed)
|
||||||
(string= (file-name-extension (car path-info)) "svg"))
|
(eq (plist-get (cdr path-info) :image-type) 'svg))
|
||||||
image-source
|
image-source
|
||||||
(org-html-close-tag
|
(let ((scaling (org-html-latex-image--scaling path-info info)))
|
||||||
"img"
|
(org-html-close-tag
|
||||||
(org-html--make-attribute-string
|
"img"
|
||||||
(list :src image-source
|
(org-html--make-attribute-string
|
||||||
:alt (org-html-encode-plain-text
|
(list :src image-source
|
||||||
(org-element-property :value element))
|
:alt (org-html-encode-plain-text
|
||||||
:style (if (eq (org-element-type element) 'latex-environment)
|
(org-element-property :value element))
|
||||||
(format "height: %.4fem"
|
:style (if block-p
|
||||||
(* rescale-factor (plist-get (cdr path-info) :height)))
|
(format "height: %.4fem; display: block" (plist-get scaling :height))
|
||||||
(format "height: %.4fem; vertical-align: -%.4fem; display: inline-block"
|
(format "height: %.4fem; vertical-align: -%.4fem; display: inline-block"
|
||||||
(* rescale-factor (plist-get (cdr path-info) :height))
|
(plist-get scaling :height) (plist-get scaling :depth)))
|
||||||
(* rescale-factor (plist-get (cdr path-info) :depth))))
|
:class (format "org-latex org-latex-%s" (if block-p "block" "inline"))))
|
||||||
:class (if (eq (org-element-type element) 'latex-environment)
|
info)))))
|
||||||
"org-latex org-latex-environment"
|
|
||||||
"org-latex org-latex-fragment")))
|
|
||||||
info))))
|
|
||||||
|
|
||||||
(defun org-html-latex-image--data (source-file hash info)
|
(defun org-html-latex-image--scaling (image-path-info info)
|
||||||
"Obtaine the image source for SOURCE-FILE as a string, based on HASH and INFO.
|
"Determine the appropriate (<height> . <depth>) of IMAGE-PATH-INFO given INFO."
|
||||||
This can take the form of a path, data URI, or <svg> element."
|
(let* ((image-options (plist-get info :html-latex-image-options))
|
||||||
|
(rescale-factor (if (eq (plist-get (cdr image-path-info) :image-type) 'svg)
|
||||||
|
(plist-get image-options :scale)
|
||||||
|
1)))
|
||||||
|
(list :height (* rescale-factor (plist-get (cdr image-path-info) :height))
|
||||||
|
:depth (* rescale-factor (plist-get (cdr image-path-info) :depth)))))
|
||||||
|
|
||||||
|
(defun org-html-latex-image--data (image-path-info hash info &optional block-p)
|
||||||
|
"Obtaine the image source for IMAGE-PATH-INFO as a string.
|
||||||
|
This can take the form of a path, data URI, or <svg> element
|
||||||
|
depending on HASH and INFO. BLOCK-P signals that the image
|
||||||
|
should be a block element."
|
||||||
(let* ((image-options (plist-get info :html-latex-image-options))
|
(let* ((image-options (plist-get info :html-latex-image-options))
|
||||||
(inline-condition (plist-get image-options :inline))
|
(inline-condition (plist-get image-options :inline))
|
||||||
(image-dir (plist-get image-options :image-dir)))
|
(image-dir (plist-get image-options :image-dir))
|
||||||
|
(image-format (plist-get (cdr image-path-info) :image-type))
|
||||||
|
(source-file (car image-path-info)))
|
||||||
(cond
|
(cond
|
||||||
((or inline-condition
|
((or inline-condition
|
||||||
(member (file-name-extension source-file)
|
(member (file-name-extension source-file)
|
||||||
|
@ -3251,10 +3258,32 @@ This can take the form of a path, data URI, or <svg> element."
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert-file-contents-literally source-file)
|
(insert-file-contents-literally source-file)
|
||||||
(cond
|
(cond
|
||||||
((and (eq inline-condition 'svg)
|
((and (eq inline-condition 'svg-embed)
|
||||||
(string= (file-name-extension source-file) "svg"))
|
(eq image-format 'svg))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let ((svg-closing-tag (and (search-forward "<svg" nil t)
|
||||||
|
(search-forward ">" nil t))))
|
||||||
|
|
||||||
|
(dolist (search '("<!-- This file was generated by dvisvgm [^\n]+ -->"
|
||||||
|
" height=['\"][^\"']+[\"']"
|
||||||
|
" width=['\"][^\"']+[\"']"))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(when (re-search-forward search svg-closing-tag t)
|
||||||
|
(replace-match "")))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(when (re-search-forward "viewBox=['\"][^\"']+[\"']" svg-closing-tag t)
|
||||||
|
(insert
|
||||||
|
" style=\""
|
||||||
|
(let ((scaling (org-html-latex-image--scaling image-path-info info)))
|
||||||
|
(if block-p
|
||||||
|
(format "height: %.4fem; display: block" (plist-get scaling :height))
|
||||||
|
(format "height: %.4fem; vertical-align: -%.4fem; display: inline-block"
|
||||||
|
(plist-get scaling :height) (plist-get scaling :depth))))
|
||||||
|
"\" class=\"org-latex org-latex-"
|
||||||
|
(if block-p "block" "inline")
|
||||||
|
"\"")))
|
||||||
(buffer-string))
|
(buffer-string))
|
||||||
((string= (file-name-extension source-file) "svg")
|
((eq image-format 'svg)
|
||||||
;; Modelled after <https://codepen.io/tigt/post/optimizing-svgs-in-data-uris>.
|
;; Modelled after <https://codepen.io/tigt/post/optimizing-svgs-in-data-uris>.
|
||||||
(concat "data:image/svg+xml,"
|
(concat "data:image/svg+xml,"
|
||||||
(url-hexify-string
|
(url-hexify-string
|
||||||
|
@ -3269,7 +3298,7 @@ This can take the form of a path, data URI, or <svg> element."
|
||||||
(t
|
(t
|
||||||
(base64-encode-region (point-min) (point-max))
|
(base64-encode-region (point-min) (point-max))
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(insert "data:image/" (file-name-extension source-file) ";base64,")
|
(insert "data:image/" (symbol-name image-format) ";base64,")
|
||||||
(buffer-string))))))
|
(buffer-string))))))
|
||||||
((stringp image-dir)
|
((stringp image-dir)
|
||||||
(let* ((image-dir (expand-file-name image-dir))
|
(let* ((image-dir (expand-file-name image-dir))
|
||||||
|
|
Loading…
Reference in New Issue