on master help sign in
Fix module layout
43c969fsamgd
src/Hakyll/Web/Template.hs+37−9
@@ -115,7 +115,8 @@
115-- That is, calling @$partial$@ is equivalent to just copying and pasting
115-- That is, calling @$partial$@ is equivalent to just copying and pasting
116-- template code.
116-- template code.
117--
117--
118+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
118−{-# LANGUAGE ScopedTypeVariables #-}
119+{-# LANGUAGE ScopedTypeVariables #-}
119module Hakyll.Web.Template
120module Hakyll.Web.Template
120 ( Template
121 ( Template
121 , templateBodyCompiler
122 , templateBodyCompiler
@@ -128,9 +129,11 @@ module Hakyll.Web.Template
128
129
129
130
130--------------------------------------------------------------------------------
131--------------------------------------------------------------------------------
131−import Control.Monad (liftM)
132import Control.Monad.Except (MonadError (..))
132import Control.Monad.Except (MonadError (..))
133+import Data.Binary (Binary)
133import Data.List (intercalate)
134import Data.List (intercalate)
135+import Data.Typeable (Typeable)
136+import GHC.Exts (IsString (..))
134import Prelude hiding (id)
137import Prelude hiding (id)
135
138
136
139
@@ -138,8 +141,33 @@ import Prelude hiding (id)
138import Hakyll.Core.Compiler
141import Hakyll.Core.Compiler
139import Hakyll.Core.Identifier
142import Hakyll.Core.Identifier
140import Hakyll.Core.Item
143import Hakyll.Core.Item
144+import Hakyll.Core.Writable
141import Hakyll.Web.Template.Context
145import Hakyll.Web.Template.Context
142import Hakyll.Web.Template.Internal
146import Hakyll.Web.Template.Internal
147+import Hakyll.Web.Template.Trim
148+
149+
150+--------------------------------------------------------------------------------
151+-- | Datatype used for template substitutions.
152+newtype Template = Template
153+ { unTemplate :: [TemplateElement]
154+ } deriving (Show, Eq, Binary, Typeable)
155+
156+
157+--------------------------------------------------------------------------------
158+instance Writable Template where
159+ -- Writing a template is impossible
160+ write _ _ = return ()
161+
162+
163+--------------------------------------------------------------------------------
164+instance IsString Template where
165+ fromString = readTemplate
166+
167+
168+--------------------------------------------------------------------------------
169+readTemplate :: String -> Template
170+readTemplate = Template . trim . readTemplateElems
143
171
144
172
145--------------------------------------------------------------------------------
173--------------------------------------------------------------------------------
@@ -163,23 +191,23 @@ applyTemplate :: Template -- ^ Template
163 -> Item a -- ^ Page
191 -> Item a -- ^ Page
164 -> Compiler (Item String) -- ^ Resulting item
192 -> Compiler (Item String) -- ^ Resulting item
165applyTemplate tpl context item = do
193applyTemplate tpl context item = do
166− body <- applyTemplate' tpl context item
194+ body <- applyTemplate' (unTemplate tpl) context item
167 return $ itemSetBody body item
195 return $ itemSetBody body item
168
196
169
197
170--------------------------------------------------------------------------------
198--------------------------------------------------------------------------------
171applyTemplate'
199applyTemplate'
172 :: forall a.
200 :: forall a.
173− Template -- ^ Template
201+ [TemplateElement] -- ^ Unwrapped Template
174− -> Context a -- ^ Context
202+ -> Context a -- ^ Context
175− -> Item a -- ^ Page
203+ -> Item a -- ^ Page
176− -> Compiler String -- ^ Resulting item
204+ -> Compiler String -- ^ Resulting item
177−applyTemplate' tpl context x = go tpl
205+applyTemplate' tes context x = go tes
178 where
206 where
179 context' :: String -> [String] -> Item a -> Compiler ContextField
207 context' :: String -> [String] -> Item a -> Compiler ContextField
180 context' = unContext (context `mappend` missingField)
208 context' = unContext (context `mappend` missingField)
181
209
182− go = liftM concat . mapM applyElem . unTemplate
210+ go = fmap concat . mapM applyElem
183
211
184 ---------------------------------------------------------------------------
212 ---------------------------------------------------------------------------
185
213
src/Hakyll/Web/Template/Internal.hs+36−77
@@ -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
6− ( Template (..)
7− , TemplateKey (..)
5+ ( TemplateKey (..)
8 , TemplateExpr (..)
6 , TemplateExpr (..)
9 , TemplateElement (..)
7 , TemplateElement (..)
10− , readTemplate
8+ , templateElems
9+ , readTemplateElems
11 ) where
10 ) where
12
11
13
12
@@ -25,31 +24,6 @@ import qualified Text.Parsec.String as P
25
24
26--------------------------------------------------------------------------------
25--------------------------------------------------------------------------------
27import Hakyll.Core.Util.Parser
26import Hakyll.Core.Util.Parser
28−import Hakyll.Core.Writable
29−
30−
31−--------------------------------------------------------------------------------
32−-- | Datatype used for template substitutions.
33−newtype Template = Template
34− { unTemplate :: [TemplateElement]
35− } deriving (Show, Eq, Binary, Typeable)
36−
37−
38−--------------------------------------------------------------------------------
39−instance Monoid Template where
40− mempty = Template []
41− (Template xs) `mappend` (Template ys) = Template (xs `mappend` ys)
42−
43−
44−--------------------------------------------------------------------------------
45−instance Writable Template where
46− -- Writing a template is impossible
47− write _ _ = return ()
48−
49−
50−--------------------------------------------------------------------------------
51−instance IsString Template where
52− fromString = readTemplate
53
27
54
28
55--------------------------------------------------------------------------------
29--------------------------------------------------------------------------------
@@ -68,9 +42,12 @@ data TemplateElement
68 = Chunk String
42 = Chunk String
69 | Expr TemplateExpr
43 | Expr TemplateExpr
70 | Escaped
44 | Escaped
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])
49+ -- filename
73− | Partial TemplateExpr -- filename
50+ | Partial TemplateExpr
74 | TrimL
51 | TrimL
75 | TrimR
52 | TrimR
76 deriving (Show, Eq, Typeable)
53 deriving (Show, Eq, Typeable)
@@ -130,36 +107,22 @@ instance Binary TemplateExpr where
130
107
131
108
132--------------------------------------------------------------------------------
109--------------------------------------------------------------------------------
133−(.~) :: [TemplateElement] -> Template -> Template
110+readTemplateElems :: String -> [TemplateElement]
134−ts .~ (Template t) = Template (ts ++ t)
135−
136−infixr 6 .~
137−
138−
139−--------------------------------------------------------------------------------
140−(~.) :: Template -> [TemplateElement] -> Template
141−(Template t) ~. ts = Template (t ++ ts)
142−
143−infixl 5 ~.
144−
145−
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
151
114
152
115
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
158 , for
121 , for
159 , partial
122 , partial
160 , expr
123 , expr
161 ])
124 ])
162− where lift = fmap (Template . (:[]))
125+ where lift = fmap (:[])
163
126
164
127
165--------------------------------------------------------------------------------
128--------------------------------------------------------------------------------
@@ -168,12 +131,12 @@ chunk = Chunk <$> P.many1 (P.noneOf "$")
168
131
169
132
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]
177
140
178
141
179--------------------------------------------------------------------------------
142--------------------------------------------------------------------------------
@@ -203,7 +166,7 @@ trimClose = do
203
166
204
167
205--------------------------------------------------------------------------------
168--------------------------------------------------------------------------------
206−conditional :: P.Parser Template
169+conditional :: P.Parser [TemplateElement]
207conditional = P.try $ do
170conditional = P.try $ do
208 -- if
171 -- if
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
214 -- then
177 -- then
215− thenBranch <- template
178+ thenBranch <- templateElems
216 -- else
179 -- else
217 elseParse <- opt "else"
180 elseParse <- opt "else"
218 -- endif
181 -- endif
@@ -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]
227
190
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]
232
195
233 elseB = Just $ [TrimR | trimRElse]
196 elseB = Just $ [TrimR | trimRElse]
234− .~ elseBranch
197+ ++ elseBranch
235− ~. [TrimL | trimLEnd]
198+ ++ [TrimL | trimLEnd]
236
199
237− pure $ [TrimL | trimLIf]
200+ pure $ [TrimL | trimLIf] ++ [If e thenBody elseBody] ++ [TrimR | trimREnd]
238− .~ Template [If e thenBody elseBody]
239− ~. [TrimR | trimREnd]
240
201
241
202
242--------------------------------------------------------------------------------
203--------------------------------------------------------------------------------
243−for :: P.Parser Template
204+for :: P.Parser [TemplateElement]
244for = P.try $ do
205for = P.try $ do
245 -- for
206 -- for
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
251 -- body
212 -- body
252− bodyBranch <- template
213+ bodyBranch <- templateElems
253 -- sep
214 -- sep
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]
264
225
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]
269
230
270 sepB = Just $ [TrimR | trimRSep]
231 sepB = Just $ [TrimR | trimRSep]
271− .~ sepBranch
232+ ++ sepBranch
272− ~. [TrimL | trimLEnd]
233+ ++ [TrimL | trimLEnd]
273
234
274− pure $ [TrimL | trimLFor]
235+ pure $ [TrimL | trimLFor] ++ [For e forBody sepBody] ++ [TrimR | trimREnd]
275− .~ Template [For e forBody sepBody]
276− ~. [TrimR | trimREnd]
277
236
278
237
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
287
246
288− pure $ [TrimL | trimLPart] .~ Template [Partial e] ~. [TrimR | trimRPart]
247+ pure $ [TrimL | trimLPart] ++ [Partial e] ++ [TrimR | trimRPart]
289
248
290
249
291--------------------------------------------------------------------------------
250--------------------------------------------------------------------------------
@@ -322,11 +281,11 @@ key = TemplateKey <$> metadataKey
322
281
323
282
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)
332
291
src/Hakyll/Web/Template/Trim.hs+27−118
@@ -1,6 +1,6 @@
1--------------------------------------------------------------------------------
1--------------------------------------------------------------------------------
2−-- | TODO
2+-- | Module for trimming whitespace.
3−module Hakyll.Web.Template.Internal.Trim
3+module Hakyll.Web.Template.Trim
4 ( trim
4 ( trim
5 ) where
5 ) where
6
6
@@ -15,13 +15,13 @@ import Hakyll.Web.Template.Internal
15
15
16
16
17--------------------------------------------------------------------------------
17--------------------------------------------------------------------------------
18−trim :: Template -> Template
18+trim :: [TemplateElement] -> [TemplateElement]
19trim = cleanse . canonicalize
19trim = cleanse . canonicalize
20
20
21
21
22--------------------------------------------------------------------------------
22--------------------------------------------------------------------------------
23−cleanse :: Template -> Template
23+cleanse :: [TemplateElement] -> [TemplateElement]
24−cleanse = tmap (recurse cleanse . process)
24+cleanse = recurse cleanse . process
25 where process [] = []
25 where process [] = []
26 process (TrimR:Chunk str:ts) = Chunk (lstrip str):process ts
26 process (TrimR:Chunk str:ts) = Chunk (lstrip str):process ts
27 process (Chunk str:TrimL:ts) = Chunk (rstrip str):process ts
27 process (Chunk str:TrimL:ts) = Chunk (rstrip str):process ts
@@ -31,83 +31,43 @@ cleanse = tmap (recurse cleanse . process)
31 rstrip = dropWhileEnd isSpace
31 rstrip = dropWhileEnd isSpace
32
32
33--------------------------------------------------------------------------------
33--------------------------------------------------------------------------------
34+-- | Enforce the invariant that:
34--
35--
35−-- Invariant: Every TrimL should have a Chunk to its Left
36+-- * Every 'TrimL' has a 'Chunk' to its left.
36−-- Every TrimR should have a Chunk to its Right
37+-- * Every 'TrimR' has a 'Chunk' to its right.
37--
38--
38−--
39+canonicalize :: [TemplateElement] -> [TemplateElement]
39−-- Some initial implementation notes. Note: Not valid syntax etc.
40−--
41−--
42−--
43−--
44−--------------------------------------------------------------------------------
45−canonicalize :: Template -> Template
46canonicalize = go
40canonicalize = go
47− where go t = let t' = redundant . swap . dedupe $ sink t
41+ where go t = let t' = redundant . swap $ dedupe t
48 in if t == t' then t else go t'
42 in if t == t' then t else go t'
49
43
50
44
51--------------------------------------------------------------------------------
45--------------------------------------------------------------------------------
52−-- | 'redundant' removes the redundant 'TrimR's and 'TrimL's from the
46+-- | Remove the 'TrimR' and 'TrimL's that are no-ops.
53−-- 'Template's list of 'TemplateExpr's. It does _not_ recurse down the AST.
47+redundant :: [TemplateElement] -> [TemplateElement]
54−--
55−-- Note: Should _only_ be used on the top level 'Template'.
56−--
57−redundant :: Template -> Template
58−redundant = tmap (recurse redundant . process)
48+redundant = recurse redundant . process
59 where -- Remove the leading 'TrimL's.
49 where -- Remove the leading 'TrimL's.
60 process (TrimL:ts) = process ts
50 process (TrimL:ts) = process ts
61 -- Remove trailing 'TrimR's.
51 -- Remove trailing 'TrimR's.
62 process ts = foldr trailing [] ts
52 process ts = foldr trailing [] ts
63 where trailing TrimR [] = []
53 where trailing TrimR [] = []
64− trailing t ts = t:ts
54+ trailing x xs = x:xs
65
55
66
56
67--------------------------------------------------------------------------------
57--------------------------------------------------------------------------------
68−-- Commute:
58+-- >>> swap $ [TrimR, TrimL]
69−--
70−-- List:
71−--
72−-- [t1, TrimR, TrimL, t2] = [t1, TrimL, TrimR, t2]
59+-- [TrimL, TrimR]
73−--
60+swap :: [TemplateElement] -> [TemplateElement]
74−-- Rest should come for free provided Trim's are Sunk/Shifted etc I think.
75−--
76−swap :: Template -> Template
77−swap = tmap (recurse swap . process)
61+swap = recurse swap . process
78 where process [] = []
62 where process [] = []
79 process (TrimR:TrimL:ts) = TrimL:process (TrimR:ts)
63 process (TrimR:TrimL:ts) = TrimL:process (TrimR:ts)
80 process (t:ts) = t:process ts
64 process (t:ts) = t:process ts
81
65
82
66
83--------------------------------------------------------------------------------
67--------------------------------------------------------------------------------
84−--
68+-- | Remove 'TrimR' and 'TrimL' duplication.
85−-- Dedupe:
69+dedupe :: [TemplateElement] -> [TemplateElement]
86−--
87−-- List:
88−--
89−-- [t1, TrimR, TrimR, t2] = [t1, TrimR, t2]
90−--
91−-- [t1, TrimL, TrimL, t2] = [t1, TrimL, t2]
92−--
93−-- If: Should come for free after Trim_'s have been sunk.
94−--
95−-- [t1, TrimR, If ex [TrimR, t] e, t2] = [t1, If ex [TrimR, t] e, t2]
96−--
97−-- [t1, If ex t [e, TrimL], TrimL, t2] = [t1, If ex t [e, TrimL], t2]
98−--
99−-- [t1, If ex [t, TrimL] Nothing, TrimL, t2] = [t1, If ex [t, TrimL] Nothing, t2]
100−--
101−-- For:
102−--
103−-- [t1, TrimR, For e [TrimR, b] sep, t2] = [t1, For e [TrimR, b] sep, t2]
104−--
105−-- [t1, For e b [sep, TrimL], TrimL, t2] = [t1, For e b [sep, TrimL], t2]
106−--
107−-- [t1, For e [b, TrimL] Nothing, TrimL, t2] = [t1, For e [b, TrimL] Nothing, t2]
108−--
109−dedupe :: Template -> Template
110−dedupe = tmap (recurse dedupe . process)
70+dedupe = recurse dedupe . process
111 where process [] = []
71 where process [] = []
112 process (TrimR:TrimR:ts) = process (TrimR:ts)
72 process (TrimR:TrimR:ts) = process (TrimR:ts)
113 process (TrimL:TrimL:ts) = process (TrimL:ts)
73 process (TrimL:TrimL:ts) = process (TrimL:ts)
@@ -115,64 +75,13 @@ dedupe = tmap (recurse dedupe . process)
115
75
116
76
117--------------------------------------------------------------------------------
77--------------------------------------------------------------------------------
118−--
119−-- Sink:
120−--
121−-- If:
122−--
123−-- [t1, TrimR, If ex t e, t2] = [t1, If ex [TrimR, t] e, t2]
124−--
125−-- [t1, If ex t e, TrimL, t2] = if isJust e
126−-- then [t1, If ex t [e, TrimL], t2]
127−-- else [t1, If ex [t, TrimL] e, t2]
128−--
129−-- For:
130−--
131−-- [t1, TrimR, For e b sep, t2] = [t1, For e [TrimR, b] sep, t2]
132−--
133−-- [t1, For e b sep, TrimL, t2] = if isJust sep
134−-- then [t1, For e b [sep, TrimL], t2]
135−-- else [t1, For e [b, TrimL] sep, t2]
136−--
137−--
138−sink :: Template -> Template
139−sink = tmap (recurse sink . process)
140− where process [] = []
141− -- Right sink TrimR into If thenbody.
142− process (TrimR:If e (Template tb) eb:ts)
143− = If e (Template (TrimR:tb)) eb:process ts
144− -- Left sink TrimL into If thenbody.
145− process (If e (Template tb) Nothing:TrimL:ts)
146− = If e (Template (tb ++ [TrimL])) Nothing:process ts
147− -- Left sink TrimL into If elsebody.
148− process (If e tb (Just (Template eb)):TrimL:ts)
149− = If e tb (Just (Template (eb ++ [TrimL]))):process ts
150− -- Right sink TrimR into For body.
151− process (TrimR:For e (Template b) sep:ts)
152− = For e (Template (TrimR:b)) sep:process ts
153− -- Left sink TrimL into For body.
154− process (For e (Template b) Nothing:TrimL:ts)
155− = For e (Template (b ++ [TrimL])) Nothing:process ts
156− -- Left sink TrimL into For sep.
157− process (For e b (Just (Template sep)):TrimL:ts)
158− = For e b (Just (Template (sep ++ [TrimL]))):process ts
159− -- Otherwise move on.
160− process (t:ts) = t:process ts
161−
162−
163−--------------------------------------------------------------------------------
164−tmap :: ([TemplateElement] -> [TemplateElement]) -> Template -> Template
78+recurse :: ([TemplateElement] -> [TemplateElement])
165−tmap f (Template t) = Template (f t)
166−
167−
168−--------------------------------------------------------------------------------
169−recurse :: (Template -> Template) -> [TemplateElement] -> [TemplateElement]
79+ -> [TemplateElement]
80+ -> [TemplateElement]
170−recurse f [] = []
81+recurse _ [] = []
171recurse f (x:xs) = process x:recurse f xs
82recurse f (x:xs) = process x:recurse f xs
172− where process x = case x of
83+ where process y = case y of
173 If e tb eb -> If e (f tb) (f <$> eb)
84 If e tb eb -> If e (f tb) (f <$> eb)
174 For e t s -> For e (f t) (f <$> s)
85 For e t s -> For e (f t) (f <$> s)
175− _ -> x
86+ _ -> y
176
87
177−
178−--------------------------------------------------------------------------------
tests/Hakyll/Web/Template/Tests.hs+39−48
@@ -31,57 +31,48 @@ tests = testGroup "Hakyll.Core.Template.Tests" $ concat
31 ]
31 ]
32
32
33 , fromAssertions "readTemplate"
33 , fromAssertions "readTemplate"
34− [ Template [Chunk "Hello ", Expr (Call "guest" [])]
34+ [ [Chunk "Hello ", Expr (Call "guest" [])]
35− @=? readTemplate "Hello $guest()$"
35+ @=? readTemplateElems "Hello $guest()$"
36− , Template
37− [If (Call "a" [StringLiteral "bar"])
36+ , [If (Call "a" [StringLiteral "bar"]) [Chunk "foo"] Nothing]
38− (Template [Chunk "foo"])
39− Nothing]
40− @=? readTemplate "$if(a(\"bar\"))$foo$endif$"
37+ @=? readTemplateElems "$if(a(\"bar\"))$foo$endif$"
41 -- 'If' trim check.
38 -- 'If' trim check.
42− , Template
43− [ TrimL
39+ , [ TrimL
44− , If (Ident (TemplateKey "body"))
40+ , If (Ident (TemplateKey "body"))
45− (Template [ TrimR
41+ [ TrimR
46− , Chunk "\n"
42+ , Chunk "\n"
47− , Expr (Ident (TemplateKey "body"))
43+ , Expr (Ident (TemplateKey "body"))
48− , Chunk "\n"
44+ , Chunk "\n"
49− , TrimL
45+ , TrimL
50− ])
46+ ]
51− (Just (Template [ TrimR
47+ (Just [ TrimR
52− , Chunk "\n"
48+ , Chunk "\n"
53− , Expr (Ident (TemplateKey "body"))
49+ , Expr (Ident (TemplateKey "body"))
54− , Chunk "\n"
50+ , Chunk "\n"
55− , TrimL
51+ , TrimL
56− ]))
52+ ])
57− , TrimR
53+ , TrimR
58− ]
54+ ]
59− @=? readTemplate "$-if(body)-$\n$body$\n$-else-$\n$body$\n$-endif-$"
55+ @=? readTemplateElems "$-if(body)-$\n$body$\n$-else-$\n$body$\n$-endif-$"
60 -- 'For' trim check.
56 -- 'For' trim check.
61− , Template
62− [ TrimL
57+ , [ TrimL
63− , For (Ident (TemplateKey "authors"))
58+ , For (Ident (TemplateKey "authors"))
64− (Template [ TrimR
65− , Chunk "\n body \n"
59+ [TrimR, Chunk "\n body \n", TrimL]
66− , TrimL])
67− Nothing
60+ Nothing
68− , TrimR
61+ , TrimR
69− ]
62+ ]
70− @=? readTemplate "$-for(authors)-$\n body \n$-endfor-$"
63+ @=? readTemplateElems "$-for(authors)-$\n body \n$-endfor-$"
71 -- 'Partial' trim check.
64 -- 'Partial' trim check.
72− , Template
73− [ TrimL
65+ , [ TrimL
74− , Partial (StringLiteral "path")
66+ , Partial (StringLiteral "path")
75− , TrimR
67+ , TrimR
76− ]
68+ ]
77− @=? readTemplate "$-partial(\"path\")-$"
69+ @=? readTemplateElems "$-partial(\"path\")-$"
78 -- 'Expr' trim check.
70 -- 'Expr' trim check.
79− , Template
80− [ TrimL
71+ , [ TrimL
81− , Expr (Ident (TemplateKey "foo"))
72+ , Expr (Ident (TemplateKey "foo"))
82− , TrimR
73+ , TrimR
83− ]
74+ ]
84− @=? readTemplate "$-foo-$"
75+ @=? readTemplateElems "$-foo-$"
85 ]
76 ]
86 ]
77 ]
87
78
@@ -126,4 +117,4 @@ testApplyJoinTemplateList = do
126 where
117 where
127 i1 = Item "item1" "Hello"
118 i1 = Item "item1" "Hello"
128 i2 = Item "item2" "World"
119 i2 = Item "item2" "World"
129− tpl = Template [Chunk "<b>", Expr (Ident "body"), Chunk "</b>"]
120+ tpl = readTemplate "<b>$body$</b>"