Pretty-printing indentation now controlled with Indent type
Getty Ritter
9 years ago
4 | 4 | |
5 | 5 | module Data.SCargot.Pretty |
6 | 6 | ( LayoutOptions(..) |
7 | , Indent(..) | |
7 | 8 | , basicPrint |
8 | 9 | , flatPrint |
9 | 10 | , prettyPrintSExpr |
14 | 15 | import qualified Data.Text as T |
15 | 16 | |
16 | 17 | import Data.SCargot.Repr |
18 | ||
19 | data Indent | |
20 | = Swing | |
21 | | SwingAfter Int | |
22 | | Align | |
23 | deriving (Eq, Show) | |
17 | 24 | |
18 | 25 | -- | A 'LayoutOptions' value describes how to pretty-print a 'SExpr'. |
19 | 26 | -- It describes how to print atoms, what horizontal space to fit |
56 | 63 | -- otherwise, subsequent lines are indented based on the size of the |
57 | 64 | -- @car@ of the list. |
58 | 65 | data LayoutOptions a = LayoutOptions |
59 | { atomPrinter :: a -> Text -- ^ How to serialize a given atom to 'Text'. | |
60 | , swingIndent :: SExpr a -> Bool -- ^ Whether or not to swing | |
61 | , indentAmount :: Int -- ^ How much to indent after a swing | |
62 | , maxWidth :: Maybe Int -- ^ The maximum width (if any) | |
66 | { atomPrinter :: a -> Text -- ^ How to serialize a given atom to 'Text'. | |
67 | , swingIndent :: SExpr a -> Indent -- ^ Whether or not to swing | |
68 | , indentAmount :: Int -- ^ How much to indent after a swing | |
69 | , maxWidth :: Maybe Int -- ^ The maximum width (if any) | |
63 | 70 | } |
64 | 71 | |
65 | 72 | flatPrint :: (a -> Text) -> LayoutOptions a |
66 | 73 | flatPrint printer = LayoutOptions |
67 | 74 | { atomPrinter = printer |
68 |
, swingIndent = const |
|
75 | , swingIndent = const Swing | |
69 | 76 | , indentAmount = 2 |
70 | 77 | , maxWidth = Nothing |
71 | 78 | } |
73 | 80 | basicPrint :: (a -> Text) -> LayoutOptions a |
74 | 81 | basicPrint printer = LayoutOptions |
75 | 82 | { atomPrinter = printer |
76 |
, swingIndent = const |
|
83 | , swingIndent = const Swing | |
77 | 84 | , indentAmount = 2 |
78 | 85 | , maxWidth = Just 80 |
79 | 86 | } |
113 | 120 | lst = k [] |
114 | 121 | flat = T.unwords (map (pHead (ind+1)) lst) |
115 | 122 | headWidth = T.length hd + 1 |
116 | indented | |
117 | | swingIndent h = | |
123 | indented = | |
124 | case swingIndent h of | |
125 | SwingAfter n -> | |
126 | let (l, ls) = splitAt n lst | |
127 | t = T.unwords (map (pHead (ind+1)) l) | |
128 | ts = indentAll (ind + indentAmount) | |
129 | (map (pHead (ind + indentAmount)) ls) | |
130 | in t <> ts | |
131 | Swing -> | |
118 | 132 | indentAll (ind + indentAmount) |
119 | 133 | (map (pHead (ind + indentAmount)) lst) |
120 |
|
|
134 | Align -> | |
121 | 135 | indentSubsequent (ind + headWidth + 1) |
122 | 136 | (map (pHead (ind + headWidth + 1)) lst) |
123 | body | length lst == 0 = "" | |
124 | | Just maxAmt <- maxWidth | |
125 | , (T.length flat + ind) > maxAmt = " " <> indented | |
126 | | otherwise = " " <> flat | |
137 | body | |
138 | | length lst == 0 = "" | |
139 | | Just maxAmt <- maxWidth | |
140 | , (T.length flat + ind) > maxAmt = " " <> indented | |
141 | | otherwise = " " <> flat |