module Util.PrettyPrint (
module Text.PrettyPrint.HughesPJ,
PrettyPrintable (prettyPrint),
tabWidth,
tabIndent,
shortDouble,
commaSeparatedInt,
angles, bars, list, dotSep,
speakNth,
punctuateFront,
)
where
import Numeric
import Text.Printf
import Text.PrettyPrint.HughesPJ
class PrettyPrintable a where
prettyPrint :: a -> Doc
tabWidth :: Int
tabWidth = 4
commaSeparatedInt :: Int -> Doc
commaSeparatedInt =
let
breakIntoGroupsOf3 (c1:c2:c3:c4:cs) =
[c3,c2,c1] : breakIntoGroupsOf3 (c4:cs)
breakIntoGroupsOf3 cs = [reverse cs]
in
fcat . punctuate comma . reverse . map text
. breakIntoGroupsOf3 . reverse . show
shortDouble :: Int -> Double -> Doc
shortDouble places d = text (showGFloat (Just places) d "")
tabIndent :: Doc -> Doc
tabIndent = nest tabWidth
angles :: Doc -> Doc
angles d = char '<' <> d <> char '>'
bars :: Doc -> Doc
bars d = char '|' <> d <> char '|'
dotSep :: [Doc] -> Doc
dotSep docs = fcat (punctuate (text ".") docs)
list :: [Doc] -> Doc
list docs = fsep (punctuate (text ",") docs)
speakNth :: Int -> Doc
speakNth 1 = text "first"
speakNth 2 = text "second"
speakNth 3 = text "third"
speakNth 4 = text "fourth"
speakNth 5 = text "fifth"
speakNth 6 = text "sixth"
speakNth n = hcat [ int n, text suffix ]
where
suffix
| n <= 20 = "th"
| last_dig == 1 = "st"
| last_dig == 2 = "nd"
| last_dig == 3 = "rd"
| otherwise = "th"
last_dig = n `rem` 10
punctuateFront :: Doc -> [Doc] -> [Doc]
punctuateFront sep [] = []
punctuateFront sep (x:xs) = x:[sep <> x | x <- xs]