I wrote my own site generator, it's called fsg. The s and g stands for Site Generator. I'll leave it to the creativity of the reader to figure out what the f stands for. It took a weekend. It's written for myself and by myself, so it doesn't have many bells and whistles, but it does what I need.

I don't put as much content on this site as I think I should. Most of the time I just update my resume whenever that needs updating. Despite that, every single time I've updated this site I've ran into issues with Hugo, which is the static site generator I use. Or did use, I should say. See, I update my site rarely enough that I generally forget which version of hugo I was using. So every time I download the latest, naively thinking that it'll be fine. Every time I have to spend a day fixing it, dealing with various changes in the framework.
Lately I've been telling myself that at least a part of the reason I haven't been putting more stuff on here is because of frustrations with the site generator situation, which brings us to the present.
There's really only a couple things I wanted out of fsg. It doesn't need to be able to deal with particularly large websites. I don't mind writing the posts in html. All I really need out of it is a way to specify a template or a couple different templates to use for the different pages, and to generate different lists of posts on the front page and the full blog list. For a while I was considering just going back to doing it the way I first learned to make websites and duplicate each page's html entirely and just deal with the hassle of updating menus and site layout changes across all pages. Instead I chose the road of procrastination, until a conversation on twitter prompted me to think about it for a bit and I had one of those classic "y'know what, I could probably knock that out in a weekend". And then I did.
The results are available at https://github.com/grouse/fsg. Alongside the generator in fsg.cpp the repo also contains the source asset files, which are intentionally vanilla html files with a bit of custom syntax in html comment blocks which are parsed by the generator in fsg.cpp to correctly insert page titles, look up templates, static pages, etc. It also has a server mode that opens a socket on port 80 and serves the generated site back. And it has file watches on the source asset to automatically re-generate the site as the source assets change.
There are definitely a bunch of improvements that could be made in the site generation part, but most of them would be so marginal an improvement I doubt I'll ever bother. The only thing I am likely to do on that end is auto-escaping the contents of code blocks, because that would be trivial to do and because it has already been a bit of a headache to ensure symbols like <
don't break the code block. The other thing is figuring out a way for the webserver to keep the socket open to the browser and push new data on it whenever the site is re-generated, or in some way make the browser re-request the same page when its source assets change. That one I'd be inclined to actually solve if writing becomes more of a habit. It's also very wasteful in what it has to re-generate when things change, and there are probably a bunch of memory-leaks, and I don't care about either at all; it re-generates the site faster than I can look over to the browser window and the webserver just will not be running long enough for memory to ever become a problem.
I'm not really gonna say anything more about details of the implementation of fsg. It's really not all that interesting. It's just my little tool that I wrote in a spare weekend for my own needs, and what I ended up with is simply what I ended up with following the process of implementing the most straight forward, simplest solution to each problem as I came across them, step by step. That process is something I find much more interesting and valuable, and so that's what I'll be ending this post talking about.
I enjoy writing things from scratch, mostly or entirely without libraries. Definitely without frameworks. It allows me to learn things at a deep level which is usable in the future to a much greater degree than some trivia knowledge about how to massage some framework into doing what you need, and it gives me opportunity to practice the fundamentals - every time I write a lexer it gets a little better and I get a little faster at writing it. I think we all just need to invent the wheel a bunch of times before we actually arrive at a wheel that works well. It also just doesn't take as long as many seem to think - if you limit yourself to solving the problems that you actually need to solve. Programmers trying to solve the imaginary problem of tomorrow and making their solutions more general happens far too often, which inherently leads to a solution more complex than required. When applied to a personal tool, you might be surprised how simple things end up.
By the way, did you know that the earliest archeological find of a wheel is a potter's wheel? I should say we're lucky our ancestors re-invented that wheel a few times to get to wheels for flour mills, trolleys, carts, and carriages before they got to the smooth, rubberised wheels of the modern car.