@@ -1,13 +1,12 @@
1--------------------------------------------------------------------------------
1--------------------------------------------------------------------------------
2-- | Module containing the template data structure
2-- | Module containing the template data structure
3−{-# LANGUAGE DeriveDataTypeable #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5module Hakyll.Web.Template.Internal
4module Hakyll.Web.Template.Internal
7− , TemplateKey (..)
5+ ( TemplateKey (..)
8 , TemplateExpr (..)
6 , TemplateExpr (..)
9 , TemplateElement (..)
7 , TemplateElement (..)
10− , readTemplate
8+ , templateElems
@@ -25,31 +24,6 @@ import qualified Text.Parsec.String as P
26--------------------------------------------------------------------------------
25--------------------------------------------------------------------------------
27import Hakyll.Core.Util.Parser
26import Hakyll.Core.Util.Parser
28−import Hakyll.Core.Writable
31−--------------------------------------------------------------------------------
32−-- | Datatype used for template substitutions.
33−newtype Template = Template
34− { unTemplate :: [TemplateElement]
35− } deriving (Show, Eq, Binary, Typeable)
38−--------------------------------------------------------------------------------
39−instance Monoid Template where
41− (Template xs) `mappend` (Template ys) = Template (xs `mappend` ys)
44−--------------------------------------------------------------------------------
45−instance Writable Template where
46− -- Writing a template is impossible
47− write _ _ = return ()
50−--------------------------------------------------------------------------------
51−instance IsString Template where
52− fromString = readTemplate
55--------------------------------------------------------------------------------
29--------------------------------------------------------------------------------
@@ -68,9 +42,12 @@ data TemplateElement
68 = Chunk String
42 = Chunk String
69 | Expr TemplateExpr
43 | Expr TemplateExpr
71− | If TemplateExpr Template (Maybe Template) -- expr, then, else
45+ -- expr, then, else
46+ | If TemplateExpr [TemplateElement] (Maybe [TemplateElement])
72− | For TemplateExpr Template (Maybe Template) -- expr, body, separator
47+ -- expr, body, separator
48+ | For TemplateExpr [TemplateElement] (Maybe [TemplateElement])
73− | Partial TemplateExpr -- filename
50+ | Partial TemplateExpr
76 deriving (Show, Eq, Typeable)
53 deriving (Show, Eq, Typeable)
@@ -130,36 +107,22 @@ instance Binary TemplateExpr where
132--------------------------------------------------------------------------------
109--------------------------------------------------------------------------------
133−(.~) :: [TemplateElement] -> Template -> Template
110+readTemplateElems :: String -> [TemplateElement]
134−ts .~ (Template t) = Template (ts ++ t)
139−--------------------------------------------------------------------------------
140−(~.) :: Template -> [TemplateElement] -> Template
141−(Template t) ~. ts = Template (t ++ ts)
146−--------------------------------------------------------------------------------
147−readTemplate :: String -> Template
148−readTemplate input = case P.parse template "" input of
111+readTemplateElems input = case P.parse templateElems "" input of
149 Left err -> error $ "Cannot parse template: " ++ show err
112 Left err -> error $ "Cannot parse template: " ++ show err
150 Right t -> t
113 Right t -> t
153--------------------------------------------------------------------------------
116--------------------------------------------------------------------------------
154−template :: P.Parser Template
117+templateElems :: P.Parser [TemplateElement]
155−template = mconcat <$> P.many (P.choice [ lift chunk
118+templateElems = mconcat <$> P.many (P.choice [ lift chunk
156 , lift escaped
119 , lift escaped
157 , conditional
120 , conditional
159 , partial
122 , partial
162− where lift = fmap (Template . (:[]))
125+ where lift = fmap (:[])
165--------------------------------------------------------------------------------
128--------------------------------------------------------------------------------
@@ -168,12 +131,12 @@ chunk = Chunk <$> P.many1 (P.noneOf "$")
170--------------------------------------------------------------------------------
133--------------------------------------------------------------------------------
171−expr :: P.Parser Template
134+expr :: P.Parser [TemplateElement]
172expr = P.try $ do
135expr = P.try $ do
173 trimLExpr <- trimOpen
136 trimLExpr <- trimOpen
174 e <- expr'
137 e <- expr'
175 trimRExpr <- trimClose
138 trimRExpr <- trimClose
176− return $ [TrimL | trimLExpr] .~ Template [Expr e] ~. [TrimR | trimRExpr]
139+ return $ [TrimL | trimLExpr] ++ [Expr e] ++ [TrimR | trimRExpr]
179--------------------------------------------------------------------------------
142--------------------------------------------------------------------------------
@@ -203,7 +166,7 @@ trimClose = do
205--------------------------------------------------------------------------------
168--------------------------------------------------------------------------------
206−conditional :: P.Parser Template
169+conditional :: P.Parser [TemplateElement]
207conditional = P.try $ do
170conditional = P.try $ do
209 trimLIf <- trimOpen
172 trimLIf <- trimOpen
@@ -212,7 +175,7 @@ conditional = P.try $ do
212 void $ P.char ')'
175 void $ P.char ')'
213 trimRIf <- trimClose
176 trimRIf <- trimClose
215− thenBranch <- template
178+ thenBranch <- templateElems
217 elseParse <- opt "else"
180 elseParse <- opt "else"
@@ -223,24 +186,22 @@ conditional = P.try $ do
223 -- As else is optional we need to sort out where any Trim_s need to go.
186 -- As else is optional we need to sort out where any Trim_s need to go.
224 let (thenBody, elseBody) = maybe (thenNoElse, Nothing) thenElse elseParse
187 let (thenBody, elseBody) = maybe (thenNoElse, Nothing) thenElse elseParse
225 where thenNoElse =
188 where thenNoElse =
226− [TrimR | trimRIf] .~ thenBranch ~. [TrimL | trimLEnd]
189+ [TrimR | trimRIf] ++ thenBranch ++ [TrimL | trimLEnd]
228 thenElse (trimLElse, elseBranch, trimRElse) = (thenB, elseB)
191 thenElse (trimLElse, elseBranch, trimRElse) = (thenB, elseB)
229 where thenB = [TrimR | trimRIf]
192 where thenB = [TrimR | trimRIf]
230− .~ thenBranch
193+ ++ thenBranch
231− ~. [TrimL | trimLElse]
194+ ++ [TrimL | trimLElse]
233 elseB = Just $ [TrimR | trimRElse]
196 elseB = Just $ [TrimR | trimRElse]
234− .~ elseBranch
197+ ++ elseBranch
235− ~. [TrimL | trimLEnd]
198+ ++ [TrimL | trimLEnd]
237− pure $ [TrimL | trimLIf]
200+ pure $ [TrimL | trimLIf] ++ [If e thenBody elseBody] ++ [TrimR | trimREnd]
238− .~ Template [If e thenBody elseBody]
239− ~. [TrimR | trimREnd]
242--------------------------------------------------------------------------------
203--------------------------------------------------------------------------------
243−for :: P.Parser Template
204+for :: P.Parser [TemplateElement]
244for = P.try $ do
205for = P.try $ do
246 trimLFor <- trimOpen
207 trimLFor <- trimOpen
@@ -249,7 +210,7 @@ for = P.try $ do
249 void $ P.char ')'
210 void $ P.char ')'
250 trimRFor <- trimClose
211 trimRFor <- trimClose
252− bodyBranch <- template
213+ bodyBranch <- templateElems
254 sepParse <- opt "sep"
215 sepParse <- opt "sep"
255 -- endfor
216 -- endfor
@@ -260,24 +221,22 @@ for = P.try $ do
260 -- As sep is optional we need to sort out where any Trim_s need to go.
221 -- As sep is optional we need to sort out where any Trim_s need to go.
261 let (forBody, sepBody) = maybe (forNoSep, Nothing) forSep sepParse
222 let (forBody, sepBody) = maybe (forNoSep, Nothing) forSep sepParse
262 where forNoSep =
223 where forNoSep =
263− [TrimR | trimRFor] .~ bodyBranch ~. [TrimL | trimLEnd]
224+ [TrimR | trimRFor] ++ bodyBranch ++ [TrimL | trimLEnd]
265 forSep (trimLSep, sepBranch, trimRSep) = (forB, sepB)
226 forSep (trimLSep, sepBranch, trimRSep) = (forB, sepB)
266 where forB = [TrimR | trimRFor]
227 where forB = [TrimR | trimRFor]
267− .~ bodyBranch
228+ ++ bodyBranch
268− ~. [TrimL | trimLSep]
229+ ++ [TrimL | trimLSep]
270 sepB = Just $ [TrimR | trimRSep]
231 sepB = Just $ [TrimR | trimRSep]
271− .~ sepBranch
232+ ++ sepBranch
272− ~. [TrimL | trimLEnd]
233+ ++ [TrimL | trimLEnd]
274− pure $ [TrimL | trimLFor]
235+ pure $ [TrimL | trimLFor] ++ [For e forBody sepBody] ++ [TrimR | trimREnd]
275− .~ Template [For e forBody sepBody]
276− ~. [TrimR | trimREnd]
279--------------------------------------------------------------------------------
238--------------------------------------------------------------------------------
280−partial :: P.Parser Template
239+partial :: P.Parser [TemplateElement]
281partial = P.try $ do
240partial = P.try $ do
282 trimLPart <- trimOpen
241 trimLPart <- trimOpen
283 void $ P.string "partial("
242 void $ P.string "partial("
@@ -285,7 +244,7 @@ partial = P.try $ do
285 void $ P.char ')'
244 void $ P.char ')'
286 trimRPart <- trimClose
245 trimRPart <- trimClose
288− pure $ [TrimL | trimLPart] .~ Template [Partial e] ~. [TrimR | trimRPart]
247+ pure $ [TrimL | trimLPart] ++ [Partial e] ++ [TrimR | trimRPart]
291--------------------------------------------------------------------------------
250--------------------------------------------------------------------------------
@@ -322,11 +281,11 @@ key = TemplateKey <$> metadataKey
324--------------------------------------------------------------------------------
283--------------------------------------------------------------------------------
325−opt :: String -> P.Parser (Maybe (Bool, Template, Bool))
284+opt :: String -> P.Parser (Maybe (Bool, [TemplateElement], Bool))
326opt clause = P.optionMaybe $ P.try $ do
285opt clause = P.optionMaybe $ P.try $ do
327 trimL <- trimOpen
286 trimL <- trimOpen
328 void $ P.string clause
287 void $ P.string clause
329 trimR <- trimClose
288 trimR <- trimClose
330− branch <- template
289+ branch <- templateElems
331 pure (trimL, branch, trimR)
290 pure (trimL, branch, trimR)