<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>notroot</title><link>https://blog.notroot.online/</link><description>Meandering Musings</description><atom:link href="https://blog.notroot.online/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2024 &lt;a href="mailto:notroot@notroot.online"&gt;Notroot&lt;/a&gt; </copyright><lastBuildDate>Sat, 18 May 2024 00:57:41 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Adding a Fediverse Share Button to my Emacs Nikola Blog</title><link>https://blog.notroot.online/posts/adding-a-fediverse-share-button-to-my-emacs-nikola-blog/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
I was browsing the Fediverse, as is my wont, and I came across a fella named Stefan Bohacek announcing the release of his new Fediverse Share Button. I tried it with my Sharkey instance and it worked! So I decided to add it to this blog. Even working with Nikola and Emacs, it was pretty frickin' easy.
&lt;/p&gt;

&lt;iframe src="https://stefanbohacek.online/@stefan/112456716124668605/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;&lt;script src="https://stefanbohacek.online/embed.js" async="async"&gt;&lt;/script&gt;

&lt;p&gt;
To continue my very meta habit of writing about blogging on my blog, here's how I added the share button at the bottom of this page.
&lt;/p&gt;

&lt;div id="outline-container-org6d755c7" class="outline-2"&gt;
&lt;h2 id="org6d755c7"&gt;Install Fediverse Share Button&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org6d755c7"&gt;
&lt;p&gt;
First, we simply need to clone the &lt;a href="https://github.com/stefanbohacek/fediverse-share-button/"&gt;fediverse-share-button&lt;/a&gt; repo. I cloned it next to my blog directory to make it a little simpler to move files into place, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cp -r ./fediverse-share-button/fediverse-share-button ./notroot-blog/files
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
That's it for now! Next, I'll show you how to incorporate those files into your Nikola builds.
&lt;/p&gt;

&lt;p&gt;
I referred to &lt;a href="https://randomgeekery.org/post/2020/01/tweaking-a-nikola-theme/"&gt;this "Random Geekery" blog post&lt;/a&gt; to figure out how to tweak Nikola themes and templates to include my fancy new share button.
&lt;/p&gt;

&lt;p&gt;
Boiling down my "learnings" (barf) for the reader, here's what I did.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org8a66f55" class="outline-2"&gt;
&lt;h2 id="org8a66f55"&gt;Create a New Theme to Tweak&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org8a66f55"&gt;
&lt;p&gt;
Rather than tweaking the installed theme – in my case, the &lt;code&gt;hack&lt;/code&gt; theme – we want to inherit from it, and make the changes to our own theme templates.
&lt;/p&gt;

&lt;p&gt;
First, I created a new theme called &lt;code&gt;notroot&lt;/code&gt;, based on &lt;code&gt;hack&lt;/code&gt;, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola theme --new notroot --parent hack
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then, I changed my theme and disabled bundling in Nikola's &lt;code&gt;conf.py&lt;/code&gt;, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notroot"&lt;/span&gt;
&lt;span class="n"&gt;USE_BUNDLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then, I copied the post template into my new &lt;code&gt;notroot&lt;/code&gt; theme, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola theme --copy-template post.tmpl
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
To make sure my new &lt;code&gt;notroot&lt;/code&gt; theme was exactly the same as &lt;code&gt;hack&lt;/code&gt;, I did a quick built and served it locally, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola build
nikola serve
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Perfect! Nothing changed… yet.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgcd8e9be" class="outline-2"&gt;
&lt;h2 id="orgcd8e9be"&gt;Add Fediverse Share Button&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgcd8e9be"&gt;
&lt;p&gt;
Next, I opened the aforementioned &lt;code&gt;post.tmpl&lt;/code&gt; file in Emacs, and more or less followed Stefan's instructions. However, because we're working with a Nikola template (Mako), there was a little more to it.
&lt;/p&gt;

&lt;p&gt;
My &lt;code&gt;post.tmpl&lt;/code&gt; has a block called &lt;code&gt;extra_head&lt;/code&gt;, so that's where I added the CSS link. It should look sorta like this afterwards:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;%block name="extra_head"&amp;gt;
&amp;lt;!-- ... the rest of 'extra_head' ... --&amp;gt;
&amp;lt;link rel="stylesheet" href="/fediverse-share-button/styles.min.css"&amp;gt;
&amp;lt;/%block&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Note that, unlike Stefan's instructions, we use an absolute path here &lt;code&gt;/&lt;/code&gt;, not a relative path &lt;code&gt;./&lt;/code&gt;, to the &lt;code&gt;fediverse-share-button/&lt;/code&gt; directory. That's because Nikola will move things around when it builds, and because we just plopped &lt;code&gt;fediverse-share-button&lt;/code&gt; into the &lt;code&gt;files/&lt;/code&gt; directory, it will be at the top level, next to &lt;code&gt;assets/&lt;/code&gt; and &lt;code&gt;images/&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
To include the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag pointing to the Javascript for our share button, I had to add an &lt;code&gt;extra_js&lt;/code&gt; block to the bottom of &lt;code&gt;post.tmpl&lt;/code&gt;. It also uses absolute paths, like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;%block name="extra_js"&amp;gt;
&amp;lt;script src="/fediverse-share-button/script.min.js" defer class="fsb-script"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/%block&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then, finally, I was able to include the actual button &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element. I chose the bottom of the post, above the navigation. The whole &lt;code&gt;content&lt;/code&gt; block, after my changes, looks like this (comments added for emphasis):
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;%block name="content"&amp;gt;
&amp;lt;article class="post-${post.meta('type')} h-entry hentry postpage" itemscope="itemscope" itemtype="http://schema.org/Article"&amp;gt;
    ${pheader.html_post_header()}
    &amp;lt;div class="e-content entry-content" itemprop="articleBody text"&amp;gt;
    ${post.text()}
    &amp;lt;/div&amp;gt;
    &amp;lt;aside class="postpromonav"&amp;gt;

	&amp;lt;!-- START fediverse-share-button form --&amp;gt;

	&amp;lt;form class="fsb-prompt"&amp;gt;
	    &amp;lt;label&amp;gt;Share with the fediverse&amp;lt;/label&amp;gt;
	    &amp;lt;div class="fsb-input-group mb-3"&amp;gt;
		&amp;lt;span class="fsb-input-group-text"&amp;gt;https://&amp;lt;/span&amp;gt;
		&amp;lt;input required
		       type="text"
		       name="fediverse-domain"
		       placeholder="mastodon.social"
		       class="fsb-input fsb-domain"
		       aria-label="Amount (to the nearest dollar)"&amp;gt;
		&amp;lt;button class="fsb-button"
			type="submit"&amp;gt;&amp;lt;img src="/fediverse-share-button/icons/mastodon.svg"
					   class="fsb-icon"&amp;gt;&amp;lt;/span&amp;gt;Share&amp;lt;/button&amp;gt;
	    &amp;lt;/div&amp;gt;
	    &amp;lt;p class="fsb-support-note fsb-d-none"&amp;gt;
		This server does not support sharing. Please visit &amp;lt;a class="fsb-support-note-link"
								      target="_blank"
								      href=""&amp;gt;&amp;lt;/a&amp;gt;.
	    &amp;lt;/p&amp;gt;
	&amp;lt;/form&amp;gt;

	&amp;lt;!-- END form --&amp;gt;

    &amp;lt;nav&amp;gt;
    ${helper.html_tags(post)}
    ${helper.html_pager(post)}
    &amp;lt;/nav&amp;gt;
    &amp;lt;/aside&amp;gt;
    % if not post.meta('nocomments') and site_has_comments:
	&amp;lt;section id="comment-section" class="comments hidden-print"&amp;gt;
	&amp;lt;h2&amp;gt;${messages("Comments")}&amp;lt;/h2&amp;gt;
	${comments.comment_form(post.permalink(absolute=True), post.title(), post._base_path)}
	&amp;lt;/section&amp;gt;
    % endif
    ${math.math_scripts_ifpost(post)}
&amp;lt;/article&amp;gt;
${comments.comment_link_script()}
&amp;lt;/%block&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then, once again, I built it and served it locally to check my work.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org97a6e42" class="outline-2"&gt;
&lt;h2 id="org97a6e42"&gt;Style the Fediverse Share Button&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org97a6e42"&gt;
&lt;p&gt;
Success! Except…
&lt;/p&gt;

&lt;p&gt;
Except the CSS was all screwy. The share button itself was enormous, due to how &lt;code&gt;hack&lt;/code&gt; CSS treats all &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags, and it was all left-justified, when my tags right below are centered.
&lt;/p&gt;

&lt;p&gt;
Let's fix that!
&lt;/p&gt;

&lt;p&gt;
It turned out to be dead simple. I inspected the classes in the browser, fixed it so it looked right, then copied those styles out of &lt;code&gt;files/fediverse-share-button/styles.css&lt;/code&gt; and into my own &lt;code&gt;files/assets/css/custom.css&lt;/code&gt; file. Then I added the attributes needed to fix things.
&lt;/p&gt;

&lt;p&gt;
To fix the enormous button, I just added &lt;code&gt;!important&lt;/code&gt; to &lt;code&gt;max-width&lt;/code&gt;:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;fsb-icon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;rem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="kt"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
To get the whole shebang centered, I modified &lt;code&gt;.fsb-prompt&lt;/code&gt; to add &lt;code&gt;auto&lt;/code&gt; margins on the right and left, which effectively centered the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; itself. I also had the form center text. It looks like this, now:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;fsb-prompt&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
And voila! Beautiful!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org373783d" class="outline-2"&gt;
&lt;h2 id="org373783d"&gt;Build and Deploy&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org373783d"&gt;
&lt;p&gt;
Once I was satisfied with the look and functionality, I was ready for the final build and deployment.
&lt;/p&gt;

&lt;p&gt;
First, though, I needed to minify the CSS changes that I had made. Stefan describes this, as well – for both JS and CSS – but here's exactly what I did:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;npm install minify -g
minify files/fediverse-share-button/styles.css &amp;gt; files/fediverse-share-button/styles.min.css
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Finally I was ready to build and deploy, as usual, from within Emacs.
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;code&gt;M-x nikola-build&lt;/code&gt; to build.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-! nikola deploy&lt;/code&gt; to deploy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgbe71453" class="outline-2"&gt;
&lt;h2 id="orgbe71453"&gt;Next Steps&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgbe71453"&gt;
&lt;p&gt;
Next steps are three-fold:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;Publish &lt;b&gt;this blog post&lt;/b&gt; to my blog.&lt;/li&gt;

&lt;li&gt;Once published, I will click the Fediverse Share Button and share to my Fediverse account.&lt;/li&gt;

