@@ -15,8 +15,9 @@ module Hakyll.Web.Template.Internal
1515import Control.Applicative ((<|>))
1616import Control.Monad (void)
1717import Data.Binary (Binary, get, getWord8, put, putWord8)
18+import Data.List (intercalate)
19+import Data.Maybe (isJust)
1820import Data.Typeable (Typeable)
19−import Data.List (intercalate)
2021import GHC.Exts (IsString (..))
2122import qualified Text.Parsec as P
2223import qualified Text.Parsec.String as P
@@ -34,6 +35,12 @@ newtype Template = Template
3435 } deriving (Show, Eq, Binary, Typeable)
3536
3637
38+--------------------------------------------------------------------------------
39+instance Monoid Template where
40+ mempty = Template []
41+ (Template xs) `mappend` (Template ys) = Template (xs `mappend` ys)
42+
43+
3744--------------------------------------------------------------------------------
3845instance Writable Template where
3946 -- Writing a template is impossible
@@ -131,13 +138,19 @@ readTemplate input = case P.parse template "" input of
131138
132139--------------------------------------------------------------------------------
133140template :: P.Parser Template
134−template = Template <$>
135− (P.many $ chunk <|> escaped <|> conditional <|> for <|> partial <|> expr)
141+template = mconcat <$> P.many (P.choice [ lift chunk
142+ , lift escaped
143+ , conditional
144+ , lift for
145+ , lift partial
146+ , lift expr
147+ ])
148+ where lift = fmap (Template . (:[]))
136149
137150
138151--------------------------------------------------------------------------------
139152chunk :: P.Parser TemplateElement
140−chunk = Chunk <$> (P.many1 $ P.noneOf "$")
153+chunk = Chunk <$> P.many1 (P.noneOf "$")
141154
142155
143156--------------------------------------------------------------------------------
@@ -156,19 +169,56 @@ expr' = stringLiteral <|> call <|> ident
156169
157170--------------------------------------------------------------------------------
158171escaped :: 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
160181
161182
162183--------------------------------------------------------------------------------
163−conditional :: P.Parser TemplateElement
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+--------------------------------------------------------------------------------
192+conditional :: P.Parser Template
164193conditional = P.try $ do
165− void $ P.string "$if("
194+ trimLIf <- trimOpen
195+ void $ P.string "if("
166196 e <- expr'
167− void $ P.string ")$"
197+ void $ P.char ')'
198+ trimRIf <- trimClose
199+
168200 thenBranch <- template
169− elseBranch <- P.optionMaybe $ P.try (P.string "$else$") >> template
170− void $ P.string "$endif$"
171− return $ If e thenBranch elseBranch
201+
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
213+ void $ P.string "endif"
214+ trimREnd <- trimClose
215+
216+ pure $ Template $ mconcat [ [TrimL | trimLIf]
217+ , [TrimR | trimRIf]
218+ , [If e thenBranch elseBranch]
219+ , [TrimL | trimLEnd]
220+ , [TrimR | trimREnd]
221+ ]
172222
173223
174224--------------------------------------------------------------------------------