Skip to content

A s-expression html DSL library compatible with cl-who

License

Notifications You must be signed in to change notification settings

alejandrogallo/el-who

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

el-who: a HTML DSL compatible with cl-who

Introduction

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.

Similar projects

  • 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 between cl-who and el-who. The main difference between the two is that in el-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").

Algorithm

Explanation of the algorithm is as follows TODO

Example

Check the tests for more examples but here are a couple:

1 A simple case

(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/htmx.org@1.9.10")
      (:script :src "https://cdn.jsdelivr.net/npm/jquery@3.6.3/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/font-awesome@4.7.0/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)))))))))))

2 cl-who compatibility

This showcases some https://edicl.github.io/cl-who/ compatibility. The function el-who-cl-who performs the following substitutions

  • who:fmtformat
  • who:stridentity
  • who:htmel-who-htm
  • loopcl-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))))))))))

Releases

No releases published

Packages

No packages published