If Trim parsing

This commit is contained in:
samgd 2016-07-23 12:19:27 +02:00
parent 02dd1cf236
commit 6c0be2e2d3
No known key found for this signature in database
GPG key ID: E69F2FF86041ADB3
2 changed files with 69 additions and 16 deletions

View file

@ -15,8 +15,9 @@ module Hakyll.Web.Template.Internal
import Control.Applicative ((<|>))
import Control.Monad (void)
import Data.Binary (Binary, get, getWord8, put, putWord8)
import Data.Typeable (Typeable)
import Data.List (intercalate)
import Data.Maybe (isJust)
import Data.Typeable (Typeable)
import GHC.Exts (IsString (..))
import qualified Text.Parsec as P
import qualified Text.Parsec.String as P
@ -34,6 +35,12 @@ newtype Template = Template
} deriving (Show, Eq, Binary, Typeable)
--------------------------------------------------------------------------------
instance Monoid Template where
mempty = Template []
(Template xs) `mappend` (Template ys) = Template (xs `mappend` ys)
--------------------------------------------------------------------------------
instance Writable Template where
-- Writing a template is impossible
@ -131,13 +138,19 @@ readTemplate input = case P.parse template "" input of
--------------------------------------------------------------------------------
template :: P.Parser Template
template = Template <$>
(P.many $ chunk <|> escaped <|> conditional <|> for <|> partial <|> expr)
template = mconcat <$> P.many (P.choice [ lift chunk
, lift escaped
, conditional
, lift for
, lift partial
, lift expr
])
where lift = fmap (Template . (:[]))
--------------------------------------------------------------------------------
chunk :: P.Parser TemplateElement
chunk = Chunk <$> (P.many1 $ P.noneOf "$")
chunk = Chunk <$> P.many1 (P.noneOf "$")
--------------------------------------------------------------------------------
@ -156,19 +169,56 @@ expr' = stringLiteral <|> call <|> ident
--------------------------------------------------------------------------------
escaped :: P.Parser TemplateElement
escaped = Escaped <$ (P.try $ P.string "$$")
escaped = Escaped <$ P.try (P.string "$$")
--------------------------------------------------------------------------------
conditional :: P.Parser TemplateElement
trimOpen :: P.Parser Bool
trimOpen = do
void $ P.char '$'
trimLIf <- P.optionMaybe $ P.try (P.char '-')
pure $ isJust trimLIf
--------------------------------------------------------------------------------
trimClose :: P.Parser Bool
trimClose = do
trimIfR <- P.optionMaybe $ P.try (P.char '-')
void $ P.char '$'
pure $ isJust trimIfR
--------------------------------------------------------------------------------
conditional :: P.Parser Template
conditional = P.try $ do
void $ P.string "$if("
trimLIf <- trimOpen
void $ P.string "if("
e <- expr'
void $ P.string ")$"
void $ P.char ')'
trimRIf <- trimClose
thenBranch <- template
elseBranch <- P.optionMaybe $ P.try (P.string "$else$") >> template
void $ P.string "$endif$"
return $ If e thenBranch elseBranch
elseBranch <- P.optionMaybe $ P.try $ do
trimLElse <- trimOpen
void $ P.string "else"
trimRElse <- trimClose
elseBody <- template
pure $ mconcat $ concat [ [Template [TrimL] | trimLElse]
, [Template [TrimR] | trimRElse]
, [elseBody]
]
trimLEnd <- trimOpen
void $ P.string "endif"
trimREnd <- trimClose
pure $ Template $ mconcat [ [TrimL | trimLIf]
, [TrimR | trimRIf]
, [If e thenBranch elseBranch]
, [TrimL | trimLEnd]
, [TrimR | trimREnd]
]
--------------------------------------------------------------------------------

View file

@ -39,16 +39,20 @@ tests = testGroup "Hakyll.Core.Template.Tests" $ concat
(Template [Chunk "foo"])
Nothing]
@=? readTemplate "$if(a(\"bar\"))$foo$endif$"
-- 'If' 'Trim_' test.
-- 'If' trim check.
, Template
[ TrimL
, TrimR
, If (Ident (TemplateKey "body"))
(Template [ TrimR
(Template [ Chunk "\n"
, Expr (Ident (TemplateKey "body"))
, Chunk "\n"
])
(Just (Template [ TrimL
, TrimR
, Chunk "\n"
, Expr (Ident (TemplateKey "body"))
, Chunk "\n"
]))
, TrimL
, TrimR
@ -65,8 +69,7 @@ case01 = do
provider <- newTestProvider store
out <- resourceString provider "template.html.out"
tpl <- testCompilerDone store provider "template.html" $
templateBodyCompiler
tpl <- testCompilerDone store provider "template.html" templateBodyCompiler
item <- testCompilerDone store provider "example.md" $
pandocCompiler >>= applyTemplate (itemBody tpl) testContext