&lt;li&gt;Then I will get the article ID of that Fediverse note, and add it to the meta for this post. Then I'll rebuild and redeploy. This will enable the "Comments" section, and replies to my Fediverse note will appear as comments on this blog post!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
It's like frickin' magic, baby!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>blog</category><category>emacs</category><category>fediverse</category><category>nikola</category><category>social</category><guid>https://blog.notroot.online/posts/adding-a-fediverse-share-button-to-my-emacs-nikola-blog/</guid><pubDate>Fri, 17 May 2024 19:46:34 GMT</pubDate></item><item><title>Blogging with Emacs: Plots and Diagrams</title><link>https://blog.notroot.online/posts/blogging-with-emacs%3A-bells-and-whistles/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
Continuing my very-meta habit of blogging about how I'm blogging, and not much else… I give you: "Bells and Whistles," perhaps better titled, "More of the Same".
&lt;/p&gt;

&lt;p&gt;
In Emacs Org Mode, there are many ways to plot and diagram, and even draw (it's terrible, don't bother). Let's see if we can get some working with my Nikola-based blogging solution.
&lt;/p&gt;

&lt;div id="outline-container-org7b74ec5" class="outline-2"&gt;
&lt;h2 id="org7b74ec5"&gt;Plotting Charts&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org7b74ec5"&gt;
&lt;p&gt;
This example is from Org Mode's &lt;a href="https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html"&gt;official documentation&lt;/a&gt;, though I've changed the output path for Nikola building.
&lt;/p&gt;

&lt;p&gt;
First I'll activate a Python &lt;code&gt;venv&lt;/code&gt; with &lt;code&gt;matplotlib&lt;/code&gt; pre-installed
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;plt&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tight_layout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'../images/myfig.png'&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;savefig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# fname[1:] # return this to org-mode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then make an HTML link (on Org export) into &lt;code&gt;images&lt;/code&gt;, like this:
&lt;/p&gt;

&lt;pre class="example" id="org6e44a8d"&gt;
[[./images/myfig.png]]
&lt;/pre&gt;

&lt;p&gt;
Which will then display the image after Nikola builds, like this:
&lt;/p&gt;


&lt;div id="orge7df8ab" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/myfig.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Voila! We plotted a chart! If I change the Python code, and re-build, I'll get a different chart.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org3826789" class="outline-2"&gt;
&lt;h2 id="org3826789"&gt;Diagramming&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org3826789"&gt;
&lt;p&gt;
Diagrams are different from plots and charts. They aren't strictly mathematical. Instead, we need to look to other possible solutions.
&lt;/p&gt;

&lt;p&gt;
Emacs package sources offer several options, but the one I have experience with is &lt;a href="https://ditaa.sourceforge.net/"&gt;ditaa&lt;/a&gt;.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;+--------+   +-------+    +-------+
|        | --+ ditaa +--&amp;gt; |       |
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |       |
|     {d}|   |       |    |       |
+---+----+   +-------+    +-------+
    :                         ^
    |       Lots of work      |
    +-------------------------+
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then make an HTML link like before:
&lt;/p&gt;


&lt;div id="org32f77ab" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/ditaa.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Voila! We made a diagram!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org1b5ad41" class="outline-2"&gt;
&lt;h2 id="org1b5ad41"&gt;Conclusion&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org1b5ad41"&gt;
&lt;p&gt;
I also tried including LaTeX equations and inline LaTeX, to no avail. Even with the default MathJax, it seems that Nikola does not do a pure Emacs Org Mode export to HTML, and I was unable to get LaTeX working.
&lt;/p&gt;

&lt;p&gt;
Which brings up the point I'd like to conclude with:
&lt;/p&gt;

&lt;p&gt;
Nikola + Org Mode is a workable solution that lets us use most Org Mode features out-of-the-box, like tables, executable code blocks, and the like.
&lt;/p&gt;

&lt;p&gt;
However, when it comes to bells and whistles, it falls a little short of pure Org Mode HTML export.
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;Having to create a separate HTML link for an image is annoying, but Nikola makes so much else easier that I can probably overlook it. If I was doing a pure Org Mode export, Emacs would create the image link for me.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ditaa&lt;/code&gt; integration was awkward, at best. I basically had to do an Org Mode HTML export to the &lt;code&gt;../images&lt;/code&gt; directory, then add an HTML link. If it was pure Org Mode export, Emacs would create the image link for me.&lt;/li&gt;
&lt;li&gt;No Emacs-based LaTeX. In fact, I couldn't get LaTeX to display at all! Even after I added the &lt;code&gt;mathjax&lt;/code&gt; tag to the post's meta file, as described in the Nikola Handbook.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
For now, I'll keep using Nikola, but my next iteration of this blog might be pure Org Mode, with HTML templates.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>blog</category><category>diagrams</category><category>emacs</category><category>org-mode</category><category>plots</category><guid>https://blog.notroot.online/posts/blogging-with-emacs%3A-bells-and-whistles/</guid><pubDate>Wed, 01 May 2024 00:39:09 GMT</pubDate></item><item><title>How I Made This Site (This Time)</title><link>https://blog.notroot.online/posts/how-i-made-this-site-%28this-time%29/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
Someone on the Fediverse was curious how I made this site, since I mentioned using Emacs org-mode, and their own site is built using org-roam and Hugo.
&lt;/p&gt;

&lt;iframe src="https://floss.social/@jgoerzen/112231865910334670/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;&lt;script src="https://floss.social/embed.js" async="async"&gt;&lt;/script&gt;

&lt;p&gt;
It's not that much different from the more complicated process I was using before, on GitHub Pages. This one is simpler in one respect: I'm deploying directly to my own host, so I don't have to use the more complicated &lt;code&gt;nikola deploy_github&lt;/code&gt; configuration, which requires separate source and deployment Git branches.
&lt;/p&gt;

&lt;p&gt;
For reference, here's my original post on how to get Nikola and &lt;code&gt;nikola.el&lt;/code&gt; working with GitHub Pages:
&lt;/p&gt;

&lt;a href="https://blog.notroot.online/posts/publishing-with-nikola-in-emacs/"&gt;Publishing with Nikola in Emacs&lt;/a&gt;

&lt;p&gt;
This time, I'm going to take the reader through the setup, step-by-step.
&lt;/p&gt;

&lt;div id="outline-container-org3890537" class="outline-2"&gt;
&lt;h2 id="org3890537"&gt;Requirements&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org3890537"&gt;
&lt;p&gt;
Here are the things you'll need for this tutorial. I'll show you some steps.
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;b&gt;Emacs&lt;/b&gt;: Obviously. With Org Mode.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Git&lt;/b&gt;: Git and a private Git repository.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Nikola&lt;/b&gt;: &lt;a href="https://getnikola.com/"&gt;Nikola&lt;/a&gt; is a static site generator, with an &lt;code&gt;orgmode&lt;/code&gt; plugin.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;nikola.el&lt;/b&gt;: &lt;a href="https://gitlab.com/drymerisnothere/nikola-el"&gt;nikola.el&lt;/a&gt; is an Emacs package that wraps Nikola functions.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Webserver&lt;/b&gt;: This setup assumes you have your own private webserver for deployment, but Nikola has a test server.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org5771357" class="outline-2"&gt;
&lt;h2 id="org5771357"&gt;Install and Configure Nikola&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org5771357"&gt;
&lt;p&gt;
From Nikola's &lt;a href="https://getnikola.com/getting-started.html"&gt;installation instructions&lt;/a&gt;, slightly tweaked to use v8.2.4:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;python3 -m venv nikola-env
cd nikola-env
bin/python -m pip install -U pip setuptools wheel
bin/python -m pip install 'Nikola[extras]==8.2.4'
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
You can now use Nikola by launching the script directly:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;bin/nikola
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Or you can activate the environment before working with Nikola and use the nikola command:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;source bin/activate
nikola
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org3744ea6" class="outline-3"&gt;
&lt;h3 id="org3744ea6"&gt;Install Nikola add-ons&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org3744ea6"&gt;
&lt;p&gt;
Now you need the Nikola &lt;code&gt;orgmode&lt;/code&gt; plugin.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola plugin -i orgmode
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
And you need to install a Nikola theme. I chose the &lt;a href="https://themes.getnikola.com/v8/hack/"&gt;hack&lt;/a&gt; theme, but you can pick another.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola theme -i hack
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org3d48511" class="outline-3"&gt;
&lt;h3 id="org3d48511"&gt;Init Local Blog&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org3d48511"&gt;
&lt;p&gt;
Nikola sites require a particular directory and file structure, and it has a command to create that for us. Let's use that method, rather than more complicated options.
&lt;/p&gt;

&lt;p&gt;
See &lt;a href="https://getnikola.com/getting-started.html#init"&gt;Nikola's instructions, here&lt;/a&gt;. Here's what I recommend:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;nikola init --demo &amp;lt;directory_name&amp;gt;
cd &amp;lt;directory_name&amp;gt;
git init
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
This creates the Blog structure, and also initializes the directory as a Git repository. You should continue and connect it to your Git repository, and push an initial commit.
&lt;/p&gt;

&lt;p&gt;
The &lt;code&gt;--demo&lt;/code&gt; option will fill in some blanks in your configuration file, and is recommended the first time.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org1c5a269" class="outline-3"&gt;
&lt;h3 id="org1c5a269"&gt;Configure Nikola&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org1c5a269"&gt;
&lt;p&gt;
Nikola settings live in the &lt;code&gt;conf.py&lt;/code&gt; file that was created when you initialized your blog.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://getnikola.com/conf.html"&gt;You can view the demo conf.py online, here.&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Most of the settings are self-explanatory, and many of them have defaults. However, we do need to change a few things for our theme and the &lt;code&gt;orgmode&lt;/code&gt; plugin.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgc88becf" class="outline-4"&gt;
&lt;h4 id="orgc88becf"&gt;Configure orgmode&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-orgc88becf"&gt;
&lt;p&gt;
At the bottom of &lt;code&gt;conf.py&lt;/code&gt;, add the following:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Add orgmode to compilers dict&lt;/span&gt;
&lt;span class="n"&gt;COMPILERS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"orgmode"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".org"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Add org files to posts and pages&lt;/span&gt;
&lt;span class="n"&gt;POSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;POSTS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"posts/*.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"post.tmpl"&lt;/span&gt;&lt;span class="p"&gt;),)&lt;/span&gt;
&lt;span class="n"&gt;PAGES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PAGES&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"stories/*.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"stories"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"story.tmpl"&lt;/span&gt;&lt;span class="p"&gt;),)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
This will allow you to write posts and pages for your blog in org-mode, with everything that comes with that.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org87227bf" class="outline-4"&gt;
&lt;h4 id="org87227bf"&gt;Configure theme&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-org87227bf"&gt;
&lt;p&gt;
Each theme may have particular settings to configure, but here are the ones for the "hack" theme.
&lt;/p&gt;

