factor/basis/xml/literals/literals.factor

110 lines
3.0 KiB
Factor
Raw Normal View History

2009-01-19 23:25:15 -05:00
! Copyright (C) 2009 Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license.
2009-01-25 22:06:45 -05:00
USING: xml xml.state kernel sequences fry assocs xml.data
accessors strings make multiline parser namespaces macros
sequences.deep generalizations words combinators
2009-01-29 14:33:04 -05:00
math present arrays unicode.categories ;
2009-01-30 12:29:30 -05:00
IN: xml.literals
2009-01-25 22:06:45 -05:00
<PRIVATE
2009-01-26 17:11:30 -05:00
: string>chunk ( string -- chunk )
2009-01-25 22:06:45 -05:00
t interpolating? [ string>xml-chunk ] with-variable ;
2009-01-26 17:11:30 -05:00
: string>doc ( string -- xml )
2009-01-25 22:06:45 -05:00
t interpolating? [ string>xml ] with-variable ;
DEFER: interpolate-sequence
: interpolate-attrs ( table attrs -- attrs )
2009-01-26 17:11:30 -05:00
swap '[
dup interpolated?
[ var>> _ at dup [ present ] when ] when
] assoc-map [ nip ] assoc-filter ;
2009-01-25 22:06:45 -05:00
: interpolate-tag ( table tag -- tag )
[ nip name>> ]
[ attrs>> interpolate-attrs ]
[ children>> [ interpolate-sequence ] [ drop f ] if* ] 2tri
<tag> ;
GENERIC: push-item ( item -- )
M: string push-item , ;
M: xml-data push-item , ;
M: object push-item present , ;
2009-01-26 17:48:14 -05:00
M: sequence push-item
dup xml-data? [ , ] [ [ push-item ] each ] if ;
M: number push-item present , ;
M: xml-chunk push-item % ;
2009-01-25 22:06:45 -05:00
GENERIC: interpolate-item ( table item -- )
M: object interpolate-item nip , ;
M: tag interpolate-item interpolate-tag , ;
M: interpolated interpolate-item
var>> swap at push-item ;
: interpolate-sequence ( table seq -- seq )
[ [ interpolate-item ] with each ] { } make ;
: interpolate-xml-doc ( table xml -- xml )
(clone) [ interpolate-tag ] change-body ;
: (each-interpolated) ( item quot: ( interpolated -- ) -- )
{
{ [ over interpolated? ] [ call ] }
{ [ over tag? ] [
[ attrs>> values [ interpolated? ] filter ] dip each
] }
{ [ over xml? ] [ [ body>> ] dip (each-interpolated) ] }
[ 2drop ]
} cond ; inline recursive
2009-01-26 00:52:25 -05:00
: each-interpolated ( xml quot -- )
'[ _ (each-interpolated) ] deep-each ; inline
: number<-> ( doc -- dup )
0 over [
2009-01-28 17:17:20 -05:00
dup var>> [
over >>var [ 1+ ] dip
] unless drop
] each-interpolated drop ;
2009-01-26 00:52:25 -05:00
2009-01-28 17:17:20 -05:00
GENERIC: interpolate-xml ( table xml -- xml )
2009-01-25 22:06:45 -05:00
2009-01-28 17:17:20 -05:00
M: xml interpolate-xml
interpolate-xml-doc ;
M: xml-chunk interpolate-xml
interpolate-sequence <xml-chunk> ;
2009-01-25 22:06:45 -05:00
: >search-hash ( seq -- hash )
[ dup search ] H{ } map>assoc ;
: extract-variables ( xml -- seq )
2009-01-26 00:52:25 -05:00
[ [ var>> , ] each-interpolated ] { } make ;
2009-01-26 17:11:30 -05:00
: nenum ( ... n -- assoc )
narray <enum> ; inline
2009-01-28 17:17:20 -05:00
: collect ( accum variables -- accum ? )
2009-01-26 00:52:25 -05:00
{
2009-01-28 17:17:20 -05:00
{ [ dup empty? ] [ drop f ] } ! Just a literal
{ [ dup [ ] all? ] [ >search-hash parsed t ] } ! locals
{ [ dup [ not ] all? ] [ length parsed \ nenum parsed t ] } ! fry
2009-01-26 00:52:25 -05:00
[ drop "XML interpolation contains both fry and locals" throw ] ! mixed
} cond ;
2009-01-25 22:06:45 -05:00
2009-01-28 17:17:20 -05:00
: parse-def ( accum delimiter quot -- accum )
2009-01-29 14:33:04 -05:00
[ parse-multiline-string [ blank? ] trim ] dip call
2009-01-28 17:17:20 -05:00
[ extract-variables collect ] keep swap
[ number<-> parsed ] dip
[ \ interpolate-xml parsed ] when ; inline
2009-01-25 22:06:45 -05:00
PRIVATE>
: <XML
2009-01-28 17:17:20 -05:00
"XML>" [ string>doc ] parse-def ; parsing
2009-01-25 22:06:45 -05:00
: [XML
2009-01-28 17:17:20 -05:00
"XML]" [ string>chunk ] parse-def ; parsing