The fresh new videah.net

It’s an unfortunate fact of life that every tech-savvy person who writes any kind of long-form content is born with an evil curse that compels them to spend more time coming up with increasingly complex byzantine blogging engines than actually writing any blog posts that use them. It’s been well over a year since my last written post, which means it’s time to deploy the latest iteration! The twist this time is it actually ends up replacing two websites.

Yes! My blog and personal site are now one and the same. The old terminal-style site was cool for the time, but I think it’s now a bit overplayed and was very limiting. Who the hell wants to type to navigate a website? Especially on mobile, oh man!

Feel free to look around, if you have any feedback on the new design I’d love to hear it!

For fun silly things I recommend checking out my 3D model display or going to the homepage and clicking on my pixel art nose.

Out with the Markdown

The old blog used Zola to generate HTML from some Markdown. It’s as nice as static Markdown site generators get. But over time I couldn’t escape the feeling that Markdown was leaving something to be desired. I think the simplicity of Markdown ends up getting in its own way a bit. I grew to hate writing Markdown.

I found myself repeatedly trying to work around its limitations using Zola’s shortcode system which lets you inject some custom HTML components. These are just hacky macros at the end of the day though, they’re not very ergonomic and you can’t do anything crazy with them.

This new website on the other hand is written in Typst, a modern markup language intended to replace LaTeX for document writing. I’d used it in the past to write my resume when I was applying for a job so I already had some good experience with it. When I noticed they were adding HTML support as a build target, I got really excited! It’s not fully mature yet but with the help of some plumbing from Rheo I think it’s crossed the threshold as just an all-round better alternative to writing Markdown.

How about some examples?

I think it would help to show off some of the code powering the site to give you a good idea of what it’s capable of. Starting off simple, the fursona callout box further up the page is a reusable component that I can call anywhere in the document like so:

#sticker-callout("poggers", side: "right", flush: true)[
  The old site and blog are not completely gone!
]

Which I think is just a really nice and simple syntax for that kind of thing.

Then consider this snippet of code from /elsewhere that takes a list of my social media accounts and renders them as a list of links:

#let accounts = (
  ("GitHub", ("https://github.com/videah", "@videah")),
  ("YouTube", ("https://youtube.com/@videah", "@videah")),
  ("Bluesky", ("https://bsky.app/profile/videah.net", "@videah.net")),
)

#let me-link(url, body) = html.elem("a", attrs:
  (href: url, rel: "me")
)[#body]

= Accounts
#list(..accounts
  .pairs()
  .sorted(key: ((name, _)) => lower(name))
  .map(((name, (url, handle))) => [#name: #me-link(url, handle)]))

This lets me easily add new handles and have it automatically render a list in alphabetical order. No need to maintain the order manually. This is all done in-line in the Typst document alongside written content. Cool right?

We can also pull off some more advanced stuff, like this snippet that helps transform all native emoji to the custom Mutant Standard emoji I use on the site:

#let mutant-transform(doc) = {
  show raw: it => _untransformed(it)
  show _emoji-re: it => context {
    let cps = it.text.codepoints().map(c => c.to-unicode())
    let key = cps
      .filter(c => c != 0xFE0F)
      .map(c => str(c, base: 16)).join("-")

    if no-emoji-transform.get() or key not in _index.seq {
      it
    } else {
      mutant-emoji(_index.seq.at(key), text: it.text)
    }
  }
  doc
}

This is great because it means we don’t need to do any JavaScript runtime transformations like Twemoji does, this is all done at compile time! 🥰

This seems like a lot… is it a lot?

The appeal here is Typst can be as simple or complex as I need it to be. I can just write posts normally and reach further down to the more programmatic stuff when I feel like it and have it all work seamlessly in a single plain-text document file.

This doesn’t even touch on the future potential this unlocks! Like writing once and having it spit out PDFs and EPUBs alongside the HTML output, which I’ll likely be using in the future for my resume.

You can read a little more about the tools powering this site at /colophon.