&lt;p&gt;
Uncomment &lt;code&gt;GLOBAL_CONTEXT&lt;/code&gt;, and set:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;THEME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hack"&lt;/span&gt;
&lt;span class="c1"&gt;# ...snip...&lt;/span&gt;
&lt;span class="n"&gt;GLOBAL_CONTEXT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;GLOBAL_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'HACK_VARIANT'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dark'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
I also have these additional settings:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;DATE_FANCINESS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="c1"&gt;# For Hack theme&lt;/span&gt;
&lt;span class="n"&gt;NAVIGATION_LINKS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DEFAULT_LANG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/index.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Home'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/archive.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Archives'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/categories/index.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Tags'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/stories/about-me'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'About Me'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/rss.xml'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'RSS'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgbbe9b59" class="outline-4"&gt;
&lt;h4 id="orgbbe9b59"&gt;Configure deployment&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-orgbbe9b59"&gt;
&lt;p&gt;
You will probably want to configure this &lt;b&gt;after&lt;/b&gt; you've successfully built and deployed manually by your usual methods, so that you get the command right, but here's what mine looks like:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;DEPLOY_COMMANDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
	&lt;span class="s2"&gt;"rsync -rav --delete output/ root@notroot:/var/www/blog.notroot.online"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
I have my host &lt;code&gt;notroot&lt;/code&gt; configured in my &lt;code&gt;.ssh/config&lt;/code&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org67bffa5" class="outline-3"&gt;
&lt;h3 id="org67bffa5"&gt;Install and Configure &lt;code&gt;nikola.el&lt;/code&gt;&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org67bffa5"&gt;
&lt;p&gt;
It's a bit outdated, and I can't get &lt;code&gt;M-x nikola-deploy&lt;/code&gt; to work, but otherwise we want this.
&lt;/p&gt;

&lt;p&gt;
Simplest thing is to use &lt;code&gt;use-package&lt;/code&gt;. Here's my config:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;;; Nikola.el config&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;nikola&lt;/span&gt;
  &lt;span class="nv"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-output-root-directory&lt;/span&gt; &lt;span class="s"&gt;"~/Dev/mine/notroot-blog/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-verbose&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-webserver-auto&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-new-post-extension&lt;/span&gt; &lt;span class="s"&gt;"org"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-new-page-extension&lt;/span&gt; &lt;span class="s"&gt;"org"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then from inside your &lt;code&gt;init.el&lt;/code&gt; buffer, do &lt;code&gt;M-x load-file RET RET&lt;/code&gt; to install and configure &lt;code&gt;nikola.el&lt;/code&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org9a3ab03" class="outline-2"&gt;
&lt;h2 id="org9a3ab03"&gt;Write a Blog Post in Emacs&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org9a3ab03"&gt;
&lt;p&gt;
Now we can write a blog post, like this one, in Emacs org-mode. Super easy!
&lt;/p&gt;

&lt;p&gt;
Just do &lt;code&gt;M-x nikola-new-post&lt;/code&gt; to create a new posts, or &lt;code&gt;M-x nikola-new-page&lt;/code&gt; to create a new page, like my "About Us" page.
&lt;/p&gt;

&lt;p&gt;
Emacs will give you an &lt;code&gt;*.org&lt;/code&gt; file, but will &lt;b&gt;also&lt;/b&gt; create a &lt;code&gt;*.meta&lt;/code&gt; file. Most things will be preset, but you will probably want to add tags. Here's the meta file for this blog post:
&lt;/p&gt;

&lt;pre class="example" id="orgd385add"&gt;
.. title: How I Made This Site (This Time)
.. slug: how-i-made-this-site-(this-time)
.. date: 2024-04-07 18:29:06
.. tags: nikola,emacs,org-mode,blogging,tutorial
&lt;/pre&gt;

&lt;p&gt;
And here's a screenshot of me writing this post! Talk about "meta" heheh:
&lt;/p&gt;


&lt;div id="org30f9a84" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/how-i-made-this-1.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orga518d03" class="outline-3"&gt;
&lt;h3 id="orga518d03"&gt;Preview and Build&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-orga518d03"&gt;
&lt;p&gt;
You can also preview your work.
&lt;/p&gt;

&lt;p&gt;
Do &lt;code&gt;M-x nikola-webserver-start&lt;/code&gt; and navigate to the URL shown in the mini-buffer.
&lt;/p&gt;

&lt;p&gt;
To see changes in the blog post, you will need to stop it with &lt;code&gt;M-x nikola-webserver-stop&lt;/code&gt;, and restart it. Nikola does not rebuild on save.
&lt;/p&gt;

&lt;p&gt;
Run &lt;code&gt;M-x nikola-build&lt;/code&gt;. You can watch the progress in the &lt;code&gt;*Nikola*&lt;/code&gt; buffer.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge1fb165" class="outline-4"&gt;
&lt;h4 id="orge1fb165"&gt;How Nikola Builds&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-orge1fb165"&gt;
&lt;p&gt;
One of the nice things about Nikola is that it builds using Emacs org-mode export to HTML directly, rather than translating to another markdown format, first. No &lt;code&gt;pandoc&lt;/code&gt; is involved. No intermediary &lt;code&gt;*.md&lt;/code&gt; files.
&lt;/p&gt;

&lt;p&gt;
The benefit is obvious: the HTML will exported from your org files pretty much how you expect.
&lt;/p&gt;

&lt;p&gt;
The one exception I've found is that inter-org file links like &lt;code&gt;[[file:another-blog-post.org]]&lt;/code&gt; will be turned into &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags, not &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags, which is too bad. That's because the slugs Nikola uses don't match org-mode's own. I'm sure there's an elisp workaround, but I haven't played with it, yet.
&lt;/p&gt;

&lt;p&gt;
Fortunately, this is org-mode! If you need to link from one blog post to another, just do something like:
&lt;/p&gt;

&lt;pre class="example" id="org0aa61ff"&gt;
#+begin_export html
&amp;lt;a href="/posts/publishing-with-nikola-in-emacs/"&amp;gt;Publishing with Nikola in Emacs&amp;lt;/a&amp;gt;
#+end_export
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgf886bf5" class="outline-2"&gt;
&lt;h2 id="orgf886bf5"&gt;Deploy Your Blog&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgf886bf5"&gt;
&lt;p&gt;
The &lt;code&gt;nikola-deploy&lt;/code&gt; command is, unfortunately, not working for me. I have forked this old project, and at some point I'll try to fix it, but for now, I just use the shell command in Emacs.
&lt;/p&gt;

&lt;p&gt;
Do &lt;code&gt;M-! nikola deploy&lt;/code&gt; to upload your site to your webserver.
&lt;/p&gt;

&lt;p&gt;
Then browse to your new blog. If everything is working, you should be live!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org0b6b9a1" class="outline-2"&gt;
&lt;h2 id="org0b6b9a1"&gt;Conclusion&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org0b6b9a1"&gt;
&lt;p&gt;
Once you get Nikola and &lt;code&gt;nikola.el&lt;/code&gt; working, this is a very easy way to blog, if you're an Emacs person. It's intuitive and highly configurable.
&lt;/p&gt;

&lt;p&gt;
For example, Nikola does it's own syntax highlighting, but I'll be adding something like &lt;code&gt;highlight.js&lt;/code&gt; down the road. I can add comments sections, and I've barely touched the possible Nikola add-ons.
&lt;/p&gt;

&lt;p&gt;
If you're an Emacs person, I think this is one of the more flexible, but robust, SSG integrations out there. I, too, love the idea of publishing natively using only Emacs, but one of the great features of Emacs is also its ability to compose cleanly with other commandline tools.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>blogging</category><category>emacs</category><category>nikola</category><category>org-mode</category><category>tutorial</category><guid>https://blog.notroot.online/posts/how-i-made-this-site-%28this-time%29/</guid><pubDate>Sun, 07 Apr 2024 22:29:06 GMT</pubDate></item><item><title>Blog Upgrade</title><link>https://blog.notroot.online/posts/blog-upgrade/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
I'm an engineer, and I'm an Emacs nut, so yes: I tinker a lot.
&lt;/p&gt;

&lt;p&gt;
My latest tinkering was to move my Nikola- and Emacs-based blog out of GitHub, when I abandoned that service entirely, and moved all my code to GitLab.
&lt;/p&gt;

&lt;p&gt;
My reasons for moving are pretty straightforward: I think the "AI" hype is bullshit, and I won't have anything to do with it. I certainly don't want Micro$oft training their "AI" LLMs on my code. Fuck our robot overlords. They can meet me in the street and we can fight it out.
&lt;/p&gt;

&lt;p&gt;
GitLab also has "AI" features, but nothing like GitHub. What's more, I can host my own GitLab and eschew their "AI" fuckstickery, entirely. Can't do that with GitHub, so it was an easy calculus to perform.
&lt;/p&gt;

&lt;p&gt;
I did try to use GitLab Pages, which is really part of GitLab CI, which is to say, "Pipelines".
&lt;/p&gt;

&lt;p&gt;
Overkill, yo. Too much configuration-over-convention for my taste. I don't like Python Django, either, for the same reason. If I'm doing web work, gimme Flask any day of the week.
&lt;/p&gt;

&lt;p&gt;
Anyhow, while I was moving my blog, I thought I'd give it a new look. No more white background, and no more left-aligned container &lt;code&gt;div&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Still not much here on this pathetic blog, but maybe now that I can write and easily deploy to my own host, I'll actually blog a little more.
&lt;/p&gt;

&lt;p&gt;
I might even write about something besides Emacs!
&lt;/p&gt;

&lt;p&gt;
Ya never know…
&lt;/p&gt;</description><category>blog</category><category>emacs</category><category>github</category><category>gitlab</category><category>nikola</category><category>org-mode</category><guid>https://blog.notroot.online/posts/blog-upgrade/</guid><pubDate>Sat, 06 Apr 2024 21:38:32 GMT</pubDate></item><item><title>Mastodon and the Fediverse: Will It Finally Happen?</title><link>https://blog.notroot.online/posts/mastodon-and-the-fediverse%3A-will-it-finally-happen/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
I set up my own &lt;a href="https://joinmastodon.org"&gt;Mastodon&lt;/a&gt; instance. Took a few hours, including the upgrade to v4.0.2, but overall, it was worth it.
&lt;/p&gt;

