module Text.Reformat.Render
( renderFromReformat
) where
import Text.Reformat.Types (Reformat(..), Value(..))
import Text.Parsec
import Text.Printf
data Render = Text String
| Var String String
| Nil
deriving (Show,Eq)
parserVar :: Stream String m Char => ParsecT String () m [Render]
parserVar = do
char '$' >> char '{' >> spaces
varName <- many1 (lower <|> digit <|> char '_' <|> char '-')
spaces >> char ':' >> spaces
format <- many1 $ oneOf "cdoxXbufFgGeEs+-0123456789."
spaces >> char '}'
(Var varName ('%':format):) <$> parserRender
parserText :: Stream String m Char => ParsecT String () m [Render]
parserText = do
text <- many1 $ noneOf "$"
(Text text:) <$> parserRender
parserD :: Stream String m Char => ParsecT String () m [Render]
parserD = string "$$" >> (Text "$":) <$> parserRender
parserEOF :: Stream String m Char => ParsecT String () m [Render]
parserEOF = eof >> return [Nil]
parserRender :: Stream String m Char => ParsecT String () m [Render]
parserRender = try parserEOF <|> try parserText <|> try parserD <|> parserVar
renderFromReformat :: (Monad m, Reformat t, Str t ~ String)
=> t
-> String
-> m (Either ParseError String)
renderFromReformat t str = (concat . step <$>) <$> runParserT parserRender () "render format" str
where pair = renderPair t
step [] = []
step (Text s:rs) = s:step rs
step (Var v f:rs) = prt f (pair v):step rs
step (Nil:rs) = step rs
prt f (I i) = printf f i
prt f (R r) = printf f r
prt f (S s) = printf f s
prt _ N = ""