Migrating to Quarto from Hugo
RIP to the clock boy but I’m different

If you haven’t visited my website in a while, you’re probably wondering why it looks a little different. The color scheme stayed mostly the same, but now I have dark mode, light mode, responsive design, and accessibility features. That’s because I rebuilt my site from the ground up using Quarto, an open-source technical publishing system for writing books, creating documents, and rendering websites.1 It’s a breath of fresh air compared to writing my own theme from scratch like what I did with Hugo.
Hugo now supports mathematics as of version v0.122.0, which voids one of the issues that I had with it. I’m still going to keep using Quarto though.
Quarto Markdown
First things first, let’s talk markup (or, more accurately, Markdown). I don’t program my website directly using HTML; instead, I write my posts in a markup language called Markdown and use a static site generator to convert them into HTML & CSS documents for my website.2 Markdown is super simple, but it but lacks tools for writing more specific documents like mathematical equations and advanced tables; hence, other markup languages & tools extend or wrap around it to support more advanced features.
R Markdown, for example, is an extension of the Markdown format that allows users to embed chunks of R code inside Markdown documents. R Markdown’s main attraction comes from its dependence on knitr and pandoc; both help convert documents from R Markdown to different formats like MS Word documents and PDF files. Julia & Python are supported in R Markdown thanks to third-party engines, but variables and functions in languages unpopular for data science aren’t preserved between code chunks. I like interlacing my code in between paragraphs of explanation, but not being able to save anything between code chunks made that impossible. The only workaround I could come up with was to restructure articles in these unpopular languages in such a way that the main part of the code was in one big block.
As someone who did tons of quick & dirty Python programming for school, I’m very fond of Project Jupyter’s Jupyter notebook .ipynb format, interactive documents with built-in read-evaluate-print loops. Unlike R Markdown, Jupyter notebooks are more language-agnostic; while Julia, Python, and R get first-class support, the format can be extended to less popular languages like Racket, Clojure, J, and Forth through third-party kernels. However, I don’t like how Jupyter notebooks are represented as JSON objects, because it makes them slow to debug and annoying to run version control on.
Quarto’s publishing ecosystem is maintained by the same company that makes the RStudio IDE and spearheaded R Markdown; it’s the next generation of R Markdown. Its .qmd format somehow combines the best of both Jupyter Notebooks and R Markdown with none of the drawbacks. Quarto Markdown can use either Jupyter kernels or knitr engines to interlace code chunks in Markdown documents, and it relies on its own pre-bundled version of pandoc for converting documents to other formats.
Transitioning from Hugo to Quarto
Building my website with Hugo wasn’t all for naught; it taught me a lot about how HTML websites are organized and how template files worked. But as I continued to use it, I noticed a glaring limitation that made it difficult for me to adapt into my article-writing workflow. While Hugo is highly configurable, it is not extensible; it’s designed to work out-of-the-box without the need for any external dependencies. While any user can customize its Markdown syntax with shortcodes, changing any of Hugo’s hard-coded configurations is impossible without forking it and editing its code directly. This issue reared its ugly head when I tried to make my math equations more accessible in my MathDoku MIP article. The LaTeX syntax for some equations used more complicated expressions with special characters like underscores and backslashes, so Hugo’s default Markdown renderer goldmark would add extra escape characters that both made them web-safe and broke compatibility with MathJax and KaTeX. While Hugo does have support for external Markdown renderers like pandoc, the quote-unquote “reasonable” arguments the Hugo developers chose when calling it don’t perform syntax highlighting. I didn’t want to trade syntax highlighting for accessible equation support.
I had already finished rewriting my technical documents in Quarto Markdown, so all Hugo did was act as an unnecessary middleman in my workflow. So, I decided that I was okay with relinquishing the more detailed controls for how my website is designed (and ways I could screw it up) if it meant that the end result will be both easier for me to use and more accessible for readers.
The biggest hiccup I had during the transition from Hugo to Quarto was restructuring my website. I have unfortunately committed the cardinal sin of changing my website’s URIs, since Quarto has no permalink support and I didn’t like having to sift through folders to find my blog posts. If I do change SSGs again, then I plan on preserving the “YYYY-MM-DD-slug” permalink format I’m using now, since it’s literally how my website is organized on my computer. There are also some color theming issues that I have to fix, but modifying Bootstrap and configuring Sass are both less overwhelming than CSS development.
I do miss Hugo’s insanely fast build speed. As Zach Leat demonstrates in his SSG benchmarking article, Hugo could render four thousand Markdown documents in less than a second. Quarto is orders of magnitude slower, since all the code in my documents gets re-executed every time the website is rendered on my computer.
Footnotes
Not to be confused with Quarto, a Python-based static site generator.↩︎
That’s one reason why I’m a member of the NeoSSG Webring!↩︎