Converting Farkup, html.components and lcs.diff2html to xml.interpolate
[factor/jcg.git] / basis / xml / interpolate / interpolate.factor
blobd8927ca728a9ee6d65dae4da31c49a9122e9dead
1 ! Copyright (C) 2009 Daniel Ehrenberg.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: xml xml.state kernel sequences fry assocs xml.data
4 accessors strings make multiline parser namespaces macros
5 sequences.deep generalizations locals words combinators
6 math present arrays ;
7 IN: xml.interpolate
9 <PRIVATE
11 : string>chunk ( string -- chunk )
12     t interpolating? [ string>xml-chunk ] with-variable ;
14 : string>doc ( string -- xml )
15     t interpolating? [ string>xml ] with-variable ;
17 DEFER: interpolate-sequence
19 : interpolate-attrs ( table attrs -- attrs )
20     swap '[
21         dup interpolated?
22         [ var>> _ at dup [ present ] when ] when
23     ] assoc-map [ nip ] assoc-filter ;
25 : interpolate-tag ( table tag -- tag )
26     [ nip name>> ]
27     [ attrs>> interpolate-attrs ]
28     [ children>> [ interpolate-sequence ] [ drop f ] if* ] 2tri
29     <tag> ;
31 GENERIC: push-item ( item -- )
32 M: string push-item , ;
33 M: xml-data push-item , ;
34 M: object push-item present , ;
35 M: sequence push-item
36     [ dup array? [ % ] [ , ] if ] each ;
38 GENERIC: interpolate-item ( table item -- )
39 M: object interpolate-item nip , ;
40 M: tag interpolate-item interpolate-tag , ;
41 M: interpolated interpolate-item
42     var>> swap at push-item ;
44 : interpolate-sequence ( table seq -- seq )
45     [ [ interpolate-item ] with each ] { } make ;
47 : interpolate-xml-doc ( table xml -- xml )
48     (clone) [ interpolate-tag ] change-body ;
50 GENERIC# (each-interpolated) 1 ( item quot -- ) inline
51 M: interpolated (each-interpolated) call ;
52 M: tag (each-interpolated)
53     swap attrs>> values
54     [ interpolated? ] filter
55     swap each ;
56 M: xml (each-interpolated)
57     [ body>> ] dip (each-interpolated) ;
58 M: object (each-interpolated) 2drop ;
60 : each-interpolated ( xml quot -- )
61     '[ _ (each-interpolated) ] deep-each ; inline
63 :: number<-> ( doc -- doc )
64     0 :> n! doc [
65         dup var>> [ n >>var n 1+ n! ] unless drop
66     ] each-interpolated doc ;
68 MACRO: interpolate-xml ( string -- doc )
69     string>doc number<-> '[ _ interpolate-xml-doc ] ;
71 MACRO: interpolate-chunk ( string -- chunk )
72     string>chunk number<-> '[ _ interpolate-sequence ] ;
74 : >search-hash ( seq -- hash )
75     [ dup search ] H{ } map>assoc ;
77 : extract-variables ( xml -- seq )
78     [ [ var>> , ] each-interpolated ] { } make ;
80 : nenum ( ... n -- assoc )
81     narray <enum> ; inline
83 : collect ( accum seq -- accum )
84     {
85         { [ dup [ ] all? ] [ >search-hash parsed ] } ! locals
86         { [ dup [ not ] all? ] [ ! fry
87             length parsed \ nenum parsed
88         ] }
89         [ drop "XML interpolation contains both fry and locals" throw ] ! mixed
90     } cond ;
92 : parse-def ( accum delimiter word -- accum )
93     [
94         parse-multiline-string but-last
95         [ string>chunk extract-variables collect ] keep
96         parsed
97     ] dip parsed ;
99 PRIVATE>
101 : <XML
102     "XML>" \ interpolate-xml parse-def ; parsing
104 : [XML
105     "XML]" \ interpolate-chunk parse-def ; parsing