summaryrefslogtreecommitdiff
path: root/macros.lisp
blob: 09b59f4e185137198198882a25af89e13e367c17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
;; Parenscript shortcut
(defmacro script (&rest body)
  "Macro expanding to (:script (:raw (ps body))). Great for embedding JS inside page."
  `(list :script 
         (list :raw 
               (ps ,@body))))

;; Templating macros
;; TODO needs to be moved to another file
(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."
  `(values
    (mu ,name " " ,attrs)
    ,@(mapcar (lambda (x) `',x) body)
    (mu "end")))

(defmacro muif (condition do do-else)
  `(mublock "if" ,condition 
     ,@do
     ,@(when do-else
         (concatenate 'list 
                       (list (mu "else"))
                       do-else))))

(defmacro muwhen (condition &rest do)
  `(muif ,condition ,do nil))

(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)))