1 ! Copyright (C) 2003, 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 IN: prettyprint-internals
4 USING: alien arrays generic hashtables io kernel math
5 namespaces parser sequences strings styles vectors words
9 TUPLE: section start end style ;
11 C: section ( style length -- section )
12 >r position [ dup rot + dup ] change r>
13 [ set-section-end ] keep
14 [ set-section-start ] keep
15 [ set-section-style ] keep ;
17 GENERIC: section-fits? ( section -- ? )
19 M: section section-fits? ( section -- ? )
20 section-end last-newline get - text-fits? ;
22 GENERIC: short-section ( section -- )
24 GENERIC: long-section ( section -- )
26 GENERIC: block-empty? ( section -- ? )
28 : pprint-section ( section -- )
30 { [ margin get zero? ] [ short-section ] }
31 { [ dup section-fits? ] [ short-section ] }
32 { [ t ] [ long-section ] }
36 TUPLE: block sections ;
38 C: block ( style -- block )
39 swap 0 <section> over set-delegate
40 V{ } clone over set-block-sections ;
42 : pprinter-block ( -- block ) pprinter-stack get peek ;
44 : add-section ( section -- )
46 [ drop ] [ pprinter-block block-sections push ] if ;
48 M: block block-empty? block-sections empty? ;
50 M: block section-fits? ( section -- ? )
54 delegate section-fits?
57 : (<block) pprinter-stack get push ;
59 : <style section-style stdio [ <nested-style-stream> ] change ;
61 : style> stdio [ delegate ] change ;
63 : change-indent ( n -- )
64 tab-size get * indent [ + ] change ;
66 : <indent ( -- ) 1 change-indent ;
68 : indent> ( -- ) -1 change-indent ;
73 C: text ( string style -- text )
74 [ >r over length 1+ <section> r> set-delegate ] keep
75 [ set-text-string ] keep ;
77 M: text block-empty? drop f ;
80 dup text-string swap section-style format ;
83 dup section-start fresh-line short-section ;
85 : styled-text ( string style -- ) <text> add-section ;
87 : text ( string -- ) H{ } styled-text ;
92 C: newline ( -- section )
93 H{ } 0 <section> over set-delegate ;
95 M: newline block-empty? drop f ;
97 M: newline section-fits? drop t ;
99 M: newline short-section section-start fresh-line ;
101 : newline ( -- ) <newline> add-section ;
106 C: inset ( style -- block )
107 swap <block> over set-delegate ;
109 M: inset section-fits? ( section -- ? )
113 section-end last-newline get - 2 + text-fits?
116 : advance ( section -- )
120 section-start last-newline get = [ bl ] unless
123 M: block short-section ( block -- )
125 block-sections unclip pprint-section
126 [ dup advance pprint-section ] each
129 M: inset long-section
131 dup section-start fresh-line dup short-section
133 section-end fresh-line ;
135 : <inset ( style -- ) <inset> (<block) ;
140 C: flow ( style -- block )
141 swap <block> over set-delegate ;
143 M: flow section-fits? ( section -- ? )
144 dup delegate section-fits? [
147 dup section-end swap section-start - text-fits? not
151 dup section-start fresh-line short-section ;
153 : <flow ( style -- ) <flow> (<block) ;
158 C: narrow ( style -- block )
159 swap <block> over set-delegate ;
161 M: narrow section-fits? ( section -- ? )
165 section-end last-newline get - 2 + text-fits?
168 : narrow-block ( block -- )
170 block-sections unclip pprint-section
171 [ dup section-start fresh-line pprint-section ] each
174 M: narrow long-section
176 dup section-start fresh-line dup narrow-block
178 section-end fresh-line ;
180 : <narrow ( style -- ) <narrow> (<block) ;
185 C: defblock ( style -- block )
186 swap <block> over set-delegate ;
188 M: defblock long-section
190 dup section-start fresh-line short-section
193 : <defblock ( style -- ) <defblock> (<block) ;
195 : end-block ( block -- ) position get swap set-section-end ;
198 pprinter-stack get pop dup end-block add-section ;
200 : last-block? ( -- ? ) pprinter-stack get length 1 = ;
202 : block> ( -- ) last-block? [ (block>) ] unless ;
204 : end-blocks ( -- ) last-block? [ (block>) end-blocks ] unless ;
208 end-printing set pprinter-block
209 dup block-empty? [ drop ] [ pprint-section ] if