HTML generator for Emacs Lisp
You can find the code here: https://github.com/tonyaldon/jack.
To install it put jack.el
file in your load path and require jack
like this:
(require 'jack)
jack
provides the function jack-html
that takes a data structure
as input representing the HTML tree you want to generate and generates it
as a string.
For instance:
(jack-html '(:section (:div (:p "foo"))))
;; "<section><div><p>foo</p></div></section>"
HTML attributes are specified in a list starting by the @
sign
(jack-html '(:div (@ :id "id" :class "class" :style "color:red;") "foo"))
;; "<div id=\"id\" class=\"class\" style=\"color:red;\">foo</div>"
In the keyword defining the HTML tag you can use /
to declare its
id
and .
to declare its classes like this:
(jack-html '(:div/id.class-1.class-2
(@ :class "class-3" :style "color:red;")
"foo"))
;; "<div id=\"id\" class=\"class-1 class-2 class-3\" style=\"color:red;\">foo</div>"
Note that I would have prefered to use #
for declaring the id
but it
has to be escaped in keywords which is ugly.
Tag content can be lists of components:
(jack-html '(:ul ((:li "1") (:li "2"))))
;; "<ul><li>1</li><li>2</li></ul>"
(jack-html '(:ul (@ :id "id") ((:li "1") (:li "2"))))
;; "<ul id=\"id\"><li>1</li><li>2</li></ul>"
Components can be generated by a forms:
(jack-html `(:p ,(concat "foo-" "bar")))
;; "<p>foo-bar</p>"
(jack-html (mapcar (lambda (n) `(:p ,n)) '(1 2 3)))
;; "<p>1</p><p>2</p><p>3</p>"
Tag content can be forms:
(jack-html `(:ul ,(mapcar (lambda (n) `(:li ,n)) '(1 2))))
;; "<ul><li>1</li><li>2</li></ul>"
(jack-html `(:ul (@ :id "id")
,(mapcar (lambda (n) `(:li ,n)) '(1 2))))
;; "<ul id=\"id\"><li>1</li><li>2</li></ul>"
Tag content and attributes can be variables:
(let ((x "foo") (y "bar"))
(jack-html `(:p (@ :id ,x) ,y)))
;; "<p id=\"foo\">bar</p>"
(jack-html
(let ((x "foo") (y "bar"))
`(:p (@ :id ,x) ,y)))
;; "<p id=\"foo\">bar</p>"
If the variable jack-html-raise-error-p
is set to nil
, which is the
default value, jack-html
processes non component object as the empty
string.
Let's consider the case of the vector like [a b c]
that is not a
component for jack-html
.
We have
(let ((jack-html-raise-error-p nil))
(jack-html "foo" [a b c] "bar"))
;; "foobar"
and,
(let ((jack-html-raise-error-p t))
(jack-html "foo" [a b c] "bar"))
which raises the error:
Object '[a b c]' of type 'vector' can't be a component in 'jack-html'
If you want to read about its implementation, here are two articles: