{-# LANGUAGE OverloadedStrings #-} module Prettyprinter.Custom ( brackets' , braces' , parens' , sexp ) where import Prettyprinter -- | An area bracketed by two delimiters. When on multiple lines the delimiters are not indented but the content is. section' :: Doc a -> Doc a -> Doc a -> Doc a -- The subtlety here is that the nest call surrounds the first delimiter and the content, but not -- the final one. This is because of how nest behaves, where it doesn't indent until it hits the first -- line break. So we need to include the first delimiter so that the main content gets indented, but not -- the final delimiter. section' :: Doc a -> Doc a -> Doc a -> Doc a section' Doc a c1 Doc a c2 Doc a d = Doc a -> Doc a forall ann. Doc ann -> Doc ann group (Doc a -> Doc a) -> Doc a -> Doc a forall a b. (a -> b) -> a -> b $ Int -> Doc a -> Doc a forall ann. Int -> Doc ann -> Doc ann nest Int 2 (Doc a c1 Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a d) Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a c2 -- | An area bracketed by two delimiters. When on one line, there are spaces between the delimiters -- and the content, when on multiple lines the delimiters are not indented but the content is. section :: Doc a -> Doc a -> Doc a -> Doc a section :: Doc a -> Doc a -> Doc a -> Doc a section Doc a c1 Doc a c2 = Doc a -> Doc a -> Doc a -> Doc a forall a. Doc a -> Doc a -> Doc a -> Doc a section' (Doc a c1 Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a forall ann. Doc ann line) (Doc a forall ann. Doc ann line Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a c2) -- | This prints a document enclosed by brackets, possibly indenting the output on -- a new line if it does not fit. brackets' :: Doc a -> Doc a brackets' :: Doc a -> Doc a brackets' = Doc a -> Doc a -> Doc a -> Doc a forall a. Doc a -> Doc a -> Doc a -> Doc a section Doc a "[" Doc a "]" -- | This prints a document enclosed by braces, possibly indenting the output on -- a new line if it does not fit. braces' :: Doc a -> Doc a braces' :: Doc a -> Doc a braces' = Doc a -> Doc a -> Doc a -> Doc a forall a. Doc a -> Doc a -> Doc a -> Doc a section Doc a "{" Doc a "}" -- | This prints a document enclosed by parentheses, aligning the opening and -- closing parentheses. parens' :: Doc a -> Doc a parens' :: Doc a -> Doc a parens' = Doc a -> Doc a -> Doc a -> Doc a forall a. Doc a -> Doc a -> Doc a -> Doc a section Doc a "(" Doc a ")" -- | Print a "sexp", i.e. something like "(keyword arg1 ... argN)". sexp :: Doc a -> [Doc a] -> Doc a sexp :: Doc a -> [Doc a] -> Doc a sexp Doc a a [Doc a] es = -- This is a bit funny, because we want the keyword to "stick" to the opening parenthesis -- when it's split over multiple lines. So we include it in the "initial" segment. But then -- we also have to have a space after that rather than no space. So we start with "(keyword" -- and a line-or-space, but end with a line-or-nothing and ")". Doc a -> Doc a -> Doc a -> Doc a forall a. Doc a -> Doc a -> Doc a -> Doc a section' (Doc a "(" Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a a Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a forall ann. Doc ann line) (Doc a forall ann. Doc ann line' Doc a -> Doc a -> Doc a forall a. Semigroup a => a -> a -> a <> Doc a ")") ([Doc a] -> Doc a forall ann. [Doc ann] -> Doc ann sep [Doc a] es)