One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
Here is some code in emacs-lisp that does that.
(let ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(lambda (src-block)
(setq language (org-element-property :language src-block))
(setq code (org-element-property :value src-block))
(setq filename (cond ((string= language "python") (format "../media/py-%d.py" counter))
((string= language "emacs-lisp") (format "../media/el-%d.elisp" counter))))
(setq counter (+ counter 1))
(with-temp-buffer
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format "Wrote %s\n" filename)))))
Open the code
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
Now, we have saved each code block into a file. The next step is inserting links to the files in published HTML files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file, and finally returning the url where that file will be served from. Code files will be served from /media in the blog.
Here is a function to save the nth code block and get its url.
(defun save-nth-src-block (nth parsetree)
"write out the nth codeblock to a file. returns the filename written to."
(catch 'url
(let ((counter 0))
(org-element-map parsetree 'src-block
(lambda (src-block)
(if (= nth counter)
(progn
(setq language (org-element-property :language src-block))
(setq code (org-element-property :value src-block))
(setq filename (cond ((string= language "python") (format "py-%d.py" counter))
((string= language "emacs-lisp") (format "el-%d.elisp" counter))))
(with-temp-buffer
(insert code)
(write-region (point-min) (point-max) (concat "../media/" filename)))
(throw 'url (concat "/media/" filename)))
;; update counter
(setq counter (+ counter 1))))))))
Open the code
Let us test that out.
(princ (save-nth-src-block 2 (org-element-parse-buffer)))
Open the code
/media/el-2.elisp
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See http://orgmode.org/worg/exporters/filter-markup.html for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is HTML. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
So our filter will use the global counter to call our save-nth-src-block function. That function will return the URL that will serve the file, so we can add it to the text rendered for the code block. Here is the code to define the filter function, and export the HTML. We return the HTML from this code block to see where the modifcations occurred.
(let ((counter 0))
(defun ox-mrkup-filter-src-block (text back-end info)
(let* ((url (save-nth-src-block counter (plist-get info :parse-tree)))
(output (format "%s
<a href=\"%s\">Open the code</a>
" text url)))
(setq counter (+ counter 1))
output))
(let ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
; now get the output into the org output
(switch-to-buffer "*Org HTML Export*")
(buffer-string))
Open the code
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1. Customizing the export of org-mode elements</a>
<ul>
<li><a href="#sec-1-1">1.1. Parsing the org-file</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1"><span class="section-number-2">1</span> Customizing the export of org-mode elements</h2>
<div class="outline-text-2" id="text-1">
<p>
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
</p>
<p>
I used a simple method with a filter to do all that in Latex, but when I looked into doing the same thing for HTML, I realized the simple method would not work. It worked in latex because the rendered text block was the literal code wrapped in the minted latex environment. So, I could just strip off the first and last line of the rendered text and save it to a file. Code rendered in HTML has lots of tags in it, and it is not practical to strip these out. So, we have to go back to the drawing board.
</p>
<p>
This is just one code block for example.
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #8b0000;">for</span> i <span style="color: #8b0000;">in</span> <span style="color: #cd0000;">range</span>(3):
<span style="color: #8b0000;">print</span> i**2
</pre>
</div>
<a href="/media/py-0.py">Open the code</a>
<pre class="example">
0
1
4
</pre>
</div>
<div id="outline-container-sec-1-1" class="outline-3">
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Parsing the org-file</h3>
<div class="outline-text-3" id="text-1-1">
<p>
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
</p>
<p>
Here is some code in emacs-lisp that does that.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">let</span> ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(<span style="color: #8b0000;">lambda</span> (src-block)
(setq language (org-element-property <span style="color: #cd0000;">:language</span> src-block))
(setq code (org-element-property <span style="color: #cd0000;">:value</span> src-block))
(setq filename (<span style="color: #8b0000;">cond</span> ((string= language <span style="color: #228b22;">"python"</span>) (format <span style="color: #228b22;">"../media/py-%d.py"</span> counter))
((string= language <span style="color: #228b22;">"emacs-lisp"</span>) (format <span style="color: #228b22;">"../media/el-%d.elisp"</span> counter))))
(setq counter (+ counter 1))
(<span style="color: #8b0000;">with-temp-buffer</span>
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format <span style="color: #228b22;">"Wrote %s\n"</span> filename)))))
</pre>
</div>
<a href="/media/el-1.elisp">Open the code</a>
<pre class="example">
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
</pre>
<p>
Now, we have saved each code block into a file. The next step is inserting links to the files in published HTML files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
</p>
<p>
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file, and finally returning the url where that file will be served from. Code files will be served from /media in the blog.
</p>
<p>
Here is a function to save the nth code block and get its url.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">defun</span> <span style="color: #8b2323;">save-nth-src-block</span> (nth parsetree)
<span style="color: #228b22;">"write out the nth codeblock to a file. returns the filename written to."</span>
(<span style="color: #8b0000;">catch</span> '<span style="color: #cd0000;">url</span>
(<span style="color: #8b0000;">let</span> ((counter 0))
(org-element-map parsetree 'src-block
(<span style="color: #8b0000;">lambda</span> (src-block)
(<span style="color: #8b0000;">if</span> (= nth counter)
(<span style="color: #8b0000;">progn</span>
(setq language (org-element-property <span style="color: #cd0000;">:language</span> src-block))
(setq code (org-element-property <span style="color: #cd0000;">:value</span> src-block))
(setq filename (<span style="color: #8b0000;">cond</span> ((string= language <span style="color: #228b22;">"python"</span>) (format <span style="color: #228b22;">"py-%d.py"</span> counter))
((string= language <span style="color: #228b22;">"emacs-lisp"</span>) (format <span style="color: #228b22;">"el-%d.elisp"</span> counter))))
(<span style="color: #8b0000;">with-temp-buffer</span>
(insert code)
(write-region (point-min) (point-max) (concat <span style="color: #228b22;">"../media/"</span> filename)))
(<span style="color: #8b0000;">throw</span> '<span style="color: #cd0000;">url</span> (concat <span style="color: #228b22;">"/media/"</span> filename)))
<span style="color: #ff0000; font-weight: bold;">;; </span><span style="color: #ff0000; font-weight: bold;">update counter </span>
(setq counter (+ counter 1))))))))
</pre>
</div>
<a href="/media/el-2.elisp">Open the code</a>
<p>
Let us test that out.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(princ (save-nth-src-block 2 (org-element-parse-buffer)))
</pre>
</div>
<a href="/media/el-3.elisp">Open the code</a>
<pre class="example">
/media/el-2.elisp
</pre>
<p>
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See <a href="http://orgmode.org/worg/exporters/filter-markup.html">http://orgmode.org/worg/exporters/filter-markup.html</a> for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is HTML. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
</p>
<p>
So our filter will use the global counter to call our save-nth-src-block function. That function will return the URL that will serve the file, so we can add it to the text rendered for the code block. Here is the code to define the filter function, and export the HTML. We return the HTML from this code block to see where the modifcations occurred.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">let</span> ((counter 0))
(<span style="color: #8b0000;">defun</span> <span style="color: #8b2323;">ox-mrkup-filter-src-block</span> (text back-end info)
(<span style="color: #8b0000;">let*</span> ((url (save-nth-src-block counter (plist-get info <span style="color: #cd0000;">:parse-tree</span>)))
(output (format <span style="color: #228b22;">"%s </span>
<span style="color: #228b22;"><a href=\"%s\">Open the code</a> </span>
<span style="color: #228b22;">"</span> text url)))
(setq counter (+ counter 1))
output))
(<span style="color: #8b0000;">let</span> ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
<span style="color: #ff0000; font-weight: bold;">; </span><span style="color: #ff0000; font-weight: bold;">now get the output into the org output</span>
(switch-to-buffer <span style="color: #228b22;">"*Org HTML Export*"</span>)
(buffer-string))
</pre>
</div>
<a href="/media/el-4.elisp">Open the code</a>
<pre class="example">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1. Customizing the export of org-mode elements</a>
<ul>
<li><a href="#sec-1-1">1.1. Parsing the org-file</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1"><span class="section-number-2">1</span> Customizing the export of org-mode elements</h2>
<div class="outline-text-2" id="text-1">
<p>
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #8b0000;">for</span> i <span style="color: #8b0000;">in</span> <span style="color: #cd0000;">range</span>(3):
<span style="color: #8b0000;">print</span> i**2
</pre>
</div>
<a href="/media/py-0.py">Open the code</a>
<pre class="example">
0
1
4
</pre>
</div>
<div id="outline-container-sec-1-1" class="outline-3">
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Parsing the org-file</h3>
<div class="outline-text-3" id="text-1-1">
<p>
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">let</span> ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(<span style="color: #8b0000;">lambda</span> (src-block)
(setq language (org-element-property <span style="color: #cd0000;">:language</span> src-block))
(setq code (org-element-property <span style="color: #cd0000;">:value</span> src-block))
(setq filename (<span style="color: #8b0000;">cond</span> ((string= language <span style="color: #228b22;">"python"</span>) (format <span style="color: #228b22;">"../media/py-%d.py"</span> counter))
((string= language <span style="color: #228b22;">"emacs-lisp"</span>) (format <span style="color: #228b22;">"../media/el-%d.elisp"</span> counter))))
(setq counter (+ counter 1))
(<span style="color: #8b0000;">with-temp-buffer</span>
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format <span style="color: #228b22;">"Wrote %s\n"</span> filename)))))
</pre>
</div>
<a href="/media/el-1.elisp">Open the code</a>
<pre class="example">
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
</pre>
<p>
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
</p>
<p>
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">defun</span> <span style="color: #8b2323;">save-nth-src-block</span> (nth parsetree)
<span style="color: #228b22;">"write out the nth codeblock to a file. returns the filename written to."</span>
(<span style="color: #8b0000;">catch</span> '<span style="color: #cd0000;">url</span>
(<span style="color: #8b0000;">let</span> ((counter 0))
(org-element-map parsetree 'src-block
(<span style="color: #8b0000;">lambda</span> (src-block)
(<span style="color: #8b0000;">if</span> (= nth counter)
(<span style="color: #8b0000;">progn</span>
(setq language (org-element-property <span style="color: #cd0000;">:language</span> src-block))
(setq code (org-element-property <span style="color: #cd0000;">:value</span> src-block))
(setq filename (<span style="color: #8b0000;">cond</span> ((string= language <span style="color: #228b22;">"python"</span>) (format <span style="color: #228b22;">"py-%d.py"</span> counter))
((string= language <span style="color: #228b22;">"emacs-lisp"</span>) (format <span style="color: #228b22;">"el-%d.elisp"</span> counter))))
(<span style="color: #8b0000;">with-temp-buffer</span>
(insert code)
(write-region (point-min) (point-max) (concat <span style="color: #228b22;">"../media/"</span> filename)))
(<span style="color: #8b0000;">throw</span> '<span style="color: #cd0000;">url</span> (concat <span style="color: #228b22;">"/media/"</span> filename)))
<span style="color: #ff0000; font-weight: bold;">;; </span><span style="color: #ff0000; font-weight: bold;">update counter </span>
(setq counter (+ counter 1))))))))
</pre>
</div>
<a href="/media/el-2.elisp">Open the code</a>
<p>
Let us test that out.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(princ (save-nth-src-block 2 (org-element-parse-buffer)))
</pre>
</div>
<a href="/media/el-3.elisp">Open the code</a>
<pre class="example">
/media/el-2.elisp
</pre>
<p>
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See <a href="http://orgmode.org/worg/exporters/filter-markup.html">http://orgmode.org/worg/exporters/filter-markup.html</a> for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
</p>
<p>
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">let</span> ((counter 0))
(<span style="color: #8b0000;">defun</span> <span style="color: #8b2323;">ox-mrkup-filter-src-block</span> (text back-end info)
(<span style="color: #8b0000;">let*</span> ((url (save-nth-src-block counter (plist-get info <span style="color: #cd0000;">:parse-tree</span>)))
(output (format <span style="color: #228b22;">"%s </span>
<span style="color: #228b22;">&lt;a href=\"%s\"&gt;Open the code&lt;/a&gt; </span>
<span style="color: #228b22;">"</span> text url)))
(setq counter (+ counter 1))
output))
(<span style="color: #8b0000;">let</span> ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
<span style="color: #ff0000; font-weight: bold;">; </span><span style="color: #ff0000; font-weight: bold;">now get the output into the org output</span>
(switch-to-buffer <span style="color: #228b22;">"*Org HTML Export*"</span>)
(buffer-string))
</pre>
</div>
<a href="/media/el-4.elisp">Open the code</a>
<pre class="example">
&lt;div id="table-of-contents"&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div id="text-table-of-contents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1"&gt;1. Customizing the export of org-mode elements&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1-1"&gt;1.1. Parsing the org-file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;&lt;span class="section-number-2"&gt;1&lt;/span&gt; Customizing the export of org-mode elements&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
&lt;p&gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; i &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;range&lt;/span&gt;(3):
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; i**2
&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="/media/py-0.py"&gt;Open the code&lt;/a&gt;
&lt;pre class="example"&gt;
0
1
4
&lt;/pre&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-1-1" class="outline-3"&gt;
&lt;h3 id="sec-1-1"&gt;&lt;span class="section-number-3"&gt;1.1&lt;/span&gt; Parsing the org-file&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-1-1"&gt;
&lt;p&gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&lt;span style="color: #8b0000;"&gt;lambda&lt;/span&gt; (src-block)
(setq language (org-element-property &lt;span style="color: #cd0000;"&gt;:language&lt;/span&gt; src-block))
(setq code (org-element-property &lt;span style="color: #cd0000;"&gt;:value&lt;/span&gt; src-block))
(setq filename (&lt;span style="color: #8b0000;"&gt;cond&lt;/span&gt; ((string= language &lt;span style="color: #228b22;"&gt;"python"&lt;/span&gt;) (format &lt;span style="color: #228b22;"&gt;"../media/py-%d.py"&lt;/span&gt; counter))
((string= language &lt;span style="color: #228b22;"&gt;"emacs-lisp"&lt;/span&gt;) (format &lt;span style="color: #228b22;"&gt;"../media/el-%d.elisp"&lt;/span&gt; counter))))
(setq counter (+ counter 1))
(&lt;span style="color: #8b0000;"&gt;with-temp-buffer&lt;/span&gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &lt;span style="color: #228b22;"&gt;"Wrote %s\n"&lt;/span&gt; filename)))))
&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="/media/el-1.elisp"&gt;Open the code&lt;/a&gt;
&lt;pre class="example"&gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&lt;/pre&gt;
&lt;p&gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&lt;/p&gt;
&lt;p&gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;save-nth-src-block&lt;/span&gt; (nth parsetree)
&lt;span style="color: #228b22;"&gt;"write out the nth codeblock to a file. returns the filename written to."&lt;/span&gt;
(&lt;span style="color: #8b0000;"&gt;catch&lt;/span&gt; '&lt;span style="color: #cd0000;"&gt;url&lt;/span&gt;
(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((counter 0))
(org-element-map parsetree 'src-block
(&lt;span style="color: #8b0000;"&gt;lambda&lt;/span&gt; (src-block)
(&lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; (= nth counter)
(&lt;span style="color: #8b0000;"&gt;progn&lt;/span&gt;
(setq language (org-element-property &lt;span style="color: #cd0000;"&gt;:language&lt;/span&gt; src-block))
(setq code (org-element-property &lt;span style="color: #cd0000;"&gt;:value&lt;/span&gt; src-block))
(setq filename (&lt;span style="color: #8b0000;"&gt;cond&lt;/span&gt; ((string= language &lt;span style="color: #228b22;"&gt;"python"&lt;/span&gt;) (format &lt;span style="color: #228b22;"&gt;"py-%d.py"&lt;/span&gt; counter))
((string= language &lt;span style="color: #228b22;"&gt;"emacs-lisp"&lt;/span&gt;) (format &lt;span style="color: #228b22;"&gt;"el-%d.elisp"&lt;/span&gt; counter))))
(&lt;span style="color: #8b0000;"&gt;with-temp-buffer&lt;/span&gt;
(insert code)
(write-region (point-min) (point-max) (concat &lt;span style="color: #228b22;"&gt;"../media/"&lt;/span&gt; filename)))
(&lt;span style="color: #8b0000;"&gt;throw&lt;/span&gt; '&lt;span style="color: #cd0000;"&gt;url&lt;/span&gt; (concat &lt;span style="color: #228b22;"&gt;"/media/"&lt;/span&gt; filename)))
&lt;span style="color: #ff0000; font-weight: bold;"&gt;;; &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;update counter &lt;/span&gt;
(setq counter (+ counter 1))))))))
&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="/media/el-2.elisp"&gt;Open the code&lt;/a&gt;
&lt;p&gt;
Let us test that out.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-emacs-lisp"&gt;(princ (save-nth-src-block 2 (org-element-parse-buffer)))
&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="/media/el-3.elisp"&gt;Open the code&lt;/a&gt;
&lt;pre class="example"&gt;
/media/el-2.elisp
&lt;/pre&gt;
&lt;p&gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&gt;http://orgmode.org/worg/exporters/filter-markup.html&lt;/a&gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&lt;/p&gt;
&lt;p&gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((counter 0))
(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ox-mrkup-filter-src-block&lt;/span&gt; (text back-end info)
(&lt;span style="color: #8b0000;"&gt;let*&lt;/span&gt; ((url (save-nth-src-block counter (plist-get info &lt;span style="color: #cd0000;"&gt;:parse-tree&lt;/span&gt;)))
(output (format &lt;span style="color: #228b22;"&gt;"%s &lt;/span&gt;
&lt;span style="color: #228b22;"&gt;&amp;lt;a href=\"%s\"&amp;gt;Open the code&amp;lt;/a&amp;gt; &lt;/span&gt;
&lt;span style="color: #228b22;"&gt;"&lt;/span&gt; text url)))
(setq counter (+ counter 1))
output))
(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&lt;span style="color: #ff0000; font-weight: bold;"&gt;; &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;now get the output into the org output&lt;/span&gt;
(switch-to-buffer &lt;span style="color: #228b22;"&gt;"*Org HTML Export*"&lt;/span&gt;)
(buffer-string))
&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="/media/el-4.elisp"&gt;Open the code&lt;/a&gt;
&lt;pre class="example"&gt;
&amp;lt;div id="table-of-contents"&amp;gt;
&amp;lt;h2&amp;gt;Table of Contents&amp;lt;/h2&amp;gt;
&amp;lt;div id="text-table-of-contents"&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href="#sec-1"&amp;gt;1. Customizing the export of org-mode elements&amp;lt;/a&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href="#sec-1-1"&amp;gt;1.1. Parsing the org-file&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id="outline-container-sec-1" class="outline-2"&amp;gt;
&amp;lt;h2 id="sec-1"&amp;gt;&amp;lt;span class="section-number-2"&amp;gt;1&amp;lt;/span&amp;gt; Customizing the export of org-mode elements&amp;lt;/h2&amp;gt;
&amp;lt;div class="outline-text-2" id="text-1"&amp;gt;
&amp;lt;p&amp;gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&amp;lt;/p&amp;gt;
&amp;lt;div class="org-src-container"&amp;gt;
&amp;lt;pre class="src src-python"&amp;gt;&amp;lt;span style="color: #8b0000;"&amp;gt;for&amp;lt;/span&amp;gt; i &amp;lt;span style="color: #8b0000;"&amp;gt;in&amp;lt;/span&amp;gt; &amp;lt;span style="color: #cd0000;"&amp;gt;range&amp;lt;/span&amp;gt;(3):
&amp;lt;span style="color: #8b0000;"&amp;gt;print&amp;lt;/span&amp;gt; i**2
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a href="py-0.py"&amp;gt;Open the code&amp;lt;/a&amp;gt;
&amp;lt;pre class="example"&amp;gt;
0
1
4
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id="outline-container-sec-1-1" class="outline-3"&amp;gt;
&amp;lt;h3 id="sec-1-1"&amp;gt;&amp;lt;span class="section-number-3"&amp;gt;1.1&amp;lt;/span&amp;gt; Parsing the org-file&amp;lt;/h3&amp;gt;
&amp;lt;div class="outline-text-3" id="text-1-1"&amp;gt;
&amp;lt;p&amp;gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&amp;lt;/p&amp;gt;
&amp;lt;div class="org-src-container"&amp;gt;
&amp;lt;pre class="src src-emacs-lisp"&amp;gt;(&amp;lt;span style="color: #8b0000;"&amp;gt;let&amp;lt;/span&amp;gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&amp;lt;span style="color: #8b0000;"&amp;gt;lambda&amp;lt;/span&amp;gt; (src-block)
(setq language (org-element-property &amp;lt;span style="color: #cd0000;"&amp;gt;:language&amp;lt;/span&amp;gt; src-block))
(setq code (org-element-property &amp;lt;span style="color: #cd0000;"&amp;gt;:value&amp;lt;/span&amp;gt; src-block))
(setq filename (&amp;lt;span style="color: #8b0000;"&amp;gt;cond&amp;lt;/span&amp;gt; ((string= language &amp;lt;span style="color: #228b22;"&amp;gt;"python"&amp;lt;/span&amp;gt;) (format &amp;lt;span style="color: #228b22;"&amp;gt;"../media/py-%d.py"&amp;lt;/span&amp;gt; counter))
((string= language &amp;lt;span style="color: #228b22;"&amp;gt;"emacs-lisp"&amp;lt;/span&amp;gt;) (format &amp;lt;span style="color: #228b22;"&amp;gt;"../media/el-%d.elisp"&amp;lt;/span&amp;gt; counter))))
(setq counter (+ counter 1))
(&amp;lt;span style="color: #8b0000;"&amp;gt;with-temp-buffer&amp;lt;/span&amp;gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &amp;lt;span style="color: #228b22;"&amp;gt;"Wrote %s\n"&amp;lt;/span&amp;gt; filename)))))
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a href="el-1.elisp"&amp;gt;Open the code&amp;lt;/a&amp;gt;
&amp;lt;pre class="example"&amp;gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&amp;lt;/p&amp;gt;
&amp;lt;div class="org-src-container"&amp;gt;
&amp;lt;pre class="src src-emacs-lisp"&amp;gt;(&amp;lt;span style="color: #8b0000;"&amp;gt;defun&amp;lt;/span&amp;gt; &amp;lt;span style="color: #8b2323;"&amp;gt;save-nth-src-block&amp;lt;/span&amp;gt; (nth parsetree)
&amp;lt;span style="color: #228b22;"&amp;gt;"write out the nth codeblock to a file. returns the filename written to."&amp;lt;/span&amp;gt;
(&amp;lt;span style="color: #8b0000;"&amp;gt;catch&amp;lt;/span&amp;gt; '&amp;lt;span style="color: #cd0000;"&amp;gt;url&amp;lt;/span&amp;gt;
(&amp;lt;span style="color: #8b0000;"&amp;gt;let&amp;lt;/span&amp;gt; ((counter 0))
(org-element-map parsetree 'src-block
(&amp;lt;span style="color: #8b0000;"&amp;gt;lambda&amp;lt;/span&amp;gt; (src-block)
(&amp;lt;span style="color: #8b0000;"&amp;gt;if&amp;lt;/span&amp;gt; (= nth counter)
(&amp;lt;span style="color: #8b0000;"&amp;gt;progn&amp;lt;/span&amp;gt;
(setq language (org-element-property &amp;lt;span style="color: #cd0000;"&amp;gt;:language&amp;lt;/span&amp;gt; src-block))
(setq code (org-element-property &amp;lt;span style="color: #cd0000;"&amp;gt;:value&amp;lt;/span&amp;gt; src-block))
(setq filename (&amp;lt;span style="color: #8b0000;"&amp;gt;cond&amp;lt;/span&amp;gt; ((string= language &amp;lt;span style="color: #228b22;"&amp;gt;"python"&amp;lt;/span&amp;gt;) (format &amp;lt;span style="color: #228b22;"&amp;gt;"py-%d.py"&amp;lt;/span&amp;gt; counter))
((string= language &amp;lt;span style="color: #228b22;"&amp;gt;"emacs-lisp"&amp;lt;/span&amp;gt;) (format &amp;lt;span style="color: #228b22;"&amp;gt;"el-%d.elisp"&amp;lt;/span&amp;gt; counter))))
(&amp;lt;span style="color: #8b0000;"&amp;gt;with-temp-buffer&amp;lt;/span&amp;gt;
(insert code)
(write-region (point-min) (point-max) (concat &amp;lt;span style="color: #228b22;"&amp;gt;"../media/"&amp;lt;/span&amp;gt; filename)))
(&amp;lt;span style="color: #8b0000;"&amp;gt;throw&amp;lt;/span&amp;gt; '&amp;lt;span style="color: #cd0000;"&amp;gt;url&amp;lt;/span&amp;gt; (concat &amp;lt;span style="color: #228b22;"&amp;gt;"/media/"&amp;lt;/span&amp;gt; filename)))
&amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;gt;;; &amp;lt;/span&amp;gt;&amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;gt;update counter &amp;lt;/span&amp;gt;
(setq counter (+ counter 1))))))))
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a href="el-2.elisp"&amp;gt;Open the code&amp;lt;/a&amp;gt;
&amp;lt;p&amp;gt;
Let us test that out.
&amp;lt;/p&amp;gt;
&amp;lt;div class="org-src-container"&amp;gt;
&amp;lt;pre class="src src-emacs-lisp"&amp;gt;(princ (save-nth-src-block 2 (org-element-parse-buffer)))
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a href="el-3.elisp"&amp;gt;Open the code&amp;lt;/a&amp;gt;
&amp;lt;pre class="example"&amp;gt;
/media/el-2.elisp
&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &amp;lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&amp;gt;http://orgmode.org/worg/exporters/filter-markup.html&amp;lt;/a&amp;gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&amp;lt;/p&amp;gt;
&amp;lt;div class="org-src-container"&amp;gt;
&amp;lt;pre class="src src-emacs-lisp"&amp;gt;(&amp;lt;span style="color: #8b0000;"&amp;gt;let&amp;lt;/span&amp;gt; ((counter 0))
(&amp;lt;span style="color: #8b0000;"&amp;gt;defun&amp;lt;/span&amp;gt; &amp;lt;span style="color: #8b2323;"&amp;gt;ox-mrkup-filter-src-block&amp;lt;/span&amp;gt; (text back-end info)
(&amp;lt;span style="color: #8b0000;"&amp;gt;let&amp;lt;/span&amp;gt; ((filename (save-nth-src-block counter (plist-get info &amp;lt;span style="color: #cd0000;"&amp;gt;:parse-tree&amp;lt;/span&amp;gt;)))
(output (format &amp;lt;span style="color: #228b22;"&amp;gt;"%s &amp;lt;/span&amp;gt;
&amp;lt;span style="color: #228b22;"&amp;gt;&amp;amp;lt;a href=\"%s\"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt; &amp;lt;/span&amp;gt;
&amp;lt;span style="color: #228b22;"&amp;gt;"&amp;lt;/span&amp;gt; text filename)))
(setq counter (+ counter 1))
output))
(&amp;lt;span style="color: #8b0000;"&amp;gt;let&amp;lt;/span&amp;gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;gt;; &amp;lt;/span&amp;gt;&amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;gt;now get the output into the org output&amp;lt;/span&amp;gt;
(switch-to-buffer &amp;lt;span style="color: #228b22;"&amp;gt;"*Org HTML Export*"&amp;lt;/span&amp;gt;)
(buffer-string))
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a href="el-4.elisp"&amp;gt;Open the code&amp;lt;/a&amp;gt;
&amp;lt;pre class="example"&amp;gt;
&amp;amp;lt;div id="table-of-contents"&amp;amp;gt;
&amp;amp;lt;h2&amp;amp;gt;Table of Contents&amp;amp;lt;/h2&amp;amp;gt;
&amp;amp;lt;div id="text-table-of-contents"&amp;amp;gt;
&amp;amp;lt;ul&amp;amp;gt;
&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href="#sec-1"&amp;amp;gt;1. Customizing the export of org-mode elements&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;ul&amp;amp;gt;
&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href="#sec-1-1"&amp;amp;gt;1.1. Parsing the org-file&amp;amp;lt;/a&amp;amp;gt;&amp;amp;lt;/li&amp;amp;gt;
&amp;amp;lt;/ul&amp;amp;gt;
&amp;amp;lt;/li&amp;amp;gt;
&amp;amp;lt;/ul&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div id="outline-container-sec-1" class="outline-2"&amp;amp;gt;
&amp;amp;lt;h2 id="sec-1"&amp;amp;gt;&amp;amp;lt;span class="section-number-2"&amp;amp;gt;1&amp;amp;lt;/span&amp;amp;gt; Customizing the export of org-mode elements&amp;amp;lt;/h2&amp;amp;gt;
&amp;amp;lt;div class="outline-text-2" id="text-1"&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;div class="org-src-container"&amp;amp;gt;
&amp;amp;lt;pre class="src src-python"&amp;amp;gt;&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;for&amp;amp;lt;/span&amp;amp;gt; i &amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;in&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;range&amp;amp;lt;/span&amp;amp;gt;(3):
&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;print&amp;amp;lt;/span&amp;amp;gt; i**2
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;a href="py-0.py"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;pre class="example"&amp;amp;gt;
0
1
4
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div id="outline-container-sec-1-1" class="outline-3"&amp;amp;gt;
&amp;amp;lt;h3 id="sec-1-1"&amp;amp;gt;&amp;amp;lt;span class="section-number-3"&amp;amp;gt;1.1&amp;amp;lt;/span&amp;amp;gt; Parsing the org-file&amp;amp;lt;/h3&amp;amp;gt;
&amp;amp;lt;div class="outline-text-3" id="text-1-1"&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;div class="org-src-container"&amp;amp;gt;
&amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;gt;(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;let&amp;amp;lt;/span&amp;amp;gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;lambda&amp;amp;lt;/span&amp;amp;gt; (src-block)
(setq language (org-element-property &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;:language&amp;amp;lt;/span&amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;:value&amp;amp;lt;/span&amp;amp;gt; src-block))
(setq filename (&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;cond&amp;amp;lt;/span&amp;amp;gt; ((string= language &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"python"&amp;amp;lt;/span&amp;amp;gt;) (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"../media/py-%d.py"&amp;amp;lt;/span&amp;amp;gt; counter))
((string= language &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"emacs-lisp"&amp;amp;lt;/span&amp;amp;gt;) (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"../media/el-%d.elisp"&amp;amp;lt;/span&amp;amp;gt; counter))))
(setq counter (+ counter 1))
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;with-temp-buffer&amp;amp;lt;/span&amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"Wrote %s\n"&amp;amp;lt;/span&amp;amp;gt; filename)))))
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;a href="el-1.elisp"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;pre class="example"&amp;amp;gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;div class="org-src-container"&amp;amp;gt;
&amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;gt;(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;defun&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span style="color: #8b2323;"&amp;amp;gt;save-nth-src-block&amp;amp;lt;/span&amp;amp;gt; (nth parsetree)
&amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"write out the nth codeblock to a file. returns the filename written to."&amp;amp;lt;/span&amp;amp;gt;
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;let&amp;amp;lt;/span&amp;amp;gt; ((counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;lambda&amp;amp;lt;/span&amp;amp;gt; (src-block)
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;if&amp;amp;lt;/span&amp;amp;gt; (= nth counter)
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;progn&amp;amp;lt;/span&amp;amp;gt;
(setq language (org-element-property &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;:language&amp;amp;lt;/span&amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;:value&amp;amp;lt;/span&amp;amp;gt; src-block))
(setq filename (&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;cond&amp;amp;lt;/span&amp;amp;gt; ((string= language &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"python"&amp;amp;lt;/span&amp;amp;gt;) (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"py-%d.py"&amp;amp;lt;/span&amp;amp;gt; counter))
((string= language &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"emacs-lisp"&amp;amp;lt;/span&amp;amp;gt;) (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"el-%d.elisp"&amp;amp;lt;/span&amp;amp;gt; counter))))
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;with-temp-buffer&amp;amp;lt;/span&amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) (concat &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"../media/"&amp;amp;lt;/span&amp;amp;gt; filename)))
(princ (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"Wrote %s\n"&amp;amp;lt;/span&amp;amp;gt; filename))))
(setq counter (+ counter 1)))))
&amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;gt;;; &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;gt;return the URL the file will be served at&amp;amp;lt;/span&amp;amp;gt;
(concat &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"/media/"&amp;amp;lt;/span&amp;amp;gt; filename))
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;a href="el-2.elisp"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
Let us test that out.
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;div class="org-src-container"&amp;amp;gt;
&amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;gt;(save-nth-src-block 2 (org-element-parse-buffer))
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;a href="el-3.elisp"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;pre class="example"&amp;amp;gt;
/media/el-2.elisp
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &amp;amp;lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&amp;amp;gt;http://orgmode.org/worg/exporters/filter-markup.html&amp;amp;lt;/a&amp;amp;gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;p&amp;amp;gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&amp;amp;lt;/p&amp;amp;gt;
&amp;amp;lt;div class="org-src-container"&amp;amp;gt;
&amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;gt;(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;let&amp;amp;lt;/span&amp;amp;gt; ((counter 0))
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;defun&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span style="color: #8b2323;"&amp;amp;gt;ox-mrkup-filter-src-block&amp;amp;lt;/span&amp;amp;gt; (text back-end info)
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;let&amp;amp;lt;/span&amp;amp;gt; ((filename (save-nth-src-block counter (plist-get info &amp;amp;lt;span style="color: #cd0000;"&amp;amp;gt;:parse-tree&amp;amp;lt;/span&amp;amp;gt;)))
(output (format &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"%s &amp;amp;lt;/span&amp;amp;gt;
&amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;&amp;amp;amp;lt;a href=\"%s\"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt; &amp;amp;lt;/span&amp;amp;gt;
&amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"&amp;amp;lt;/span&amp;amp;gt; text filename)))
(setq counter (+ counter 1))
output))
(&amp;amp;lt;span style="color: #8b0000;"&amp;amp;gt;let&amp;amp;lt;/span&amp;amp;gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;gt;; &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;gt;now get the output into the org output&amp;amp;lt;/span&amp;amp;gt;
(switch-to-buffer &amp;amp;lt;span style="color: #228b22;"&amp;amp;gt;"*Org HTML Export*"&amp;amp;lt;/span&amp;amp;gt;)
(buffer-string))
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;a href="el-4.elisp"&amp;amp;gt;Open the code&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;pre class="example"&amp;amp;gt;
&amp;amp;amp;lt;div id="table-of-contents"&amp;amp;amp;gt;
&amp;amp;amp;lt;h2&amp;amp;amp;gt;Table of Contents&amp;amp;amp;lt;/h2&amp;amp;amp;gt;
&amp;amp;amp;lt;div id="text-table-of-contents"&amp;amp;amp;gt;
&amp;amp;amp;lt;ul&amp;amp;amp;gt;
&amp;amp;amp;lt;li&amp;amp;amp;gt;&amp;amp;amp;lt;a href="#sec-1"&amp;amp;amp;gt;1. Customizing the export of org-mode elements&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;ul&amp;amp;amp;gt;
&amp;amp;amp;lt;li&amp;amp;amp;gt;&amp;amp;amp;lt;a href="#sec-1-1"&amp;amp;amp;gt;1.1. Parsing the org-file&amp;amp;amp;lt;/a&amp;amp;amp;gt;&amp;amp;amp;lt;/li&amp;amp;amp;gt;
&amp;amp;amp;lt;/ul&amp;amp;amp;gt;
&amp;amp;amp;lt;/li&amp;amp;amp;gt;
&amp;amp;amp;lt;/ul&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;div id="outline-container-sec-1" class="outline-2"&amp;amp;amp;gt;
&amp;amp;amp;lt;h2 id="sec-1"&amp;amp;amp;gt;&amp;amp;amp;lt;span class="section-number-2"&amp;amp;amp;gt;1&amp;amp;amp;lt;/span&amp;amp;amp;gt; Customizing the export of org-mode elements&amp;amp;amp;lt;/h2&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="outline-text-2" id="text-1"&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="src src-python"&amp;amp;amp;gt;&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;for&amp;amp;amp;lt;/span&amp;amp;amp;gt; i &amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;in&amp;amp;amp;lt;/span&amp;amp;amp;gt; &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;range&amp;amp;amp;lt;/span&amp;amp;amp;gt;(3):
&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;print&amp;amp;amp;lt;/span&amp;amp;amp;gt; i**2
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="py-0.py"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="example"&amp;amp;amp;gt;
0
1
4
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;div id="outline-container-sec-1-1" class="outline-3"&amp;amp;amp;gt;
&amp;amp;amp;lt;h3 id="sec-1-1"&amp;amp;amp;gt;&amp;amp;amp;lt;span class="section-number-3"&amp;amp;amp;gt;1.1&amp;amp;amp;lt;/span&amp;amp;amp;gt; Parsing the org-file&amp;amp;amp;lt;/h3&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="outline-text-3" id="text-1-1"&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;gt;(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;let&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;lambda&amp;amp;amp;lt;/span&amp;amp;amp;gt; (src-block)
(setq language (org-element-property &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;:language&amp;amp;amp;lt;/span&amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;:value&amp;amp;amp;lt;/span&amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;cond&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((string= language &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"python"&amp;amp;amp;lt;/span&amp;amp;amp;gt;) (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"../media/py-%d.py"&amp;amp;amp;lt;/span&amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;lt;/span&amp;amp;amp;gt;) (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"../media/el-%d.elisp"&amp;amp;amp;lt;/span&amp;amp;amp;gt; counter))))
(setq counter (+ counter 1))
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;lt;/span&amp;amp;amp;gt; filename)))))
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="el-1.elisp"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="example"&amp;amp;amp;gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;gt;(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;defun&amp;amp;amp;lt;/span&amp;amp;amp;gt; &amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;gt;save-nth-src-block&amp;amp;amp;lt;/span&amp;amp;amp;gt; (nth parsetree)
&amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"write out the nth codeblock to a file. returns the filename written to."&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;let&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;lambda&amp;amp;amp;lt;/span&amp;amp;amp;gt; (src-block)
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;if&amp;amp;amp;lt;/span&amp;amp;amp;gt; (= nth counter)
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;progn&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(setq language (org-element-property &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;:language&amp;amp;amp;lt;/span&amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;:value&amp;amp;amp;lt;/span&amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;cond&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((string= language &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"python"&amp;amp;amp;lt;/span&amp;amp;amp;gt;) (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"py-%d.py"&amp;amp;amp;lt;/span&amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;lt;/span&amp;amp;amp;gt;) (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"el-%d.elisp"&amp;amp;amp;lt;/span&amp;amp;amp;gt; counter))))
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) (concat &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"../media/"&amp;amp;amp;lt;/span&amp;amp;amp;gt; filename)))
(princ (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;lt;/span&amp;amp;amp;gt; filename))))
(setq counter (+ counter 1)))))
&amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;gt;;; &amp;amp;amp;lt;/span&amp;amp;amp;gt;&amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;gt;return the URL the file will be served at&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(concat &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"/media/"&amp;amp;amp;lt;/span&amp;amp;amp;gt; filename))
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="el-2.elisp"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
Let us test that out.
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;gt;(save-nth-src-block 2 (org-element-parse-buffer))
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="el-3.elisp"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="example"&amp;amp;amp;gt;
/media/el-2.elisp
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &amp;amp;amp;lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&amp;amp;amp;gt;http://orgmode.org/worg/exporters/filter-markup.html&amp;amp;amp;lt;/a&amp;amp;amp;gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&amp;amp;amp;lt;/p&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;gt;(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;let&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((counter 0))
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;defun&amp;amp;amp;lt;/span&amp;amp;amp;gt; &amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;gt;ox-mrkup-filter-src-block&amp;amp;amp;lt;/span&amp;amp;amp;gt; (text back-end info)
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;let&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((filename (save-nth-src-block counter (plist-get info &amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;gt;:parse-tree&amp;amp;amp;lt;/span&amp;amp;amp;gt;)))
(output (format &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"%s &amp;amp;amp;lt;/span&amp;amp;amp;gt;
&amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;&amp;amp;amp;amp;lt;a href=\"%s\"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt; &amp;amp;amp;lt;/span&amp;amp;amp;gt;
&amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"&amp;amp;amp;lt;/span&amp;amp;amp;gt; text filename)))
(setq counter (+ counter 1))
output))
(&amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;gt;let&amp;amp;amp;lt;/span&amp;amp;amp;gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;gt;; &amp;amp;amp;lt;/span&amp;amp;amp;gt;&amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;gt;now get the output into the org output&amp;amp;amp;lt;/span&amp;amp;amp;gt;
(switch-to-buffer &amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;gt;"*Org HTML Export*"&amp;amp;amp;lt;/span&amp;amp;amp;gt;)
(buffer-string))
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="el-4.elisp"&amp;amp;amp;gt;Open the code&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;pre class="example"&amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div id="table-of-contents"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;h2&amp;amp;amp;amp;gt;Table of Contents&amp;amp;amp;amp;lt;/h2&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div id="text-table-of-contents"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;ul&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;li&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;a href="#sec-1"&amp;amp;amp;amp;gt;1. Customizing the export of org-mode elements&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;ul&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;li&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;a href="#sec-1-1"&amp;amp;amp;amp;gt;1.1. Parsing the org-file&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/li&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/ul&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/li&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/ul&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div id="outline-container-sec-1" class="outline-2"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;h2 id="sec-1"&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span class="section-number-2"&amp;amp;amp;amp;gt;1&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; Customizing the export of org-mode elements&amp;amp;amp;amp;lt;/h2&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="outline-text-2" id="text-1"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="src src-python"&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;for&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; i &amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;in&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;range&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;(3):
&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;print&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; i**2
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;a href="py-0.py"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;gt;
0
1
4
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div id="outline-container-sec-1-1" class="outline-3"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;h3 id="sec-1-1"&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span class="section-number-3"&amp;amp;amp;amp;gt;1.1&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; Parsing the org-file&amp;amp;amp;amp;lt;/h3&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="outline-text-3" id="text-1-1"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;gt;(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;let&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;lambda&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; (src-block)
(setq language (org-element-property &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;:language&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;:value&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;cond&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((string= language &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"python"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"../media/py-%d.py"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"../media/el-%d.elisp"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; counter))))
(setq counter (+ counter 1))
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; filename)))))
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;a href="el-1.elisp"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;gt;(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;defun&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;amp;gt;save-nth-src-block&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; (nth parsetree)
&amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"write out the nth codeblock to a file. returns the filename written to."&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;let&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;lambda&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; (src-block)
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;if&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; (= nth counter)
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;progn&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
(setq language (org-element-property &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;:language&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;:value&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;cond&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((string= language &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"python"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"py-%d.py"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"el-%d.elisp"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; counter))))
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) (concat &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"../media/"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; filename)))
(princ (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; filename))))
(setq counter (+ counter 1)))))
(concat &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"/media/"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; filename))
&amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;gt;;; &amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;gt;return the URL the file will be served at&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
))))
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;a href="el-2.elisp"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
Let us test that out.
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;gt;(save-nth-src-block 2 (org-element-parse-buffer))
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;a href="el-3.elisp"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;gt;
Wrote el-2.elisp
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &amp;amp;amp;amp;lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&amp;amp;amp;amp;gt;http://orgmode.org/worg/exporters/filter-markup.html&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;gt;(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;let&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((counter 0))
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;defun&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;amp;gt;ox-mrkup-filter-src-block&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; (text back-end info)
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;let&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((filename (save-nth-src-block counter (plist-get info &amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;gt;:parse-tree&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;)))
(output (format &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"%s &amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;a href=\"%s\"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; text filename)))
(setq counter (+ counter 1))
output))
(&amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;gt;let&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;gt;; &amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;gt;now get the output into the org output&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;
(switch-to-buffer &amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;gt;"*Org HTML Export*"&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;)
(buffer-string))
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;a href="el-4.elisp"&amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div id="table-of-contents"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;h2&amp;amp;amp;amp;amp;gt;Table of Contents&amp;amp;amp;amp;amp;lt;/h2&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div id="text-table-of-contents"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;ul&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;li&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;a href="#sec-1"&amp;amp;amp;amp;amp;gt;1. Customizing the export of org-mode elements&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;ul&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;li&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;a href="#sec-1-1"&amp;amp;amp;amp;amp;gt;1.1. Parsing the org-file&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;/li&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/ul&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/li&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/ul&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div id="outline-container-sec-1" class="outline-2"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;h2 id="sec-1"&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;span class="section-number-2"&amp;amp;amp;amp;amp;gt;1&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; Customizing the export of org-mode elements&amp;amp;amp;amp;amp;lt;/h2&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="outline-text-2" id="text-1"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
In a recent project I have used org-mode to create a document with lots of src blocks describing how to use python. I wanted to find a way to modify the export process so that each code block would be saved to a file, and a link to that file would be put in the exported pdf. I could have used tangling to do that, but I did not want the burden of having to name the code blocks. I wanted them named sequentially, and I often rearrange the blocks or add new ones in.
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="src src-python"&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;for&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; i &amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;in&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;range&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;(3):
&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;print&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; i**2
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;a href="py-0.py"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;amp;gt;
0
1
4
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div id="outline-container-sec-1-1" class="outline-3"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;h3 id="sec-1-1"&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;span class="section-number-3"&amp;amp;amp;amp;amp;gt;1.1&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; Parsing the org-file&amp;amp;amp;amp;amp;lt;/h3&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="outline-text-3" id="text-1-1"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
One strategy we can use is to parse the org-buffer, and for each code block get the language, construct a filename that is appropriate, and write the file to where we want it. I am going to write the files to a location in my blogofile root so I can later link to them in the blog.
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;amp;gt;(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;let&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((parsetree (org-element-parse-buffer))
(counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;lambda&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; (src-block)
(setq language (org-element-property &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;:language&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;:value&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;cond&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((string= language &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"python"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"../media/py-%d.py"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"../media/el-%d.elisp"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; counter))))
(setq counter (+ counter 1))
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) filename))
(princ (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; filename)))))
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;a href="el-1.elisp"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;amp;gt;
Wrote ../media/py-0.py
Wrote ../media/el-1.elisp
Wrote ../media/el-2.elisp
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
Now, we have saved each code block into a file. The next step is inserting links to the files in published html files. For this, we need to create a filter for src-blocks. In the blog, the files will be served at /media/filename. We are going to insert a hyperlink to that file after the HTML rendered code.
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
It turned out that I needed a new way to think about connecting the export filter to the code blocks. We need to keep track of which code block is being exported, so we can know which file to link to. I decided a way to do that is to create a function that gets the nth code block and write it to a file. Then, as we go through the
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;amp;gt;(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;defun&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;amp;amp;gt;save-nth-src-block&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; (nth parsetree)
&amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"write out the nth codeblock to a file. returns the filename written to."&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;let&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((counter 0))
(org-element-map parsetree 'src-block
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;lambda&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; (src-block)
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;if&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; (= nth counter)
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;progn&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(setq language (org-element-property &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;:language&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; src-block))
(setq code (org-element-property &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;:value&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; src-block))
(setq filename (&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;cond&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((string= language &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"python"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"py-%d.py"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; counter))
((string= language &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"emacs-lisp"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;) (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"el-%d.elisp"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; counter))))
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;with-temp-buffer&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(insert code)
(write-region (point-min) (point-max) (concat &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"../media/"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; filename)))
(princ (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"Wrote %s\n"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; filename))))
(setq counter (+ counter 1))
&amp;amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;amp;gt;;; &amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;amp;gt;return the URL the file will be served at&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(concat &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"/media/"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; filename)))))
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;a href="el-2.elisp"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
Let us test that out.
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;amp;gt;(save-nth-src-block 2 (org-element-parse-buffer))
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;a href="el-3.elisp"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;amp;gt;
Wrote el-2.elisp
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
It looks like that is working. During the export process, the parse tree is actually stored in an object called info that is passed to the export filters, so we can use that. See &amp;amp;amp;amp;amp;lt;a href="http://orgmode.org/worg/exporters/filter-markup.html"&amp;amp;amp;amp;amp;gt;http://orgmode.org/worg/exporters/filter-markup.html&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt; for more details about setting up filters for export. What follows here is built off of that. We are going to define a filter for src-blocks that saves the src-block, and adds a hyperlink after the text. The text that is handed to the filter has already been rendered by the backend, in this case that is html. All we have to do is add our hyperlink. We will keep a global counter that is updated by the filter, so we know which codeblock we are in for creating the link.
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;gt;
So our filter will use the global counter to call our save-nth-src-block function. That function will return the filename the codeblock was saved to. That is not the same as the path on the blog,
&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;div class="org-src-container"&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="src src-emacs-lisp"&amp;amp;amp;amp;amp;gt;(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;let&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((counter 0))
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;defun&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;lt;span style="color: #8b2323;"&amp;amp;amp;amp;amp;gt;ox-mrkup-filter-src-block&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; (text back-end info)
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;let&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((filename (save-nth-src-block counter (plist-get info &amp;amp;amp;amp;amp;lt;span style="color: #cd0000;"&amp;amp;amp;amp;amp;gt;:parse-tree&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;)))
(output (format &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"%s &amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;a href=\"%s\"&amp;amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; text filename)))
(setq counter (+ counter 1))
output))
(&amp;amp;amp;amp;amp;lt;span style="color: #8b0000;"&amp;amp;amp;amp;amp;gt;let&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt; ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
&amp;amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;amp;gt;; &amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;lt;span style="color: #ff0000; font-weight: bold;"&amp;amp;amp;amp;amp;gt;now get the output into the org output&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;
(switch-to-buffer &amp;amp;amp;amp;amp;lt;span style="color: #228b22;"&amp;amp;amp;amp;amp;gt;"*Org HTML Export*"&amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;gt;)
(buffer-string))
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;a href="el-4.elisp"&amp;amp;amp;amp;amp;gt;Open the code&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;pre class="example"&amp;amp;amp;amp;amp;gt;
Wrote py-0.py
Wrote el-1.elisp
Wrote el-2.elisp
Wrote el-3.elisp
Wrote el-4.elisp
&amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;lt;/pre&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;lt;/pre&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;lt;/pre&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</pre>
</div>
</div>
</div>
</pre>
<p>
Finally, lets put it all together and save the html to blogofile:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #8b0000;">let</span> ((counter 0))
(<span style="color: #8b0000;">defun</span> <span style="color: #8b2323;">ox-mrkup-filter-src-block</span> (text back-end info)
(<span style="color: #8b0000;">let*</span> ((url (save-nth-src-block counter (plist-get info <span style="color: #cd0000;">:parse-tree</span>)))
(output (format <span style="color: #228b22;">"%s </span>
<span style="color: #228b22;"><a href=\"%s\">Open the code</a> </span>
<span style="color: #228b22;">"</span> text url)))
(setq counter (+ counter 1))
output))
(<span style="color: #8b0000;">let</span> ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
<span style="color: #ff0000; font-weight: bold;">; </span><span style="color: #ff0000; font-weight: bold;">now get the output into the org output</span>
(switch-to-buffer <span style="color: #228b22;">"*Org HTML Export*"</span>)
(setq HTML (buffer-string)))
(setq YAML <span style="color: #228b22;">"---</span>
<span style="color: #228b22;">title: Customizing export of code blocks in HTML</span>
<span style="color: #228b22;">date: 2013/09/28 10:45:00</span>
<span style="color: #228b22;">categories: org-mode</span>
<span style="color: #228b22;">---</span>
<span style="color: #228b22;">"</span>)
(<span style="color: #8b0000;">with-temp-buffer</span>
(insert YAML)
(insert HTML)
(write-region (point-min) (point-max) <span style="color: #228b22;">"../_posts/2013-09-28-Customizing-export-of-code-blocks-in-HTML.html"</span>))
</pre>
</div>
<a href="/media/el-5.elisp">Open the code</a>
<p>
Now, I should be able to build blogofile, and the code files I saved will be in the media folder, and the links to those files will work in a browser!
</p>
</div>
</div>
</div>
Finally, lets put it all together and save the html to blogofile. This requires us to build the YAML header, and save the file in a formatted filename in _posts of the blogofile directory.
(let ((counter 0))
(defun ox-mrkup-filter-src-block (text back-end info)
(let* ((url (save-nth-src-block counter (plist-get info :parse-tree)))
(output (format "%s
<a href=\"%s\">Open the code</a>
" text url)))
(setq counter (+ counter 1))
output))
(let ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))
(async nil)
(subtreep nil)
(visible-only nil)
(body-only t)
(ext-plist '()))
(org-html-export-as-html async subtreep visible-only body-only ext-plist))
; now get the output into the org output
(switch-to-buffer "*Org HTML Export*")
(setq HTML (buffer-string)))
(setq YAML "---
title: Customizing export of code blocks in HTML
date: 2013/09/28 10:45:00
categories: org-mode
---
")
(with-temp-buffer
(insert YAML)
(insert HTML)
(write-region (point-min) (point-max) "../_posts/2013-09-28-Customizing-export-of-code-blocks-in-HTML.html"))
(princ "Done.")
Open the code
Now, I should be able to build blogofile, and the code files I saved will be in the media folder, and the links to those files will work in a browser!