Pretty-printing indentation now controlled with Indent type
Getty Ritter
10 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 | |