module Text.CSL.Output.Plain
( renderPlain
, renderPlainStrict
, procList
, (<+>)
, (<>)
) where
import Data.Char
import Data.List
import Text.CSL.Style
renderPlain :: [FormattedOutput] -> String
renderPlain = concatMap $ render False
renderPlainStrict :: [FormattedOutput] -> String
renderPlainStrict = concatMap $ render True
render :: Bool -> FormattedOutput -> String
render _ (Delimiter s) = s
render b (FO str fm xs) = prefix fm <++> format (trim str <++> rest) <++> suffix fm
where
rest = procList xs $ concatM (render b)
trim = if b then id else unwords . words
(<++>) = if b then (++) else (<>)
concatM f = foldr (<++>) [] . map f
quote s = if s /= [] && quotes fm then "\"" ++ s ++ "\"" else s
capital s = toUpper (head s) : (tail s)
format s = quote . text_case $ s
text_case s
| "capitalize-first" <- textCase fm = procList s capital
| "capitalize-all" <- textCase fm = procList s $ unwords . map capital . words
| "lowercase" <- textCase fm = map toLower s
| "uppercase" <- textCase fm = map toUpper s
| otherwise = s
procList :: Eq a => [a] -> ([a] -> [b]) -> [b]
procList s f = if s /= [] then f s else []
(<+>) :: String -> String -> String
[] <+> ss = ss
s <+> [] = s
s <+> ss = s ++ " " ++ ss
(<>) :: String -> String -> String
sa <> sb
| sa /= [], (s:xs) <- sb
, last sa == s
, s `elem` ";:,. " = sa ++ xs
| otherwise = sa ++ sb