module Pencil.Content.Nodes where
import Pencil.App.Internal
import Pencil.Env.Internal
import Pencil.Parser
import Pencil.Content.Internal
import Pencil.Config
import Control.Monad.Reader
import Control.Monad.Except
import Control.Exception (tryJust)
import Data.Text.Encoding (decodeUtf8)
import qualified Data.HashMap.Strict as H
import qualified Data.Text as T
import qualified Text.Pandoc as P
import qualified Text.Sass as Sass
import qualified Data.Text.IO as TIO
evalNodes :: Env -> [PNode] -> PencilApp [PNode]
evalNodes _ [] = return []
evalNodes env (PVar var : rest) = do
nodes <- evalNodes env rest
case H.lookup var env of
Nothing ->
return $ PVar var : nodes
Just envData -> do
displayValue <- asks getDisplayValue
return $ PText (displayValue envData) : nodes
evalNodes env (PIf var nodes : rest) = do
rest' <- evalNodes env rest
case H.lookup var env of
Nothing ->
return rest'
Just _ -> do
nodes' <- evalNodes env nodes
return $ nodes' ++ rest'
evalNodes env (PFor var nodes : rest) = do
rest' <- evalNodes env rest
case H.lookup var env of
Nothing ->
return rest'
Just (VEnvList envs) -> do
forNodes <-
foldM
(\accNodes e -> do
nodes' <- evalNodes (H.union e env) nodes
return $ accNodes ++ nodes')
[] envs
return $ forNodes ++ rest'
Just _ -> return rest'
evalNodes env (PPartial fp : rest) = do
(_, nodes) <- parseAndConvertTextFiles (T.unpack fp)
nodes' <- evalNodes env nodes
rest' <- evalNodes env rest
return $ nodes' ++ rest'
evalNodes env (n : rest) = do
rest' <- evalNodes env rest
return $ n : rest'
parseAndConvertTextFiles :: FilePath -> PencilApp (T.Text, [PNode])
parseAndConvertTextFiles fp = do
content <- loadTextFile fp
content' <-
case fileType fp of
Markdown -> do
pandocReaderOptions <- asks getPandocReaderOptions
pandocWriterOptions <- asks getPandocWriterOptions
result <- liftIO $ P.runIO (readMarkdownWriteHtml pandocReaderOptions pandocWriterOptions content)
case result of
Left _ -> return content
Right text -> return text
Sass -> do
sassOptions <- asks getSassOptions
sitePrefix <- asks getSourceDir
result <- liftIO $ Sass.compileFile (sitePrefix ++ fp) sassOptions
case result of
Left _ -> return content
Right byteStr -> return $ decodeUtf8 byteStr
_ -> return content
let nodes = case parseText content' of
Left _ -> []
Right n -> n
return (content', nodes)
loadTextFile :: FilePath -> PencilApp T.Text
loadTextFile fp = do
sitePrefix <- asks getSourceDir
eitherContent <- liftIO $ tryJust toPencilException (TIO.readFile (sitePrefix ++ fp))
case eitherContent of
Left e -> throwError e
Right a -> return a
readMarkdownWriteHtml :: P.PandocMonad m => P.ReaderOptions -> P.WriterOptions -> T.Text -> m T.Text
readMarkdownWriteHtml readerOptions writerOptions content = do
pandoc <- P.readMarkdown readerOptions content
P.writeHtml5String writerOptions pandoc