module Text.Karver
( renderTemplate
, renderTemplate'
, module Text.Karver.Types
) where
import Text.Karver.Types
import Text.Karver.Parse
import Control.Applicative ((<$>))
import Data.Aeson (decode')
import Data.Attoparsec.Text
import qualified Data.ByteString.Lazy.Char8 as L
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as H
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as TI
import qualified Data.Vector as V
import System.IO.Unsafe (unsafePerformIO)
renderTemplate :: HashMap Text Value
-> Text
-> Text
renderTemplate varTable = encode
where encode :: Text -> Text
encode tlp
| T.null tlp = tlp
| otherwise = merge $
case parseOnly templateParser tlp of
(Left err) -> [LiteralTok $ T.pack err]
(Right res) -> res
merge :: [Token] -> Text
merge = T.concat . map (decodeToken varTable)
decodeToken _ (LiteralTok x) = x
decodeToken vTable (IdentityTok x) =
case H.lookup x vTable of
(Just (Literal s)) -> s
_ -> T.empty
decodeToken vTable (ObjectTok i k) =
case H.lookup i vTable of
(Just (Object m)) -> maybe T.empty id $ H.lookup k m
_ -> T.empty
decodeToken vTable (ListTok a i) =
case H.lookup a vTable of
(Just (List l)) -> case l V.! i of
(Literal t) -> t
_ -> T.empty
_ -> T.empty
decodeToken _ (ConditionTok c t f) =
encode $ if hasVariable c then t else f
where hasVariable txt =
case parseOnly variableParser' txt of
(Right res) -> not . T.null $ decodeToken varTable res
_ -> False
decodeToken vTable (LoopTok a v b) =
case H.lookup a vTable of
(Just (List l)) ->
let toks = either (\_ -> []) id $ parseOnly templateParser b
mapVars x = let vTable' = H.insert v x vTable
in map (decodeToken vTable') toks
in if null toks
then T.empty
else T.concat . V.toList $ V.map (T.concat . mapVars) l
_ -> T.empty
decodeToken _ (IncludeTok f) =
unsafePerformIO $ encode . T.init <$> TI.readFile (T.unpack f)
renderTemplate' :: Text
-> Text
-> Text
renderTemplate' json tpl =
case decode' . L.pack $ T.unpack json of
(Just hash) -> renderTemplate hash tpl
Nothing -> T.empty