&lt;p&gt;
I'm not a regular blogger, and besides, this blog is supposed to be a little more technical. But, I'm also a longtime proponent of federated social network experiments, like &lt;a href="https://diasporafoundation.org/"&gt;diaspora*&lt;/a&gt; – none of which have ever quite achieved the &lt;a href="https://en.wikipedia.org/wiki/Network_effect"&gt;network effect&lt;/a&gt; to gain the widespread adoption needed to go viral.
&lt;/p&gt;

&lt;p&gt;
Without commenting on what, or who, is driving the migration of users from Twitter to Mastodon, I believe the moment George Takei and Jeri Ryan of Star Trek fame joined Mastodon, it had finally achieved the notoriety needed to flourish. I think it's over. A done deal.
&lt;/p&gt;

&lt;p&gt;
Which means, I'm interested in the &lt;a href="https://fediverse.party/"&gt;Fediverse&lt;/a&gt; all over again.
&lt;/p&gt;

&lt;p&gt;
Mastodon, in particular, has the potential to make setting up instances turnkey easy. Whether for personal, group, institutional, or brand localization, if it's push-button easy to make your own instance, even more people will join. If upstream UI/UX adapts to user needs, as they appear they will, then it should be ever-easier.
&lt;/p&gt;

&lt;p&gt;
I don't know if that will happen, and I'm nowhere near plugged-in enough to even speculate.
&lt;/p&gt;

&lt;p&gt;
But you can expect me to blog more often on this topic, if it starts to catch on.
&lt;/p&gt;</description><category>mastodon</category><guid>https://blog.notroot.online/posts/mastodon-and-the-fediverse%3A-will-it-finally-happen/</guid><pubDate>Sun, 20 Nov 2022 18:55:06 GMT</pubDate></item><item><title>Yes, I am an Emacs Evangelist. Deal with it.</title><link>https://blog.notroot.online/posts/yes-i-am-an-emacs-evangelist-deal-with-it/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
Basically, see the title.
&lt;/p&gt;

&lt;p&gt;
I have good reasons. Small example:
&lt;/p&gt;

&lt;p&gt;
Recently, I worked with a partner's team on one project's API documentation, and with a contractor on completely different project, and its API docs. Different companies, even.
&lt;/p&gt;

&lt;p&gt;
The Partner Team at one company uses &lt;a href="https://swagger.io"&gt;Swagger&lt;/a&gt;. The Contractor wants to use the &lt;a href="https://www.postman.com/api-documentation-tool/"&gt;Postman API Documentation Tool&lt;/a&gt;. Meanwhile, I don't use either.
&lt;/p&gt;

&lt;p&gt;
I use Emacs. I need no other tool for these things.
&lt;/p&gt;

&lt;p&gt;
As I describe elsewhere in this blog, to generate API documentation after making changes in my literate API org file, I type &lt;code&gt;C-c C-e h h&lt;/code&gt;. That's it. Dude clicks a button. Other dude clicks a button. I type that mess. Which is harder?
&lt;/p&gt;

&lt;p&gt;
After I type &lt;code&gt;C-c C-e h h&lt;/code&gt;, unlike dudes clicking buttons, I have to wait a bit as Emacs makes innumerable &lt;b&gt;&lt;i&gt;actual&lt;/i&gt;&lt;/b&gt; API requests to get data to fill out the "Response" section in the API docs. I don't get an instantaneous response, because unlike other solutions, &lt;b&gt;&lt;i&gt;this isn't a toy&lt;/i&gt;&lt;/b&gt;.
&lt;/p&gt;

&lt;p&gt;
It took skill to write. The same skill on display in the API, itself.
&lt;/p&gt;

&lt;p&gt;
I usually watch as Emacs builds my static API documentation, replete with JS, because as soon as I see unusual errors popping up, I know something is wrong. I can hit &lt;code&gt;C-g&lt;/code&gt; and switch to the &lt;code&gt;*Messages*&lt;/code&gt; buffer to find out how the API responded. What the error was, and maybe how to fix it.
&lt;/p&gt;

&lt;p&gt;
Then I can run again. &lt;code&gt;C-c C-e h h&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
I still have not left Emacs.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Swagger&lt;/b&gt;:
&lt;/p&gt;

&lt;p&gt;
Compare to Swagger. I spent a day and part of a night writing &lt;code&gt;yaml&lt;/code&gt; that does nothing. It does not make any API requests. It does not let me make SQL requests, or use &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;python&lt;/code&gt; or &lt;code&gt;R&lt;/code&gt; or &lt;code&gt;restclient&lt;/code&gt;. It just makes cookie-cutter API documentation with extremely limited "documentation" because you basically have to document in &lt;code&gt;yaml&lt;/code&gt; or &lt;code&gt;json&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
The real issue with Swagger is that it's a toy. It's buttons with rudimentary documentation, and an ecosystem that encourages code-generation. Sorry, but no. I &lt;i&gt;like&lt;/i&gt; writing code. I don't &lt;i&gt;want&lt;/i&gt; to spend days learning and setting up a configuration-first system where I don't have to write code.
&lt;/p&gt;

&lt;p&gt;
I did the work to make some Swagger, because it was required. But while I did it, I also wrote an org file that actually &lt;i&gt;calls&lt;/i&gt; each endpoint, and shows me the response and response headers, in full. In Emacs. In the file, under version control. As an afterthought, I added a link to the Swagger file as a link when the API documentation exports.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Postman API Documentation Tool&lt;/b&gt;:
&lt;/p&gt;

&lt;p&gt;
Recently, a contractor wanted to update the API documentation on the project we're working on together, and he was confused. He immediately concluded that I was manually updating the API documentation, and suggested something that everyone could use, like Postman.
&lt;/p&gt;

&lt;p&gt;
I sent him a link to &lt;a href="https://gitlab.com/publicvoit/orgdown"&gt;Orgdown&lt;/a&gt;. I'm sorry, but why should I learn Postman – a proprietary commercial product – instead of him learning Orgdown? He doesn't have to install anything. I have to install Postman, get an account, share that account with him… so much STUFF for something I will only use because of him. The other back-end engineer already groks org.
&lt;/p&gt;

&lt;p&gt;
It got me to thinking, though. Why &lt;i&gt;not&lt;/i&gt; switch to Postman? He has a point. I'm an Emacs evangelist… definitely a fringe group. I'm also not a snob. VS Code is fantastic. Vim does stuff. I know &lt;code&gt;:qw&lt;/code&gt; so… Why not embrace some API documentation framework?
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Conclusion&lt;/b&gt;:
&lt;/p&gt;

&lt;p&gt;
No. I will continue to use the &lt;code&gt;README.org&lt;/code&gt; that magically turns into a beautiful, up-to-date API doc with four key-chords. That makes SQL queries to my dev DB to find out which records to use in queries. That uses free &lt;code&gt;bash&lt;/code&gt; tools like &lt;code&gt;jq&lt;/code&gt; to compose data for display.
&lt;/p&gt;

&lt;p&gt;
I want to keep my API documentation under version control with the API code. So, if I roll back… bye-bye documented changes. I want my API to be in &lt;i&gt;perfect sync&lt;/i&gt; with the documentation. I want it to be programmatic. I want it to actually make an HTTP request with a valid bearer token to a real endpoint, get a response, and include that response in pretty HTML. I want it all.
&lt;/p&gt;

&lt;p&gt;
I don't want a demo, like Swagger. I'm not writing a business plan. I'm writing documentation for something that already exists. I don't want to &lt;code&gt;yaml&lt;/code&gt; that describes the structure of example responses and maintain them when they change.
&lt;/p&gt;

&lt;p&gt;
And I don't want to login to an app and click buttons. My RSI is bad enough as it is, and it's all mouse (my left pinky is just fine, thank you). When I want to know what's in an S3 bucket, do I browse to the AWS console? No. I use &lt;code&gt;awscli&lt;/code&gt;. It's under my fingers, already. When I want to test my new API endpoint while I'm working on it, do I make a new request in a collection of Postman, which is completely useless anywhere else? No. I create a &lt;code&gt;restclient&lt;/code&gt; source block and hit &lt;code&gt;C-c C-c&lt;/code&gt;. That simple.
&lt;/p&gt;

&lt;p&gt;
Yes, I know how to use Emacs.
&lt;/p&gt;

&lt;p&gt;
No, I do not know how to use Postman.
&lt;/p&gt;

&lt;p&gt;
Yes, I'm the Software Architect.
&lt;/p&gt;

&lt;p&gt;
Guess which way we're generating API docs?
&lt;/p&gt;</description><guid>https://blog.notroot.online/posts/yes-i-am-an-emacs-evangelist-deal-with-it/</guid><pubDate>Thu, 24 Feb 2022 01:41:27 GMT</pubDate></item><item><title>Writing Literate API Documentation in Emacs Org Mode</title><link>https://blog.notroot.online/posts/writing-literate-api-documentation-in-emacs-org-mode/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
On a scale of "NFT" to "Integer", &lt;a href="http://howardism.org/Technical/Emacs/literate-programming-tutorial.html"&gt;Literate Programming&lt;/a&gt; usually rates a little below the bottom on the usefulness scale. Unfair! It's not entirely unearned, but there are some things that "LitProg" (kidding!) is very good for.
&lt;/p&gt;

&lt;p&gt;
With &lt;a href="https://github.com/pashky/restclient.el"&gt;restclient&lt;/a&gt;, &lt;a href="https://github.com/alf/ob-restclient.el"&gt;ob-restclient&lt;/a&gt; and Emacs Org Mode, I'll show you how to write beautiful, useful, self-generating API documentation that easily renders to a static website, using a template forked off of &lt;a href="https://readthedocs.org/"&gt;Read the Docs&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Where's the &lt;b&gt;"WOW!"&lt;/b&gt; you may ask? Using this technique, you can entirely get rid of &lt;a href="https://postman.com"&gt;Postman&lt;/a&gt; or whatever clunky proprietary REST API client you're using. The API documentation &lt;b&gt;IS&lt;/b&gt; the program.
&lt;/p&gt;


&lt;div id="orgfaa47e0" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-1.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
The only other requisite is an API to talk to. For this tutorial, we'll be using the free, public &lt;a href="https://jsonplaceholder.typicode.com/"&gt;JSON Placeholder&lt;/a&gt; API.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;&lt;b&gt;NOTE&lt;/b&gt;&lt;/b&gt;: Since I wrote this blog post in Org Mode, the included examples of Org are exported as plain-text examples, without syntax-highlighting. Suffice it to say that Org text looks much prettier in Emacs.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;&lt;b&gt;TL;DR&lt;/b&gt;&lt;/b&gt;: &lt;a href="https://gist.github.com/joseph8th/9a87c4f14b867c1abe8d2e81322f4eac#file-jsonplaceholder-org"&gt;Complete Example Org File&lt;/a&gt;
&lt;/p&gt;

