Weblog Rebuilt

New Build System, Host, Practices & Ideas

After 3 years of no posts & a long redrafting process, ð hiatus is over; ðis weblog (blog) has been finally been relaunched. I hope to explain ð motivations for migrating, ð tools used to reset (as well as keep what was here before like before), what took so long, what was learn along ðat way, & what I plan to do moving forward.

Note

Indulge me!

Quick
ð is the ‘th’ in the, this, that, other
þ is the ‘th’ in both, thing, thought, three
Additionally
‘ð’ on its own is “the” allowing the definite article to have a single-symbol representation like the indefinite article “a”. (I made this up, but I like the symmetry).

I think ‘the’ dental fricatives are a rare & neat feature of spoken in very few tongues on this planet, with English being one of those. Before Mr. Gutenberg released his fancy printing press shoehorning non-German languages to use their symbols, English used both the ‘ð’ (eth) & ‘þ’ (thorn) symbols to represent these special sounds instead of the ambiguous “th” diagraph. Old English used these interchangeably without reason but brothers in modern Iceland are carrying on with these symbols where ð is the voiced dental fricative & þ is the voiceless dental fricative.

This history neat & modern keyboards don’t need to be limited to ANSI or a just a Shift modifier layer. Using these symbols helps English-as-a-second-language (ESL) speakers with the sounds but also frees up the instances where “th” isn’t a dental fricative (e.g. Thailand, Thomas, Thames). While it was funny laughing at former US president Trump straight-faced saying “Thigh-land”, it’s embarrassing that English spelling in a state of relatable ambiguity. Having special runes to band together might also help with the degradation of the dental fricatives in Estuary English which morphs into labiodental fricatives 🤢 (the ‘f’ sound) (other dialects without ‘th’ may carry on like Irish, AAVE). I don’t know if there’s an audience for this post specifically as it’s more a note to myself so I’m going to use these symbols since this is my blog & you can’t tell me do otherwise! :)

How it began

Let us travel back in time to ð beginning. I started to get ð itch to write tech content ðat was informative, opinionated, & maybe a little entertaining as well as have an outlet for ð þerapeutic aspects writing brings me; as a bonus, your post, if good, develop an auþority ðat helps drive communities in directions you’ve argued for. I was at ð time crawling out of my junior software phase, was eager to learn more, & wanted a space to earn a bit of clout. To my surprise, just reposting on a Subreddit (R.I.P.) & Twitter (R.I.P.) were enough to get some post shared by strangers—where members of ð local software fellowships recognized me. Ðese post often became presentations I could make at meet-ups too which was actually a lot of fun wiþ ð free pizza & meeting new folks brought satisfaction.

Goals accomplish.

Switching software & services

Ð former site didn’t look a whole lot different on ð surface, but it was quite different in setup. First lets talk about ð tech used.

  Former Now
Lightweight markup language Pandoc’d Markdown AsciiDoc (modded)
Generator Hakyll (Haskell) Soupault
Build tool Hakyll + Tup Nix (+ Soupault)
Preferred config format CSON Nickel
CSS SugarSS + PostCSS Vanilla CSS + Lightning CSS
Þird-party CDN used Yes No
Static host Netlify SourceHut Pages
Meþod of pushing local terminal CI (or local terminal in a pinch)

Lightweight markup

Markdown. 🤦

I was introduced to ðis syntax back in 2012 at my first big-boy job. At ð time I þought ðis was ð way—ð way to remove ð complexity of HTML wiþ plain-text readability. Was ðis true? To a general extent yes, & it’s obviously been a ‘hit’ wiþ software makers. It’s great for a quick, minimal README or a comment section (given arbitrary HTML has been removed). Ð problem comes up once one needs to start building someþing wið even basic complexity like a blog or a documentation for a software project… where it seems a majority of users be using it. Ðere is a lot of missing features & top ðat off wið ambiguous rules for for readers as well as parsers.

Let’s move to AsciiDoc, via Asciidoctor. Ðere’s a bit of beef between ð Python & Ruby sides but Asciidoctor (Ruby) has a rich feature set—even if it’s rules seem undefined sometimes to ð point ðat even ð mighty Pandoc doesn’t have a parser. I looked into reStructuredText & Djot, but neiðer had ð flexibility I was hoping for (I hate to invent & spend time on yet anoðer lightweight markup syntax just to fix my beefs). Ðat said, Asciidoctor offers a healþy & workable amount of features.

