Source

pico-org / picostache.l

Full commit
Joe Bogner da42eb2 






































































Joe Bogner 58c62c7 
Joe Bogner da42eb2 
































# picostache.l Tiny mustache template implementation
# (c) 2012 Joe Bogner 
# https://bitbucket.org/joebo/picostache/

(default *DELIM_S (chop "{{") *DELIM_E (chop "}}"))

(de lookup (Key Model)
	(cdr (assoc Key Model)))

(de context (View Key)
    (setq Func (lookup Key Model))
    (if (pair (fun? Func))
        (Func View)
        (if (= Key ".")
            View
            (lookup Key View) ) ) )

(de section (View Key Rest Inverted)
    (setq Func (lookup Key Model))
    (if (pair (fun? Func))
        (link (Func (pack (make (render View Rest)))))
        (setq Subview (context View Key))
        (ifn Inverted 
            (for X Subview (render X Rest))
            (if (not Subview) (render X Rest) ))))

(de render (View Tree)
    (for X Tree 
        (case (car X) 
            (Name (link (context View (cadr X))))
            (Text (link (cdr X)))
            (Section (section View (cadr X) (cddr X)))
            (NonSection (section View (cadr X) (cddr X) T)))
        (if (pair (cadr X)) (render View (cdr X))) ) ) 

(de renderTree (View Tree)
    (pack (make (render View Tree))) )

(de renderHtml (View Html)
    (renderTree View (parse Html)) )

(de headUntil (Lst Delim)
   (make  
        (let DelimLen (length Delim)
            (for (C Lst C (cdr C))
                (ifn (= Delim (head DelimLen C))
                    (link (car C))
                    (setq C NIL) ) ) ) ) )  

(de addCell (Type Cell Force)
    (when (or Force (<> CurType Type)) 
        (if CurType (queue RootPtr (list CurType (pack (reverse Cur)))))
        (when (or (= CurType "Section") (= CurType "NonSection")) 
						(push 'Levels (last (car RootPtr)))
            (setq RootPtr (list (last (car RootPtr)))))
        (setq CurType Type)
        (setq Cur NIL) )
    (push 'Cur Cell))  

(de parse (Html)
    (setq Root (list))
    (setq RootPtr Root)
    (setq Cur NIL)
		(setq Levels NIL)
    (for (C (chop Html) C (cdr C))
        (ifn (= *DELIM_S (head 2 C))
            (addCell 'Text (car C))
            (let (TokenStart (nth C 3) Token (headUntil TokenStart *DELIM_E))
                (case (car Token)
                    ("#" (addCell 'Section (cdr Token) T)) 
                    ("~" (addCell 'NonSection (cdr Token) T)) 
                    ("/" (addCell NIL (cdr Token) T ) (pop 'Levels) (setq RootPtr (or Levels Root)))
                    (T (addCell 'Name Token T)) )
                (setq C (nth C (+ (length *DELIM_S) (length Token) (length *DELIM_E))))) ) ) 
    (addCell NIL NIL T)
    (car Root) )

(de testParse ()
    (setq Html "hello {{name}}{{#names}}^J- {{.}}{{/#names}}")
    (setq Template (parse Html))
    (setq Expected '((Text "hello ") (Name "name") (Section "names" (Text "^J- ") (Name "."))))
    (test Expected Template)
    (push 'Model (cons "name" "joe"))
    (setq Names '(names . ("joe" "bob" "frank")))
    (push 'Model Names)
    (test "hello joe^J- joe^J- bob^J- frank" (renderTree Model Template)) 
    (test "sleep,eat," (renderHtml '((todos ((todo . "sleep")) ((todo . "eat")))) "{{#todos}}{{todo}},{{/todos}}"))
)

(de testRender ()
    (setq Tree (quote 
        (Text "hello ") 
        (Name "name") 
        (Text "^J") 
        (NonSection "missing" (Text "nothing here^J")) 
        (Section "names" (Text " - ") (Section "Upper" (Name ".")) (Text "^J"))))
    (push 'Model (cons "name" "joe"))
    (setq Names '(names . ("joe" "bob" "frank")))
    (push 'Model Names)
    (push 'Model (cons "Upper" '((X) (uppc X))))
    (test "hello joe^Jnothing here^J - JOE^J - BOB^J - FRANK^J" (renderTree Model Tree)) 
) 


# (testRender)
# (testParse)