Add IsString instance for Template

Closes #150
This commit is contained in:
Jasper Van der Jeugt 2014-01-19 21:24:52 +01:00
parent c024ed8a93
commit 677cca0578
6 changed files with 94 additions and 104 deletions

View file

@ -119,7 +119,6 @@ Library
Hakyll.Web.Template Hakyll.Web.Template
Hakyll.Web.Template.Context Hakyll.Web.Template.Context
Hakyll.Web.Template.List Hakyll.Web.Template.List
Hakyll.Web.Template.Read
Other-Modules: Other-Modules:
Hakyll.Check Hakyll.Check

View file

@ -28,7 +28,6 @@ module Hakyll
, module Hakyll.Web.Template , module Hakyll.Web.Template
, module Hakyll.Web.Template.Context , module Hakyll.Web.Template.Context
, module Hakyll.Web.Template.List , module Hakyll.Web.Template.List
, module Hakyll.Web.Template.Read
) where ) where
@ -59,4 +58,3 @@ import Hakyll.Web.Tags
import Hakyll.Web.Template import Hakyll.Web.Template
import Hakyll.Web.Template.Context import Hakyll.Web.Template.Context
import Hakyll.Web.Template.List import Hakyll.Web.Template.List
import Hakyll.Web.Template.Read

View file

@ -35,7 +35,6 @@ import Hakyll.Core.Item
import Hakyll.Web.Template import Hakyll.Web.Template
import Hakyll.Web.Template.Context import Hakyll.Web.Template.Context
import Hakyll.Web.Template.List import Hakyll.Web.Template.List
import Hakyll.Web.Template.Read
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -122,6 +122,7 @@ module Hakyll.Web.Template
, applyTemplate , applyTemplate
, loadAndApplyTemplate , loadAndApplyTemplate
, applyAsTemplate , applyAsTemplate
, readTemplate
) where ) where
@ -139,7 +140,6 @@ import Hakyll.Core.Identifier
import Hakyll.Core.Item import Hakyll.Core.Item
import Hakyll.Web.Template.Context import Hakyll.Web.Template.Context
import Hakyll.Web.Template.Internal import Hakyll.Web.Template.Internal
import Hakyll.Web.Template.Read
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -5,16 +5,22 @@
module Hakyll.Web.Template.Internal module Hakyll.Web.Template.Internal
( Template (..) ( Template (..)
, TemplateElement (..) , TemplateElement (..)
, readTemplate
) where ) where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Control.Applicative (pure, (<$>), (<*>)) import Control.Applicative (pure, (<$), (<$>), (<*>), (<|>))
import Data.Binary (Binary, get, getWord8, put, putWord8) import Control.Monad (void)
import Data.Typeable (Typeable) import Data.Binary (Binary, get, getWord8, put, putWord8)
import Data.Typeable (Typeable)
import GHC.Exts (IsString (..))
import qualified Text.Parsec as P
import qualified Text.Parsec.String as P
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Hakyll.Core.Util.Parser
import Hakyll.Core.Writable import Hakyll.Core.Writable
@ -46,10 +52,10 @@ data TemplateElement
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
instance Binary TemplateElement where instance Binary TemplateElement where
put (Chunk string) = putWord8 0 >> put string put (Chunk string) = putWord8 0 >> put string
put (Key key) = putWord8 1 >> put key put (Key k) = putWord8 1 >> put k
put (Escaped) = putWord8 2 put (Escaped) = putWord8 2
put (If key t f) = putWord8 3 >> put key >> put t >> put f put (If k t f ) = putWord8 3 >> put k >> put t >> put f
put (For key b s) = putWord8 4 >> put key >> put b >> put s put (For k b s) = putWord8 4 >> put k >> put b >> put s
put (Partial p) = putWord8 5 >> put p put (Partial p) = putWord8 5 >> put p
get = getWord8 >>= \tag -> case tag of get = getWord8 >>= \tag -> case tag of
@ -61,3 +67,84 @@ instance Binary TemplateElement where
5 -> Partial <$> get 5 -> Partial <$> get
_ -> error $ _ -> error $
"Hakyll.Web.Template.Internal: Error reading cached template" "Hakyll.Web.Template.Internal: Error reading cached template"
--------------------------------------------------------------------------------
instance IsString Template where
fromString = readTemplate
--------------------------------------------------------------------------------
readTemplate :: String -> Template
readTemplate input = case P.parse template "" input of
Left err -> error $ "Cannot parse template: " ++ show err
Right t -> t
--------------------------------------------------------------------------------
template :: P.Parser Template
template = Template <$>
(P.many1 $ chunk <|> escaped <|> conditional <|> for <|> partial <|> key)
--------------------------------------------------------------------------------
chunk :: P.Parser TemplateElement
chunk = Chunk <$> (P.many1 $ P.noneOf "$")
--------------------------------------------------------------------------------
escaped :: P.Parser TemplateElement
escaped = Escaped <$ (P.try $ P.string "$$")
--------------------------------------------------------------------------------
conditional :: P.Parser TemplateElement
conditional = P.try $ do
void $ P.string "$if("
i <- metadataKey
void $ P.string ")$"
thenBranch <- template
elseBranch <- P.optionMaybe $ P.try (P.string "$else$") >> template
void $ P.string "$endif$"
return $ If i thenBranch elseBranch
--------------------------------------------------------------------------------
for :: P.Parser TemplateElement
for = P.try $ do
void $ P.string "$for("
i <- metadataKey
void $ P.string ")$"
body <- template
sep <- P.optionMaybe $ P.try (P.string "$sep$") >> template
void $ P.string "$endfor$"
return $ For i body sep
--------------------------------------------------------------------------------
partial :: P.Parser TemplateElement
partial = P.try $ do
void $ P.string "$partial("
i <- stringLiteral
void $ P.string ")$"
return $ Partial i
--------------------------------------------------------------------------------
key :: P.Parser TemplateElement
key = P.try $ do
void $ P.char '$'
k <- metadataKey
void $ P.char '$'
return $ Key k
--------------------------------------------------------------------------------
stringLiteral :: P.Parser String
stringLiteral = do
void $ P.char '\"'
str <- P.many $ do
x <- P.noneOf "\""
if x == '\\' then P.anyChar else return x
void $ P.char '\"'
return str

