<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Schemescape | Nara</title>
<id>https://fita-slovo.codeberg.page/luasmith-theme-nara/categories/schemescape</id>
<link rel="self" href="https://fita-slovo.codeberg.page/luasmith-theme-nara/categories/schemescape/feed.xml"/>
<link rel="alternate" type="text/html" hreflang="en" href="https://fita-slovo.codeberg.page/luasmith-theme-nara/categories/schemescape/index.html"/>
<author>
  <name>ѲС</name>
  <email>fita-slovo@yandex.ru</email>
</author>
<updated>2026-06-02T00:00:00.000Z</updated>

<entry>
  <title>Optimizing for text-mode browsers</title>
  <id>https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/index.html</id>
  <link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/index.html"/>
  <updated>2026-06-02T00:00:00.000Z</updated>
  <summary type="text">Here&#039;s how I finally optimized my site for viewing in w3m (a text-mode browser).</summary>
  <content type="html">&lt;blockquote&gt;
&lt;p&gt;This page is copied from &lt;a href=&quot;https://log.schemescape.com/posts/web-development/designing-for-text-browsers.html&quot;&gt;the blog of Jared Krinke, the creator of Luasmith&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I still use text-mode browsers (mostly &lt;a href=&quot;https://w3m.sourceforge.net/&quot;&gt;w3m&lt;/a&gt;, sometimes &lt;a href=&quot;https://en.wikipedia.org/wiki/Lynx_(web_browser)&quot;&gt;Lynx&lt;/a&gt;), especially on old computers, because they&amp;#x27;re fast, use little memory, and don&amp;#x27;t take up much disk space. They also aren&amp;#x27;t funded by ad cartels, but that&amp;#x27;s not my primary motivation.&lt;/p&gt;
&lt;p&gt;While the prior version of this site was &lt;em&gt;functional&lt;/em&gt; in text-mode browsers (thanks to minimalist design and static HTML), I wanted to try &lt;strong&gt;optimizing for text-mode (and old) browsers &lt;em&gt;first&lt;/em&gt;&lt;/strong&gt;, both so that the site works great in those browsers and also as an exercise in simplicity.&lt;/p&gt;
&lt;h2 id=&quot;issues-with-the-old-design&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#issues-with-the-old-design&quot;&gt;Issues with the old design&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While I liked the CGA palette of my previous blog theme in graphical browsers, it was unwieldy in Lynx and w3m because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You had to scroll past a list of tags to get to the main content&lt;/li&gt;
&lt;li&gt;The article list took up too much vertical space&lt;/li&gt;
&lt;li&gt;The publish dates of articles weren&amp;#x27;t visually obvious&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See for yourself:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/lynx-old.png&quot; alt=&quot;Screenshot of the old version of this blog in Lynx, showing wasted vertical space&quot;&gt;&lt;em&gt;Screenshot of the old design in Lynx&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It was better than most of the modern web, but I didn&amp;#x27;t &lt;em&gt;enjoy&lt;/em&gt; it.&lt;/p&gt;
&lt;h2 id=&quot;fixes&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#fixes&quot;&gt;Fixes&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;header&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#header&quot;&gt;Header&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The obvious way to ensure text-mode users don&amp;#x27;t have to scroll past branding and navigation links is to put those features last in the HTML and have CSS display those items up top (CSS is generally ignored by text-mode browsers).&lt;/p&gt;
&lt;p&gt;But I took a simpler approach and just dropped branding from all but my landing page and then moved the tag list to the end (and kept it there, even for modern browsers) on most pages.&lt;/p&gt;
&lt;p&gt;Now, when you open the site in Lynx, you get to the content right away:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/lynx.png&quot; alt=&quot;Screenshot of the new version of this blog in Lynx, showing content up top, along with a concise article list&quot;&gt;
&lt;em&gt;Screenshot of the new design in Lynx&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;(I also added an introductory blurb, but for the landing page I&amp;#x27;m counting that as content.)&lt;/p&gt;
&lt;h3 id=&quot;article-list&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#article-list&quot;&gt;Article list&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To simplify the article list, I decided to group articles by year, align their publish dates, and just not bother to show a (usually redundant) blurb. The result looks great in monochrome w3m:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/w3m-posts.png&quot; alt=&quot;Screenshot of this site in w3m, showing a concise list of articles, grouped by year, with dates aligned for easy scanning&quot;&gt;
&lt;em&gt;The new, concise article list, as shown in w3m&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;syntax-highlighting&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#syntax-highlighting&quot;&gt;Syntax highlighting&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Pushing beyond reasonable affordances, I decided to use old school &lt;code&gt;&amp;lt;b&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; tags for syntax highlighting, to ensure syntax highlighting was applied both on text-mode browsers as well as older graphical ones.&lt;/p&gt;
&lt;p&gt;Here&amp;#x27;s functional syntax highlighting in Internet Explorer 6 (on Windows XP):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/ie6.png&quot; alt=&quot;Screenshot of this site in Internet Explorer 6, showing syntax highlighting working on an old browser&quot;&gt;
&lt;em&gt;Syntax highlighting even works in IE6!&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;dark-mode&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#dark-mode&quot;&gt;Dark mode&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unrelated to text-mode browsing, I took this opportunity to finally implement both light and dark mode:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;hl-pseudoclass&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hl-identifier&quot;&gt;color-scheme&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;light&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;dark&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;hl-default&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hl-default&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;lighter&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;color-mix&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;srgb&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;currentColor&lt;/span&gt; &lt;i class=&quot;hl-number&quot;&gt;70%&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-constant&quot;&gt;transparent&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;hl-default&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hl-default&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;bg&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;color-mix&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;srgb&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;currentColor&lt;/span&gt; &lt;i class=&quot;hl-number&quot;&gt;12%&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-constant&quot;&gt;transparent&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;hl-operator&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;#x27;s it. &lt;strong&gt;Rather than torture myself with choosing colors for both light and dark color schemes via media queries, I decided to try taking advantage of modern browsers&amp;#x27; default stylesheets&lt;/strong&gt; and then just crank up/down the amount of color (via transparency). I had toyed with this approach before, but Safari on iOS had a broken dark mode default stylesheet for many years (resulting in dark blue-on-black links). Fortunately, that issue finally got resolved, so I can unleash this questionable design upon the web!&lt;/p&gt;
&lt;h2 id=&quot;bonus-benefits&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#bonus-benefits&quot;&gt;Bonus benefits&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One side effect of optimizing for text-based browsers is that older and more limited browsers benefit as well. In fact, the new site looks only marginally worse with CSS &lt;em&gt;disabled entirely&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/no-css.jpg&quot; alt=&quot;Screenshot of this site in Firefox, with CSS disabled, showing a perfectly usable design&quot;&gt;
&lt;em&gt;This site with CSS completely disabled&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The acid test of old browsers is NCSA Mosaic. I doubt anyone still uses it for anything more than historical curiosity, but it&amp;#x27;s nice to see my site render fine on a roughly 30 year old browser:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../assets/site/mosaic.png&quot; alt=&quot;Screenshot of this site in NCSA Mosaic 3, showing that the site works in very old browsers&quot;&gt;
&lt;em&gt;This site works OK in NCSA Mosaic&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;compromises&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#compromises&quot;&gt;Compromises&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I doubt that deferring color decisions to browsers&amp;#x27; default stylesheets is going to catch on. Maybe I&amp;#x27;ll eventually decide to choose my own colors (perhaps from the EGA palette, this time). Relying on default colors and transparency might introduce issues with low contrast.&lt;/p&gt;
&lt;p&gt;I also opted to switch the tag list from a semantic list into just a bunch of links separated by &amp;quot;|&amp;quot; characters. I&amp;#x27;m sure this is suboptimal from a semantic web (and perhaps accessibility) perspective, but I didn&amp;#x27;t see a simple and obvious solution to collapse the list onto a few lines in text-mode browsers without this sacrifice.&lt;/p&gt;
&lt;p&gt;Regardless, if you notice any egregious problems, send me an email.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Is this a good idea? I think keeping sites simple is a good idea, but optimizing for rarely used browsers is, at best, probably not a good use of time. Additionally, fiddling with CSS feels a bit silly when most readers would best be served using their browser&amp;#x27;s reader mode anyway.&lt;/p&gt;
&lt;p&gt;But the great part of having a personal web site on The Indie Web is that you can do crazy experiments like this. I hope you enjoy my creation.&lt;/p&gt;
&lt;p&gt;If you like this theme, possibly because you have analysis paralysis around color schemes, I will be integrating it directly into the &lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/../luasmith.html&quot;&gt;luasmith&lt;/a&gt; static site generator (the code is in the repository, but I haven&amp;#x27;t cut a new release yet). Feel free to copy any portion of the design.&lt;/p&gt;
&lt;h2 id=&quot;credit&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/designing-for-text-browsers/#credit&quot;&gt;Credit&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While brainstorming new ideas and tweaks, I was inspired by the design of the following sites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://luke8086.dev/&quot;&gt;Luke&amp;#x27;s web space&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20241227223933/https://journal.stuffwithstuff.com/archive/&quot;&gt;journal.stuffwithstuff.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://artemis.sh/blog.html&quot;&gt;Artemis Everfree&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>
<entry>
  <title>A 450 KB static site generator based on Markdown and Lua</title>
  <id>https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/index.html</id>
  <link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/index.html"/>
  <updated>2025-08-22T00:00:00.000Z</updated>
  <author>
    <name>Jared Krinke</name>
    <email>scms@mail.schemescape.com</email>
  </author>
  <summary type="text">Tired of bloat, I made a new static site generator that is 5x faster and 50x smaller than my last effort. And this one runs on 32-bit NetBSD.</summary>
  <content type="html">&lt;header&gt;
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;home&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/../&quot;&gt;Go Home&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;h1&gt;A 450 KB static site generator based on Markdown and Lua&lt;/h1&gt;
&lt;/header&gt;
&lt;main&gt;
&lt;blockquote&gt;
&lt;p&gt;This page is copied from &lt;a href=&quot;https://log.schemescape.com/posts/static-site-generators/smallest-static-site-generator.html&quot;&gt;the blog of Jared Krinke, the creator of Luasmith&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Today, I unveil my most gratuitous static site generator yet: &lt;a href=&quot;https://codeberg.org/jaredkrinke/luasmith&quot;&gt;luasmith&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It&amp;#x27;s 450 KB&lt;/strong&gt; (static binary, including templates for this site, gzip compressed)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It builds my ~140 page site in 300 ms&lt;/strong&gt; (wall clock time, on an 11-year-old old laptop)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It performs acceptably on a 28-year-old laptop, running NetBSD&lt;/strong&gt; (Pentium 166 MHz)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&amp;#x27;s trivial to compile&lt;/strong&gt;, requiring only a C compiler, GNU Make, &lt;code&gt;sed&lt;/code&gt;, and &lt;code&gt;sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Despite the small size, it still includes &lt;strong&gt;&lt;a href=&quot;https://log.schemescape.com/posts/static-site-generators/luasmith-syntax-highlighting.html&quot;&gt;syntax highlighting for ~150 languages&lt;/a&gt; and &lt;a href=&quot;https://log.schemescape.com/posts/static-site-generators/extending-luasmith.html&quot;&gt;internal link-checking&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;show-me-the-code&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#show-me-the-code&quot;&gt;Show me the code!&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&amp;#x27;s like &lt;a href=&quot;https://metalsmith.io/&quot;&gt;Metalsmith&lt;/a&gt; in Lua. See &lt;a href=&quot;https://codeberg.org/jaredkrinke/luasmith/src/branch/main/docs/tutorial.md&quot;&gt;the tutorial&lt;/a&gt; for more, but here&amp;#x27;s an example that converts Markdown to HTML and adds the page&amp;#x27;s title to the resulting HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;i class=&quot;hl-comment&quot;&gt;-- Minimal HTML template (used below)&lt;/i&gt;
&lt;b class=&quot;hl-keyword&quot;&gt;local&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;outer&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt; &lt;i class=&quot;hl-string&quot;&gt;[[
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;%= title %&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;&amp;lt;%- content %&amp;gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
]]&lt;/i&gt;

&lt;i class=&quot;hl-comment&quot;&gt;-- Read content/*.md, convert to HTML,&lt;/i&gt;
&lt;i class=&quot;hl-comment&quot;&gt;-- apply template, write to out/*.html&lt;/i&gt;
&lt;b class=&quot;hl-keyword&quot;&gt;return&lt;/b&gt; &lt;span class=&quot;hl-operator&quot;&gt;{&lt;/span&gt;
  &lt;b class=&quot;hl-function&quot;&gt;readFromSource&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;content&amp;quot;&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
  &lt;b class=&quot;hl-function&quot;&gt;processMarkdown&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
  &lt;b class=&quot;hl-function&quot;&gt;applyTemplates&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;{&lt;/span&gt; &lt;i class=&quot;hl-string&quot;&gt;&amp;quot;%.html$&amp;quot;&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;outer&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
  &lt;b class=&quot;hl-function&quot;&gt;writeToDestination&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;out&amp;quot;&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;hl-operator&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: templates use a Lua-native templating language called &lt;a href=&quot;https://github.com/leafo/etlua&quot;&gt;etlua&lt;/a&gt; and file matching uses Lua &lt;a href=&quot;https://www.lua.org/manual/5.2/manual.html#6.4.1&quot;&gt;patterns&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Obviously, the world does not need another static site generator. So how did I end up here?&lt;/p&gt;
&lt;p&gt;In a word, my motivation was: &lt;strong&gt;simplicity&lt;/strong&gt;. I wanted an SSG that was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple to understand&lt;/li&gt;
&lt;li&gt;Simple to bootstrap&lt;/li&gt;
&lt;li&gt;Simple to maintain&lt;/li&gt;
&lt;li&gt;Simple to deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;implementation&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#implementation&quot;&gt;Implementation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here&amp;#x27;s my take on the goals above.&lt;/p&gt;
&lt;h3 id=&quot;simple-to-understand&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#simple-to-understand&quot;&gt;Simple to understand&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First, I wanted the architecture to be simple, both in design and use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The build pipeline is just a Lua script (similar to &lt;a href=&quot;https://metalsmith.io/&quot;&gt;Metalsmith&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Page templates are constructed using Lua&lt;/strong&gt; (via &lt;a href=&quot;https://github.com/leafo/etlua&quot;&gt;etlua&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Metadata on items can be specified in frontmatter using Lua (or a subset of YAML)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relative links between Markdown files &amp;quot;just work&amp;quot;&lt;/strong&gt; and are checked at build time (including links to headings)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instead of creating a bespoke domain-specific language for defining the structure of a generated site or its templates, you just write some Lua code that glues together a few processing nodes and then supply templates that &lt;em&gt;also&lt;/em&gt; use Lua (e.g. for iteration).&lt;/p&gt;
&lt;p&gt;Overall, I&amp;#x27;d describe the architecture as &amp;quot;&lt;strong&gt;minimalist Metalsmith in Lua, with zero runtime dependencies&lt;/strong&gt;&amp;quot;.&lt;/p&gt;
&lt;h3 id=&quot;simple-to-bootstrap&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#simple-to-bootstrap&quot;&gt;Simple to bootstrap&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Given my &lt;a href=&quot;https://log.schemescape.com/posts/programming-languages/future-proof-languages.html&quot;&gt;musings about future-proof programming languages&lt;/a&gt;, it&amp;#x27;s obvious that I&amp;#x27;d like to be able to compile and use my software in the future. That is easier said than done! The problem is that identifying languages that will stick around is hard. Twenty years ago, Perl might have been a reasonable choice for an SSG, but today I don&amp;#x27;t even remember how to install Perl modules.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://jaredkrinke.github.io/md2blog/&quot;&gt;The (previous) best static site generator ever made&lt;/a&gt; is built on TypeScript/JavaScript and &lt;a href=&quot;https://deno.com/&quot;&gt;Deno&lt;/a&gt;. As much as I like Deno, I&amp;#x27;m not confident it will be maintained decades down the road. Given that I&amp;#x27;ll never know how to get it running on an i586 computer, I have doubts I&amp;#x27;d be able to get it running on potential future architectures (RISC-V?) either.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To avoid these headaches, I went with the lowest common denominator: C&lt;/strong&gt;. It&amp;#x27;s not convenient, it&amp;#x27;s not modern, but C works everywhere and I&amp;#x27;m certain C will persist (for better or worse).&lt;/p&gt;
&lt;p&gt;Aside: ideally, I&amp;#x27;d be writing as much native code in Rust as possible, to ensure memory safety. Unfortunately, &lt;strong&gt;Rust&amp;#x27;s modern approach is at odds with my desire for simplicity&lt;/strong&gt;. The toolchain is huge, the dependency trees are large, and the language is vast. Rust definitely looks like the future of robust low-level software, but &lt;strong&gt;for cozy side projects, I prefer being a simpleton living in the past&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;simple-to-maintain&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#simple-to-maintain&quot;&gt;Simple to maintain&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One frustration I have with the JavaScript ecosystem is that it&amp;#x27;s constantly changing. Node, Deno, and Bun do a respectable job of keeping old versions around, but I don&amp;#x27;t want to have to worry about breaking changes.&lt;/p&gt;
&lt;p&gt;On the other hand, C changes very slowly, and previous versions of Lua are essentially set in stone. Throw in some static linking, and you&amp;#x27;ve even got an artifact that should stay usable for a long time.&lt;/p&gt;
&lt;p&gt;I&amp;#x27;ve also minimized the number of (vendored, compile-time) dependencies involved. Here&amp;#x27;s the full list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mity/md4c&quot;&gt;md4c&lt;/a&gt; for converting Markdown to HTML&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lua.org/&quot;&gt;Lua&lt;/a&gt; for metadata, scripting, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/leafo/etlua&quot;&gt;etlua&lt;/a&gt; for templates&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/orbitalquark/scintillua&quot;&gt;Scintillua&lt;/a&gt; for syntax highlighting&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.inf.puc-rio.br/~roberto/lpeg/&quot;&gt;LPeg&lt;/a&gt; to support Scintillua&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;You&amp;#x27;ll note that these libraries are doing all of the heavy lifting&lt;/strong&gt;. I&amp;#x27;ve basically only written glue code, an entry point, and some infrastructure. And most of the code I wrote is in Lua (which is much easier to write than C--and fast enough for all but the innermost loops).&lt;/p&gt;
&lt;h3 id=&quot;simple-to-deploy&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#simple-to-deploy&quot;&gt;Simple to deploy&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Static binaries are wonderful. &lt;em&gt;Tiny&lt;/em&gt; static binaries are even wonderful-er. &lt;strong&gt;Just copy over a tiny zip file, unzip it, and you&amp;#x27;re done&lt;/strong&gt;. Need I say more?&lt;/p&gt;
&lt;h2 id=&quot;downsides&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#downsides&quot;&gt;Downsides&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Of course, there are downsides to the approach I took:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing C code is fraught with peril -- fortunately, the hardest parts were mostly already done by the md4c and Lua authors&lt;/li&gt;
&lt;li&gt;Syntax highlighting is &lt;em&gt;not&lt;/em&gt; simple -- good news: &lt;a href=&quot;https://log.schemescape.com/posts/static-site-generators/luasmith-syntax-highlighting.html&quot;&gt;Scintillua already solved this problem for me&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;The security model of an SSG that uses Lua scripts for everything is... not ideal -- &lt;strong&gt;only use templates you trust!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, I haven&amp;#x27;t taken the time to set up a proper development and debugging environment for C and Lua. I need to investigate static analysis and debugging tools for Lua, as well as find a tolerable frontend for GDB. This is where I really miss Emacs+SLIME for Common Lisp or VS Code for TypeScript/Python.&lt;/p&gt;
&lt;h2 id=&quot;future-areas-of-exploration&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#future-areas-of-exploration&quot;&gt;Future areas of exploration&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that I&amp;#x27;ve got a static site generator running on a vintage laptop with NetBSD, where am I headed next? I&amp;#x27;m not exactly sure, but some ideas follow.&lt;/p&gt;
&lt;h3 id=&quot;designing-for-the-text-mode-web&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#designing-for-the-text-mode-web&quot;&gt;Designing for the text-mode web&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;At some point, I&amp;#x27;d like to redesign my site using an even more minimal theme. In fact, &lt;strong&gt;I&amp;#x27;d like to optimize my site for text mode browsers&lt;/strong&gt; like &lt;a href=&quot;https://lynx.browser.org/&quot;&gt;lynx&lt;/a&gt; and &lt;a href=&quot;https://w3m.sourceforge.net/&quot;&gt;w3m&lt;/a&gt;. Why? Because I like using w3m and I want my site to be easy to use within w3m. Or maybe it&amp;#x27;s because I hate how bloated modern web browsers have become.&lt;/p&gt;
&lt;h3 id=&quot;further-simplifying-distribution&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#further-simplifying-distribution&quot;&gt;Further simplifying distribution&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Distributing native code necessarily requires per-platform packages. Or does it? Can I package and release this minimal static site generator as a multi-OS polyglot binary using &lt;a href=&quot;https://github.com/jart/cosmopolitan&quot;&gt;Cosmopolitan libc&lt;/a&gt;? &lt;strong&gt;Update&lt;/strong&gt;: this now exists, but sadly, it is 64-bit only.&lt;/p&gt;
&lt;h3 id=&quot;simplifying-the-entire-system&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#simplifying-the-entire-system&quot;&gt;Simplifying the entire system&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I&amp;#x27;d like to see if I can bootstrap my entire web site&amp;#x27;s workflow from &lt;a href=&quot;https://github.com/oasislinux/oasis&quot;&gt;Oasis Linux&lt;/a&gt; (a small, statically linked, Linux-based operating system that is simple, but capable). &lt;strong&gt;Oasis sounds like a modern system that a single person can wrap their head around&lt;/strong&gt; (minus the Linux kernel--though perhaps a simpler kernel could be substituted in the future?).&lt;/p&gt;
&lt;h3 id=&quot;blogging-on-vintage-computers&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#blogging-on-vintage-computers&quot;&gt;Blogging on vintage computers&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I&amp;#x27;m curious how far back I can go as far as vintage computing and still be able to build a static site. Can I build my SSG on Windows 98? DOS? Amiga? Inquiring minds want to know!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Creating a &lt;em&gt;non-bloated&lt;/em&gt; Markdown-based static site generator has been a bucket list item for me--and now it&amp;#x27;s done!&lt;/p&gt;
&lt;p&gt;Beyond personal goals, &lt;strong&gt;I found C+Lua to be a comfortable combination for side projects&lt;/strong&gt;. This came as a surprise! Lua isn&amp;#x27;t my favorite language to write (though it&amp;#x27;s certainly much simpler to wield than C). Having said that, it&amp;#x27;s a beautifully simple language that&amp;#x27;s easy to integrate. Despite being primarily driven to Lua by my goal of building a small (in binary size) tool, Lua&amp;#x27;s minimalist take on a mostly-normal-looking scripting language won me over because I could literally pick it up and be productive within an hour or two.&lt;/p&gt;
&lt;p&gt;With that out of the way, &lt;strong&gt;I should probably attend to hobbies other than static site generator performance art&lt;/strong&gt;. Until next time!&lt;/p&gt;
&lt;h2 id=&quot;resources&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/#resources&quot;&gt;Resources&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codeberg.org/jaredkrinke/luasmith&quot;&gt;Repository for luasmith&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codeberg.org/jaredkrinke/luasmith/src/branch/main/docs/tutorial.md&quot;&gt;Tutorial for luasmith&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://til.schemescape.com/&quot;&gt;Example site: a blog of things I&amp;#x27;ve learned&lt;/a&gt; (&lt;a href=&quot;https://git.sr.ht/~jaredkrinke/til&quot;&gt;source&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: the example repository contains &lt;a href=&quot;https://git.sr.ht/~jaredkrinke/til/tree/main/item/readme.lua&quot;&gt;a simple self-contained luasmith pipeline for generating its README file&lt;/a&gt;.&lt;/p&gt;

&lt;/main&gt;
&lt;footer&gt;
  &lt;hr/&gt;
  &lt;section class=&quot;page&quot;&gt;
    &lt;p class=&quot;pub-label&quot;&gt;Written by &lt;a href=&quot;&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#99;&amp;#109;&amp;#115;&amp;#64;&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#46;&amp;#115;&amp;#99;&amp;#104;&amp;#101;&amp;#109;&amp;#101;&amp;#115;&amp;#99;&amp;#97;&amp;#112;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot;&gt;Jared Krinke&lt;/a&gt;&lt;/p&gt;
    &lt;p class=&quot;pub-label&quot;&gt;Published on &lt;time datetime=&quot;2025-04-22&quot;&gt;April 22, 2025&lt;/time&gt;&lt;/p&gt;
    &lt;p class=&quot;pub-label&quot;&gt;Last updated on &lt;time datetime=&quot;2025-08-22&quot;&gt;August 22, 2025&lt;/time&gt;&lt;/p&gt;
        &lt;ul&gt;
            &lt;li class=&quot;taxonomy&quot;&gt;Tags: &lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/../tags/lua/index.html&quot;&gt;#LUA&lt;/a&gt;, &lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/../tags/ssg/index.html&quot;&gt;#SSG&lt;/a&gt;&lt;/li&gt;
            &lt;li class=&quot;taxonomy&quot;&gt;Categories: &lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/../categories/schemescape/index.html&quot;&gt;Schemescape&lt;/a&gt;&lt;/li&gt;
            &lt;li class=&quot;home&quot;&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-theme-nara/luasmith/../&quot;&gt;Go Home&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
      &lt;/section&gt;
  &lt;hr/&gt;
  &lt;section class=&quot;site&quot;&gt;
    &lt;ul class=&quot;links&quot;&gt;
      &lt;li&gt;&lt;a href=&quot;https://codeberg.org/fita-slovo/luasmith-theme-nara&quot;&gt;Codeberg repo&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#102;&amp;#105;&amp;#116;&amp;#97;&amp;#45;&amp;#115;&amp;#108;&amp;#111;&amp;#118;&amp;#111;&amp;#64;&amp;#121;&amp;#97;&amp;#110;&amp;#100;&amp;#101;&amp;#120;&amp;#46;&amp;#114;&amp;#117;&quot;&gt;Contact the author&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Nara_(Oka)&quot;&gt;About the Nara river&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;Made with &lt;span class=&quot;heart&quot;&gt;❤&lt;/span&gt; for &lt;a href=&quot;https://codeberg.org/jaredkrinke/luasmith&quot;&gt;Luasmith&lt;/a&gt; users.&lt;/p&gt;
&lt;/section&gt;
&lt;/footer&gt;
</content>
</entry>
</feed>
