It's a good idea to reduce templating languages into a simpler form, I'll agree to that, but the issue here is that you still need loops and data input.<p>For example, the test script has a 'li' function but <li>s are list <i>items</i> and they reside, usually more than one, inside <ol> or <ul> elements. At the very least, there should be a way to take some form of data file (list of blog posts and nested metadata) an iterate over it. Otherwise you're just writing whatever markup you want as the output, with an additional layer, and nothing of added value.<p>Otherwise what, template the slisp in Jinja too?
While Lisp is my preferred normally my go-to language, tbh I think sed or awk are probably adequate and, already being installed, probably in some sense “better”.<p>That being said, thanks for posting this; it made me think.
Seems similar in spirit to Lips, a pre-processor which can evaluate Lisp and splice it into the output (Common Lisp <a href="https://github.com/zc1036/lips">https://github.com/zc1036/lips</a> or Scheme <a href="https://github.com/rbryan/guile-lips">https://github.com/rbryan/guile-lips</a> )
I am not happy with the "joke" in the README and if I could I would report it but it looks like it doesn't fall into Github categorization of abuse. Keep your bad jokes to yourself, inside your head, where nobody can see them.
Based on the rationale given I think the author could have used GNU m4. While I'm definitely not fond of the syntax, it can get the job done. I don't think many (if any) projects use it (excluding autoconf).<p>Here's the manual on one page <a href="https://www.gnu.org/software/m4/manual/m4.html" rel="nofollow noreferrer">https://www.gnu.org/software/m4/manual/m4.html</a><p>An m4 example, similar with the snippet within the README<p><pre><code> define(`foo', `$1' `$2')
foo(hello, world)
define(`bar', hello)
foo(`bar', world)
esyscmd(`./executable-path')
esyscmd(`cat /tmp/file')</code></pre>
There is a port of the CL-WHO HTML templater or TXR Lisp called TL-WHO.<p>It has a <i>deftag</i> macro for defining new tags.<p><pre><code> $ txr -i tl-who.tl
If you get your macros hot enough, you get syntactic caramel!
1> (in-package :tl-who)
#<package: tl-who>
</code></pre>
We can define :atag, which destructures the first two items of its body as url and class:<p><pre><code> 2> (deftag :atag other-attrs (url cls . body)
^(:a :href ,url :class ,cls ,*other-attrs ,*body))
#<interpreted fun: lambda (#:g0203 . other-attrs)>
</code></pre>
Then use that in the definition of :page:<p><pre><code> 3> (deftag :page () (url . body)
^(:atag ,url "pages" ,*body))
#<interpreted fun: lambda (#:g0217 . #:g0232)>
</code></pre>
So now that we have :page, wrap that in :li:<p><pre><code> 4> (with-html-output (*stdout*)
(:li (:page "./writing" "My writing")))
<li><a href='./writing' class='pages'>My writing</a></li>
</code></pre>
TL-WHO, like CL-WHO, compiles the with-html-output form into something that uses constant string literals that are as long as possible. It closes all your tags, HTML-escapes what has to be escaped and can pretty-print with indentation.<p>Code can be freely used: attributes and tags are distinguished by virtue of being Lisp keywords. Anything that is not a keyword is evaluated as code.<p>Only when code produces a string is that string interpolated into the output, making it possible to write code with useful side effects and no HTML output, by not returning a string.<p>Side-effecting code can explicitly write into the HTML stream; the output will go to the right place in the generated HTML:<p><pre><code> 5> (with-html-output (*stdout*)
(:div :class "foo"
(:pre (:code (sh "ls -l /etc/a*.conf")))))
<div class='foo'><pre><code>-rw-r--r-- 1 root root 3026 Dec 16 2019 /etc/adduser.conf
-rw-r--r-- 1 root root 433 Oct 1 2017 /etc/apg.conf
-rw-r--r-- 1 root root 769 Apr 4 2018 /etc/appstream.conf
</code></pre></div>
</code></pre>
Note that the output of "ls -l" isn't being HTML escaped; this example just shows how something can write to the stream as an alternative to interpolation, not that it's a good idea to dump ls -l into that HTML stream.
Have you thought about adding car, cdr, and cons? You wouldn't need to shell out to subprocesses if you had the full list of minimal lisp primitives.<p>Technically you also need cond, eq?, and pair? (because car and cdr only take pairs not symbols).