on master help sign in
Refactored Template data structure.
acbdf6cJasper Van der Jeugt
src/Text/Hakyll/Internal/Template.hs+19−16
@@ -22,16 +22,22 @@ import Text.Hakyll.Internal.Template.Template
22import Text.Hakyll.Internal.Template.Hamlet
22import Text.Hakyll.Internal.Template.Hamlet
23
23
24-- | Construct a @Template@ from a string.
24-- | Construct a @Template@ from a string.
25+--
25fromString :: String -> Template
26fromString :: String -> Template
26−fromString [] = End
27+fromString = Template . fromString'
27−fromString string
28− | "$$" `isPrefixOf` string = EscapeCharacter (fromString $ tail tail')
29− | "$" `isPrefixOf` string = let (key, rest) = span isAlphaNum tail'
30− in Identifier key (fromString rest)
31− | otherwise = let (chunk, rest) = break (== '$') string
32− in Chunk chunk (fromString rest)
33 where
28 where
29+ fromString' [] = []
30+ fromString' string
31+ | "$$" `isPrefixOf` string =
32+ EscapeCharacter : (fromString' $ tail tail')
33+ | "$" `isPrefixOf` string =
34+ let (key, rest) = span isAlphaNum tail'
35+ in Identifier key : fromString' rest
36+ | otherwise =
37+ let (chunk, rest) = break (== '$') string
38+ in Chunk chunk : fromString' rest
39+ where
34− tail' = tail string
40+ tail' = tail string
35
41
36-- | Read a @Template@ from a file. This function might fetch the @Template@
42-- | Read a @Template@ from a file. This function might fetch the @Template@
37-- from the cache, if available.
43-- from the cache, if available.
@@ -60,15 +66,12 @@ readTemplate path = do
60-- "Context". When a key is not found, it is left as it is. You can specify
66-- "Context". When a key is not found, it is left as it is. You can specify
61-- the characters used to replace escaped dollars (@$$@) here.
67-- the characters used to replace escaped dollars (@$$@) here.
62substitute :: String -> Template -> Context -> String
68substitute :: String -> Template -> Context -> String
63−substitute escaper (Chunk chunk template) context =
69+substitute escaper template context = substitute' =<< unTemplate template
64− chunk ++ substitute escaper template context
65−substitute escaper (Identifier key template) context =
66− replacement ++ substitute escaper template context
67 where
70 where
71+ substitute' (Chunk chunk) = chunk
72+ substitute' (Identifier key) =
68− replacement = fromMaybe ('$' : key) $ M.lookup key $ unContext context
73+ fromMaybe ('$' : key) $ M.lookup key $ unContext context
69−substitute escaper (EscapeCharacter template) context =
74+ substitute' (EscapeCharacter) = escaper
70− escaper ++ substitute escaper template context
71−substitute _ End _ = []
72
75
73-- | @substitute@ for use during a chain. This will leave escaped characters as
76-- | @substitute@ for use during a chain. This will leave escaped characters as
74-- they are.
77-- they are.
src/Text/Hakyll/Internal/Template/Hamlet.hs+10−9
@@ -6,7 +6,6 @@ module Text.Hakyll.Internal.Template.Hamlet
6 , fromHamletRT
6 , fromHamletRT
7 ) where
7 ) where
8
8
9−import Data.List (intercalate)
10import Control.Monad.Trans (liftIO)
9import Control.Monad.Trans (liftIO)
11import System.FilePath (takeExtension)
10import System.FilePath (takeExtension)
12
11
@@ -29,16 +28,18 @@ readHamletRT fileName = do
29 string <- liftIO $ readFile fileName
28 string <- liftIO $ readFile fileName
30 liftIO $ parseHamletRT settings string
29 liftIO $ parseHamletRT settings string
31
30
32−
33-- | Convert a 'HamletRT' to a 'Template'
31-- | Convert a 'HamletRT' to a 'Template'
34--
32--
35fromHamletRT :: HamletRT -- ^ Hamlet runtime template
33fromHamletRT :: HamletRT -- ^ Hamlet runtime template
36 -> Template -- ^ Hakyll template
34 -> Template -- ^ Hakyll template
37−fromHamletRT (HamletRT sd) = fromSimpleDoc sd
35+fromHamletRT (HamletRT sd) = Template $ map fromSimpleDoc sd
38 where
36 where
39− fromSimpleDoc :: [SimpleDoc] -> Template
37+ fromSimpleDoc :: SimpleDoc -> TemplateElement
40− fromSimpleDoc [] = End
41− fromSimpleDoc (SDRaw chunk : xs) = Chunk chunk $ fromSimpleDoc xs
38+ fromSimpleDoc (SDRaw chunk) = Chunk chunk
42− fromSimpleDoc (SDVar vars : xs) =
39+ fromSimpleDoc (SDVar [var]) = Identifier var
43− Identifier (intercalate "." vars) $ fromSimpleDoc xs
40+ fromSimpleDoc (SDVar _) =
41+ error "Hakyll does not support '.' in identifier names when using \
42+ \hamlet templates."
44− fromSimpleDoc (_ : xs) = fromSimpleDoc xs -- Unsupported elements
43+ fromSimpleDoc _ =
44+ error "Only simple $key$ identifiers are allowed when using hamlet \
45+ \templates."
src/Text/Hakyll/Internal/Template/Template.hs+23−20
@@ -1,31 +1,34 @@
1-- | Module containing the template data structure.
1-- | Module containing the template data structure.
2--
2--
3+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3module Text.Hakyll.Internal.Template.Template
4module Text.Hakyll.Internal.Template.Template
4 ( Template (..)
5 ( Template (..)
6+ , TemplateElement (..)
5 ) where
7 ) where
6
8
7−import Control.Monad (liftM, liftM2)
9+import Control.Applicative ((<$>))
8−import Data.Word (Word8)
9
10
10−import Data.Binary (Binary, get, put, getWord8)
11+import Data.Binary (Binary, get, getWord8, put, putWord8)
11
12
12-- | Datatype used for template substitutions.
13-- | Datatype used for template substitutions.
13--
14--
14−data Template = Chunk String Template
15+newtype Template = Template { unTemplate :: [TemplateElement] }
15− | Identifier String Template
16− | EscapeCharacter Template
17− | End
18− deriving (Show, Read, Eq)
16+ deriving (Show, Eq, Binary)
19−
20−instance Binary Template where
21− put (Chunk string template) = put (0 :: Word8) >> put string >> put template
22− put (Identifier key template) = put (1 :: Word8) >> put key >> put template
23− put (EscapeCharacter template) = put (2 :: Word8) >> put template
24− put (End) = put (3 :: Word8)
25
17
18+-- | Elements of a template.
19+--
20+data TemplateElement = Chunk String
21+ | Identifier String
22+ | EscapeCharacter
23+ deriving (Show, Eq)
24+
25+instance Binary TemplateElement where
26+ put (Chunk string) = putWord8 0 >> put string
27+ put (Identifier key) = putWord8 1 >> put key
28+ put (EscapeCharacter) = putWord8 2
29+
26− get = do tag <- getWord8
30+ get = getWord8 >>= \tag ->
27− case tag of 0 -> liftM2 Chunk get get
31+ case tag of 0 -> Chunk <$> get
28− 1 -> liftM2 Identifier get get
32+ 1 -> Identifier <$> get
29− 2 -> liftM EscapeCharacter get
33+ 2 -> return EscapeCharacter
30− 3 -> return End
31− _ -> error "Error reading template"
34+ _ -> error "Error reading cached template"