&lt;div id="outline-container-orgb97e9a9" class="outline-2"&gt;
&lt;h2 id="orgb97e9a9"&gt;Getting Started&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgb97e9a9"&gt;
&lt;p&gt;
First, install and configure &lt;code&gt;restclient&lt;/code&gt; and &lt;code&gt;ob-restclient&lt;/code&gt; in your Emacs.
&lt;/p&gt;

&lt;p&gt;
Then, create a new file in Emacs, called &lt;code&gt;jsonplaceholder.org&lt;/code&gt;. At the top of this file, include the following header information (obviously change the author and email):
&lt;/p&gt;

&lt;pre class="example" id="org4898508"&gt;
#+title: JSON Placeholder API Documentation
#+author: Joseph Edwards VIII
#+email: foobar@example.com

#+startup: indent
#+export_file_name: index.html
#+options: num:nil ^:nil H:5 toc:2

#+setupfile: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup
&lt;/pre&gt;

&lt;p&gt;
Let's talk about this header a bit, since it's not immediately apparent what's going on.
&lt;/p&gt;

&lt;p&gt;
The top section is self-explanatory. The second section just tells Emacs to display org-mode with indents, specifies the name of the file to export to, and controls the way that section headings and the table of contents will be displayed.
&lt;/p&gt;

&lt;p&gt;
The final section loads the HTML template &lt;code&gt;setupfile&lt;/code&gt; to use when exporting to HTML. In practice, I also add a number of &lt;code&gt;#+html_head:&lt;/code&gt; items to customize the &lt;a href="https://github.com/fniessen/org-html-themes"&gt;ReadTheOrg&lt;/a&gt; theme CSS.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id="outline-container-org0324581" class="outline-3"&gt;
&lt;h3 id="org0324581"&gt;Initialize&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org0324581"&gt;
&lt;p&gt;
The first section we'll add will serve a functional purpose, and initialize the document. In practice, this section can be quite detailed, allowing you to obtain a bearer token, read values from a database, or otherwise initialize elements that will be used later in the program. For our simple example, we only need one element: the URL to the API.
&lt;/p&gt;

&lt;p&gt;
It may seem odd to parameterize the API URL. Don't we want it shown in our requests? Perhaps. But perhaps, like most software engineers, we have separate development, staging and production environments? We would have to find and replace each URL to change environment. This way, we can just change it in one place.
&lt;/p&gt;

&lt;p&gt;
One small note: we don't want to export this section to HTML. We can tell Emacs this by adding the &lt;code&gt;:noexport:&lt;/code&gt; tag to the section header.
&lt;/p&gt;

&lt;p&gt;
In your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file, add:
&lt;/p&gt;

&lt;pre class="example" id="orgadb68dd"&gt;
* Init :noexport:

#+name: api-url
: https://jsonplaceholder.typicode.com
&lt;/pre&gt;

&lt;p&gt;
Setting the &lt;code&gt;#+name: api-url&lt;/code&gt; means we can reference the scalar value &lt;code&gt;: https://jsonplaceholder.typicode.com&lt;/code&gt; from other source blocks in our document. &lt;b&gt;We can take &lt;code&gt;api-url&lt;/code&gt; as input.&lt;/b&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org0bd20ae" class="outline-3"&gt;
&lt;h3 id="org0bd20ae"&gt;Introduce&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org0bd20ae"&gt;
&lt;p&gt;
While in practice, we're going to be &lt;i&gt;using&lt;/i&gt; &lt;code&gt;jsonplaceholder.org&lt;/code&gt; to make API requests, Emacs will &lt;i&gt;also&lt;/i&gt; be making API requests when we export to HTML to generate the API documentation.
&lt;/p&gt;

&lt;p&gt;
That reminds us that this is documentation. So write a nice introduction for your readers, as well.
&lt;/p&gt;

&lt;p&gt;
In your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file, add the following (copied from the actual API documentation for JSON Placeholder):
&lt;/p&gt;

&lt;pre class="example" id="org23a9214"&gt;
* Introduction

JSONPlaceholder is a free online REST API that you can use whenever you need some fake data. It can be in a README on GitHub, for a demo on CodeSandbox, in code examples on Stack Overflow, ...or simply to test things locally.
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org0f94c2b" class="outline-2"&gt;
&lt;h2 id="org0f94c2b"&gt;Making Requests&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org0f94c2b"&gt;
&lt;p&gt;
Now let's document our first request and response. JSON Placeholder provides six resources, and routes for all HTTP methods. We'll start with the &lt;code&gt;/posts&lt;/code&gt; resource.
&lt;/p&gt;

&lt;p&gt;
In your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file, add:
&lt;/p&gt;

&lt;pre class="example" id="org294e7b2"&gt;
* Posts

The ~/posts~ resource allows us to create, read, update, and delete posts.

#+name: get-posts
#+begin_src restclient :var api=api-url
  GET :api/posts
#+end_src
&lt;/pre&gt;

&lt;p&gt;
Notice in the source block header, we are directing Org to use &lt;code&gt;restclient&lt;/code&gt; as the language.
&lt;/p&gt;

&lt;p&gt;
We also set the variable &lt;code&gt;api&lt;/code&gt; to the value stored in the scalar named &lt;code&gt;api-url&lt;/code&gt;. When using Org variables inside a source block, you just use the variable as you normally would in that language. In &lt;code&gt;restclient&lt;/code&gt;, we preface variables with a colon, so that's how we use it in the request, &lt;code&gt;GET :api/posts&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Now, make the API call by typing &lt;code&gt;C-c C-c&lt;/code&gt; with the cursor inside the source block. The response will be displayed below the request block, in all its gory glory!
&lt;/p&gt;

&lt;p&gt;
And this illustrates the usefulness of literate API documentation. We aren't going to include example requests and example responses that have to be updated whenever changes are made to the API endpoints or responses.
&lt;/p&gt;

&lt;p&gt;
We're only including &lt;b&gt;real&lt;/b&gt; requests!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge02fd60" class="outline-2"&gt;
&lt;h2 id="orge02fd60"&gt;Exporting&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orge02fd60"&gt;
&lt;p&gt;
We only have the one request, but it's enough to export. Let's try it!
&lt;/p&gt;

&lt;p&gt;
In your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file, type &lt;code&gt;C-c C-e h o&lt;/code&gt; to export to &lt;code&gt;index.html&lt;/code&gt; in the same directory as your org file, and then open that file in the browser. It should look like this:
&lt;/p&gt;


&lt;div id="orgaa1b0ad" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-2.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Ok, but where's the response? Emacs didn't make the API request and include the response like I promised! Oh no!
&lt;/p&gt;

&lt;p&gt;
That's OK. By default, Emacs only exports the source block. To also export results, edit the header of the source block named &lt;code&gt;get-posts&lt;/code&gt;. Add &lt;code&gt;:exports both&lt;/code&gt; so that it looks like:
&lt;/p&gt;

&lt;pre class="example" id="orge2e0224"&gt;
#+begin_src restclient :var api=api-url :exports both
&lt;/pre&gt;

&lt;p&gt;
And export, again. Now you should see the response, as well!
&lt;/p&gt;


&lt;div id="org2c6f9f1" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-3.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
No more updating example responses and including embarrassing typos! This is real, live response data.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orga9c8a3f" class="outline-2"&gt;
&lt;h2 id="orga9c8a3f"&gt;Appearance&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orga9c8a3f"&gt;
&lt;p&gt;
Before we go any further with the "programming" part of "literate programming", let's recall for a moment that we are writing API documentation, and we want it to be clean and readable. Let's spend a little time sprucing up the appearance.
&lt;/p&gt;

&lt;p&gt;
Currently, our document is ugly in three ways:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;The anchors to headings are ugly, and read like: &lt;code&gt;index.html#orga1b1b2d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The response is too big! We will have to scroll for pages to get to the next request.&lt;/li&gt;
&lt;li&gt;The response headers are dumped out at the bottom of the response. It's not clean JSON.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge1e26bc" class="outline-3"&gt;
&lt;h3 id="orge1e26bc"&gt;Ugly Anchors&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-orge1e26bc"&gt;
&lt;p&gt;
The ugly anchors issue is easily solved. When Emacs exports to HTML, it generates random anchor tags for headings, but we can easily specify a custom ID.
&lt;/p&gt;

&lt;p&gt;
In your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file, place your cursor at the end of the &lt;code&gt;Introduction&lt;/code&gt; heading, and then type &lt;code&gt;C-c C-x p&lt;/code&gt; to add a property. Type in &lt;code&gt;CUSTOM_ID&lt;/code&gt; for the property name, and &lt;code&gt;introduction&lt;/code&gt; for the value.
&lt;/p&gt;

&lt;p&gt;
Now do the same thing for the &lt;code&gt;Posts&lt;/code&gt; heading, setting &lt;code&gt;CUSTOM_ID&lt;/code&gt; to &lt;code&gt;resource-posts&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
It should now look like this:
&lt;/p&gt;