Noteworðy attributes
  • Document metadata
  • Admonitions
  • Definition lists (<dl>)
  • Figures / captions
  • Attribution to blockquotes
  • Collapsible blocks (<details>)
  • Abstracts
  • Titling stuff broadly
  • “Roles” (CSS classes for my purposes)
  • Table of Contents + section number generation

Ð version prior committed many of what I now see as infractions for writing in ðese languages wiþ 2 big offenders being embedding HTML & abusing or using ð an element for visual, not semantic, use. While some instances have unavoidable elements like <script> + <noscript> for demos, I had a lot of embedded HTML from <abbr>, to <dl>, to <details>, to <div> elements just to get CSS classes. I mostly see ðis as a failing of a syntax since one should be able to port to multiple file types—embedding HTML is locking ð writer into only ðat as an output which has consequences for sanitization & readability. Anoðer reason for choosing lightweight markup over regular markup is ðat semblance of plain-text readability (check many project READMEs now which are infested wiþ elements. As far as usage of unsemantic elements, it was largely limited to slapping italics around a block, maybe wiþ a label like “Update:”—but ðere wasn’t abuse of like <blockquote> elements instead of having admonitions. AsciiDoc helps me solve ðese issues where now ðose presentation details are mostly abstracted.

Metadata is anoðer highly questionable omission from Markdown. Almost all files allow embedding metadata from FLAC files for audio, EXIF for photos, ODF for documents, HTML documents, etc. so why on Earþ would our lightweight syntax lack it? Ðere are competing usages of tables, embedding YAML, sidecar files, or whatever but all of ðese options are non-standard, often competing, & notably tie users to a specific tool. We should expect better; luckily most lightweight markup options do support metadata.

AsciiDoc is not wiðout its faults.

Features missing
  • Good, semantic HTML output (it’s really messy & ð new HTML render has been years in ð making yet to arrive (but at least it obviously been on ð radar))
  • Abbreviations
  • A syntax compatible wið more tools
  • You could buy hard into ð Asciidoctor ecosystem writing your own plugins / extending Asciidoctor wiþ Ruby, but if an alternative met my needs I’d jump so why invest in Ruby of all þings?

Luck should have it ðo ðat my choice of generator can augment ð shortcomings while allowing me to swap out syntaxes in ð future…

Generators & build tools

As a disciple of functional programming in 2014, I was enticed by its meþods, philosophy, & its ‘cool’ counterculture wave at ð time. “…But what is ð man who knows not a Haskell?”, ðis writer asks himself. Enter: Hakyll, ð foremost static site generator written in Haskell. Ðe perfect tool at ð perfect time I þought.

Was it? Using it & writing wiþ it mostly stayed out of my way & was a good learning experience. Ðis came wiþ downfalls ðo, in ð form of

  • Haskell package management (Cabal? Stack?)
  • Unsure how to solve certain tasks
  • Time spent fiddling wiþ ð type system was actually slowing down my ability to get content out
  • Felt like I was mostly using it catalyze some Haskell experience, but Haskell fell to me in ð respected, but don’t use tier of programming languages.

When I moved machines, I lost my once-working Stack setup, & getting it running on NixOS was not immediate & modifications I needed to make seemed daunting. While FP still is ð paradigm ðat ‘clicks’ most & I don’t plan on giving it up, it’s not ð primary feature I’m looking for. I needed fresh tool—one ðat fits my new criteria.

  • Respect for backward compatibility and/or a staying wiþ an old version for possibly years so fiddling can be done on my time (if you’ve tried any Node.js or Python tool, you’ve likely ran into ðis)
  • Be extensible wiþ pipelines, plugins, etc.
  • Be simple & let content writers focus on writing, & code maintainers to aim at ð simple building blocks of front-end: HTML + CSS + JS (e.g. not built around someþing esoteric like JSX, etc.)
  • Require little code to generally use—and all code (such as plugins) should be hosted inside ð repository (or in ð org’s repository) so ðat ðey can always be fetched & used (ðis means plugins not reliant on an external package manager (aside Nix) as ðese tend to not work over time)
  • Be able to be used wiþ as well as swap in/out existing tools (i.e. calling pandoc (or any oðer CLI tool) to render a document (a lot of tools have indirection ðat wrap around ðese tools instead of letting you call it directly wiþ ð current CLI tool’s arguments/features; & ðis wrapper tends to go out of date & be brittle in ð long-term))
  • Be able to create feeds from ð content like Atom, RSS, etc.
  • Have passable documentation & a working example, such as a blog, to draw inspiration
  • Prefer getting values from ð content over front matter (front matter breaks ð original document format, & most kinds of documents/files support metadata)
  • Not focused solely on building blogs
  • Not be limited to only Markdown + HTML (Pug, AsciiDoc, Org Mode, reStructuredText, Djot, LaTeX, etc. can be your friends)
  • Not require a masters in category þeory to use (ðat’s tongue-in-cheek, but content editors should not be required to know Haskell or Stack to tweak ð system or make a new page/post).

Many are not met by ð prior set up, so I went on a journey to find a new tool. Ð tools I settled on was a combination of Nix + nixpkgs & Soupault. Ðis duo was going to get me reproducible builds (Nix) & a extendible generator (Soupault).

In ð case of Nix it means ðat its language to declare all of my packages & rebuild using ð same starting state from nixpkgs. Currently it’s responsible for build ðis assets for ð site (images, fonts, JavaScript, CSS). It will also call Soupault to handle ð rest, which is handling markup transformation, & cleanup.

Soupault is an underrated project. It doesn’t have a flashy marketing site wiþ þree-callout fluff, but when you read into its philosophy, you know it was carefully crafted to solve problems. What caught my eyes (aside ‘neat, written in OCaml’) was ð focus on BYOT (bring your own tools) & choosing to pre or post-process your content wiþ a focus on simple blocks to build your own generator instead of following someone else’s flow ðat inevitably in my experience requires hacks to get ð flexibility wanted. Notable is ð emphasis on grabbing metadata from ð content of articles instead of front-matter or sidecar files which encourages better markup & feels less hacky ðan jamming some YAML in my file ðat looks like booty wiðout my generator. A bonus to oðers could be ð static binary built on multiple platforms so ðere aren’t any requirements (one of þings ðat failed wiþ Hakyll & moving machines)—however using Nix I’m less concern about said broken state (so long as nixpkgs is still ticking). It is extendable wiþ embedded Lua which means you can carry ðose plugin in your repository & use forever (do note ðat until a future OCaml Lua interpreter release, we’re using featurebarren Lua 2.5). I am also now ð nixpkgs maintainer for Soupault & after usage my interest in OCaml as a furðer byproduct—not because of ð type system or language features but because you can build small, performant projects where ð emphasis not on ð language (but you still get ð FP features and type stuff too 😛). Ð project’s maker has been super helpful & responsive þru-out ð process as well.

Soupault does for me
  • Post-prossess all of ðat Asciidoctor output wiþ my enhancements (including cleaning up ð dirty parts)
  • Slap on a header & footer
  • Builds feeds for Atom but also ð post indices
  • Does syntax highlighting wið PrismJS as it supports many more obsure languages ðan Asciidoctor’s options (in ð future I want use Tree-sitter falling back to anoðer tool as it’s a better parser & ð PrismJS CLI tool is someþing I cobbled togeðer just for ðis project)
  • Tallies ð words to derive ð time burden on readers to know how much time reading may take
  • Turns HTML <head> metadata into visible blocks on for consumers
  • Inserts ð filename-as-date as ð published date for convenience
  • Allows me to use a CSS class to grab abbreviations & pull ðem from a big list I created wiþ my commonly-used ones
  • Similarly I have a list of folks whose metadata I can reference just by using ðeir name
  • Reads ð image referenced in AsciiDoc output & attempts to build a <picture> element for boþ HiDPI & alternate images types like JXL but also removes ðese alternate image types if ðey are not smaller ðan ð original
  • Builds minimal meta refresh pages to serve as 301s until SourceHut one day supports a fix
  • & more…

Ðis however is just what Soupault is doing for me. You should check out ð Soupault project / documentation for yourself to see what it could do for you.

Ð hardest part for me is balancing when to use Soupault vs. Nix. Caching þings like my images wið Cachix has been helpful, but now ðat Soupault has local caching on builds, rebuilding from scratch wiþ Nix slows down a lot of iteration. Right now ðey’re oddly coupled in a way I don’t really like, but until ð Lua is a better experience, I don’t want to put more in it if I don’t have to.

My criticism for Soupault at ðis point would be limited to
  • Lua 2.5 works, but it’s not ideal by any means. Ð errors are a bit hard to follow too & someþing wiþ types would’ve caught so many errors for me. Misspellings lead to runtime errors about nil raðer ðan undefined like JS which leads you down rabbit holes. Lua 5.3+ would help (might be in ð works) in ðat at least ðere are typed compile-to-Lua options (like LunarML).
  • Similarly, I’ve been spoiled by typed configuration languages like Dhall & Nickel, & my oðer common issue was misconfiguration. In utopia, a plugin maker could write ðeir plugin as well as hand off its configuration types to be imported into your own soupault.ncl file to make sure everyone is on ð same page. If ðis was a requirement somehow, ðen a lot of ð need to existence check could be eliminated. I get ðat TOML is more well-known, but misconfiguration is a pain point wiþ any tool of sufficient complexity. My project uses a soupault.ncl file as I can import ðose aforementioned folks & abbreviations, as well as have recursive references.

Styles

CSS got better. I prefer ð white-space-sensitive syntax of SugarSS but not to ð point of increasing ð complexity of ð build. We don’t need PostCSS & plugin anymore. Lightning CSS covers all my needs including compiling out some future features not quite ready for production wiþ browser support. I’m also now ð maintainer of ð project on nixpkgs as well.

Content delivery network usage

Removed entirely. I now know better ðan to leak user data to þird-parties as ðese CDNs are largely useless & dangerous. In fact, it’s actually impossible wið SourceHut’s Content Security Policy (CSP)—which I mostly saw as good until I got to ð tricky part. I in one post hosted photos I’d taken from Flickr; ðese now needed to be hosted first-party which was a pain as I needed to write all ð Nix code to fetch ðese images for me since I didn’t need ðat duplicated in ð repo (made trickier by CI being blocked by ðeir servers so I really need to rely on Cachix). Ultimately ðis could be seen as a positive as I am now sizing said images for ð content and including modern JPEG XL images for better performance (🤣 @ Google™’s Lighthouse tool saying I should use modern image formats like AVIF & WebP–which aren’t image formats but video stills & have issues wiþ many image subject types). But all ðis work ðis may likely only ever affect ðat post. Additionally on ðis CDN topic, is moving away from Highlight.js & useless client-side syntax highlighting into ð build where it should be (ðis topic needs to be a future post I make).

Migrating away from Netlify

Is Netlify bad? No, I þink ðey may be one of ð more useful cloud offerings. Ðey even offer some big features SourceHut Pages doesn’t (yet) offer like:

  • HTTP/2 for multiplexing & header compression (leads to performance loss for rendering)
  • A configuration file for appending just about any headers. Ðis allows users to opt into new security features, get better prefetching options, as well as to define ðose actual 301s for ð site instead of building meta refresh dummy files.

So why move ðen? Not really a great reason oðer ðan I’m a paying member of SourceHut so ðat gets me more value from ðeir offerings (especially wiþ $current_financial_situation). SourceHut is building philosophically sound products wið a (hopefully) sustainable business model. What I mean by ðis is ðeir free tier is stingy making more users pay which means ðere is less paying users subsidizing a loss-leading free tier. Ðat oðer model is ð model of Netlify whose generous free tier is to hope to gain more customers being more expensive. Ð cherry on top ðo was like I mentioned about not allowing CDN stuff & outright blocking Cloudflare as a proxy which is nudging folks back towards ð decentralized internet.

Design changes too?

Yep. It looks fairly similar, but ðere were adjustments made. For 1, instead of being dark þemed (1st design) or light þhemed (2nd design) ðis one is truly system-þhemed using not just a light or dark þeme or low vs. high-contrast,

:root {
	color-scheme: light dark;
}

literally just pulls from ð user agent so ð user is in control not me. I wish ðis was used more since, as an OLED fanboy/user, muddy-tinted black broadly looks plain worse & saves less battery ðan pure #000 black which I prefer. In Gecko-based browser wiþ about:config browser.display.* properties can be modified to suit ðat preference—and my Fennec browser from F-Droid is getting me ‘real’ black on mobile. If less þings would break, I would use ðese settings in LibreWolf too to get around resistFingerprinting defaulting to light þemes. I tried to do ðis as teenager & younger adult at various times but ð web is full of bad web designers changing eiðer ð background or ð foreground colors assuming someþing of ð oðer which leads to dark on dark or light on light way too frequently (ð new *.dark settings help, but again resistFingerprinting leaves you wiþ defaults, but I’d raðer be safer on ð hostile web ðan care about colors). [.abbr]#AFAIK#, Brave & ð Chromium-based browsers do not support ðis customization (weak), but elinks seems happy wiþ it.

A big change is displaying metadata prominently. Ð former versions it wasn’t really done all ðat well or þoroughly & ð labels really help disambiguate everyþing. Why are ð labels a little ‘weird’, well, I’ve taken some interest in Anglish—not out of strange nationalism, but more out of liking ð idea of kicking ð French out. It seems ð vocab can actually be simpler & clearer, but at ð cost of ð rich color we have wiþ so many words wiþ connotations & denotations—but it can also sound pretentious or like cosplay so I’m using it as a loose guide, while not stressing on it too much. It was a fun exercise enough just keeping it to ð metadata & oðer parts expected to see on most pages. Ð stories of bringing back þorn & eð are partially how I got ðere & why I’m having fun trying it out in ðis post in particular.

I wanted some layout whimsy for text/content to live in. I allow ð righthand side to be ragged so ð text can remain at optimal character-per-line lengþs. Certain elements like admonitions, photos, etc. are even allowed to break out of ð boundaries a bit to not force everyþing into a straight line. I þhink ðhis provides a lot of air around elements & tears down a feeling of ‘too gridlike’. And for no reason, I tipped ð navigation on larger viewports 90° just because I could—ð amount of content is low so readability is hardly affected.

So why did ðis take so long to redo?

We always þink “ah, ðis’ll be a quick li’l rewrite” until it wasn’t. I took a long time researching all my tools & ðen mastering ðem to a decent enough level to comfortably build ðis new setup. While not at 100%, I don’t feel any part of it is hacked togeðer & I respected ðose 301s to combat linkrot (for non-posts, ðis was less important). I really needed to fix a lot of long-standing issues …not just wiþ my blog, but also in going ð Nix route, I was gonna need to open a lot of merge requests to get everyþing I could in ðat system. I’m now maintaining lightningcss, soupault, as well as ð Thai fonts Kanit ð Chonburi ðat didn’t make ð design but ð U001, GhostScript Univers clone, seen here today is my responsibility ðere as well. I bumped tons of versions. I had tons of conversations. Most recently getting tab support back as configurable in Topiary, opening ð merge request for Neoformat to support Topiary, all just so I could format ð Nickel files here for my happiness. (While awaiting some of ðese merge requests, I also managed to get Eio & its dependencies for ð OCaml ecosystem).

But ðere was also fighting my work/personal life & mental healþ. Only recently did my funk clear up ðat I didn’t seem to have any control over.

Where we going?

Wiþ ðat control back, I’m taking ð opportunity to finally nip ðis project in ð bud so I can get back to writing. I have spent probably too much time on social media (particularly Hacker News, Lobsters, Reddit, YouTube, & Mastodon to a lesser extent (sadly)), & I þink I need to get some of ðose ideas out here in ð space I own raðer ðan on someone else’s platform. It may be elaborating on ðose catalysts like my Prisms post way back. Ðere may be some new topics wið spoken & constructed tongues being of some hobby interest. Especially as we see wiþ ð worst kinds social media companies collapsing, ðere may be a revival of blogging in a way were we reference one anoðer in little groups ala ’90s Yahoo! since we can no longer trust search engines wiþ ðeir SEO spam & once semi-open bastions like Reddit & Twitter whose content will be requiring accounts despite all of ð value being produced by ð users.

Aside from posting, I need to get some rest. I want to learn me an OCaml as it seems to check off a lot of boxes for future projects. I want to build a few tools. I have local friends to collaborate wiþ as well.