on master help sign in
Style changes, move stuff to common parser module
4100083Jasper Van der Jeugt
hakyll.cabal+1
@@ -131,6 +131,7 @@ Library
131 Hakyll.Core.Runtime
131 Hakyll.Core.Runtime
132 Hakyll.Core.Store
132 Hakyll.Core.Store
133 Hakyll.Core.Util.File
133 Hakyll.Core.Util.File
134+ Hakyll.Core.Util.Parser
134 Hakyll.Web.Template.Internal
135 Hakyll.Web.Template.Internal
135 Paths_hakyll
136 Paths_hakyll
136
137
src/Hakyll/Core/Compiler/Internal.hs+4−3
@@ -1,9 +1,9 @@
1--------------------------------------------------------------------------------
1--------------------------------------------------------------------------------
2-- | Internally used compiler module
2-- | Internally used compiler module
3+{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE GADTs #-}
4{-# LANGUAGE GADTs #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−{-# LANGUAGE FlexibleInstances #-}
6−{-# LANGUAGE MultiParamTypeClasses #-}
6+{-# LANGUAGE MultiParamTypeClasses #-}
7module Hakyll.Core.Compiler.Internal
7module Hakyll.Core.Compiler.Internal
8 ( -- * Types
8 ( -- * Types
9 CompilerRead (..)
9 CompilerRead (..)
@@ -31,7 +31,7 @@ import Control.Applicative (Alternative (..),
31 Applicative (..), (<$>))
31 Applicative (..), (<$>))
32import Control.Exception (SomeException, handle)
32import Control.Exception (SomeException, handle)
33import Control.Monad (forM_)
33import Control.Monad (forM_)
34−import Control.Monad.Error
34+import Control.Monad.Error (MonadError (..))
35import Data.Monoid (Monoid (..))
35import Data.Monoid (Monoid (..))
36import Data.Set (Set)
36import Data.Set (Set)
37import qualified Data.Set as S
37import qualified Data.Set as S
@@ -149,6 +149,7 @@ instance MonadMetadata Compiler where
149 getMetadata = compilerGetMetadata
149 getMetadata = compilerGetMetadata
150 getMatches = compilerGetMatches
150 getMatches = compilerGetMatches
151
151
152+
152--------------------------------------------------------------------------------
153--------------------------------------------------------------------------------
153instance MonadError [String] Compiler where
154instance MonadError [String] Compiler where
154 throwError = compilerThrow
155 throwError = compilerThrow
src/Hakyll/Core/Provider/Metadata.hs+6−1
@@ -4,6 +4,9 @@ module Hakyll.Core.Provider.Metadata
4 ( loadMetadata
4 ( loadMetadata
5 , metadata
5 , metadata
6 , page
6 , page
7+
8+ -- This parser can be reused in some places
9+ , metadataKey
7 ) where
10 ) where
8
11
9
12
@@ -23,6 +26,7 @@ import Text.Parsec.String (Parser)
23import Hakyll.Core.Identifier
26import Hakyll.Core.Identifier
24import Hakyll.Core.Metadata
27import Hakyll.Core.Metadata
25import Hakyll.Core.Provider.Internal
28import Hakyll.Core.Provider.Internal
29+import Hakyll.Core.Util.Parser
26import Hakyll.Core.Util.String
30import Hakyll.Core.Util.String
27
31
28
32
@@ -93,7 +97,8 @@ newline = P.string "\n" <|> P.string "\r\n"
93-- | Parse a single metadata field
97-- | Parse a single metadata field
94metadataField :: Parser (String, String)
98metadataField :: Parser (String, String)
95metadataField = do
99metadataField = do
96− key <- P.manyTill P.alphaNum $ P.char ':'
100+ key <- metadataKey
101+ _ <- P.char ':'
97 P.skipMany1 inlineSpace <?> "space followed by metadata for: " ++ key
102 P.skipMany1 inlineSpace <?> "space followed by metadata for: " ++ key
98 value <- P.manyTill P.anyChar newline
103 value <- P.manyTill P.anyChar newline
99 trailing' <- P.many trailing
104 trailing' <- P.many trailing
src/Hakyll/Core/Util/Parser.hsnew file+25
@@ -0,0 +1,25 @@
1+--------------------------------------------------------------------------------
2+-- | Parser utilities
3+module Hakyll.Core.Util.Parser
4+ ( metadataKey
5+ , reservedKeys
6+ ) where
7+
8+
9+--------------------------------------------------------------------------------
10+import Control.Applicative ((<$>), (<*>), (<|>))
11+import Control.Monad (mzero)
12+import qualified Text.Parsec as P
13+import Text.Parsec.String (Parser)
14+
15+
16+--------------------------------------------------------------------------------
17+metadataKey :: Parser String
18+metadataKey = do
19+ i <- (:) <$> P.letter <*> (P.many $ P.alphaNum <|> P.oneOf " _-.")
20+ if i `elem` reservedKeys then mzero else return i
21+
22+
23+--------------------------------------------------------------------------------
24+reservedKeys :: [String]
25+reservedKeys = ["if", "else","endif"]
src/Hakyll/Web/Template.hs+7−6
@@ -116,14 +116,15 @@ applyAsTemplate context item =
116applyTemplateWith :: MonadError e m
116applyTemplateWith :: MonadError e m
117 => (String -> a -> m String)
117 => (String -> a -> m String)
118 -> Template -> a -> m String
118 -> Template -> a -> m String
119−applyTemplateWith context tpl x = go tpl where
119+applyTemplateWith context tpl x = go tpl
120−
120+ where
121 go = liftM concat . mapM applyElem . unTemplate
121 go = liftM concat . mapM applyElem . unTemplate
122
122
123 applyElem (Chunk c) = return c
123 applyElem (Chunk c) = return c
124 applyElem Escaped = return "$"
124 applyElem Escaped = return "$"
125 applyElem (Key k) = context k x
125 applyElem (Key k) = context k x
126− applyElem (If k t mf) = (context k x >> go t) `catchError` handler where
126+ applyElem (If k t mf) = (context k x >> go t) `catchError` handler
127+ where
127− handler _ = case mf of
128+ handler _ = case mf of
128− Nothing -> return ""
129+ Nothing -> return ""
129− Just f -> go f
130+ Just f -> go f
src/Hakyll/Web/Template/Internal.hs+11−11
@@ -22,8 +22,7 @@ import Hakyll.Core.Writable
22-- | Datatype used for template substitutions.
22-- | Datatype used for template substitutions.
23newtype Template = Template
23newtype Template = Template
24 { unTemplate :: [TemplateElement]
24 { unTemplate :: [TemplateElement]
25− }
26− deriving (Show, Eq, Binary, Typeable)
25+ } deriving (Show, Eq, Binary, Typeable)
27
26
28
27
29--------------------------------------------------------------------------------
28--------------------------------------------------------------------------------
@@ -41,17 +40,18 @@ data TemplateElement
41 | If String Template (Maybe Template) -- key, then branch, else branch
40 | If String Template (Maybe Template) -- key, then branch, else branch
42 deriving (Show, Eq, Typeable)
41 deriving (Show, Eq, Typeable)
43
42
43+
44--------------------------------------------------------------------------------
44--------------------------------------------------------------------------------
45instance Binary TemplateElement where
45instance Binary TemplateElement where
46 put (Chunk string) = putWord8 0 >> put string
46 put (Chunk string) = putWord8 0 >> put string
47− put (Key key) = putWord8 1 >> put key
47+ put (Key key) = putWord8 1 >> put key
48− put (Escaped) = putWord8 2
48+ put (Escaped) = putWord8 2
49− put (If key t f) = putWord8 3 >> put key >> put t >> put f
49+ put (If key t f) = putWord8 3 >> put key >> put t >> put f
50
50
51 get = getWord8 >>= \tag -> case tag of
51 get = getWord8 >>= \tag -> case tag of
52− 0 -> Chunk <$> get
52+ 0 -> Chunk <$> get
53− 1 -> Key <$> get
53+ 1 -> Key <$> get
54− 2 -> pure Escaped
54+ 2 -> pure Escaped
55− 3 -> If <$> get <*> get <*> get
55+ 3 -> If <$> get <*> get <*> get
56− _ -> error $ "Hakyll.Web.Template.Internal: "
56+ _ -> error $
57− ++ "Error reading cached template"
57+ "Hakyll.Web.Template.Internal: Error reading cached template"
src/Hakyll/Web/Template/Read.hs+29−28
@@ -4,56 +4,57 @@ module Hakyll.Web.Template.Read
4 ( readTemplate
4 ( readTemplate
5 ) where
5 ) where
6
6
7+
7--------------------------------------------------------------------------------
8--------------------------------------------------------------------------------
8−import Control.Applicative ((<$>), (<$), (<*>))
9+import Control.Applicative ((<$), (<$>))
9−import Control.Monad (void, mzero)
10+import Control.Monad (void)
10import Text.Parsec
11import Text.Parsec
11import Text.Parsec.String
12import Text.Parsec.String
12
13
14+
13--------------------------------------------------------------------------------
15--------------------------------------------------------------------------------
16+import Hakyll.Core.Util.Parser
14import Hakyll.Web.Template.Internal
17import Hakyll.Web.Template.Internal
15
18
16−--------------------------------------------------------------------------------
17
19
20+--------------------------------------------------------------------------------
18readTemplate :: String -> Template
21readTemplate :: String -> Template
19−readTemplate input =
20− case parse template "" input of
22+readTemplate input = case parse template "" input of
21 Left err -> error $ "Cannot parse template: " ++ show err
23 Left err -> error $ "Cannot parse template: " ++ show err
22 Right t -> t
24 Right t -> t
23
25
26+
27+--------------------------------------------------------------------------------
24template :: Parser Template
28template :: Parser Template
25−template = Template <$>
26− (many1 $ chunk <|> escaped <|> conditional <|> key)
29+template = Template <$> (many1 $ chunk <|> escaped <|> conditional <|> key)
30+
27
31
32+--------------------------------------------------------------------------------
28chunk :: Parser TemplateElement
33chunk :: Parser TemplateElement
29chunk = Chunk <$> (many1 $ noneOf "$")
34chunk = Chunk <$> (many1 $ noneOf "$")
30
35
36+
37+--------------------------------------------------------------------------------
31escaped :: Parser TemplateElement
38escaped :: Parser TemplateElement
32escaped = Escaped <$ (try $ string "$$")
39escaped = Escaped <$ (try $ string "$$")
33
40
41+
42+--------------------------------------------------------------------------------
34conditional :: Parser TemplateElement
43conditional :: Parser TemplateElement
35conditional = try $ do
44conditional = try $ do
36− void $ string "$if("
45+ void $ string "$if("
37− i <- ident
46+ i <- metadataKey
38− void $ string ")$"
47+ void $ string ")$"
39− thenBranch <- template
48+ thenBranch <- template
40− elseBranch <- optionMaybe $ try (string "$else$") >> template
49+ elseBranch <- optionMaybe $ try (string "$else$") >> template
41− void $ string "$endif$"
50+ void $ string "$endif$"
42− return $ If i thenBranch elseBranch
51+ return $ If i thenBranch elseBranch
43−
52+
44−ident :: Parser String
45−ident = do
46− i <- (:) <$> letter <*> (many $ alphaNum <|> oneOf " _-.")
47− if i `elem` reserved
48− then mzero
49− else return i
50−
51−reserved :: [String]
52−reserved = ["if", "else","endif"]
53
53
54+--------------------------------------------------------------------------------
54key :: Parser TemplateElement
55key :: Parser TemplateElement
55key = try $ do
56key = try $ do
56− void $ char '$'
57+ void $ char '$'
57− k <- ident
58+ k <- metadataKey
58− void $ char '$'
59+ void $ char '$'
59− return $ Key k
60+ return $ Key k