&lt;pre class="example" id="org31a24f3"&gt;
* Posts
:PROPERTIES:
:CUSTOM_ID: resource-posts
:END:
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org6ec845f" class="outline-3"&gt;
&lt;h3 id="org6ec845f"&gt;Enormous Response&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org6ec845f"&gt;
&lt;p&gt;
Inspecting &lt;code&gt;index.html&lt;/code&gt; reveals that the size of the response block is determined by the tag and class &lt;code&gt;pre.src&lt;/code&gt;. Some tinkering on my part results in the following snippet:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;style&amp;gt;pre.src{background:#343131;color:white;max-height:500px;overflow-y:auto;}&amp;lt;/style&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
We can add this to our exported &lt;code&gt;index.html&lt;/code&gt; very easily in Org Mode using the &lt;code&gt;#+html_head:&lt;/code&gt; header. After the line that starts with &lt;code&gt;#+setupfile:&lt;/code&gt;, add:
&lt;/p&gt;

&lt;pre class="example" id="org12b318a"&gt;
#+html_head: &amp;lt;style&amp;gt;pre.src{background:#343131;color:white;max-height:500px;overflow-y:auto;} &amp;lt;/style&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
Also, nobody likes "Light Mode," so I changed to "Dark Mode".
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org270d236" class="outline-3"&gt;
&lt;h3 id="org270d236"&gt;Ugly Response&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org270d236"&gt;
&lt;p&gt;
The ugly response headers we see are coming from the &lt;code&gt;restclient&lt;/code&gt; package, and there's no way to suppress them without hacking over &lt;code&gt;restclient&lt;/code&gt; itself. That of course is do-able … this &lt;i&gt;is&lt;/i&gt; Emacs, after all.
&lt;/p&gt;

&lt;p&gt;
We will instead use a &lt;i&gt;literate&lt;/i&gt; solution.
&lt;/p&gt;

&lt;p&gt;
One of the more powerful features of Literate Programming is language-agnosticism. We run a SQL query from Org Mode, and pipe the data to a Python source block where we manipulate it, then pass it on to Bash, then to R, then to Elisp, then to Common Lisp, then back to Python and save it back to the database.
&lt;/p&gt;

&lt;p&gt;
In our case, we're going to leverage &lt;code&gt;shell&lt;/code&gt; and &lt;a href="https://github.com/stedolan/jq/wiki/Installation"&gt;the 'jq' command-line JSON processor&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Go ahead and install &lt;code&gt;jq&lt;/code&gt; now, and then change your &lt;code&gt;Posts&lt;/code&gt; request so it looks like the following:
&lt;/p&gt;

&lt;pre class="example" id="org4f0c978"&gt;
#+name: get-posts
#+begin_src restclient :var api=api-url :results value
  GET :api/posts
#+end_src

#+begin_src shell :var response=get-posts :results value raw :wrap src js :exports results
  echo $response | jq
#+end_src
&lt;/pre&gt;

&lt;p&gt;
And now place your cursor in the bottom (&lt;code&gt;shell&lt;/code&gt;) source block, and type &lt;code&gt;C-c C-c&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
The response block calls the &lt;code&gt;get-posts&lt;/code&gt; request block, and then pipes &lt;code&gt;$response&lt;/code&gt; into &lt;code&gt;jq&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Wow! No more response headers! Just nice, clean JSON.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id="outline-container-org8647a57" class="outline-4"&gt;
&lt;h4 id="org8647a57"&gt;Black Magic Explained&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-org8647a57"&gt;
&lt;p&gt;
"But what is this black magic?!" you may ask. Let's pop the hood.
&lt;/p&gt;

&lt;p&gt;
The first big change was to the request. No longer are we saying, &lt;code&gt;:exports both&lt;/code&gt;. Now we are instead saying, &lt;code&gt;:results value&lt;/code&gt;. As mentioned, the default for &lt;code&gt;:exports&lt;/code&gt; is &lt;i&gt;only the source block&lt;/i&gt;. By deleting &lt;code&gt;:exports both&lt;/code&gt;, we're going back to that default. This source block will not be evaluated, nor will the results be exported.
&lt;/p&gt;

&lt;p&gt;
Instead, we now tell the request, &lt;code&gt;:results value&lt;/code&gt;. What does that mean? &lt;a href="https://orgmode.org/manual/Results-of-Evaluation.html"&gt;It's complicated&lt;/a&gt;, but basically it just means that Org gets the value from the evaluated code, itself, rather than using an external process.
&lt;/p&gt;

&lt;p&gt;
The second, more obvious change is that we've added a second source block, just for results. Several important things are happening in the block header:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;We call &lt;code&gt;shell&lt;/code&gt; this time. That will be whatever shell (bash, cmd.exe, fish, etc.) you are using.&lt;/li&gt;
&lt;li&gt;We set a new variable &lt;code&gt;:var response=get-posts&lt;/code&gt;. Now this source block will call the request block named &lt;code&gt;get-posts&lt;/code&gt; and put the results in the variable named &lt;code&gt;response&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We set &lt;code&gt;:results value raw&lt;/code&gt; because we don't want Org to wrap the results in &lt;code&gt;shell&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;We set &lt;code&gt;:wrap src js&lt;/code&gt; because we DO want Org to wrap the results in &lt;code&gt;js&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;We set &lt;code&gt;:exports results&lt;/code&gt; because we don't want to see the source code, only the results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Finally, inside the &lt;code&gt;shell&lt;/code&gt; block, we pipe the &lt;code&gt;$results&lt;/code&gt; variable into &lt;code&gt;jq&lt;/code&gt;, which strips out the response header comment lines and outputs nicely formatted, prettified JSON for our results block.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org038c411" class="outline-3"&gt;
&lt;h3 id="org038c411"&gt;Putting It All Together&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org038c411"&gt;
&lt;p&gt;
Let's see how our tweaks to appearance worked out! Export your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file again with &lt;code&gt;C-c C-e h o&lt;/code&gt; and you should now see something like:
&lt;/p&gt;


&lt;div id="org19ad199" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-4.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge085b7f" class="outline-4"&gt;
&lt;h4 id="orge085b7f"&gt;Finishing Touches&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-orge085b7f"&gt;
&lt;p&gt;
Looks much better, but there's a few more tweaks to make. Since it's just applying the same principles we already discussed, let's fast-forward to the end.
&lt;/p&gt;

&lt;p&gt;
Change your &lt;code&gt;jsonplaceholder.org&lt;/code&gt; file so it looks like this:
&lt;/p&gt;

&lt;pre class="example" id="org7cc7beb"&gt;
#+title: JSON Placeholder API Documentation
#+author: Joseph Edwards VIII
#+email: foobar@example.com

#+startup: indent
#+export_file_name: index.html
#+options: num:nil ^:nil H:5 toc:2

#+setupfile: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup
#+html_head: &amp;lt;style&amp;gt;pre.src{background:#343131;color:white;max-height:500px;overflow-y:auto;} &amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;p{margin-bottom:1em;}&amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;h2{padding-top:1em;margin-top:2em;border-top:darkgray 2px solid;}&amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;h3{padding-top:1em;margin-top:2em;border-top:lightblue 1px dashed;}&amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;h4{padding-top:1em;margin-bottom:1em;}&amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;h5{color:black;font-size:1em;padding-top:1em;margin-bottom:1em;} &amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;div.response&amp;gt;h5,div.request&amp;gt;h5{padding-top:0;margin-bottom:0.5em;color:darkgray;font-size:0.8em;}&amp;lt;/style&amp;gt;
#+html_head: &amp;lt;style&amp;gt;h6{margin-bottom:1em;}&amp;lt;/style&amp;gt;

* Init :noexport:

#+name: api-url
: https://jsonplaceholder.typicode.com

* Introduction
:PROPERTIES:
:CUSTOM_ID: introduction
:END:

JSONPlaceholder is a free online REST API that you can use whenever you need some fake data. It can be in a README on GitHub, for a demo on CodeSandbox, in code examples on Stack Overflow, ...or simply to test things locally.

* Posts
:PROPERTIES:
:CUSTOM_ID: resource-posts
:END:

The ~/posts~ resource allows us to create, read, update, and delete posts.

** ~GET /posts~
:PROPERTIES:
:CUSTOM_ID: method-get-posts
:END:

Obtain all posts.

**** Request
:PROPERTIES:
:HTML_CONTAINER_CLASS: request
:END:

#+name: get-posts
#+begin_src restclient :var api=api-url :results value
  GET :api/posts
#+end_src

**** Response
:PROPERTIES:
:HTML_CONTAINER_CLASS: response
:END:

#+begin_src shell :var response=get-posts :results value raw :wrap src js :exports results
  echo $response | jq
#+end_src
&lt;/pre&gt;

&lt;p&gt;
Now our &lt;code&gt;index.html&lt;/code&gt; should look like this:
&lt;/p&gt;


&lt;div id="org395aee1" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-5.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org930dbc1" class="outline-4"&gt;
&lt;h4 id="org930dbc1"&gt;Discussion&lt;/h4&gt;
&lt;div class="outline-text-4" id="text-org930dbc1"&gt;
&lt;p&gt;
Briefly let's highlight a couple items in the above changes.
&lt;/p&gt;

&lt;p&gt;
First, note the use of a new property, &lt;code&gt;:HTML_CONTAINER_CLASS: request&lt;/code&gt; and &lt;code&gt;:HTML_CONTAINER_CLASS: response&lt;/code&gt;. Upon export, this property attaches the respective CSS class of &lt;code&gt;.request&lt;/code&gt; or &lt;code&gt;.response&lt;/code&gt; to the &lt;code&gt;div&lt;/code&gt; element containing the heading. In this way, we can style &lt;code&gt;div.request&amp;gt;h5&lt;/code&gt; and &lt;code&gt;div.response&amp;gt;h5&lt;/code&gt; to make clear what each of these blocks is for.
&lt;/p&gt;

&lt;p&gt;
Also, note that we have moved our request and response sections inside a new subheading of &lt;code&gt;Posts&lt;/code&gt;, called &lt;code&gt;GET /posts&lt;/code&gt;. Now, when we click on "Posts" in the sidebar menu, we see "GET /posts" as a submenu item. This is controlled at by the Org header directive &lt;code&gt;#+options: toc:2&lt;/code&gt; included. If we set it to &lt;code&gt;toc:1&lt;/code&gt; we would not see the submenu. If we set it to &lt;code&gt;toc:3&lt;/code&gt; we would see "Request" and "Response" in the submenu below "GET /posts". Try it and see!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org997fe75" class="outline-2"&gt;
&lt;h2 id="org997fe75"&gt;Finish the Job&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org997fe75"&gt;
&lt;p&gt;
Documenting the rest of the API now proceeds according to a set pattern. Indeed, a &lt;code&gt;yasnippet&lt;/code&gt; could be constructed to insert a new method section, and speed the process along.
&lt;/p&gt;

&lt;p&gt;
However, that doesn't reflect the utility of the Literate Programming approach to API documentation. Normally, I write this documentation &lt;i&gt;as I am building new API endpoints&lt;/i&gt;, in order to test and perfect the endpoint. I use this method &lt;i&gt;instead of Postman&lt;/i&gt;, and when I am done working on the API, it is &lt;i&gt;already documented&lt;/i&gt; and under version control with the source code.
&lt;/p&gt;

&lt;p&gt;
For example, I would have written what we have so far &lt;i&gt;at the same time I was writing&lt;/i&gt; &lt;code&gt;GET :api/posts&lt;/code&gt;, and I would have used that file extensively, making note of any parameters required.
&lt;/p&gt;

&lt;p&gt;
When I pushed code, anyone on my team (who uses Emacs) could open the &lt;code&gt;README.org&lt;/code&gt; and test the API for themselves.
&lt;/p&gt;

&lt;p&gt;
As a last step before I push code, I can generate the &lt;code&gt;index.html&lt;/code&gt; and pop it into a public static directory. Now when you browse to the base URL of my API, instead of getting an error message, you get API documentation.
&lt;/p&gt;

&lt;p&gt;
Let's wrap up this post by documenting the rest of the &lt;code&gt;/posts&lt;/code&gt; resource methods. This will also serve to illustrate how to use &lt;code&gt;restclient&lt;/code&gt; to perform &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt; HTTP methods.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge08f50c" class="outline-3"&gt;
&lt;h3 id="orge08f50c"&gt;Adding a POST Method&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-orge08f50c"&gt;
&lt;p&gt;
Let's add a &lt;code&gt;POST /posts&lt;/code&gt; header under &lt;code&gt;GET /posts&lt;/code&gt;. You can copy and paste, and then change the following:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;Change &lt;code&gt;:CUSTOM_ID:&lt;/code&gt; from &lt;code&gt;method-get-posts&lt;/code&gt; to &lt;code&gt;method-post-posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Change the "Request" &lt;code&gt;#+name:&lt;/code&gt; from &lt;code&gt;get-posts&lt;/code&gt; to &lt;code&gt;post-posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Change the "Response" &lt;code&gt;:var response&lt;/code&gt; from &lt;code&gt;get-posts&lt;/code&gt; to &lt;code&gt;post-posts&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Now, add the variable &lt;code&gt;:var user-id=1&lt;/code&gt; to the &lt;code&gt;post-posts&lt;/code&gt; request source block header. With &lt;code&gt;requests&lt;/code&gt;, we also need to specify the content type and JSON payload to deliver.
&lt;/p&gt;

&lt;p&gt;
Notice that we can use Org variables &lt;i&gt;inside the JSON payload&lt;/i&gt;. &lt;b&gt;WOW!&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
The final POST request should look like:
&lt;/p&gt;

&lt;pre class="example" id="org34e2ec5"&gt;
#+name: post-posts
#+begin_src restclient :var api=api-url :var user-id=1 :results value
  POST :api/posts
  Content-Type: application/json

  {
    "title": "foo",
    "body": "bar",
    "userId": :user-id
  }
#+end_src
&lt;/pre&gt;

&lt;p&gt;
Now, when you put the cursor in the "Response" block and type &lt;code&gt;C-c C-c&lt;/code&gt; you should get back the new post data you created in JSON Placeholder. It should look something like:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"body"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"userId"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;101&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org53a2b13" class="outline-3"&gt;
&lt;h3 id="org53a2b13"&gt;Adding a PUT Method&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-org53a2b13"&gt;
&lt;p&gt;
As you can imagine, the process proceeds similarly. Copy and paste &lt;code&gt;POST /posts&lt;/code&gt; to &lt;code&gt;PUT /posts/:id&lt;/code&gt;, and change the custom ID, request name, and response variable to &lt;code&gt;put-posts&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Now our request should look similar to a POST request, except now we must specify the post's &lt;code&gt;id&lt;/code&gt; in the URL, and the JSON we use will update an existing post, rather than creating a new one.
&lt;/p&gt;

&lt;p&gt;
Our final PUT request should look like:
&lt;/p&gt;

&lt;pre class="example" id="org73f8183"&gt;
#+name: put-posts
#+begin_src restclient :var api=api-url :var id=1 :var user-id=1 :results value
  PUT :api/posts/:id
  Content-Type: application/json

  {
    "title": "foo",
    "body": "bar",
    "userId": :user-id
  }
#+end_src
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgef70f12" class="outline-3"&gt;
&lt;h3 id="orgef70f12"&gt;Adding a DELETE Method&lt;/h3&gt;
&lt;div class="outline-text-3" id="text-orgef70f12"&gt;
&lt;p&gt;
Surprise, surprise! Same idea as before. Copy, paste, change, run, profit!
&lt;/p&gt;

&lt;pre class="example" id="orgde27ff7"&gt;
#+name: delete-posts
#+begin_src restclient :var api=api-url :var id=1 :results value
  DELETE :api/posts/:id
#+end_src
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org33850c9" class="outline-2"&gt;
&lt;h2 id="org33850c9"&gt;Conclusion&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org33850c9"&gt;
&lt;p&gt;
Our final API documentation isn't very detailed (we only documented the &lt;code&gt;/posts&lt;/code&gt; resource) but the rest is just a repetition of what we've already discussed. Still, it's quite nice, and can easily be made nicer:
&lt;/p&gt;


&lt;div id="org7dccc02" class="figure"&gt;
&lt;p&gt;&lt;img src="https://blog.notroot.online/images/lit-api-ex-6.png" alt="nil"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Also, as discussed, it would be easy enough to write a &lt;code&gt;yasnippet&lt;/code&gt; to automate create new method sections, then tab from field to field filling it out.
&lt;/p&gt;

&lt;p&gt;
Also as discussed, that's not really the most useful approach to writing Literate API documentation. More useful is to write it as you go, using the document instead of Postman. Then not only is your documentation never wrong or out of sync with the API, but you don't have to go back and "waste time" documenting something you've already completed!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgf08cbf6" class="outline-2"&gt;
&lt;h2 id="orgf08cbf6"&gt;Next Steps&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgf08cbf6"&gt;
&lt;p&gt;
More advanced Literate Programming techniques may also prove useful when writing Literate API Documentation.
&lt;/p&gt;

&lt;p&gt;
I have one such document I wrote for the &lt;a href="https://wurkzen.com"&gt;Wurkzen API&lt;/a&gt; which allows you to acquire and cache a bearer token used in later requests.
&lt;/p&gt;

&lt;p&gt;
It then creates a number of objects using the API, and then uses them to construct an entire dummy client, customers, locations, and perform all the API actions against dummy data that was created by the document, and then deleted by the document.
&lt;/p&gt;

&lt;p&gt;
And if there are errors in my API, then the API documentation displays the errors! It also acts as an integration test, as detailed as you want to make it.
&lt;/p&gt;

&lt;p&gt;
AND every request made by Emacs as it exports to HTML is displayed in Emacs &lt;code&gt;minibuffer&lt;/code&gt; and logged in Emacs &lt;code&gt;*Messages*&lt;/code&gt; buffer, so you can find errors with an incremental search instead of reading the &lt;code&gt;index.html&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Literate Programming: beautiful, elegant, powerful.
&lt;/p&gt;

&lt;p&gt;
And useful!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org798cd9e" class="outline-2"&gt;
&lt;h2 id="org798cd9e"&gt;P.S.&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org798cd9e"&gt;
&lt;p&gt;
I ended up &lt;a href="https://gist.github.com/joseph8th/9a87c4f14b867c1abe8d2e81322f4eac#file-lit-api-method-section"&gt;writing a yasnippet for this&lt;/a&gt; anyway.
&lt;/p&gt;

&lt;p&gt;
Type in &lt;code&gt;lit-api&lt;/code&gt; and &lt;code&gt;C-&amp;lt;tab&amp;gt;&lt;/code&gt; and then tab from field to field.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>api</category><category>emacs</category><category>literate programming</category><category>org-mode</category><guid>https://blog.notroot.online/posts/writing-literate-api-documentation-in-emacs-org-mode/</guid><pubDate>Wed, 26 Jan 2022 00:48:54 GMT</pubDate></item><item><title>Publishing with Nikola in Emacs</title><link>https://blog.notroot.online/posts/publishing-with-nikola-in-emacs/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
Publishing Emacs Org Mode files to &lt;a href="https://pages.github.com/"&gt;GitHub Pages&lt;/a&gt; with &lt;a href="https://getnikola.com/"&gt;Nikola&lt;/a&gt; is fairly straight-forward. But if you want, as I did, to write and publish from within Emacs using org-mode, then there's more setup involved. It's still not terribly difficult, however. I did this all today.
&lt;/p&gt;

&lt;p&gt;
The final blog is going to be very vanilla, so I've included some additional resources to play with, as much for my own reference as for you, the reader's.
&lt;/p&gt;

&lt;div id="outline-container-orgefe0b00" class="outline-2"&gt;
&lt;h2 id="orgefe0b00"&gt;UPDATES!&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgefe0b00"&gt;
&lt;p&gt;
&lt;span class="timestamp-wrapper"&gt;&lt;span class="timestamp"&gt;&amp;lt;2022-01-29 Sat&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="timestamp-wrapper"&gt;&lt;span class="timestamp"&gt;&amp;lt;2024-04-07 Sun&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;
The really nice tutorial linked to above and below is 404. Since this tutorial picks up where that one left off, I've added a few other links. Some of these are old. Some don't talk about Org Mode. But the objective is this:
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Before continuing this tutorial, get Nikola to publish Org files from the command-line to your GitHub Pages.&lt;/b&gt; Here's some resources that describe how to do that:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;a href="https://streakycobra.github.io/posts/blogging-in-org-mode-with-nikola/"&gt;https://streakycobra.github.io/posts/blogging-in-org-mode-with-nikola/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://meshlogic.github.io/posts/web-design/starting-a-personal-blog-with-nikola/"&gt;https://meshlogic.github.io/posts/web-design/starting-a-personal-blog-with-nikola/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://randlow.github.io/posts/python/create-nikola-coding-blog/"&gt;https://randlow.github.io/posts/python/create-nikola-coding-blog/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://knowsuchagency.github.io/pyhi/posts/make-your-own-blog-with-github-pages-and-nikola/"&gt;http://knowsuchagency.github.io/pyhi/posts/make-your-own-blog-with-github-pages-and-nikola/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shankarmsy.github.io/posts/blogging-with-the-awesome-nikola-ipython-and-github.html"&gt;https://shankarmsy.github.io/posts/blogging-with-the-awesome-nikola-ipython-and-github.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
I will try to come back and write my own command-line tutorial later as a prequel to this post.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orge1cd598" class="outline-2"&gt;
&lt;h2 id="orge1cd598"&gt;Get Nikola Working&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orge1cd598"&gt;
&lt;p&gt;
Before we start, save yourself a headache and &lt;b&gt;don't&lt;/b&gt; install Nikola in a Python virtual environment. Or if you're using &lt;a href="https://github.com/pyenv/pyenv"&gt;pyenv&lt;/a&gt;, install it in the &lt;code&gt;global&lt;/code&gt; environment. This works fine in the terminal, but we're going to be writing some extra elisp for the &lt;code&gt;nikola.el&lt;/code&gt; package. I have no doubt there's a way to get this package working with virtual environments, but as of this writing, I haven't figured it out.
&lt;/p&gt;

&lt;p&gt;
Next, follow the instructions in &lt;a href="https://mindtoilet.github.io/posts/how-to-write-a-blog-using-nikola/"&gt;this excellent tutorial&lt;/a&gt; to get all the pieces working together, and to learn the command-line way of doing things as a fallback.
&lt;/p&gt;

&lt;p&gt;
The end result will be your first blog post on your GitHub Page. Now that you know it works, let's move on to setting up Emacs so you never have to leave it to write and publish.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org472f3f5" class="outline-2"&gt;
&lt;h2 id="org472f3f5"&gt;Install and Configure &lt;code&gt;nikola.el&lt;/code&gt;&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org472f3f5"&gt;
&lt;p&gt;
We're going to use the "simple wrapper" &lt;code&gt;nikola.el&lt;/code&gt; package as a base. Follow &lt;a href="https://gitlab.com/drymerisnothere/nikola-el"&gt;these instructions&lt;/a&gt; to install and configure it.
&lt;/p&gt;

&lt;p&gt;
We want to default to Org files, instead of HTML, so here's the &lt;code&gt;use-package&lt;/code&gt; config I have in my &lt;code&gt;init.el&lt;/code&gt;. Note that I've turned on &lt;code&gt;nikola-verbose&lt;/code&gt; and &lt;code&gt;nikola-webserver-auto&lt;/code&gt; as well as setting the default extension to &lt;code&gt;"org"&lt;/code&gt;:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;;; Nikola.el config&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;nikola&lt;/span&gt;
  &lt;span class="nv"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-output-root-directory&lt;/span&gt; &lt;span class="s"&gt;"~/Dev/mine/blog.notroot.online/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-verbose&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-webserver-auto&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-new-post-extension&lt;/span&gt; &lt;span class="s"&gt;"org"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;nikola-new-page-extension&lt;/span&gt; &lt;span class="s"&gt;"org"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-orgc0746ec" class="outline-2"&gt;
&lt;h2 id="orgc0746ec"&gt;Add Wrapper for &lt;code&gt;github_deploy&lt;/code&gt;&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-orgc0746ec"&gt;
&lt;p&gt;
At this point, we &lt;b&gt;could&lt;/b&gt; just start writing by using the &lt;code&gt;nikola-new-post&lt;/code&gt; command. It will open an Org file and you can start typing, as I am right now.
&lt;/p&gt;

&lt;p&gt;
The problem comes when we run &lt;code&gt;nikola-deploy&lt;/code&gt;. That command basically runs &lt;code&gt;nikola deploy&lt;/code&gt; in a shell, &lt;b&gt;but that's not the command we want to run&lt;/b&gt;. We want to run &lt;code&gt;nikola github_deploy&lt;/code&gt;, as we did on the command-line.
&lt;/p&gt;

&lt;p&gt;
So you'll also need to add the following &lt;code&gt;nikola-github-deploy&lt;/code&gt; function to your &lt;code&gt;init.el&lt;/code&gt;, which I simply whittled down from the &lt;code&gt;nikola-deploy&lt;/code&gt;:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;;; Custom nikola-github-deploy function&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;nikola-github-deploy&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Deploys the site to GitHub using github_deploy subcommand."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"Deploying the site to GitHub pages..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;async-start&lt;/span&gt;
   &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;async-inject-variables&lt;/span&gt; &lt;span class="s"&gt;"\\(nikola-\\)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;output&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;default-directory&lt;/span&gt; &lt;span class="nv"&gt;nikola-output-root-directory&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run-hook-with-args&lt;/span&gt; &lt;span class="ss"&gt;'nikola-deploy-before-hook&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;nikola-deploy-before-hook-script&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;output&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;shell-command-to-string&lt;/span&gt;
			  &lt;span class="nv"&gt;nikola-deploy-before-hook-script&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;output&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;shell-command-to-string&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt; &lt;span class="nv"&gt;nikola-command&lt;/span&gt; &lt;span class="s"&gt;" github_deploy"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;nikola-deploy-after-hook-script&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;output&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;shell-command-to-string&lt;/span&gt;
			  &lt;span class="nv"&gt;nikola-deploy-after-hook-script&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
	&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run-hook-with-args&lt;/span&gt; &lt;span class="ss"&gt;'nikola-deploy-before-hook&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cl-search&lt;/span&gt; &lt;span class="s"&gt;"This command needs to run inside an existing Nikola site."&lt;/span&gt;
		    &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;nikola-verbose&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong. You may want to set nikola-verbo\&lt;/span&gt;
&lt;span class="s"&gt;se to t and retry it."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong. You may want to check the *Nikola*\&lt;/span&gt;
&lt;span class="s"&gt;buffer."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"Site deployed correctly."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;nikola-verbose&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;save-window-excursion&lt;/span&gt;
	   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;switch-to-buffer&lt;/span&gt; &lt;span class="s"&gt;"*Nikola*"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
	   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;inhibit-read-only&lt;/span&gt; &lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
	     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)))))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org440038c" class="outline-2"&gt;
