Added beginnings of Pretty module
Getty Ritter
10 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 |