! Copyright (C) 2003, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: prettyprint USING: alien arrays generic hashtables io kernel math namespaces parser sequences strings styles vectors words ; ! State SYMBOL: position SYMBOL: last-newline SYMBOL: recursion-check SYMBOL: line-count SYMBOL: end-printing SYMBOL: indent SYMBOL: pprinter-stack ! Configuration SYMBOL: tab-size SYMBOL: margin SYMBOL: nesting-limit SYMBOL: length-limit SYMBOL: line-limit SYMBOL: string-limit ! Special trick to highlight a word in a quotation SYMBOL: hilite-quotation SYMBOL: hilite-index SYMBOL: hilite-next? global [ 4 tab-size set 64 margin set 0 position set 0 indent set 0 last-newline set 1 line-count set string-limit off ] bind GENERIC: pprint-section* ( section -- ) TUPLE: section start end nl-after? indent style ; C: section ( style length -- section ) >r position [ dup rot + dup ] change r> [ set-section-end ] keep [ set-section-start ] keep [ set-section-style ] keep 0 over set-section-indent ; : line-limit? ( -- ? ) line-limit get dup [ line-count get <= ] when ; : do-indent ( -- ) indent get CHAR: \s write ; : fresh-line ( n -- ) dup last-newline get = [ drop ] [ last-newline set line-limit? [ "..." write end-printing get continue ] when line-count inc terpri do-indent ] if ; TUPLE: text string ; C: text ( string style -- text ) [ >r over length 1+
r> set-delegate ] keep [ set-text-string ] keep ; M: text pprint-section* dup text-string swap section-style format ; TUPLE: block sections ; C: block ( style -- block ) [ >r 0
r> set-delegate ] keep V{ } clone over set-block-sections t over set-section-nl-after? tab-size get over set-section-indent ; : pprinter-block ( -- block ) pprinter-stack get peek ; : block-empty? ( section -- ? ) dup block? [ block-sections empty? ] [ drop f ] if ; : add-section ( section -- ) dup block-empty? [ drop ] [ pprinter-block block-sections push ] if ; : styled-text ( string style -- ) add-section ; : text ( string -- ) H{ } styled-text ; : ( section -- ) section-indent indent [ swap - ] change ; : inset-section ( section -- ) dup dup section-nl-after? [ section-end fresh-line ] [ drop ] if ; : section-fits? ( section -- ? ) margin get dup zero? [ 2drop t ] [ line-limit? pick block? and [ 2drop t ] [ >r section-end last-newline get - indent get + r> <= ] if ] if ; : pprint-section ( section -- ) dup section-fits? [ pprint-section* ] [ inset-section ] if ; TUPLE: newline ; C: newline ( -- section ) H{ } 0
over set-delegate ; M: newline pprint-section* section-start fresh-line ; : newline ( -- ) add-section ; : advance ( section -- ) dup newline? [ drop ] [ section-start last-newline get = [ bl ] unless ] if ; :