&lt;h2 id="org440038c"&gt;Write and Publish from Emacs&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org440038c"&gt;
&lt;p&gt;
Now you can evaluate the &lt;code&gt;init.el&lt;/code&gt; buffer, or restart Emacs, and do &lt;code&gt;nikola-new-post&lt;/code&gt;. Emacs will ask for the title, and create the post files, and open a buffer to write a new post.
&lt;/p&gt;

&lt;p&gt;
You'll immediately notice that, unlike the command-line experience you had earlier, the meta is not included at the top of the new buffer that opens. If your new post is named &lt;code&gt;publishing-with-nikola-in-emacs.org&lt;/code&gt;, then the meta will be in the same directory, and named &lt;code&gt;publishing-with-nikola-in-emacs.meta&lt;/code&gt;. You will have to edit it separately.
&lt;/p&gt;

&lt;pre class="example" id="org250e9a9"&gt;
.. title: Publishing with Nikola in Emacs
.. slug: publishing-with-nikola-in-emacs
.. date: 2020-11-12 17:25:34
.. tags: emacs,nikola,blogging
&lt;/pre&gt;

&lt;p&gt;
When you're done writing your amazing blog post, just save it.
&lt;/p&gt;

&lt;p&gt;
Now try previewing your new post by running &lt;code&gt;nikola-webserver-start&lt;/code&gt;. Notice that that this is a &lt;b&gt;live preview&lt;/b&gt;, and if you make changes and save again, you will see them when you refresh your browser.
&lt;/p&gt;

