<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://dbarenholz.github.io/halcyon-zola/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://dbarenholz.github.io/halcyon-zola/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-01T00:00:00+00:00</updated>
    <id>https://dbarenholz.github.io/halcyon-zola/atom.xml</id>
    <entry xml:lang="en">
        <title>MathJax</title>
        <published>2026-05-01T00:00:00+00:00</published>
        <updated>2026-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dbarenholz.github.io/halcyon-zola/features/mathjax/"/>
        <id>https://dbarenholz.github.io/halcyon-zola/features/mathjax/</id>
        
        <content type="html" xml:base="https://dbarenholz.github.io/halcyon-zola/features/mathjax/">&lt;p&gt;Halcyon has built-in support for MathJax, which allows you to include mathematical notation in your content using LaTeX syntax. I personally heavily use math notation in Obsidian, so I wanted to make sure that this feature was supported in Halcyon as well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-sad&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-sad&quot; aria-label=&quot;Anchor link for: the-sad&quot;&gt;The Sad&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Zola does not have support for MathJax on &lt;em&gt;generation&lt;&#x2F;em&gt; side of things. So we have to &quot;patch&quot; the HTML directly, or write some sort of preprocessor that is completely separate from the &lt;code&gt;zola&lt;&#x2F;code&gt; binary. For now, I&#x27;ve opted for the former, but eventually I&#x27;d like to have some form of preprocessor, either Rust based or JS based, that we can use to preprocess &lt;em&gt;before&lt;&#x2F;em&gt; Zola does its thing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-good&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-good&quot; aria-label=&quot;Anchor link for: the-good&quot;&gt;The Good&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Client-side MathJax support isn&#x27;t necessarily hard to add to a site. You have to include the MathJax script through CDN in your &lt;code&gt;&amp;lt;head&amp;gt;&lt;&#x2F;code&gt;, and have an accompanying script that does configuration.&lt;&#x2F;p&gt;
