Home About Articles zoomlogo's site

Static site generation.

This site is static like most other blog sites, but the way the site is built is a mildly interesting one.

The old way.

Initially when I made the site, it was very very simple. A few HTML dependencies like marked, hljs and MathJax and I used a rather convoluted method to make the site.

The textarea method.

The html files had a textarea element which contained the Markdown source of the site. A JS script then removed the component and replaced it with its corresponding HTML.

The reason why anyone uses Markdown for writing sites is because of editability. It is easy to edit Markdown and easy to imagine how the final site looks like. It is also easy to track in version control.

Why it kinda sucked.

The weird way of first loading the site with the textarea element then deleting it and replacing it with the site contents dynamically caused the site to be slow. A good website should load quickly. (If you have noticed, this website still loads a bit slowly, I will hopefully fix this in the future, but its still faster than the old site.)

This was unacceptable to me. The site loading very slowly caused me to lose my mind ;)

The new shell script.

So instead of generating the HTML from Markdown when the site loads, I wrote a script to generate the HTML files before pushing it to Codeberg. This makes it load faster and I can edit Markdown files instead of HTML files.

The power of the POSIX shell.

The shell script is very simple thanks to the UNIX philosophy (do one thing and do it well). The heart of the script is the following few lines:

cat "$file" \
| awk '/^```pikchr/ { print; system("cat macros.pikchr"); next } 1' \
| expand_class_spans \
| pikchr -C \
| md2html --flatex-math --ftables --fstrikethrough --ftasklists --fwiki-links --fpermissive-autolinks --fpermissive-url-autolinks --stat

This first takes the file and prepends the macros.pikchr file in every pikchr code block (more about pikchr later). The next step is to call the function expand_class_spans which adds support for [text]{span class name} to add support for colors by converting it to <span class="span class name">text</span> using AWK.

Next we pass the output of that to pikchr and finally we use md2html to convert all the remaining Markdown to HTML. You can read through the md2html manpage to figure out what all of those options mean (they are pretty much self explanatory though).

Templating HTML.

The script generates HTML by placing the generated markdown into an HTML template. This can easily be done in shell script using something similar to:

wrap_html() {
    title="$1"
    body="$2"
cat <<EOF
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>${title}</title>
    </head>
    <body>
        ${body}
    </body>
</html>
EOF
}

pikchr.

If you aren't familiar with pikchr, it is a PIC-like markup language for diagrams. A quick example is something like

arrow right 200% "2" above
box rad 5px "f(x)"
arrow right 200% "1" above

generates the following svg:

2 f(x) 1

pikchr is powerful enough for me to use. All circuit diagrams in my previous articles were written in pikchr.

There are few advantages to using pikchr instead of separate images. First of all, pikchr generates inline svgs, so it is fast. And since it is text-based, I can use any standard text editor to change the diagram, making it really fast to iterate between diagrams.

I even wrote a vim plugin to add syntax highlighting for pikchr.

Source.

If you want to see the full script, check it out here. You can easily modify it to make your own static site using the same technique.