&lt;p&gt;
Next, run &lt;code&gt;nikola-build&lt;/code&gt; to make sure everything is rebuilt and updated.
&lt;/p&gt;

&lt;p&gt;
When you're happy with the final result, then just publish it with &lt;code&gt;nikola-github-deploy&lt;/code&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-org1bfc8bd" class="outline-2"&gt;
&lt;h2 id="org1bfc8bd"&gt;Additional Resources&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-org1bfc8bd"&gt;
&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;b&gt;Syntax Highlighting&lt;/b&gt;: If you included source blocks in your Org file, you probably noticed that syntax highlighting isn't supported. I'm going to look at &lt;a href="https://github.com/redguardtoo/org2nikola"&gt;org2nikola&lt;/a&gt; package to add &lt;code&gt;highlight.js&lt;/code&gt; support at some point.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Themes and Templates&lt;/b&gt;: Since I'm almost as new at this as you, the reader, are, I've got jack. I'm going to look into &lt;a href="https://getnikola.com/creating-a-theme.html"&gt;Nikola theme creation&lt;/a&gt; at some point in the future, and if suddenly this blog looks better, it's because I learned something. I'll probably blog about it!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>blogging</category><category>emacs</category><category>nikola</category><guid>https://blog.notroot.online/posts/publishing-with-nikola-in-emacs/</guid><pubDate>Thu, 12 Nov 2020 22:25:34 GMT</pubDate></item><item><title>EXWM on Raspberry Pi OS Lite</title><link>https://blog.notroot.online/posts/exwm-on-raspberry-pi-os-lite/</link><dc:creator>Notroot</dc:creator><description>&lt;ol class="org-ol"&gt;
&lt;li&gt;Install Raspberry Pi OS Lite (buster)&lt;/li&gt;
&lt;li&gt;Login as &lt;code&gt;pi/raspberry&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enable sources in &lt;code&gt;/etc/apt/sources.list&lt;/code&gt;, then &lt;code&gt;sudo apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;
Install basic but required build tools:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;sudo apt install build-essential&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Install &lt;code&gt;xorg&lt;/code&gt; and WebKitGTK+:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;sudo apt install xorg xorg-dev libwebkit2gtk-4.0-dev&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Prepare for latest Emacs install by installing dependencies of latest previous version in the repo:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;sudo apt build-dep emacs&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Get the latest Emacs, and configure it thusly:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;./configure --with-imagemagick --with-xwidgets&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Build and install Emacs:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;make &amp;amp;&amp;amp; sudo make install&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Get my literate README:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;git clone https://github.com/joseph8th/literatemacs.git&lt;/code&gt;
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;Open &lt;code&gt;README.org&lt;/code&gt; in Emacs, then follow instructions to get a basic &lt;code&gt;init.el&lt;/code&gt; installed in &lt;code&gt;.emacs.d/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In addition, copy the &lt;code&gt;elisp/&lt;/code&gt; directory into &lt;code&gt;.emacs.d/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;
Run Emacs to install packages and debug init as needed:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;emacs --debug-init&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Open &lt;code&gt;README.org&lt;/code&gt; again, and enable the EXWM entanglement. Then save, and it will tangle EXWM files.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    cp xinitrc.exwm ~/.xinitrc
    ln -s exwm-init.el ~/.emacs.d/
&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;

&lt;li&gt;Reboot and do &lt;code&gt;startx&lt;/code&gt; after login. Debug init as needed.&lt;/li&gt;
&lt;/ol&gt;</description><category>emacs</category><category>exwm</category><category>pi</category><guid>https://blog.notroot.online/posts/exwm-on-raspberry-pi-os-lite/</guid><pubDate>Thu, 12 Nov 2020 20:59:41 GMT</pubDate></item><item><title>Blog is a Weird Word</title><link>https://blog.notroot.online/posts/blog-is-a-weird-word/</link><dc:creator>Notroot</dc:creator><description>&lt;p&gt;
Hello, World.
&lt;/p&gt;

&lt;p&gt;
I've had many blogs off and on over the years, but I was never satisfied with the blogging platforms I chose, which, admittedly, is not a very large set. OK, it was two: WordPress and Octopress. Octopress at least satisfied my penchant for working in the terminal, and let me use my favorite editor (Emacs, obviously), but I was broke at the time and self-hosting. Eventually, I just let it die off naturally.
&lt;/p&gt;

&lt;p&gt;
Now I'm not broke, but I'm still cheap. With GitHub Pages, and Nikola, I can write posts in Emacs Org Mode and publish for free and with ease. Let's see how long it lasts.
&lt;/p&gt;</description><category>blogging</category><guid>https://blog.notroot.online/posts/blog-is-a-weird-word/</guid><pubDate>Thu, 12 Nov 2020 20:43:26 GMT</pubDate></item></channel></rss>