the one correct templating language
2020-06-17
Contents
- Background
- Exposure
- First Steps
- Catalyst
- Adoption
- Conclusion
Background
m4 is a macro processor, in the sense that it copies its input to the output, rising macros as it goes
https://www.gnu.org/savannah-checkouts/gnu/m4/handbook/m4-1.4.18/m4.html#Preliminaries
m4 is a core gnu utility, and is installed by default on most *nix systems. Every particular individual that I’ve encountered, in point of fact. Including macOS.
I procure in tips myself a barely serious relate line nerd and am accustomed to sed
, awk
, grep
, carve
, variety
, tr
, and so forth. But I had by no methodology heard of this macro processor. It looked very mysterious and imprecise when I first encountered it.
Exposure
I’m now not 100% when and the put I first encountered m4. It totally may well well beget been in the colophon of technomancy.us the put the creator boasts that the entire dwelling is “printed through GNU M4, rsync, and a 12-line Makefile,” which used to be vast magnificent to the minimalist in me.
I then be unsleeping reading Notes on the M4 Macro Language on my phone in the airport lounge on my ability off to vacation somewhere, attempting to learn more about this mysterious little program that has been below my nostril this entire time.
Later I found apostl on github, a miniature wrapper for m4 with the purpose of with out utter at the side of partials in your HTML. This used to be an application that resonated with me: a 0 overhead, framework-free strategy of modularizing HTML for of us like me who steady beget to jot down static stammer material with no additional instruments or bloat.
Lastly I will abstract out my header, footer, and nav parts, and consist of them the put ever I want.
First Steps
What I wished from m4 used to be as a intention to tumble an consist of(nav.md)
and an consist of(footer.md)
in my markdown and introduce somewhat of bit of modularity into my workflow.
I did this for a hot minute, and it used to be vast. I had expandable macros embedded in my markdown. I’ll well well pipe each markdown file thru m4 to boost it, after which pipe the assembled markdown thru pandoc to assemble an HTML page.
It used to be glorious.
Besides for, I couldn’t abet the feeling that it ought to be better. I was silent doing lots of things by hand like updating the “all posts” page of my blog. And I had the sneaking suspicion that things may well well rating intention more programmatic if I’ll well well greatest fully remove the aptitude of these macros.
Tranquil, it used to be steady adequate.
Catalyst
Unless it wasn’t.
The catalyst for corpulent adoption, for a deep dive into the aptitude of m4, came from something I by no methodology idea I’d ever glimpse.
I started attempting to blog on my new pinebook. This arm64 machine now not greatest didn’t beget pandoc installed, but pandoc wasn’t even in the application repository. I idea of as compiling it myself, but the language it’s written in, Haskel, doesn’t even collect on arm64.
The component I idea I’d by no methodology glimpse is a computer with no pandoc.
So I started down the path of looking out down all markdown from my blog, resigning myself to writing HTML. And I at remaining reversed that option due to I abominate writing HTML that a lot, and went motivate to writing markdown all once more and merely the utilization of a markdown to HTML converter that isn’t pandoc.
Pandoc is definitely overkill for steady converting markdown to HTML. I don’t need a swiss military knife. I need a butter knife.
But between looking out down markdown and inserting it motivate, I spent an afternoon with Technomancy’s makefile and m4 scientific doctors, and surely started to fancy.
Adoption
The essential component I surely overlooked about losing pandoc used to be atmosphere metadata in the YAML frontmatter.
Easy fix, even when. That every particular person modified into macro definitions on the live of the doc:
clarify(__timestamp, 2020-06-17)dnl
clarify(__title, `m4')dnl
clarify(__subtitle, `the one correct templating language')dnl
clarify(__id, 9)dnl
Then the stammer material will get sandwiched between the includes that I first fell in like with:
consist of(src/header.html)
markdown markdown markdown
consist of(src/footer.html)
And the motive that works so well is–and I by no methodology idea I’d ever hear myself mumble this–thanks to the not most likely thing about global inform!
Any macro you clarify in Relate A is supplied to Relate B if you happen to consist of Relate B from Relate A.
So the title, subtitle, and so forth is supplied to header.html on this case. The put I will region
in the head and tumble an
in the body, very like pandoc did.
Lastly, I learned to swap the default quote strings. Because when writing markdown corpulent of code blocks
, it merely does now not attain to beget m4 attempting to escape a string each time it encounters a backtick.
So now a blog put up looks as if this:
clarify(__timestamp, 2020-06-17)dnl
clarify(__title, `m4')dnl
clarify(__subtitle, `the one correct templating language')dnl
clarify(__id, 9)dnl
consist of(src/header.html)
changequote()dnl Or else `code blocks` confuse m4
markdown markdown markdown markdown
changequote`'dnl swap quotes `motivate to default'
consist of(src/footer.html)
Now right here are two things I lifted straight from Technomancy: populating the “All posts” list, and auto-populating the rss feed.
Here’s implement a “countdown” for loop in m4, straight from Notes on the M4 Macro Language with minor adjustments:
clarify(`for',`ifelse($#,0,``$0'',`ifelse(eval($2>=$3),1,
`pushdef(`$1',$2)$4`'popdef(`$1')$0(`$1',decr($2),$3,`$4')')')')
Mistaken, comely? m4 is vast for macros and includes. Now not vast relaxing for frequent programming. But, like immigrants, it will get the job accomplished.
So now “all posts” and rss.xml can each, with the introduction of one “LATEST” variable outlined in the Makefile (which tells the macros what number of recordsdata there are in entire), iterate over the entire recordsdata and cargo them, diverting their output to a throwaway register but maintaining their macro definitions. So it’s that it’s most likely you’ll well perhaps also deem of to yank the title and timestamp from each put up, as an example, and spit them out into the list of all posts. Like so.
The final bit of cleverness that I borrowed from Technomancy used to be to beget header.html and footer.html both, reckoning on the precense of a “__feed” macro passed in by the Makefile, wrap the put up up in an HTML doc for the blog or an XML doc for the feed. Like so.
Conclusion
m4 isn’t very most likely for rapid macro growth and for at the side of recordsdata.
But it surely speedily becomes vast unwieldly if you happen to want, mumble, to implement a for loop or attain a lot of the rest programmatic in any appreciate.
It is subtle to debug. I speedily found my default habits when encountering something surprising is to steady enlarge the escape quotes round something. That in general fixed it.
That acknowledged, it’s an gripping language, and I found it rewarding to learn and work with, and I’ll potentially attain for all of it once more if I surely beget the chance to.
I’m perfectly relaxed with the present inform of writing for this blog. I surely feel like I’m 90% of the ability there to my normal imaginative and prescient of “gross markdown with includes,” and the additional m4 doesn’t surely distress me in the slightest. It’s silent surely trim, with nearly the entire complexity and grotesque stuff moved faraway from the put I write into auxiliary recordsdata.