This package simplifies the creation of an HTML DSL using S expressions, inspired by the common Lisp library CL-who.
Its primary goal is to facilitate sharing HTML snippets between libraries, with compatibility as a key focus.
On another note, this library is exceptionally easy to write and
illustrates the usefulness of the pcase
function in Emacs Lisp for
manipulating lists.
- https://github.com/philjackson/xmlgen
Is an excellent package and very similar to the syntax of
el-who
, you can use that if you’re not interested in compatibility betweencl-who
andel-who
. The main difference between the two is that inel-who
s-expressions like(concat "hello" " " "world" )
, i.e., where the first element of the list is a symbol and not a keyword, are evaluated by the emacs-lisp evaluator.In the case of
xmlgen
this would be interpreted as<concat>hello world</concat>
which in
el-who
would be(:concat "hello" " " "world")
.
Explanation of the algorithm is as follows TODO
Check the tests for more examples but here are a couple:
(let ((title "Some title"))
(el-who
`(:html
(:head
(:meta :charset "UTF-8")
(:meta :name "apple-mobile-web-app-capable" :content "yes")
(:meta :name "viewport" :content "width=device-width, initial-scale=1")
(:title (identity title))
(:script :src "https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js")
(:script :src "https://unpkg.com/[email protected]")
(:script :src "https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js")
(:link :rel "stylesheet"
:type "text/css"
:href "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css")
(:link :rel "stylesheet"
:type "text/css"
:href "https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css")
(:body
(:h1 "Hello World")
(:p "Fusce suscipit, wisi nec facilisis facilisis, est dui fermentum
leo, quis tempor ligula erat quis odio.")
(:div
(:ul :class "list"
(:li "Nam euismod tellus id erat. ")
(:li "Nullam rutrum. ")
(let ((name "📘 el-who"))
(cl-loop for i below 3
collect `(:li :id ,i
(format "%s 🍏 %s" ,i ,name)))))))))))
This showcases some https://edicl.github.io/cl-who/ compatibility.
The function el-who-cl-who
performs the following substitutions
who:fmt
⇒format
who:str
⇒identity
who:htm
⇒el-who-htm
loop
⇒cl-loop
(let ((deck "🍎 Deckoration"))
(el-who-cl-who
`(:div :class "card w-100"
(who:fmt "The %s" deck)
(:div :class "card-footer"
(:form :method "POST"
:action "/grade"
(:input :name "card-id"
:value deck
:class "d-none invisible")
(:span :class "badge fs-7 bg-secondary"
(who:str deck))
(:div :class "btn-group float-end"
(loop for i below 5
do
(who:htm (:button :class "btn btn-primary"
:value i
:name "grade"
(who:str i))))))))))