Blog

| Hello, World!

Erekose Craft

A new adventure begins~

Along with a whole new site design, I am now officially opening my tech blog!

I had been exploring options to get started with the blog for a while, but kept getting side-tracked or busy…

For 4 years — Whoops.

I had looked into using Tumblr, but they have limits to their templates and inline styling that would prevent me from customizing things to the extent I want - like for code block syntax highlighting. I was going to use Github Pages with Jekyll, but I’m not a fan of the Jekyll template syntax - and hosting on Github is also limiting. Running Jekyll locally on my box to statically generate the pages is also plausible, but that involves installing the Ruby language runtime on Windows and that’s an obtuse process. All of the template engines for Express.js have their own weird Domain Specific Languages (DSL) and limitations - some don’t work with newer CSS / HTML standards, for example.

Everything has tradeoffs, and much of it reflects problems I have with development in general. Like overcomplicating processes, or creating scenarios where you need to interface with a dozen different languages.

I wanted something simple and minimally invasive. I didn’t want to install a language runtime or learn a whole new language and syntax to generate HTML - especially with generators that might not support the newer standards. I could use markdown for my blog itself, but that still needs to know how the content fits within my website layout.

In the end, I made the awful decision to make my own static site generator. In C++.

Huge Mistake

Without proper tooling, and with iffy standard library features like the filesystem API, getting things to work as needed was a headache.

I really wanted to use C++20 modules, even though they’re barely supported - and it was only very recently that Visual Studio stopped highlighting everything as errors. (It still falls apart frequently) So that slowed everything down.

And then there’s the usual dependency management headache with C++ - I tried to avoid it as much as possible, but trying to create everything from scratch, including a markdown parser, became too much. So then I lost a good amount of time to trying to link against a C markdown library that isn’t supported on the package manager I use (VCPKG). To be fair, even if it was there, it probably still would be a nightmare - because that’s just the tooling experience here.

I also underestimated the amount of work required for even a minimum viable site generator. There is a ton more logic and use of loops than I had considered. In the end, I very nearly created an entire scripting language. At the least, I have a bare-bones single expression parser - including function calls, variable lookups, and math expression precedence ordering.

All that said…

Behold, the Results of my Suffering:

  1. <body>
  2. <!--meta:content-->
  3. <section>
  4. <!--meta:for each="posts"-->
  5. <article>
  6. <!--meta:shortContent-->
  7. <!--meta:if condition="isShortContent"-->
  8. <p>Read More</p>
  9. <!--meta:/if-->
  10. <a href="../post/<!--meta:var name="addressFileName"-->.html">Link</a>
  11. <!--meta:var name="datePosted"-->
  12. </article>
  13. <!--meta:/for-->
  14. </section>
  15. <ul class="pagination">
  16. <!--meta:if condition="pageIndex-pageStride/2 > 0"-->
  17. <li><a href="./<!--meta:write format="{:0>5}" value="firstPage"-->.html">&lt;&lt;</a></li>
  18. <li>...</li>
  19. <!--meta:/if-->
  20. <!--meta:for start="min(max(pageIndex-pageStride/2, 0), max(pageCount-pageStride, 0))" end="min(startIndex+pageStride, pageCount)"-->
  21. <!--meta:if condition="index != pageIndex"-->
  22. <li><a href="./<!--meta:write format="{:0>5}" value="index"-->.html"><!--meta:write value="index+1"--></a></li>
  23. <!--meta:else-->
  24. <li><span><!--meta:write value="index+1"--></span></li>
  25. <!--meta:/if-->
  26. <!--meta:/for-->
  27. <!--meta:if condition="max(pageIndex-pageStride/2, 0) + pageStride < max(pageCount, pageStride)"-->
  28. <li>...</li>
  29. <li><a href="./<!--meta:write format="{:0>5}" value="lastPage"-->.html">&gt;&gt;</a></li>
  30. <!--meta:/if-->
  31. <li></li>
  32. </ul>
  33. </body>

What I was aiming for was something that would fit in with regular HTML - so embedding it in comments like this makes sense. This allows for mixing in with any HTML standard without having to ensure support like you would with another DSL. It also gives semi-free syntax highlighting in existing editors, plus error tolerance (worst case: non-obviously visible comments end up getting downloaded to visitors clients instead of a totally malformed page).

I think it’s at a good enough point now to use, hence the fact I’m currently using it to generate this whole site~ although it is definitely not at a “shareable” state. Maybe one day I’ll get it there, but until then, we have posts!

Of course, writing my own offline template engine has its own merits and demerits - like everything else I evaluated. That said, I feel like the benefits outweigh the problems - especially now that it’s at a stable point. Whenever I need a new feature, or want to expand the flexibility of it, I can! That does mean I end up pouring time into maintaining the template engine in addition to using it, but I have the internals to a point where it’s super easy to work with.

For instance, adding a new meta:tag type is just:

  1. context.RegisterTagBuilder("calc", [](const TagNode& calcTag, TemplateContext& calcContext) -> std::string
  2. {
  3. if (const AttributeValue* const valueAttribute = calcTag.FindAttribute("value"))
  4. {
  5. double result = Expression::ParseAndExecute(valueAttribute->GetAsString(), calcContext).value_or(0);
  6. return std::format("{}", result);
  7. }
  8. return {};
  9. });

That is an actual, functional tag for <! --meta:calc value="1+1"--> (which will output 2).

I could keep going, but this is turning into a paper. n_n' There are plans in the works for the next few blog posts, so I hope y'all look forward to it! (RSS and Atom feeds are Coming Soon™)

Until next time~

Newer: We Have RSS Here
©2023 AirAKose. All Rights Reserved.