1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: combinators generic assocs help http io io.styles io.files
5 continuations io.streams.string kernel math math.order math.parser
6 namespaces quotations assocs sequences strings words html.elements
7 xml.entities sbufs continuations destructors accessors arrays ;
11 GENERIC: browser-link-href ( presented -- href )
13 M: object browser-link-href drop f ;
15 TUPLE: html-stream stream last-div ;
17 ! stream-nl after with-nesting or tabular-output is
18 ! ignored, so that HTML stream output looks like
20 : last-div? ( stream -- ? )
21 [ f ] change-last-div drop ;
23 : not-a-div ( stream -- stream )
26 : a-div ( stream -- straem )
29 : <html-stream> ( stream -- stream )
34 TUPLE: html-sub-stream < html-stream style parent ;
36 : new-html-sub-stream ( style stream class -- stream )
42 : end-sub-stream ( substream -- string style stream )
43 [ stream>> >string ] [ style>> ] [ parent>> ] tri ;
45 : object-link-tag ( style quot -- )
50 ] [ call ] if* ; inline
52 : hex-color, ( color -- )
53 [ red>> ] [ green>> ] [ blue>> ] tri
54 [ 255 * >fixnum >hex 2 CHAR: 0 pad-left % ] tri@ ;
56 : fg-css, ( color -- )
57 "color: #" % hex-color, "; " % ;
59 : bg-css, ( color -- )
60 "background-color: #" % hex-color, "; " % ;
62 : style-css, ( flag -- )
64 { italic bold-italic } member?
65 "font-style: " % "italic" "normal" ? % "; " %
66 { bold bold-italic } member?
67 "font-weight: " % "bold" "normal" ? % "; " % ;
69 : size-css, ( size -- )
70 "font-size: " % # "pt; " % ;
72 : font-css, ( font -- )
73 "font-family: " % % "; " % ;
75 : apply-style ( style key quot -- style gadget )
76 >r over at r> when* ; inline
78 : make-css ( style quot -- str )
81 : span-css-style ( style -- str )
83 foreground [ fg-css, ] apply-style
84 background [ bg-css, ] apply-style
85 font [ font-css, ] apply-style
86 font-style [ style-css, ] apply-style
87 font-size [ size-css, ] apply-style
90 : span-tag ( style quot -- )
94 <span =style span> call </span>
97 : format-html-span ( string style stream -- )
99 [ [ drop write ] span-tag ] object-link-tag
100 ] with-output-stream* ;
102 TUPLE: html-span-stream < html-sub-stream ;
104 M: html-span-stream dispose
105 end-sub-stream not-a-div format-html-span ;
107 : border-css, ( border -- )
108 "border: 1px solid #" % hex-color, "; " % ;
110 : padding-css, ( padding -- ) "padding: " % # "px; " % ;
112 : pre-css, ( margin -- )
113 [ "white-space: pre; font-family: monospace; " % ] unless ;
115 : div-css-style ( style -- str )
117 page-color [ bg-css, ] apply-style
118 border-color [ border-css, ] apply-style
119 border-width [ padding-css, ] apply-style
120 wrap-margin over at pre-css,
123 : div-tag ( style quot -- )
127 <div =style div> call </div>
130 : format-html-div ( string style stream -- )
132 [ [ write ] div-tag ] object-link-tag
133 ] with-output-stream* ;
135 TUPLE: html-block-stream < html-sub-stream ;
137 M: html-block-stream dispose ( quot style stream -- )
138 end-sub-stream a-div format-html-div ;
140 : border-spacing-css, ( pair -- )
141 "padding: " % first2 max 2 /i # "px; " % ;
143 : table-style ( style -- str )
145 table-border [ border-css, ] apply-style
146 table-gap [ border-spacing-css, ] apply-style
149 : table-attrs ( style -- )
150 table-style " border-collapse: collapse;" append =style ;
152 : do-escaping ( string style -- string )
153 html swap at [ escape-string ] unless ;
158 M: html-stream stream-flush
159 stream>> stream-flush ;
161 M: html-stream stream-write1
162 >r 1string r> stream-write ;
164 M: html-stream stream-write
165 not-a-div >r escape-string r> stream>> stream-write ;
167 M: html-stream stream-format
168 >r html over at [ >r escape-string r> ] unless r>
171 M: html-stream stream-nl
172 dup last-div? [ drop ] [ [ <br/> ] with-output-stream* ] if ;
174 M: html-stream make-span-stream
175 html-span-stream new-html-sub-stream ;
177 M: html-stream make-block-stream
178 html-block-stream new-html-sub-stream ;
180 M: html-stream make-cell-stream
181 html-sub-stream new-html-sub-stream ;
183 M: html-stream stream-write-table
185 <table dup table-attrs table> swap [
187 <td "top" =valign swap table-style =style td>
188 stream>> >string write
192 ] with-output-stream* ;
194 M: html-stream dispose stream>> dispose ;
196 : with-html-stream ( quot -- )
197 output-stream get <html-stream> swap with-output-stream* ; inline