diff options
| author | eltrac <hi@eltr.ac> | 2026-08-29 12:04:10 +0800 |
|---|---|---|
| committer | eltrac <hi@eltr.ac> | 2026-08-29 12:04:10 +0800 |
| commit | 186818c2c5cbb65a993fc152dc3f1b60c81a3c98 (patch) | |
| tree | d63b1af39c8c98b1b8f65ff5a23e2f1ca3c98e19 | |
| parent | 8b6ff1a1a65b1d3c4356842a01e530a3eb774100 (diff) | |
macros: templating macros
mustache syntax
if, when blocks
chaining properties
define variables
| -rw-r--r-- | macros.lisp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/macros.lisp b/macros.lisp index 85f2c9d..0245fdb 100644 --- a/macros.lisp +++ b/macros.lisp @@ -4,3 +4,53 @@ `(list :script (list :raw (ps ,@body)))) + +;; Templating macros +(defmacro mu (&rest body) + "Macro writing Mustache syntax, namely the '{{ mustache }}'" + `(list :raw (concatenate 'string "{{ " ,@body " }}"))) + +(defun keyword-to-chain (string-or-keyword) + (if (keywordp string-or-keyword) + (concatenate 'string "." + (-> string-or-keyword + symbol-name + string-downcase)) + string-or-keyword)) + +(defun muc (&rest chain-of-props) + "Shortcut chaining props in a mustache" + (mu (reduce (lambda (a b) + (concatenate 'string + (keyword-to-chain a) + (keyword-to-chain b))) + chain-of-props))) + +(defmacro mublock (name attrs &rest body) + "Macro writing a block where a '{{ end }}' is followed." + `(list + (mu ,name " " ,attrs) + ,@(mapcar (lambda (x) `',x) body) + (mu "end"))) + +(defmacro muwhen (condition &rest body) + `(mublock "if" ,condition ,@body)) + +(defmacro muif (condition do do-else) + `(muwhen ,condition + (values ,do) + (list :RAW (mu "else")) + (values ,do-else))) + +(defun quote-if-string (str) + (if (stringp str) + (concatenate 'string "\"" str "\"") + (write-to-string str))) + +;; TODO support function calls as values +(defmacro mudefvar (var val) + `(mu "$" + (string-downcase (symbol-name ',var)) + " := " + (quote-if-string ,val))) + |
