<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/atom.xsl" type="text/xsl"?><feed
	xmlns="http://www.w3.org/2005/Atom"
	xmlns:thr="http://purl.org/syndication/thread/1.0"
	xml:lang="en-US"
	><title>Sacha Chua - category - images</title>
	<subtitle>Emacs, sketches, and life</subtitle>
	<link rel="self" type="application/atom+xml" href="https://sachachua.com/blog/category/images/feed/atom/index.xml" />
  <link rel="alternate" type="text/html" href="https://sachachua.com/blog/category/images" />
  <id>https://sachachua.com/blog/category/images/feed/atom/index.xml</id>
  <generator uri="https://11ty.dev">11ty</generator>
	<updated>2024-09-26T16:54:34Z</updated>
<entry>
		<title type="html">Include inline SVGs in Org Mode HTML and Markdown exports</title>
		<link rel="alternate" type="text/html" href="https://sachachua.com/blog/2024/09/include-inline-svgs-in-org-mode-html-and-markdown-exports/"/>
		<author><name><![CDATA[Sacha Chua]]></name></author>
		<updated>2025-01-10T17:41:48Z</updated>
    <published>2024-09-26T16:54:34Z</published>
    <category term="emacs" />
<category term="org" />
<category term="images" />
		<id>https://sachachua.com/blog/2024/09/include-inline-svgs-in-org-mode-html-and-markdown-exports/</id>
		<content type="html"><![CDATA[<div class="update" id="org7bc2749">
<ul class="org-ul">
<li><span class="timestamp-wrapper"><time class="timestamp" datetime="2025-01-10">[2025-01-10 Fri]</time></span>: Fixed descriptions.</li>
<li><span class="timestamp-wrapper"><time class="timestamp" datetime="2024-10-14">[2024-10-14 Mon]</time></span>: Fixed path when inlining file URLs.</li>
<li><span class="timestamp-wrapper"><time class="timestamp" datetime="2024-10-07">[2024-10-07 Mon]</time></span>: Now I can specify <code>#+ATTR_HTML :data-link t</code> to make it link instead of include.</li>
<li><span class="timestamp-wrapper"><time class="timestamp" datetime="2024-09-26">[2024-09-26 Thu]</time></span>: Whoops, forgot to make sure ox-11ty is also covered.</li>
</ul>

</div>

<p>
In my Org Mode HTML and Markdown exports, I
usually want to include SVGs inline so that I can
use links. Sometimes I also want to use Javascript
and CSS to modify elements within the images. I
used to use a <a href="https://sachachua.com/dotemacs#org-mode-including-portions-of-files-between-two-regular-expressions">my-include:</a> link to do this, but I
realized that I can also modify this behaviour by
making my own functions that call <code>org-html-link</code>
or <code>org-md-link</code> and then put those functions in
<code>org-export-backend-transcoders</code>.
</p>

<p>
Here is an example of an SVG:
</p>


<div class="org-src-container">
<pre class="src src-dot"><code><span class="org-keyword">digraph</span> <span class="org-function-name">g</span> {
    <span class="org-variable-name">rankdir=</span><span class="org-constant">LR</span>;
    <span class="org-keyword">node</span> [<span class="org-variable-name">fontcolor=</span><span class="org-string">"#000000"</span>,<span class="org-variable-name">fontname=</span><span class="org-string">"Roboto,Arial,sans-serif"</span>];
    <span class="org-keyword">edge</span> [<span class="org-variable-name">fontcolor=</span><span class="org-string">"#000000"</span>,<span class="org-variable-name">fontname=</span><span class="org-string">"Roboto,Arial,sans-serif"</span>];
    Graphviz -&gt; <span class="org-string">"Org Mode"</span> [<span class="org-variable-name">label=</span><span class="org-string">"SVG"</span>];
    <span class="org-string">"Org Mode"</span> -&gt; {HTML Markdown};
    Graphviz[<span class="org-variable-name">URL=</span><span class="org-string">"https://graphviz.org"</span>,<span class="org-variable-name">fontcolor=</span><span class="org-string">"blue"</span>];
}
</code></pre>
</div>


<p>
The following code overrides HTML and Markdown exports
to include SVGs.
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code><span class="org-comment-delimiter">;;;</span><span class="org-comment">###</span><span class="org-comment"><span class="org-warning">autoload</span></span>
(<span class="org-keyword">defun</span> <span class="org-function-name">my-ox-link-path</span> (link _ info)
  (<span class="org-keyword">let*</span> ((raw-path (org-element-property <span class="org-builtin">:path</span> link)))
    (<span class="org-keyword">setq</span> raw-path
          (org-export-file-uri
           (org-publish-file-relative-name raw-path info)))
    <span class="org-comment-delimiter">;; </span><span class="org-comment">Possibly append `</span><span class="org-comment"><span class="org-constant">:html-link-home</span></span><span class="org-comment">' to relative file</span>
    <span class="org-comment-delimiter">;; </span><span class="org-comment">name.</span>
    (<span class="org-keyword">let</span> ((home (<span class="org-keyword">and</span> (plist-get info <span class="org-builtin">:html-link-home</span>)
                     (org-trim (plist-get info <span class="org-builtin">:html-link-home</span>)))))
      (<span class="org-keyword">when</span> (<span class="org-keyword">and</span> home
                 (plist-get info <span class="org-builtin">:html-link-use-abs-url</span>)
                 (not (file-name-absolute-p raw-path)))
        (<span class="org-keyword">setq</span> raw-path (concat (file-name-as-directory home) raw-path))))
    raw-path))

<span class="org-comment-delimiter">;;;</span><span class="org-comment">###</span><span class="org-comment"><span class="org-warning">autoload</span></span>
(<span class="org-keyword">defun</span> <span class="org-function-name">my-org-html-link</span> (link desc info)
  (<span class="org-keyword">if</span> (<span class="org-keyword">and</span>
       (string= (org-element-property <span class="org-builtin">:type</span> link) <span class="org-string">"file"</span>)
       (not (plist-get (org-export-read-attribute <span class="org-builtin">:attr_html</span> (org-element-parent-element link))
                       <span class="org-builtin">:data-link</span>))
       (org-export-inline-image-p link (plist-get info <span class="org-builtin">:html-inline-image-rules</span>)))
      (<span class="org-keyword">let</span> ((path (org-element-property <span class="org-builtin">:path</span> link))
            (attr (org-export-read-attribute <span class="org-builtin">:attr_html</span> (org-element-parent-element link))))
        (<span class="org-keyword">if</span> (string= (file-name-extension path) <span class="org-string">"svg"</span>)
            (<span class="org-keyword">with-temp-buffer</span>
              (set-buffer-multibyte t)
              (insert-file-contents path)
              (<span class="org-keyword">if</span> attr
                  (replace-regexp-in-string
                   <span class="org-string">"&lt;svg "</span>
                   (concat
                    <span class="org-string">"&lt;svg "</span>
                    (org-html&#45;&#45;make-attribute-string attr)
                    <span class="org-string">" "</span>)
                   (buffer-string))
                (buffer-string)))
          (org-html-link link desc info)))
    (org-html-link link desc info)))

<span class="org-comment-delimiter">;;;</span><span class="org-comment">###</span><span class="org-comment"><span class="org-warning">autoload</span></span>
(<span class="org-keyword">defun</span> <span class="org-function-name">my-org-md-link</span> (link desc info)
  (<span class="org-keyword">if</span> (<span class="org-keyword">and</span> (string= (org-element-property <span class="org-builtin">:type</span> link) <span class="org-string">"file"</span>)
           (not (plist-get (org-export-read-attribute <span class="org-builtin">:attr_html</span> (org-element-parent-element link))
                       <span class="org-builtin">:data-link</span>)))
      (<span class="org-keyword">let</span> ((path (org-element-property <span class="org-builtin">:path</span> link)))
        (<span class="org-keyword">if</span> (string= (file-name-extension path) <span class="org-string">"svg"</span>)
            (<span class="org-keyword">with-temp-buffer</span>
              (insert-file-contents-literally path)
              (buffer-string))
          (org-md-link link desc info)))
    (org-md-link link desc info)))

<span class="org-comment-delimiter">;;;</span><span class="org-comment">###</span><span class="org-comment"><span class="org-warning">autoload</span></span>
(<span class="org-keyword">defun</span> <span class="org-function-name">my-org-11ty-link</span> (link desc info)
  (<span class="org-keyword">if</span> (<span class="org-keyword">and</span> (string= (org-element-property <span class="org-builtin">:type</span> link) <span class="org-string">"file"</span>)
           (not (plist-get (org-export-read-attribute <span class="org-builtin">:attr_html</span> (org-element-parent-element link))
                           <span class="org-builtin">:data-link</span>))
           (not desc))
      (<span class="org-keyword">let</span> ((path (org-element-property <span class="org-builtin">:path</span> link))
            (attr (org-export-read-attribute <span class="org-builtin">:attr_html</span> (org-element-parent-element link))))
        (<span class="org-keyword">if</span> (string= (file-name-extension path) <span class="org-string">"svg"</span>)
            (<span class="org-keyword">with-temp-buffer</span>
              (set-buffer-multibyte t)
              (insert-file-contents path)
              (<span class="org-keyword">if</span> attr
                  (replace-regexp-in-string
                   <span class="org-string">"&lt;svg "</span>
                   (concat
                    <span class="org-string">"&lt;svg "</span>
                    (org-html&#45;&#45;make-attribute-string attr)
                    <span class="org-string">" "</span>)
                   (buffer-string))
                (buffer-string)))
          (org-11ty-link link desc info)))
    (org-11ty-link link desc info)))
</code></pre>
</div>



<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">with-eval-after-load</span> <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">ox-html</span>
  (<span class="org-keyword">setf</span>
   (alist-get <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">link</span> (org-export-backend-transcoders (org-export-get-backend <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">html</span>)))
   <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">my-org-html-link</span>))
(<span class="org-keyword">with-eval-after-load</span> <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">ox-md</span>
  (<span class="org-keyword">setf</span>
   (alist-get <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">link</span> (org-export-backend-transcoders (org-export-get-backend <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">md</span>)))
   <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">my-org-md-link</span>))
(<span class="org-keyword">with-eval-after-load</span> <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">ox-11ty</span>
  (<span class="org-keyword">setf</span>
   (alist-get <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">link</span> (org-export-backend-transcoders (org-export-get-backend <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">11ty</span>)))
   <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">my-org-11ty-link</span>))
</code></pre>
</div>


<div class="note">This is part of my <a href="https://sachachua.com/dotemacs#org-inline-svg">Emacs configuration.</a></div><div><a href="https://sachachua.com/blog/2024/09/include-inline-svgs-in-org-mode-html-and-markdown-exports/index.org">View Org source for this post</a></div><p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2024%2F09%2Finclude-inline-svgs-in-org-mode-html-and-markdown-exports%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></content>
		</entry>
</feed>