View file

@ -1,93 +0,0 @@
--------------------------------------------------------------------------------
-- | Read templates in Hakyll's native format
module Hakyll.Web.Template.Read
( readTemplate
) where
--------------------------------------------------------------------------------
import Control.Applicative ((<$), (<$>))
import Control.Monad (void)
import Text.Parsec
import Text.Parsec.String
--------------------------------------------------------------------------------
import Hakyll.Core.Util.Parser
import Hakyll.Web.Template.Internal
--------------------------------------------------------------------------------
readTemplate :: String -> Template
readTemplate input = case parse template "" input of
Left err -> error $ "Cannot parse template: " ++ show err
Right t -> t
--------------------------------------------------------------------------------
template :: Parser Template
template = Template <$>
(many1 $ chunk <|> escaped <|> conditional <|> for <|> partial <|> key)
--------------------------------------------------------------------------------
chunk :: Parser TemplateElement
chunk = Chunk <$> (many1 $ noneOf "$")
--------------------------------------------------------------------------------
escaped :: Parser TemplateElement
escaped = Escaped <$ (try $ string "$$")
--------------------------------------------------------------------------------
conditional :: Parser TemplateElement
conditional = try $ do
void $ string "$if("
i <- metadataKey
void $ string ")$"
thenBranch <- template
elseBranch <- optionMaybe $ try (string "$else$") >> template
void $ string "$endif$"
return $ If i thenBranch elseBranch
--------------------------------------------------------------------------------
for :: Parser TemplateElement
for = try $ do
void $ string "$for("
i <- metadataKey
void $ string ")$"
body <- template
sep <- optionMaybe $ try (string "$sep$") >> template
void $ string "$endfor$"
return $ For i body sep
--------------------------------------------------------------------------------
partial :: Parser TemplateElement
partial = try $ do
void $ string "$partial("
i <- stringLiteral
void $ string ")$"
return $ Partial i
--------------------------------------------------------------------------------
key :: Parser TemplateElement
key = try $ do
void $ char '$'
k <- metadataKey
void $ char '$'
return $ Key k
--------------------------------------------------------------------------------
stringLiteral :: Parser String
stringLiteral = do
void $ char '\"'
str <- many $ do
x <- noneOf "\""
if x == '\\' then anyChar else return x
void $ char '\"'
return str