&lt;p&gt;For the Halcyon theme, the configuration is done in &lt;code&gt;static&#x2F;js&#x2F;mathjax.js&lt;&#x2F;code&gt;. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.mathjax.org&#x2F;en&#x2F;stable&#x2F;web&#x2F;start.html#configuring-mathjax&quot;&gt;the mathjax documentation&lt;&#x2F;a&gt; on how this configuration works. The interesting part is that we have to do some work to ensure that math is properly rendered when &lt;code&gt;\\&lt;&#x2F;code&gt; is used, which Zola interprets as an escaped backslash. Clearly, directly passing that to e.g. &lt;code&gt;\begin{align}&lt;&#x2F;code&gt; or simimlar won&#x27;t work, as we expect &lt;code&gt;\\&lt;&#x2F;code&gt; there for linebreaks!&lt;&#x2F;p&gt;
&lt;p&gt;To fix this, we need to replace all instances of &lt;code&gt;\&lt;&#x2F;code&gt; in the HTML with &lt;code&gt;\\&lt;&#x2F;code&gt;, but only for math content. The mathjax configuration allows me to call a function before math is rendered. Said function -- &lt;code&gt;fixCollapsedNewlines&lt;&#x2F;code&gt; -- uses a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Document&#x2F;createTreeWalker&quot;&gt;&lt;code&gt;TreeWalker&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to get text nodes in the page, ignoring when the parent node is e.g. &lt;code&gt;&amp;lt;script&amp;gt;&lt;&#x2F;code&gt; or &lt;code&gt;&amp;lt;code&amp;gt;&lt;&#x2F;code&gt;, and ignoring if the text node doesn&#x27;t include &lt;code&gt;$$&lt;&#x2F;code&gt; -- which is the syntax for math. The nodes left over are indeed math equations, and we can safely replace &lt;code&gt;\&lt;&#x2F;code&gt; with &lt;code&gt;\\&lt;&#x2F;code&gt; in those nodes.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{align*}
E &amp;amp;= m\cdot c^2 \
m \cdot c^2 &amp;amp;= E
\end{align*}
$$&lt;&#x2F;p&gt;
&lt;p&gt;As can be seen, the above renders, so our replacement works. It&#x27;s done with the functions below (comments stripped to save space, but you can see the full code in &lt;code&gt;static&#x2F;js&#x2F;mathjax.js&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; normalizeDisplayMathLine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; lines&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; lines&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-character-class z-regexp&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-character-class z-regexp&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;line&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; String&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;raw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            :&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;11&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; normalizeDisplayMathBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;inner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; inner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replaceAll&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\r&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;split&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; ls&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; normalizeDisplayMathLine&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; ls&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;join&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;17&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; normalizeDisplayMathText&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replaceAll&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-character-class z-regexp&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\s&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-character-class z-regexp&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;_match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; inner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;18&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; normalizedInner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; normalizeDisplayMathBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;inner&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;19&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;$$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;normalizedInner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;$$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The equation shown above is made with the following notation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;latex&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;$$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;\&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-be&quot;&gt;begin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;align*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-class&quot;&gt;    E &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt;= m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;\&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt;cdot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; \\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-class&quot;&gt;    m &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;\&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt;cdot&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class&quot;&gt;= E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;\&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-be&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;align*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;$$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Diagramming with Mermaid</title>
        <published>2026-05-01T00:00:00+00:00</published>
        <updated>2026-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dbarenholz.github.io/halcyon-zola/features/mermaid/"/>
        <id>https://dbarenholz.github.io/halcyon-zola/features/mermaid/</id>
        
        <content type="html" xml:base="https://dbarenholz.github.io/halcyon-zola/features/mermaid/">&lt;p&gt;Halcyon has built-in support for Mermaid, which allows you to include diagrams in your content using Mermaid syntax. This is yet another feature to get parity with Obsidian.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-bad&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-bad&quot; aria-label=&quot;Anchor link for: the-bad&quot;&gt;The Bad&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Like [[features&#x2F;mathjax|mathjax]], Zola does not have support for MathJax on &lt;em&gt;generation&lt;&#x2F;em&gt; side of things. So we have the same choice to either &quot;patch&quot; the HTML directly, or write some sort of preprocessor that is completely separate from the &lt;code&gt;zola&lt;&#x2F;code&gt; binary.&lt;&#x2F;p&gt;
&lt;p&gt;Even &lt;em&gt;if&lt;&#x2F;em&gt; Zola did have support for Mermaid, Mermaid itself doesn&#x27;t have support for dark-light theming, so we&#x27;d still have to do some effort to make things work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-bug&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-bug&quot; aria-label=&quot;Anchor link for: the-bug&quot;&gt;The Bug!&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Right now, there&#x27;s a slight issue with how things work (see below). Because mermaid has no notions of theme switching on-the-fly, by switching themes we have to rerender the entire diagram, which resets the scroll position. This is a known issue, and should be fixed in a future release of the Halcyon theme.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-yeah-no-word-starting-with-b-here&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-yeah-no-word-starting-with-b-here&quot; aria-label=&quot;Anchor link for: the-yeah-no-word-starting-with-b-here&quot;&gt;The .. yeah, no word starting with B here&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Including Mermaid is done with a script tag in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;&#x2F;code&gt;, and then we have an accompanying script that looks for code blocks with &lt;code&gt;mermaid&lt;&#x2F;code&gt; as the language, and transforms them into Mermaid diagrams. Because of the aforementioned issue with theme switching, we also have to listen for theme changes, and re-render the diagrams when that happens.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph TD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A[Code block with mermaid] --&amp;gt; B[JS looks for code blocks with mermaid language]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B --&amp;gt; C[JS transforms code block into Mermaid diagram]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D[User switches theme] --&amp;gt; E[JS listens for theme change event]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    E --&amp;gt; F[JS re-renders Mermaid diagrams to apply new theme]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above diagram is made using following mermaid codeblock:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph TD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A[Code block with mermaid] --&amp;gt; B[JS looks for code blocks with mermaid language]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B --&amp;gt; C[JS transforms code block into Mermaid diagram]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D[User switches theme] --&amp;gt; E[JS listens for theme change event]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    E --&amp;gt; F[JS re-renders Mermaid diagrams to apply new theme]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Table of Contents</title>
        <published>2026-05-01T00:00:00+00:00</published>
        <updated>2026-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dbarenholz.github.io/halcyon-zola/features/toc/"/>
        <id>https://dbarenholz.github.io/halcyon-zola/features/toc/</id>
        
        <content type="html" xml:base="https://dbarenholz.github.io/halcyon-zola/features/toc/">&lt;p&gt;From Typora days I&#x27;ve become accustomed to generating a table of contents with &lt;code&gt;[TOC]&lt;&#x2F;code&gt; syntax. This is a feature that Zola doesn&#x27;t have built-in support for, but it&#x27;s easy enough to add since Zola &lt;em&gt;does&lt;&#x2F;em&gt; keep track of the actual headings in the page.&lt;&#x2F;p&gt;
&lt;p&gt;[TOC]&lt;&#x2F;p&gt;
&lt;p&gt;Even if the [TOC] string is placed inline here, it is shown on the top of the page. And, as you can see, including it a second time as I&#x27;ve done, doesn&#x27;t generate a second one or errors out. Below are some unused headers so you can see how everything works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hello-world&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#hello-world&quot; aria-label=&quot;Anchor link for: hello-world&quot;&gt;Hello World&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;headers-are-nice&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#headers-are-nice&quot; aria-label=&quot;Anchor link for: headers-are-nice&quot;&gt;Headers are nice&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;we-can-do-subheaders-too&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#we-can-do-subheaders-too&quot; aria-label=&quot;Anchor link for: we-can-do-subheaders-too&quot;&gt;We can do subheaders too&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;this-one-is-too-deep-so-isn-t-shown&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#this-one-is-too-deep-so-isn-t-shown&quot; aria-label=&quot;Anchor link for: this-one-is-too-deep-so-isn-t-shown&quot;&gt;This one is too deep, so isn&#x27;t shown!&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;h3 id=&quot;this-one-will-be-shown-again&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#this-one-will-be-shown-again&quot; aria-label=&quot;Anchor link for: this-one-will-be-shown-again&quot;&gt;This one will be shown again&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;you-can-use-code-in-headers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#you-can-use-code-in-headers&quot; aria-label=&quot;Anchor link for: you-can-use-code-in-headers&quot;&gt;You can use &lt;code&gt;code&lt;&#x2F;code&gt; in headers&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This gets rendered in the page, and not in the TOC, as one would expect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;and-if-you-really-want-to-math-too&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-if-you-really-want-to-math-too&quot; aria-label=&quot;Anchor link for: and-if-you-really-want-to-math-too&quot;&gt;And if you really want to, $math$ too&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;It gets rendered in the page, and the TOC. I should change this so it&#x27;s only in the page, probably. But who is using math in headers?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;icons&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#icons&quot; aria-label=&quot;Anchor link for: icons&quot;&gt;





  



  &lt;i data-lucide=&quot;thumbs-down&quot; color=&quot;var(--halcyon-palette-salmon)&quot;&gt;&lt;&#x2F;i&gt;

 Icons&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Technically work, but not in TOC. This uses the icon shortcode!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;before-links-is-fine-but-after&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#before-links-is-fine-but-after&quot; aria-label=&quot;Anchor link for: before-links-is-fine-but-after&quot;&gt;Before &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;example.com&quot;&gt;links&lt;&#x2F;a&gt; is fine but after ...&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;links&lt;&#x2F;code&gt; in the header above is a distinct link. You shouldn&#x27;t put links in headers -- it will break things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wikilinks</title>
        <published>2026-04-27T00:00:00+00:00</published>
        <updated>2026-04-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://dbarenholz.github.io/halcyon-zola/features/wikilinks/"/>
        <id>https://dbarenholz.github.io/halcyon-zola/features/wikilinks/</id>
        
        <content type="html" xml:base="https://dbarenholz.github.io/halcyon-zola/features/wikilinks/">&lt;p&gt;If you happen to use Obsidian, you&#x27;ll be very familiar with &lt;code&gt;[[wikilinks]]&lt;&#x2F;code&gt;. This feature is a DIY implementation that, client-side, transforms raw &lt;code&gt;[[link]]&lt;&#x2F;code&gt; into &lt;code&gt;&amp;lt;a&amp;gt;&lt;&#x2F;code&gt; tags. It&#x27;s &lt;strong&gt;very bad&lt;&#x2F;strong&gt; for SEO, and I don&#x27;t necessarily recommend using it. But it&#x27;s there, for the period of time that Zola doesn&#x27;t yet have official wikilink support.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-details&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-details&quot; aria-label=&quot;Anchor link for: the-details&quot;&gt;The Details&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation for wikilinks lives in &lt;code&gt;static&#x2F;js&#x2F;wikilinks.js&lt;&#x2F;code&gt;. It works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;For each node in the DOM, if it&#x27;s a &lt;code&gt;text&lt;&#x2F;code&gt; node and its parent is not a &lt;code&gt;script&lt;&#x2F;code&gt;, &lt;code&gt;style&lt;&#x2F;code&gt;, &lt;code&gt;code&lt;&#x2F;code&gt;, &lt;code&gt;pre&lt;&#x2F;code&gt;, or &lt;code&gt;textarea&lt;&#x2F;code&gt; element, do:&lt;&#x2F;li&gt;
&lt;li&gt;Check for a match with a wikilink regex pattern.&lt;&#x2F;li&gt;
&lt;li&gt;If we match, construct a document fragment, where we replace the wikilink syntax with an anchor tag. The URL of the anchor tag is generated by a simple slugification of the page name, and the display text is either the page name or the custom display text if provided.&lt;&#x2F;li&gt;
&lt;li&gt;Replace the original text node with the constructed document fragment.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The interesting part of the implementation is shown below, where we convert a page name, e.g. &lt;code&gt;chicken&lt;&#x2F;code&gt; for &lt;code&gt;[[chicken]]&lt;&#x2F;code&gt;, into a URL, e.g. &lt;code&gt;&#x2F;chicken&#x2F;&lt;&#x2F;code&gt;. The slugification process is very basic, and simply lowercases the page name, trims whitespace, and replaces spaces with dashes. There are also special cases for &lt;code&gt;home&lt;&#x2F;code&gt; (which links to the root) and for in-page anchors (which start with &lt;code&gt;#&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pageNameToUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;pageName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; slug&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; pageName&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toLowerCase&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replaceAll&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Special case: &amp;quot;home&amp;quot; links to root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;slug&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ===&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;home&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Special case: #some-header links to in-page anchor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;slug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;startsWith&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;14&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; currentPage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; globalThis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;location&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pathname&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure trailing slash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; currentPage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; slug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;18&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure leading slash, trailing slash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;19&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; slug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replaceAll&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-anchor z-regexp&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Ensure we respect the base URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;21&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; base&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; document&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;querySelector&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;base&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;?.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getAttribute&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;href&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;22&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; base&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;23&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Go back to read [[#The Details]] (made with wikilink syntax, e.g. &lt;code&gt;[[#The Details]]&lt;&#x2F;code&gt;) or alternatively &lt;a href=&quot;https:&#x2F;&#x2F;dbarenholz.github.io&#x2F;halcyon-zola&#x2F;features&#x2F;wikilinks&#x2F;#the-details&quot;&gt;The Details&lt;&#x2F;a&gt; with regular anchor link syntax.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
