@@ -1,3 +1,4 @@
1+--------------------------------------------------------------------------------
1-- | This module provides a declarative DSL in which the user can specify the
2-- | This module provides a declarative DSL in which the user can specify the
2-- different rules used to run the compilers.
3-- different rules used to run the compilers.
@@ -13,8 +14,8 @@
13-- > match "css/*" $ do
14-- > match "css/*" $ do
14-- > route idRoute
15-- > route idRoute
15-- > compile compressCssCompiler
16-- > compile compressCssCompiler
16−--
17+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−{-# LANGUAGE GeneralizedNewtypeDeriving, OverloadedStrings #-}
18+{-# LANGUAGE OverloadedStrings #-}
18module Hakyll.Core.Rules
19module Hakyll.Core.Rules
@@ -29,35 +30,43 @@ module Hakyll.Core.Rules
29 , freshIdentifier
30 , freshIdentifier
32−import Control.Applicative ((<$>))
33−import Control.Monad.Writer (tell)
34−import Control.Monad.Reader (ask, local)
35−import Control.Arrow ((>>>), arr, (>>^), (***))
36−import Control.Monad.State (get, put)
37−import Data.Monoid (mempty, mappend)
38−import qualified Data.Set as S
40−import Data.Typeable (Typeable)
41−import Data.Binary (Binary)
43−import Hakyll.Core.Resource
44−import Hakyll.Core.Resource.Provider
45−import Hakyll.Core.Identifier
46−import Hakyll.Core.Identifier.Pattern
47−import Hakyll.Core.Compiler.Internal
48−import Hakyll.Core.Routes
49−import Hakyll.Core.CompiledItem
50−import Hakyll.Core.Writable
51−import Hakyll.Core.Rules.Internal
52−import Hakyll.Core.Util.Arrow
34+--------------------------------------------------------------------------------
35+import Control.Applicative ((<$>))
36+import Control.Arrow (arr, (***), (>>>), (>>^))
37+import Control.Monad.Reader (ask, local)
38+import Control.Monad.State (get, put)
39+import Control.Monad.Writer (tell)
40+import Data.Monoid (mappend, mempty)
41+import qualified Data.Set as S
44+--------------------------------------------------------------------------------
45+import Data.Binary (Binary)
46+import Data.Typeable (Typeable)
49+--------------------------------------------------------------------------------
50+import Hakyll.Core.CompiledItem
51+import Hakyll.Core.Compiler.Internal
52+import Hakyll.Core.Identifier
53+import Hakyll.Core.Identifier.Pattern
54+import Hakyll.Core.Resource
55+import Hakyll.Core.Resource.Provider
56+import Hakyll.Core.Routes
57+import Hakyll.Core.Rules.Internal
58+import Hakyll.Core.Util.Arrow
59+import Hakyll.Core.Writable
62+--------------------------------------------------------------------------------
54-- | Add a route
63-- | Add a route
56tellRoute :: Routes -> Rules
64tellRoute :: Routes -> Rules
57tellRoute route' = RulesM $ tell $ RuleSet route' mempty mempty
65tellRoute route' = RulesM $ tell $ RuleSet route' mempty mempty
68+--------------------------------------------------------------------------------
59-- | Add a number of compilers
69-- | Add a number of compilers
61tellCompilers :: (Binary a, Typeable a, Writable a)
70tellCompilers :: (Binary a, Typeable a, Writable a)
62 => [(Identifier a, Compiler () a)]
71 => [(Identifier a, Compiler () a)]
@@ -68,15 +77,17 @@ tellCompilers compilers = RulesM $ do
69 boxCompiler = (>>> arr compiledItem >>> arr CompileRule)
78 boxCompiler = (>>> arr compiledItem >>> arr CompileRule)
81+--------------------------------------------------------------------------------
71-- | Add resources
82-- | Add resources
73tellResources :: [Resource]
83tellResources :: [Resource]
75tellResources resources' = RulesM $ tell $
85tellResources resources' = RulesM $ tell $
76 RuleSet mempty mempty $ S.fromList resources'
86 RuleSet mempty mempty $ S.fromList resources'
89+--------------------------------------------------------------------------------
78-- | Only compile/route items satisfying the given predicate
90-- | Only compile/route items satisfying the given predicate
80match :: Pattern a -> RulesM b -> RulesM b
91match :: Pattern a -> RulesM b -> RulesM b
81match pattern = RulesM . local addPredicate . unRulesM
92match pattern = RulesM . local addPredicate . unRulesM
@@ -84,8 +95,9 @@ match pattern = RulesM . local addPredicate . unRulesM
84 { rulesPattern = rulesPattern env `mappend` castPattern pattern
95 { rulesPattern = rulesPattern env `mappend` castPattern pattern
99+--------------------------------------------------------------------------------
87-- | Greate a group of compilers
100-- | Greate a group of compilers
89-- Imagine you have a page that you want to render, but you also want the raw
101-- Imagine you have a page that you want to render, but you also want the raw
90-- content available on your site.
102-- content available on your site.
@@ -114,18 +126,18 @@ match pattern = RulesM . local addPredicate . unRulesM
115-- This will put the compiler for the raw content in a separate group
127-- This will put the compiler for the raw content in a separate group
116-- (@\"raw\"@), which causes it to be compiled as well.
128-- (@\"raw\"@), which causes it to be compiled as well.
118group :: String -> RulesM a -> RulesM a
129group :: String -> RulesM a -> RulesM a
119group g = RulesM . local setGroup' . unRulesM
130group g = RulesM . local setGroup' . unRulesM
121 setGroup' env = env { rulesGroup = Just g }
132 setGroup' env = env { rulesGroup = Just g }
135+--------------------------------------------------------------------------------
123-- | Add a compilation rule to the rules.
136-- | Add a compilation rule to the rules.
125-- This instructs all resources to be compiled using the given compiler. When
138-- This instructs all resources to be compiled using the given compiler. When
126-- no resources match the current selection, nothing will happen. In this case,
139-- no resources match the current selection, nothing will happen. In this case,
127-- you might want to have a look at 'create'.
140-- you might want to have a look at 'create'.
129compile :: (Binary a, Typeable a, Writable a)
141compile :: (Binary a, Typeable a, Writable a)
130 => Compiler Resource a -> RulesM (Pattern a)
142 => Compiler Resource a -> RulesM (Pattern a)
131compile compiler = do
143compile compiler = do
@@ -134,7 +146,9 @@ compile compiler = do
134 (identifier, constA (fromIdentifier identifier) >>> compiler)
146 (identifier, constA (fromIdentifier identifier) >>> compiler)
135 tellResources $ map fromIdentifier ids
147 tellResources $ map fromIdentifier ids
136 return $ list ids
148 return $ list ids
151+--------------------------------------------------------------------------------
138-- | Add a compilation rule
152-- | Add a compilation rule
140-- This sets a compiler for the given identifier. No resource is needed, since
154-- This sets a compiler for the given identifier. No resource is needed, since
@@ -143,7 +157,6 @@ compile compiler = do
143-- actual content itself. Note that the group of the given identifier is
157-- actual content itself. Note that the group of the given identifier is
144-- replaced by the group set via 'group' (or 'Nothing', if 'group' has not been
158-- replaced by the group set via 'group' (or 'Nothing', if 'group' has not been
147create :: (Binary a, Typeable a, Writable a)
160create :: (Binary a, Typeable a, Writable a)
148 => Identifier a -> Compiler () a -> RulesM (Identifier a)
161 => Identifier a -> Compiler () a -> RulesM (Identifier a)
149create id' compiler = RulesM $ do
162create id' compiler = RulesM $ do
@@ -152,10 +165,11 @@ create id' compiler = RulesM $ do
152 unRulesM $ tellCompilers [(id'', compiler)]
165 unRulesM $ tellCompilers [(id'', compiler)]
153 return id''
166 return id''
169+--------------------------------------------------------------------------------
155-- | Add a route.
170-- | Add a route.
157-- This adds a route for all items matching the current pattern.
172-- This adds a route for all items matching the current pattern.
159route :: Routes -> Rules
173route :: Routes -> Rules
160route route' = RulesM $ do
174route route' = RulesM $ do
161 -- We want the route only to be applied if we match the current pattern and
175 -- We want the route only to be applied if we match the current pattern and
@@ -164,9 +178,10 @@ route route' = RulesM $ do
164 group' <- rulesGroup <$> ask
178 group' <- rulesGroup <$> ask
165 unRulesM $ tellRoute $ matchRoute (pattern `mappend` inGroup group') route'
179 unRulesM $ tellRoute $ matchRoute (pattern `mappend` inGroup group') route'
182+--------------------------------------------------------------------------------
167-- | Get a list of resources matching the current pattern. This will also set
183-- | Get a list of resources matching the current pattern. This will also set
168-- the correct group to the identifiers.
184-- the correct group to the identifiers.
170resources :: RulesM [Identifier a]
185resources :: RulesM [Identifier a]
171resources = RulesM $ do
186resources = RulesM $ do
172 pattern <- rulesPattern <$> ask
187 pattern <- rulesPattern <$> ask
@@ -176,6 +191,8 @@ resources = RulesM $ do
177 toId g = setGroup g . toIdentifier
192 toId g = setGroup g . toIdentifier
195+--------------------------------------------------------------------------------
179-- | Apart from regular compilers, one is also able to specify metacompilers.
196-- | Apart from regular compilers, one is also able to specify metacompilers.
180-- Metacompilers are a special class of compilers: they are compilers which
197-- Metacompilers are a special class of compilers: they are compilers which
181-- produce other compilers.
198-- produce other compilers.
@@ -205,9 +222,8 @@ resources = RulesM $ do
205-- For simple hakyll systems, it is no need for this construction. More
222-- For simple hakyll systems, it is no need for this construction. More
206-- formally, it is only needed when the content of one or more items determines
223-- formally, it is only needed when the content of one or more items determines
207-- which items must be rendered.
224-- which items must be rendered.
209metaCompile :: (Binary a, Typeable a, Writable a)
225metaCompile :: (Binary a, Typeable a, Writable a)
210− => Compiler () [(Identifier a, Compiler () a)]
226+ => Compiler () [(Identifier a, Compiler () a)]
211 -- ^ Compiler generating the other compilers
227 -- ^ Compiler generating the other compilers
213 -- ^ Resulting rules
229 -- ^ Resulting rules
@@ -215,13 +231,14 @@ metaCompile compiler = do
215 id' <- freshIdentifier "Hakyll.Core.Rules.metaCompile"
231 id' <- freshIdentifier "Hakyll.Core.Rules.metaCompile"
216 metaCompileWith id' compiler
232 metaCompileWith id' compiler
235+--------------------------------------------------------------------------------
218-- | Version of 'metaCompile' that allows you to specify a custom identifier for
236-- | Version of 'metaCompile' that allows you to specify a custom identifier for
219-- the metacompiler.
237-- the metacompiler.
221metaCompileWith :: (Binary a, Typeable a, Writable a)
238metaCompileWith :: (Binary a, Typeable a, Writable a)
222 => Identifier ()
239 => Identifier ()
223 -- ^ Identifier for this compiler
240 -- ^ Identifier for this compiler
224− -> Compiler () [(Identifier a, Compiler () a)]
241+ -> Compiler () [(Identifier a, Compiler () a)]
225 -- ^ Compiler generating the other compilers
242 -- ^ Compiler generating the other compilers
227 -- ^ Resulting rules
244 -- ^ Resulting rules
@@ -239,6 +256,8 @@ metaCompileWith identifier compiler = RulesM $ do
240 tell $ RuleSet mempty compilers mempty
257 tell $ RuleSet mempty compilers mempty
260+--------------------------------------------------------------------------------
242-- | Generate a fresh Identifier with a given prefix
261-- | Generate a fresh Identifier with a given prefix
243freshIdentifier :: String -- ^ Prefix
262freshIdentifier :: String -- ^ Prefix
244 -> RulesM (Identifier a) -- ^ Fresh identifier
263 -> RulesM (Identifier a) -- ^ Fresh identifier