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:
- Takes Markdown on standard input.
- Produces HTML on standard output.
- 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
Header and Footer Template Files
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.
Top Link
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!
The performance issue is mitigated by using Make build rules to only recompile files as necessary.âŠī¸