-- | Common 'Doc'-related functions for writting printers with a little more clarity.
module Utils.Drasil.Document (blank, indent, indentList, contSep, filterEmpty,
  listToDoc, Separator) where

import Text.PrettyPrint.HughesPJ

-- | Separates document sections.
type Separator = Doc

contSep :: Separator
contSep :: Separator
contSep = String -> Separator
text String
"\n"

-- | Creates a blank document with no text.
blank :: Doc
blank :: Separator
blank = String -> Separator
text String
""

-- | Indents a document (by 4 spaces).
indent :: Doc -> Doc
indent :: Separator -> Separator
indent = Int -> Separator -> Separator
nest Int
4

-- | Indents a list of Docs and combines into one Doc.
indentList :: [Doc] -> Doc
indentList :: [Separator] -> Separator
indentList = Separator -> Separator
indent (Separator -> Separator)
-> ([Separator] -> Separator) -> [Separator] -> Separator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Separator] -> Separator
vcat

-- | Filter blank `Doc`s from a list.
filterEmpty :: [Doc] -> [Doc]
filterEmpty :: [Separator] -> [Separator]
filterEmpty = (Separator -> Bool) -> [Separator] -> [Separator]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Separator -> Bool) -> Separator -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Separator -> Bool
isEmpty) 

-- | Merge a list of `String`s into a `Doc` format:
--
-- e.g., `listToDoc [a,b,c,...] ~= a, b, c, ...`
listToDoc :: [String] -> Doc
listToDoc :: [String] -> Separator
listToDoc = [Separator] -> Separator
hsep ([Separator] -> Separator)
-> ([String] -> [Separator]) -> [String] -> Separator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Separator -> [Separator] -> [Separator]
punctuate Separator
comma ([Separator] -> [Separator])
-> ([String] -> [Separator]) -> [String] -> [Separator]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Separator) -> [String] -> [Separator]
forall a b. (a -> b) -> [a] -> [b]
map String -> Separator
text