A blog post about this blog itself.
Published on 5 Aug, 2025 · Updated 21 Aug, 2025
Coming up with the design
I've been wanting to set up a blog for several years now, but I didn't want to use a cookie-cutter template. I wanted to make a design from scratch that actually looked good to me. The problem is, I have no artistic talent for this kind of thing. Show me a design and I can probably tell you what looks good and what does not (at least in my opinion), but making one from scratch is, to say the least, hard.
So for the last two years, every time I came across a website and thought "This looks super nice!", I'd note it down it in a list. That list has become pretty long at this point, so I'll only mention the ones that I feel were the most influential: Adam Blank, Notes on Data Structures and Programming Techniques, Nota, Daemonic Dispatches, Urban Terror, Gwern.net, Satvik Saha, Tony Zorman.
Most of the people I've shown my website to so far, besides a few, don't seem to like the design as much as I do. But I'm biased. In any case, I like it, so I'm going to keep it as it is for now.
Reinventing the static site generator wheel for kicks
Since I was already doing the design from scratch, I figured I might as well do the static site generator from scratch too. I didn't want to fight my setup in case whichever one I picked would not do things exactly how I wanted. And how hard could a static site generator really be? Yeah, I keep falling for that one.
That said, I'm mostly done with the scripts I'm using to generate this site. It has most run-of-the-mill features you'd expect from a static site generator, even some extras like a font subsetting script.
I'm using Jinja2 as the templating engine and Mistletoe as the Markdown parser combined with python-frontmatter to parse, well, frontmatter. There were faster alternatives to Mistletoe, but the article about standards compliance in their documentation won me over.
There's also a live mode where only the requested pages are built on the fly. I started with Flask for this but transitioned to Quart later for the native websocket support, which is required to auto-reload the page when watchfiles or Quart's built-in reloader detects a change in the source files.
Markdown++
I've also added some additional syntax in my markdown posts.
Custom blocks
The following syntax can be used to add blocks of markdown with custom rendering:
::: block_type | arg_1 | arg_2 | arg_n
contents
:::
Substituting aside
in place of block_type
, asides can be rendered as visible on the right, or below this paragraph
if you're viewing on a smaller screen size.
The layout for asides is a bit wrong for now. It does not work for asides that are too close to one another, in which case they'll overlap. Also, an aside that is too close to the bottom of the page might overflow to the footer. For now, I'll just rely on myself as the author of the post to not reach those edge cases, because the fix I have in mind right now will require javascript. Something I'm trying to avoid for layout at least.
Code fences with arguments
Line numbers can be enabled on code fences by passing the linenos
argument to a code fence as below:
```python | linenos
import foo
print("bar")
```
which will render as:
1 2 3 | import foo print("bar") |
And you can even highlight some lines with the highlight
argument:
```python | linenos | highlight=[2, (6, 7)]
class Vector:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def __add__(self, other: "Vector"):
return Vector(self.x + other.x, self.y + other.y)
```
Output:
1 2 3 4 5 6 7 | class Vector: def __init__(self, x: int, y: int): self.x = x self.y = y def __add__(self, other: "Vector"): return Vector(self.x + other.x, self.y + other.y) |
The highlight argument uses relative numbering by default (relative to the line where the code fence begins). It is
possible to use absolute numbering as displayed in your text editor by passing absolute_numbering
.
I intend to work on asciidoc style "`smart quotes"`
next.
If you want more details, you can dig through the source repository. I've hardcoded some things here and there that I could have generalized but then what would be the point of writing my own scripts in the first place.
Do as I say, not as I do
Should've just used a cookie-cutter template with a prebuilt static site generator. Would've taken a lot less time. But having put in the work, I'm liking this setup so far.