I’m occasionally asked how I put my site together. In short, AsciiDoc and MathJax. And for the pages that run code, mostly Haste.

On some pages, there’s an Easter egg of sorts. Replace html with lhs in the URL to see its source:

Other times, the secret extension is txt, such as the source of this page:

I have a few public repos containing the source of entire subsites, such as:

Those who can’t, do anyway

I’m neither a frontend engineer nor a web designer, but I find what I do works well enough.

I write best with a text editor using old-school text file and email conventions, such as minus signs or asterisks for list bullet points, and LaTeX notation for equations. The minimalist distraction-free environment makes me want to churn out line after line. Or maybe it subconsciously reminds me of long and glorious coding sessions, of heated debates on mailing lists, and of rushing to meet thesis deadlines, and I just go with the flow.

AsciiDoc turns classic text file flourishes into pretty HTML, and MathJax turns LaTeX into pretty equations rendered with JavaScript. I first encountered AsciiDoc when looking at Git documentation, and I wound up choosing it over its competitors for the same reasons Linus Torvalds did: it’s fairly well-defined and powerful, yet the source resembles the text files I once downloaded from BBS’s and studied on a 80x25 character terminal. (Though one annoyance is dealing with tildes in URLs, like on this very page.)

A custom script named stitch automates building pages, and can be found in my homebrew Haskell compiler repo, which was the first subsite to use it. It deals with things like CSS; Google Analytics; including a menu HTML file if appropriate. This lets me achieve my ideal workflow: type, type, type, run script, type, type, type…​

The Upgrade Treadmill

There was a time I wrote HTML by hand. Some old files may still lurk in dark corners of this website.

For mathematical symbols, I first used itex2MML, which defaults to LaTeX delimiters, that is, dollar signs for inline equations and backslash-square brackets for display equations.

I migrated to AsciiDoc with MathJax, which uses different delimiters, so for backwards compatibility, I wrote a fragile script (cobble) so I could avoid converting my old files and keep my old habits.

Then the original Python version of AsciiDoc was deprecated in favour of Asciidoctor, which introduces yet more changes. I decided backwards compatibility was a lost cause, and committed to migrating my site’s source files rather than cling to my old script.

The migration is partial and imperfect, so for example, some equations might appear strange because they have been wrongly delimited. Or text meant to be italic will instead appear in single quotes.


I did keep one idiosyncracy. Like its predecessor, the stitch script changes LaTeX-style code blocks (\begin{code} and \end{code}) into AsciiDoc code blocks, so that the same file can serve as a Haskell program as well as a webpage documenting the program.

Older pages used the the Haste compiler to compile the Haskell featured on a webpage to produce JavaScript that demonstrate it, such as a Tic-tac-toe player using minimax search with alpha-beta pruning. Conditional compilation lets me run the program locally as well as on the browser. Sadly, the Haste compiler seems to have been abandoned.

The Asterius compiler is a promising alternative. Asterius compiles to WebAssembly, which may mean better performance. Asterius worked well for a first-order logic theorem prover which Haste was unable to handle.

Last and least are my own compilers. Though primitive, they produce small WebAssembly binaries. It can compile Haskell on the browser and run it and I’m proud it could handle an experimental PuzzleScript interpreter. Even though my compiler performs few optimizations, some of the interpreted games are playable. (Or perhaps it’s because modern machines and WebAssembly engines are so fast!)

Ben Lynn 💡