on master help sign in
If Trim parsing
6c0be2esamgd
src/Hakyll/Web/Template/Internal.hs+61−11
@@ -15,8 +15,9 @@ module Hakyll.Web.Template.Internal
15import Control.Applicative ((<|>))
15import Control.Applicative ((<|>))
16import Control.Monad (void)
16import Control.Monad (void)
17import Data.Binary (Binary, get, getWord8, put, putWord8)
17import Data.Binary (Binary, get, getWord8, put, putWord8)
18+import Data.List (intercalate)
19+import Data.Maybe (isJust)
18import Data.Typeable (Typeable)
20import Data.Typeable (Typeable)
19−import Data.List (intercalate)
20import GHC.Exts (IsString (..))
21import GHC.Exts (IsString (..))
21import qualified Text.Parsec as P
22import qualified Text.Parsec as P
22import qualified Text.Parsec.String as P
23import qualified Text.Parsec.String as P
@@ -34,6 +35,12 @@ newtype Template = Template
34 } deriving (Show, Eq, Binary, Typeable)
35 } deriving (Show, Eq, Binary, Typeable)
35
36
36
37
38+--------------------------------------------------------------------------------
39+instance Monoid Template where
40+ mempty = Template []
41+ (Template xs) `mappend` (Template ys) = Template (xs `mappend` ys)
42+
43+
37--------------------------------------------------------------------------------
44--------------------------------------------------------------------------------
38instance Writable Template where
45instance Writable Template where
39 -- Writing a template is impossible
46 -- Writing a template is impossible
@@ -131,13 +138,19 @@ readTemplate input = case P.parse template "" input of
131
138
132--------------------------------------------------------------------------------
139--------------------------------------------------------------------------------
133template :: P.Parser Template
140template :: P.Parser Template
134−template = Template <$>
141+template = mconcat <$> P.many (P.choice [ lift chunk
142+ , lift escaped
135− (P.many $ chunk <|> escaped <|> conditional <|> for <|> partial <|> expr)
143+ , conditional
144+ , lift for
145+ , lift partial
146+ , lift expr
147+ ])
148+ where lift = fmap (Template . (:[]))
136
149
137
150
138--------------------------------------------------------------------------------
151--------------------------------------------------------------------------------
139chunk :: P.Parser TemplateElement
152chunk :: P.Parser TemplateElement
140−chunk = Chunk <$> (P.many1 $ P.noneOf "$")
153+chunk = Chunk <$> P.many1 (P.noneOf "$")
141
154
142
155
143--------------------------------------------------------------------------------
156--------------------------------------------------------------------------------
@@ -156,19 +169,56 @@ expr' = stringLiteral <|> call <|> ident
156
169
157--------------------------------------------------------------------------------
170--------------------------------------------------------------------------------
158escaped :: P.Parser TemplateElement
171escaped :: P.Parser TemplateElement
159−escaped = Escaped <$ (P.try $ P.string "$$")
172+escaped = Escaped <$ P.try (P.string "$$")
173+
174+
175+--------------------------------------------------------------------------------
176+trimOpen :: P.Parser Bool
177+trimOpen = do
178+ void $ P.char '$'
179+ trimLIf <- P.optionMaybe $ P.try (P.char '-')
180+ pure $ isJust trimLIf
160
181
161
182
162--------------------------------------------------------------------------------
183--------------------------------------------------------------------------------
184+trimClose :: P.Parser Bool
185+trimClose = do
186+ trimIfR <- P.optionMaybe $ P.try (P.char '-')
187+ void $ P.char '$'
188+ pure $ isJust trimIfR
189+
190+
191+--------------------------------------------------------------------------------
163−conditional :: P.Parser TemplateElement
192+conditional :: P.Parser Template
164conditional = P.try $ do
193conditional = P.try $ do
194+ trimLIf <- trimOpen
165− void $ P.string "$if("
195+ void $ P.string "if("
166 e <- expr'
196 e <- expr'
167− void $ P.string ")$"
197+ void $ P.char ')'
198+ trimRIf <- trimClose
199+
168 thenBranch <- template
200 thenBranch <- template
201+
169− elseBranch <- P.optionMaybe $ P.try (P.string "$else$") >> template
202+ elseBranch <- P.optionMaybe $ P.try $ do
203+ trimLElse <- trimOpen
204+ void $ P.string "else"
205+ trimRElse <- trimClose
206+ elseBody <- template
207+ pure $ mconcat $ concat [ [Template [TrimL] | trimLElse]
208+ , [Template [TrimR] | trimRElse]
209+ , [elseBody]
210+ ]
211+
212+ trimLEnd <- trimOpen
170− void $ P.string "$endif$"
213+ void $ P.string "endif"
214+ trimREnd <- trimClose
215+
216+ pure $ Template $ mconcat [ [TrimL | trimLIf]
217+ , [TrimR | trimRIf]
171− return $ If e thenBranch elseBranch
218+ , [If e thenBranch elseBranch]
219+ , [TrimL | trimLEnd]
220+ , [TrimR | trimREnd]
221+ ]
172
222
173
223
174--------------------------------------------------------------------------------
224--------------------------------------------------------------------------------
tests/Hakyll/Web/Template/Tests.hs+8−5
@@ -39,16 +39,20 @@ tests = testGroup "Hakyll.Core.Template.Tests" $ concat
39 (Template [Chunk "foo"])
39 (Template [Chunk "foo"])
40 Nothing]
40 Nothing]
41 @=? readTemplate "$if(a(\"bar\"))$foo$endif$"
41 @=? readTemplate "$if(a(\"bar\"))$foo$endif$"
42− -- 'If' 'Trim_' test.
42+ -- 'If' trim check.
43 , Template
43 , Template
44 [ TrimL
44 [ TrimL
45+ , TrimR
45 , If (Ident (TemplateKey "body"))
46 , If (Ident (TemplateKey "body"))
46− (Template [ TrimR
47+ (Template [ Chunk "\n"
47 , Expr (Ident (TemplateKey "body"))
48 , Expr (Ident (TemplateKey "body"))
49+ , Chunk "\n"
48 ])
50 ])
49 (Just (Template [ TrimL
51 (Just (Template [ TrimL
50 , TrimR
52 , TrimR
53+ , Chunk "\n"
51 , Expr (Ident (TemplateKey "body"))
54 , Expr (Ident (TemplateKey "body"))
55+ , Chunk "\n"
52 ]))
56 ]))
53 , TrimL
57 , TrimL
54 , TrimR
58 , TrimR
@@ -65,9 +69,8 @@ case01 = do
65 provider <- newTestProvider store
69 provider <- newTestProvider store
66
70
67 out <- resourceString provider "template.html.out"
71 out <- resourceString provider "template.html.out"
68− tpl <- testCompilerDone store provider "template.html" $
72+ tpl <- testCompilerDone store provider "template.html" templateBodyCompiler
69− templateBodyCompiler
70− item <- testCompilerDone store provider "example.md" $
73+ item <- testCompilerDone store provider "example.md" $
71 pandocCompiler >>= applyTemplate (itemBody tpl) testContext
74 pandocCompiler >>= applyTemplate (itemBody tpl) testContext
72
75
73 out @=? itemBody item
76 out @=? itemBody item