Added beginnings of Pretty module
Getty Ritter
9 years ago
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 |