Skip to content

What Is SSGSS?

SSGSS is a static site generator based on GNU core utilities and other things, notably GNU M4 and Make. It can compile and update individual pages, with the most recent date of compilation at the bottom of each page, so you can get an idea of how old a given page's content is. Pages are written in Markdown, and it has support for a primitive blog. This system is too simple for a complex site, but is good enough for mine.

It is available on GitLab, although the version available there is likely to lag far behind what I'm using for this site.

The name is a reference to the stupidest transformation in anime, as well as another static site generator, which SSGSS is obviously superior to.

Markdown

Due to the way the SSGSS system works, different Markdown engines can be swapped in for generation, with different pros and cons.

The requirements for a Markdown processor to work with SSGSS are as follows:

  1. Takes Markdown on standard input.
  2. Produces HTML on standard output.
  3. Does not escape HTML code or attempt to add <html><body> tags etc.

These are a few I have at least tried:

smu

Small and fast. Used by suckless!

discount

Has a few nice extensions which may or may not be useful, but still quite nippy.

pandoc

Massive and slow, with many major extensions. More suitable for use with a few large files, rather than many small ones1. Can mess with M4 by escaping single-quote characters in code blocks.

M4

Pages are preprocessed by GNU M4, which provides various highly useful utilities. For example, when writing Markdown, I may want to make links that point to other pages on the site, with the .md extension so I can move between the Markdown source files by using the gf binding in Vim or find-file-at-point in Emacs. However, on the actual website, the links must point to the generated html files. To solve this, I can use the following M4 macro:

m4_define(`SSGPAGE', `m4_patsubst($1, .md, .html)')

This allows me to link to the Markdown file in the source, but have the link redirect to the html file after it is processed:

SSGPAGE(index.md)

becomes

index.html

I could theoretically make it more useful by automatically inserting the Markdown link syntax, but that is so simple that I decided I preferred just replacing the extension.

The Pipeline

This is an oversimplified view of the SSGSS pipeline:

markdown < page.md | m4 -P > page.html

There are additional headers and M4 macro files loaded, but the key point is that the Markdown engine is called before M4. This means that M4 macros cannot insert Markdown, since once the text reaches M4, Markdown conversion has already occurred. This is primarily done so M4 doesn't get confused by Markdown code blocks, which are delimited by back-tics (`).

Make

The Makefile is what I consider the core of SSGSS, since it is where most of the code for actually generating the site is. I had to learn a lot about the intricacies of dependencies and implicit/wildcard rules which I promptly forgot soon after.

The system almost certainly contains a lot of inefficiencies, but it works just about well enough for my purposes.

Minor Features

As you can see, every page has a fairly uniform format, with the same navigation bar and a footer containing information pertaining to the page in question.

This is done through the highly sophisticated technique of passing these to M4 before and after the Markdown file for the page!!!: essentially cat.

Changes File

Using a highly involved shell script, which I partially copied from a StackOverflow post somewhere, I print out the most recent commit for each Markdown file on the site, except the changes file itself, and sort them in descending date order.

Floating Navigation Bar

In a sufficiently wide window, the navigation pane is displayed at the side and floats at the left side of the page, so it is always visible. This is primarily achieved with a combination of the CSS grid layout and position: sticky properties.

A link to the top in the footer. It's nothing spectacular, but probably useful for mobile users, especially since the navigation pane is kept at the top for them.

Blog

The blog posts are contained within <article> tags, which act as some nice semantic markup that might be useful for accessibility purposes. This is the object that is styled with the box around it.

Blog files are generated automatically, with their contents and names determined by the time of creation and a user-supplied title. File names need to have fairly restrictive character sets, so the script includes a mechanism for normalising them, which initially only used sed, with the expedient addition of uconv to properly transliterate the titles into a suitable subset of ASCII.

In the future, I would like to arrange a way to manage separate categories for blogs, possibly with independently-operated blog directories. This would make me feel more comfortable to make posts about topics that aren't technology-related.

GitLab Pages and Git pre-commit Hook

Since the site is now hosted on GitLab pages, it is necessary to commit HTML files into the repository. This could have gotten messy, so I set up a surprisingly simple Git pre-commit hook, which builds the site by running make, then stages (git add) the HTML directory. This way, I don't have to think about keeping the HTML files updated, or even explicitly compiling the site.

The site is published with git push. I was using this arrangement a long time ago, but I have found a more satisfactory way to do it (certainly in comparison to a Raspberry Pi that is offline due to power supply issues most of the time) so I have returned!


  1. The performance issue is mitigated by using Make build rules to only recompile files as necessary.↩ī¸Ž