gdritter repos s-cargot / 2d234b8
Added beginnings of Pretty module Getty Ritter 9 years ago
1 changed file(s) with 58 addition(s) and 0 deletion(s). Collapse all Expand all
1 module Data.SCargot.Pretty where
2
3
4 -- | A 'LayoutOptions' value describes how to pretty-print a 'SExpr'.
5 -- It describes how to print atoms, what horizontal space to fit
6 -- it into, and other related options.
7 --
8 -- The 'swingIndent' value might require a big of explanation: in
9 -- pretty-printing s-expressions, you have the option of whether
10 -- to 'swing' expressions which get pushed to subsequent lines
11 -- to the left, or to align them along the right. e.g. the
12 -- s-expression @(foo a b)@ could use a non-swing indent as
13 --
14 -- > (foo arg-one
15 -- > arg-two)
16 --
17 -- or a swing indent as
18 --
19 -- > (foo arg-one
20 -- > arg-two)
21 --
22 -- often, in formatting Lisp code, control structures will
23 -- swing subsequent expressions, as in
24 --
25 -- > (define (factorial n)
26 -- > (if (= n 0)
27 -- > 1
28 -- > (* n (fact (- n 1)))))
29 --
30 -- but most functions will _not_ swing:
31 --
32 -- > (call-my-func arg-number-one
33 -- > arg-number-two
34 -- > arg-number-three)
35 --
36 -- The 'swingIndent' field lets you choose whether or not to
37 -- swing subsequent s-expressions based on the atom in the car
38 -- position of a list. You can default to always swinging subsequent
39 -- expressions with @const True@ and never with @const False@, or
40 -- choose based on some more advanced criteria. _If_ a swing happens,
41 -- subsequent lines are indented based on the 'indentAmount' variable;
42 -- otherwise, subsequent lines are indented based on the size of the
43 -- @car@ of the list.
44 data LayoutOptions a = LayoutOptions
45 { atomPrinter :: a -> Text -- ^ How to serialize a given atom to 'Text'.
46 , swingIndent :: a -> Bool -- ^ Whether or not to swing
47 , indentAmount :: Int -- ^ How much to indent after a swing
48 , maxWidth :: Maybe Int -- ^ The maximum width (if any)
49 }
50
51 basicPrint :: (a -> Text) -> LayoutOptions a
52 basicPrint f = LayoutOptions
53 { atomPrinter = f
54 , swingIndent = const False
55 , maxWidth = Nothing
56 }
57
58 prettyPrintSExpr :: LayoutOptions a -> SExpr a -> Text