]> gitweb.factorcode.org Git - factor.git/blob - basis/html/templates/chloe/compiler/compiler.factor
Updating code for make and fry changes
[factor.git] / basis / html / templates / chloe / compiler / compiler.factor
1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs namespaces make kernel sequences accessors
4 combinators strings splitting io io.streams.string present
5 xml.writer xml.data xml.entities html.forms
6 html.templates.chloe.syntax ;
7 IN: html.templates.chloe.compiler
8
9 : chloe-attrs-only ( assoc -- assoc' )
10     [ drop url>> chloe-ns = ] assoc-filter ;
11
12 : non-chloe-attrs-only ( assoc -- assoc' )
13     [ drop url>> chloe-ns = not ] assoc-filter ;
14
15 : chloe-tag? ( tag -- ? )
16     dup xml? [ body>> ] when
17     {
18         { [ dup tag? not ] [ f ] }
19         { [ dup url>> chloe-ns = not ] [ f ] }
20         [ t ]
21     } cond nip ;
22
23 SYMBOL: string-buffer
24
25 SYMBOL: tag-stack
26
27 DEFER: compile-element
28
29 : compile-children ( tag -- )
30     [ compile-element ] each ;
31
32 : [write] ( string -- ) string-buffer get push-all ;
33
34 : reset-buffer ( -- )
35     string-buffer get [
36         [ >string , \ write , ] [ delete-all ] bi
37     ] unless-empty ;
38
39 : [code] ( quot -- )
40     reset-buffer % ;
41
42 : [code-with] ( obj quot -- )
43     reset-buffer [ , ] [ % ] bi* ;
44
45 : expand-attr ( value -- )
46     [ value present write ] [code-with] ;
47
48 : compile-attr ( value -- )
49     reset-buffer "@" ?head [ , [ value present ] % ] [ , ] if ;
50
51 : compile-attrs ( assoc -- )
52     [
53         " " [write]
54         swap name>string [write]
55         "=\"" [write]
56         "@" ?head [ expand-attr ] [ escape-quoted-string [write] ] if
57         "\"" [write]
58     ] assoc-each ;
59
60 : compile-start-tag ( tag -- )
61     "<" [write]
62     [ name>string [write] ] [ compile-attrs ] bi
63     ">" [write] ;
64
65 : compile-end-tag ( tag -- )
66     "</" [write]
67     name>string [write]
68     ">" [write] ;
69
70 : compile-tag ( tag -- )
71     {
72         [ main>> tag-stack get push ]
73         [ compile-start-tag ]
74         [ compile-children ]
75         [ compile-end-tag ]
76         [ drop tag-stack get pop* ]
77     } cleave ;
78
79 : compile-chloe-tag ( tag -- )
80     ! "Unknown chloe tag: " prepend throw
81     dup main>> dup tags get at
82     [ curry assert-depth ] [ 2drop ] ?if ;
83
84 : compile-element ( element -- )
85     {
86         { [ dup chloe-tag? ] [ compile-chloe-tag ] }
87         { [ dup [ tag? ] [ xml? ] bi or ] [ compile-tag ] }
88         { [ dup string? ] [ escape-string [write] ] }
89         { [ dup comment? ] [ drop ] }
90         [ [ write-item ] [code-with] ]
91     } cond ;
92
93 : with-compiler ( quot -- quot' )
94     [
95         SBUF" " string-buffer set
96         V{ } clone tag-stack set
97         call
98         reset-buffer
99     ] [ ] make ; inline
100
101 : compile-nested-template ( xml -- quot )
102     [ compile-element ] with-compiler ;
103
104 : compile-chunk ( seq -- )
105     [ compile-element ] each ;
106
107 : compile-quot ( quot -- )
108     reset-buffer
109     [
110         SBUF" " string-buffer set
111         call
112         reset-buffer
113     ] [ ] make , ; inline
114
115 : process-children ( tag quot -- )
116     [ [ compile-children ] compile-quot ] [ % ] bi* ; inline
117
118 : compile-children>string ( tag -- )
119      [ with-string-writer ] process-children ;
120
121 : compile-with-scope ( quot -- )
122     compile-quot [ with-scope ] [code] ; inline
123
124 : compile-template ( xml -- quot )
125     [
126         {
127             [ prolog>> [ write-prolog ] [code-with] ]
128             [ before>> compile-chunk ]
129             [ compile-element ]
130             [ after>> compile-chunk ]
131         } cleave
132     ] with-compiler ;