on master help sign in
WIP
commit760b4344377c81922ce5ab4ba05a41f88f45165d authorJasper Van der Jeugt <m@jaspervdj.be> dateMon 12 Nov 2012, 16:10 (14 years ago) parentc7d3c60
9 files changed+172−212
src/Hakyll/Core/Compiler.hs+21−17 src/Hakyll/Core/Compiler/Internal.hs+89−154 src/Hakyll/Core/Identifier/Pattern.hs+7−1 src/Hakyll/Core/ResourceProvider/Internal.hs+4−4 src/Hakyll/Core/ResourceProvider/Modified.hs+1−1 src/Hakyll/Core/Routes.hs+28−12 src/Hakyll/Core/Rules.hs+18−19 src/Hakyll/Core/Rules/Internal.hs+3−3 tests/Hakyll/Core/Dependencies/Tests.hs+1−1
src/Hakyll/Core/Compiler.hs+21−17
@@ -116,7 +116,7 @@ module Hakyll.Core.Compiler
116116
117117import Prelude hiding ((.), id)
118118import Control.Arrow ((>>>), (&&&), arr, first)
119−import Control.Applicative ((<$>))
119+import Control.Applicative ((<$>), (*>))
120120import Control.Exception (SomeException, handle)
121121import Control.Monad.Reader (ask)
122122import Control.Monad.Trans (liftIO)
@@ -144,7 +144,7 @@ import qualified Hakyll.Core.Store as Store
144144-- | Run a compiler, yielding the resulting target and it's dependencies. This
145145-- version of 'runCompilerJob' also stores the result
146146--
147−runCompiler :: Compiler () CompiledItem -- ^ Compiler to run
147+runCompiler :: Compiler CompiledItem -- ^ Compiler to run
148148 -> Identifier () -- ^ Target identifier
149149 -> ResourceProvider -- ^ Resource provider
150150 -> [Identifier ()] -- ^ Universe
@@ -174,18 +174,18 @@ runCompiler compiler id' provider universe routes store modified logger = do
174174
175175-- | Get the identifier of the item that is currently being compiled
176176--
177−getIdentifier :: Compiler a (Identifier b)
177+getIdentifier :: Compiler (Identifier b)
178178getIdentifier = fromJob $ const $ CompilerM $
179179 castIdentifier . compilerIdentifier <$> ask
180180
181181-- | Get the route we are using for this item
182182--
183−getRoute :: Compiler a (Maybe FilePath)
183+getRoute :: Compiler (Maybe FilePath)
184184getRoute = getIdentifier >>> getRouteFor
185185
186186-- | Get the route for a specified item
187187--
188−getRouteFor :: Compiler (Identifier a) (Maybe FilePath)
188+getRouteFor :: Compiler (Identifier a -> Maybe FilePath)
189189getRouteFor = fromJob $ \identifier -> CompilerM $ do
190190 routes <- compilerRoutes <$> ask
191191 return $ runRoutes routes identifier
@@ -193,27 +193,27 @@ getRouteFor = fromJob $ \identifier -> CompilerM $ do
193193
194194--------------------------------------------------------------------------------
195195-- | Get the body of the underlying resource
196−getResourceBody :: Compiler a String
196+getResourceBody :: Compiler String
197197getResourceBody = getResourceWith resourceBody
198198
199199
200200
201201--------------------------------------------------------------------------------
202202-- | Get the resource we are compiling as a string
203−getResourceString :: Compiler a String
203+getResourceString :: Compiler String
204204getResourceString = getResourceWith $ const resourceString
205205
206206
207207--------------------------------------------------------------------------------
208208-- | Get the resource we are compiling as a lazy bytestring
209209--
210−getResourceLBS :: Compiler a ByteString
210+getResourceLBS :: Compiler ByteString
211211getResourceLBS = getResourceWith $ const resourceLBS
212212
213213
214214--------------------------------------------------------------------------------
215215-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
216−getResourceWith :: (ResourceProvider -> Identifier a -> IO b) -> Compiler c b
216+getResourceWith :: (ResourceProvider -> Identifier a -> IO b) -> Compiler b
217217getResourceWith reader = fromJob $ \_ -> CompilerM $ do
218218 provider <- compilerResourceProvider <$> ask
219219 r <- compilerIdentifier <$> ask
@@ -251,13 +251,14 @@ getDependency id' = CompilerM $ do
251251--
252252require_ :: (Binary a, Typeable a, Writable a)
253253 => Identifier a
254− -> Compiler b a
254+ -> Compiler a
255255require_ identifier =
256256 fromDependency identifier >>> fromJob (const $ getDependency identifier)
257257
258258-- | Require another target. Using this function ensures automatic handling of
259259-- dependencies
260260--
261+{-
261262require :: (Binary a, Typeable a, Writable a)
262263 => Identifier a
263264 -> (b -> a -> c)
@@ -271,13 +272,14 @@ requireA :: (Binary a, Typeable a, Writable a)
271272 -> Compiler (b, a) c
272273 -> Compiler b c
273274requireA identifier = (id &&& require_ identifier >>>)
275+-}
274276
275277-- | Variant of 'requireAll' which drops the current value
276278--
277279requireAll_ :: (Binary a, Typeable a, Writable a)
278280 => Pattern a
279− -> Compiler b [a]
280−requireAll_ pattern = fromDependencies (const getDeps) >>> fromJob requireAll_'
281+ -> Compiler [a]
282+requireAll_ pattern = fromDependencies (const getDeps) *> fromJob requireAll_'
281283 where
282284 getDeps = map castIdentifier . filterMatches pattern . map castIdentifier
283285 requireAll_' = const $ CompilerM $ do
@@ -287,6 +289,7 @@ requireAll_ pattern = fromDependencies (const getDeps) >>> fromJob requireAll_'
287289-- | Require a number of targets. Using this function ensures automatic handling
288290-- of dependencies
289291--
292+{-
290293requireAll :: (Binary a, Typeable a, Writable a)
291294 => Pattern a
292295 -> (b -> [a] -> c)
@@ -300,12 +303,13 @@ requireAllA :: (Binary a, Typeable a, Writable a)
300303 -> Compiler (b, [a]) c
301304 -> Compiler b c
302305requireAllA pattern = (id &&& requireAll_ pattern >>>)
306+-}
303307
304308cached :: (Binary a, Typeable a, Writable a)
305309 => String
306− -> Compiler () a
307− -> Compiler () a
308−cached name (Compiler d j) = Compiler d $ const $ CompilerM $ do
310+ -> Compiler a
311+ -> Compiler a
312+cached name (Compiler d j) = Compiler d $ CompilerM $ do
309313 logger <- compilerLogger <$> ask
310314 identifier <- castIdentifier . compilerIdentifier <$> ask
311315 store <- compilerStore <$> ask
@@ -326,8 +330,8 @@ cached name (Compiler d j) = Compiler d $ const $ CompilerM $ do
326330
327331-- | Create an unsafe compiler from a function in IO
328332--
329−unsafeCompiler :: (a -> IO b) -- ^ Function to lift
330− -> Compiler a b -- ^ Resulting compiler
333+unsafeCompiler :: (a -> IO b) -- ^ Function to lift
334+ -> Compiler (a -> b) -- ^ Resulting compiler
331335unsafeCompiler f = fromJob $ CompilerM . liftIO . f
332336
333337-- | Compiler for debugging purposes
src/Hakyll/Core/Compiler/Internal.hs+89−154
@@ -1,63 +1,35 @@
11--------------------------------------------------------------------------------
22-- | Internally used compiler module
3+{-# LANGUAGE GADTs #-}
34{-# LANGUAGE GeneralizedNewtypeDeriving #-}
45module Hakyll.Core.Compiler.Internal
5− ( Dependencies
6− , DependencyEnvironment (..)
7− , CompilerEnvironment (..)
8− , Throwing
9− , CompilerM (..)
6+ ( CompilerRead (..)
107 , Compiler (..)
11− , runCompilerJob
12− , runCompilerDependencies
13− , fromJob
14− , fromDependencies
15− , fromDependency
8+ , compilerTell
9+ , compilerAsk
10+ , compilerThrow
11+ , compilerCatch
1612 ) where
1713
1814
1915--------------------------------------------------------------------------------
20−import Control.Applicative (Alternative (..), Applicative,
21− pure, (<$>), (<*>))
22−import Control.Arrow
23−import Control.Category (Category, id, (.))
24−import Control.Monad (liftM2, (<=<))
25−import Control.Monad.Error (ErrorT, catchError, runErrorT,
26− throwError)
27−import Control.Monad.Reader (Reader, ReaderT, ask, runReader,
28− runReaderT)
29−import Data.Set (Set)
30−import qualified Data.Set as S
31−import Prelude hiding (id, (.))
16+import Control.Applicative (Alternative (..),
17+ Applicative (..))
18+import Data.Monoid (mappend, mempty)
3219
3320
3421--------------------------------------------------------------------------------
22+import Hakyll.Core.Dependencies
3523import Hakyll.Core.Identifier
3624import Hakyll.Core.Logger
3725import Hakyll.Core.ResourceProvider
3826import Hakyll.Core.Routes
3927import Hakyll.Core.Store
40−import Hakyll.Core.Util.Arrow
41−
42−
43−--------------------------------------------------------------------------------
44−-- | A set of dependencies
45−type Dependencies = Set (Identifier ())
46−
47−
48−--------------------------------------------------------------------------------
49−-- | Environment in which the dependency analyzer runs
50−data DependencyEnvironment = DependencyEnvironment
51− { -- | Target identifier
52− dependencyIdentifier :: Identifier ()
53− , -- | List of available identifiers we can depend upon
54− dependencyUniverse :: [Identifier ()]
55− }
5628
5729
5830--------------------------------------------------------------------------------
5931-- | Environment in which a compiler runs
60−data CompilerEnvironment = CompilerEnvironment
32+data CompilerRead = CompilerRead
6133 { -- | Target identifier
6234 compilerIdentifier :: Identifier ()
6335 , -- | Resource provider
@@ -76,164 +48,127 @@ data CompilerEnvironment = CompilerEnvironment
7648
7749
7850--------------------------------------------------------------------------------
79−-- | A calculation possibly throwing an error
80−type Throwing a = Either String a
51+type CompilerWrite = [Dependency]
8152
8253
8354--------------------------------------------------------------------------------
84−-- | The compiler monad
85−newtype CompilerM a = CompilerM
86− { unCompilerM :: ErrorT String (ReaderT CompilerEnvironment IO) a
87− } deriving (Monad, Functor, Applicative)
55+data CompilerResult a where
56+ CompilerDone :: a -> CompilerWrite -> CompilerResult a
57+ CompilerError :: String -> CompilerResult a
58+ CompilerRequire :: Identifier b -> (b -> Compiler a) -> CompilerResult a
8859
8960
9061--------------------------------------------------------------------------------
91−-- | The compiler arrow
92−data Compiler a b = Compiler
93− { compilerDependencies :: Reader DependencyEnvironment Dependencies
94− , compilerJob :: a -> CompilerM b
62+newtype Compiler a = Compiler
63+ { unCompiler :: CompilerRead -> IO (CompilerResult a)
9564 }
9665
9766
9867--------------------------------------------------------------------------------
99−instance Functor (Compiler a) where
100− fmap f (Compiler d j) = Compiler d $ fmap f . j
68+instance Functor Compiler where
69+ fmap f (Compiler c) = Compiler $ \r -> do
70+ res <- c r
71+ return $ case res of
72+ CompilerDone x w -> CompilerDone (f x) w
73+ CompilerError e -> CompilerError e
74+ CompilerRequire i g -> CompilerRequire i (\x -> fmap f (g x))
10175 {-# INLINE fmap #-}
10276
10377
10478--------------------------------------------------------------------------------
105−instance Applicative (Compiler a) where
106− pure = fromJob . const . return
107− {-# INLINE pure #-}
79+instance Monad Compiler where
80+ return x = Compiler $ \_ -> return $ CompilerDone x mempty
81+ {-# INLINE return #-}
10882
109− Compiler d1 j1 <*> Compiler d2 j2 =
110− Compiler (liftM2 S.union d1 d2) $ \x -> j1 x <*> j2 x
111− {-# INLINE (<*>) #-}
112−
113−
114−--------------------------------------------------------------------------------
115−instance Alternative (Compiler a) where
116− empty = fromJob $ const $ CompilerM $
117− throwError "Hakyll.Core.Compiler.Internal: empty alternative"
83+ Compiler c >>= f = Compiler $ \r -> do
84+ res <- c r
85+ case res of
86+ CompilerDone x w -> do
87+ res' <- unCompiler (f x) r
88+ return $ case res' of
89+ CompilerDone y w' -> CompilerDone y (w `mappend` w')
90+ CompilerError e -> CompilerError e
91+ CompilerRequire i g -> CompilerRequire i $ \z -> do
92+ compilerTell w -- Save dependencies!
93+ g z
11894
119− Compiler d1 j1 <|> Compiler d2 j2 =
120− Compiler (liftM2 S.union d1 d2) $ \x -> CompilerM $
121− catchError (unCompilerM $ j1 x) (\_ -> unCompilerM $ j2 x)
122− {-# INLINE (<|>) #-}
95+ CompilerError e -> return $ CompilerError e
96+ CompilerRequire i g -> return $ CompilerRequire i $ \z -> g z >>= f
97+ {-# INLINE (>>=) #-}
12398
12499
125100--------------------------------------------------------------------------------
126−instance Category Compiler where
127− id = Compiler (return S.empty) return
128− {-# INLINE id #-}
101+instance Applicative Compiler where
102+ pure x = return x
103+ {-# INLINE pure #-}
129104
130− Compiler d1 j1 . Compiler d2 j2 =
131− Compiler (liftM2 S.union d1 d2) (j1 <=< j2)
132− {-# INLINE (.) #-}
105+ f <*> x = f >>= \f' -> fmap f' x
106+ {-# INLINE (<*>) #-}
133107
134108
135109--------------------------------------------------------------------------------
136−instance Arrow Compiler where
137− arr f = fromJob (return . f)
138− {-# INLINE arr #-}
139−
140− first (Compiler d j) = Compiler d $ \(x, y) -> do
141− x' <- j x
142− return (x', y)
143− {-# INLINE first #-}
144−
145− second (Compiler d j) = Compiler d $ \(x, y) -> do
146− y' <- j y
147− return (x, y')
148− {-# INLINE second #-}
110+instance Alternative Compiler where
111+ empty = compilerThrow "Hakyll.Core.Compiler.Internal: empty alternative"
112+ x <|> y = compilerCatch x (\_ -> y)
113+ {-# INLINE (<|>) #-}
149114
150− Compiler d1 j1 *** Compiler d2 j2 =
151− Compiler (liftM2 S.union d1 d2) $ \(x, y) -> do
152− x' <- j1 x
153− y' <- j2 y
154− return (x', y')
155− {-# INLINE (***) #-}
156115
157− Compiler d1 j1 &&& Compiler d2 j2 =
158− Compiler (liftM2 S.union d1 d2) $ \x -> do
159− y1 <- j1 x
160− y2 <- j2 x
161− return (y1, y2)
162− {-# INLINE (&&&) #-}
116+--------------------------------------------------------------------------------
117+compilerAsk :: Compiler CompilerRead
118+compilerAsk = Compiler $ \r -> return $ CompilerDone r mempty
119+{-# INLINE compilerAsk #-}
163120
164121
165122--------------------------------------------------------------------------------
166−instance ArrowChoice Compiler where
167− left (Compiler d j) = Compiler d $ \e -> case e of
168− Left l -> Left <$> j l
169− Right r -> Right <$> return r
170− {-# INLINE left #-}
171−
172− Compiler d1 j1 ||| Compiler d2 j2 = Compiler (liftM2 S.union d1 d2) $
173− \e -> case e of Left x -> j1 x; Right y -> j2 y
174− {-# INLINE (|||) #-}
123+compilerTell :: [Dependency] -> Compiler ()
124+compilerTell deps = Compiler $ \_ -> return $ CompilerDone () deps
125+{-# INLINE compilerTell #-}
175126
176127
177128--------------------------------------------------------------------------------
178−instance ArrowMap Compiler where
179− mapA (Compiler d j) = Compiler d $ mapM j
180− {-# INLINE mapA #-}
129+compilerThrow :: String -> Compiler a
130+compilerThrow e = Compiler $ \_ -> return $ CompilerError e
131+{-# INLINE compilerThrow #-}
181132
182133
183134--------------------------------------------------------------------------------
184−-- | Run a compiler, yielding the resulting target
185−runCompilerJob :: Compiler () a -- ^ Compiler to run
186− -> Identifier () -- ^ Target identifier
187− -> ResourceProvider -- ^ Resource provider
188− -> [Identifier ()] -- ^ Universe
189− -> Routes -- ^ Route
190− -> Store -- ^ Store
191− -> Bool -- ^ Was the resource modified?
192− -> Logger -- ^ Logger
193− -> IO (Throwing a) -- ^ Result
194−runCompilerJob compiler id' provider universe route store modified logger =
195− runReaderT (runErrorT $ unCompilerM $ compilerJob compiler ()) env
196− where
197− env = CompilerEnvironment
198− { compilerIdentifier = id'
199− , compilerResourceProvider = provider
200− , compilerUniverse = universe
201− , compilerRoutes = route
202− , compilerStore = store
203− , compilerResourceModified = modified
204− , compilerLogger = logger
205− }
135+compilerCatch :: Compiler a -> (String -> Compiler a) -> Compiler a
136+compilerCatch (Compiler x) f = Compiler $ \r -> do
137+ res <- x r
138+ case res of
139+ CompilerError e -> unCompiler (f e) r
140+ _ -> return res
141+{-# INLINE compilerCatch #-}
206142
207143
144+{-
208145--------------------------------------------------------------------------------
209−runCompilerDependencies :: Compiler () a
210− -> Identifier ()
211− -> [Identifier ()]
212− -> Dependencies
213−runCompilerDependencies compiler identifier universe =
214− runReader (compilerDependencies compiler) env
215− where
216− env = DependencyEnvironment
217− { dependencyIdentifier = identifier
218− , dependencyUniverse = universe
219− }
146+-- | The compiler monad
147+newtype CompilerM a = CompilerM
148+ { unCompilerM :: ErrorT String (ReaderT CompilerEnvironment IO) a
149+ } deriving (Monad, Functor, Applicative)
220150
221151
222152--------------------------------------------------------------------------------
223−fromJob :: (a -> CompilerM b) -> Compiler a b
224−fromJob = Compiler $ return S.empty
225−{-# INLINE fromJob #-}
153+-- | The compiler arrow
154+data Compiler a = Compiler
155+ { compilerDependencies :: Reader DependencyEnvironment Dependencies
156+ , compilerJob :: CompilerM a
157+ }
226158
227159
228160--------------------------------------------------------------------------------
229−fromDependencies :: (Identifier () -> [Identifier ()] -> [Identifier ()])
230− -> Compiler b b
231−fromDependencies collectDeps = flip Compiler return $ do
232− DependencyEnvironment identifier universe <- ask
233− return $ S.fromList $ collectDeps identifier universe
161+instance Functor Compiler where
162+ fmap f (Compiler d j) = Compiler d $ fmap f j
163+ {-# INLINE fmap #-}
234164
235165
236166--------------------------------------------------------------------------------
237−-- | Wait until another compiler has finished before running this compiler
238−fromDependency :: Identifier a -> Compiler b b
239−fromDependency = fromDependencies . const . const . return . castIdentifier
167+instance Applicative Compiler where
168+ pure = fromJob . return
169+ {-# INLINE pure #-}
170+
171+ Compiler d1 j1 <*> Compiler d2 j2 =
172+ Compiler (liftM2 S.union d1 d2) $ j1 <*> j2
173+ {-# INLINE (<*>) #-}
174+-}
src/Hakyll/Core/Identifier/Pattern.hs+7−1
@@ -43,6 +43,7 @@ module Hakyll.Core.Identifier.Pattern
4343 , fromGlob
4444 , fromList
4545 , fromRegex
46+ , fromVersion
4647
4748 -- * Manipulating patterns
4849 , complement
@@ -175,6 +176,11 @@ fromRegex :: String -> Pattern a
175176fromRegex = Regex
176177
177178
179+--------------------------------------------------------------------------------
180+fromVersion :: Maybe String -> Pattern a
181+fromVersion = Version
182+
183+
178184--------------------------------------------------------------------------------
179185-- | Inverts a pattern, e.g.
180186--
@@ -190,7 +196,7 @@ complement = Complement
190196--
191197-- > "foo/*.markdown" `withVersion` "pdf"
192198withVersion :: Pattern a -> String -> Pattern a
193−withVersion p v = And p $ Version $ Just v
199+withVersion p v = And p $ fromVersion $ Just v
194200
195201
196202--------------------------------------------------------------------------------
src/Hakyll/Core/ResourceProvider/Internal.hs+4−4
@@ -48,7 +48,7 @@ newResourceProvider :: Store -- ^ Store to use
4848 -> FilePath -- ^ Search directory
4949 -> IO ResourceProvider -- ^ Resulting provider
5050newResourceProvider store ignore directory = do
51− list <- map parseIdentifier . filter (not . ignore) <$>
51+ list <- map fromFilePath . filter (not . ignore) <$>
5252 getRecursiveContents False directory
5353 cache <- newIORef M.empty
5454 return $ ResourceProvider (S.fromList list) cache store
@@ -60,10 +60,10 @@ resourceList = S.toList . resourceSet
6060
6161
6262--------------------------------------------------------------------------------
63−-- | Check if a given resiyrce exists
63+-- | Check if a given resource exists
6464resourceExists :: ResourceProvider -> Identifier a -> Bool
6565resourceExists provider =
66− (`S.member` resourceSet provider) . setGroup Nothing . castIdentifier
66+ (`S.member` resourceSet provider) . setVersion Nothing . castIdentifier
6767
6868
6969--------------------------------------------------------------------------------
@@ -71,7 +71,7 @@ resourceExists provider =
7171-- filename)
7272resourceMetadataResource :: Identifier a -> Identifier ()
7373resourceMetadataResource =
74− parseIdentifier . flip addExtension "metadata" . toFilePath
74+ fromFilePath . flip addExtension "metadata" . toFilePath
7575
7676
7777--------------------------------------------------------------------------------
src/Hakyll/Core/ResourceProvider/Modified.hs+1−1
@@ -47,7 +47,7 @@ resourceModified rp r
4747
4848 return m
4949 where
50− normalized = castIdentifier $ setGroup Nothing r
50+ normalized = castIdentifier $ setVersion Nothing r
5151 exists = resourceExists rp r
5252 store = resourceStore rp
5353 cacheRef = resourceModifiedCache rp
src/Hakyll/Core/Routes.hs+28−12
@@ -1,3 +1,4 @@
1+--------------------------------------------------------------------------------
12-- | Once a target is compiled, the user usually wants to save it to the disk.
23-- This is where the 'Routes' type comes in; it determines where a certain
34-- target should be written.
@@ -24,7 +25,6 @@
2425-- not appear in your site directory.
2526--
2627-- * If an item matches multiple routes, the first rule will be chosen.
27−--
2828{-# LANGUAGE Rank2Types #-}
2929module Hakyll.Core.Routes
3030 ( Routes
@@ -38,33 +38,44 @@ module Hakyll.Core.Routes
3838 , composeRoutes
3939 ) where
4040
41+
42+--------------------------------------------------------------------------------
4143import Data.Monoid (Monoid, mempty, mappend)
4244import Control.Monad (mplus)
4345import System.FilePath (replaceExtension)
4446
47+
48+--------------------------------------------------------------------------------
4549import Hakyll.Core.Identifier
4650import Hakyll.Core.Identifier.Pattern
4751import Hakyll.Core.Util.String
4852
53+
54+--------------------------------------------------------------------------------
4955-- | Type used for a route
50−--
5156newtype Routes = Routes {unRoutes :: forall a. Identifier a -> Maybe FilePath}
5257
58+
59+--------------------------------------------------------------------------------
5360instance Monoid Routes where
5461 mempty = Routes $ const Nothing
5562 mappend (Routes f) (Routes g) = Routes $ \id' -> f id' `mplus` g id'
5663
64+
65+--------------------------------------------------------------------------------
5766-- | Apply a route to an identifier
58−--
5967runRoutes :: Routes -> Identifier a -> Maybe FilePath
6068runRoutes = unRoutes
6169
70+
71+--------------------------------------------------------------------------------
6272-- | A route that uses the identifier as filepath. For example, the target with
6373-- ID @foo\/bar@ will be written to the file @foo\/bar@.
64−--
6574idRoute :: Routes
6675idRoute = Routes $ Just . toFilePath
6776
77+
78+--------------------------------------------------------------------------------
6879-- | Set (or replace) the extension of a route.
6980--
7081-- Example:
@@ -82,29 +93,34 @@ idRoute = Routes $ Just . toFilePath
8293-- Result:
8394--
8495-- > Just "posts/the-art-of-trolling.html"
85−--
8696setExtension :: String -> Routes
87−setExtension extension = Routes $ fmap (`replaceExtension` extension)
88− . unRoutes idRoute
97+setExtension extension = Routes $
98+ fmap (`replaceExtension` extension) . unRoutes idRoute
99+
89100
101+--------------------------------------------------------------------------------
90102-- | Apply the route if the identifier matches the given pattern, fail
91103-- otherwise
92−--
93104matchRoute :: Pattern a -> Routes -> Routes
94105matchRoute pattern (Routes route) = Routes $ \id' ->
95106 if matches pattern (castIdentifier id') then route id' else Nothing
96107
108+
109+--------------------------------------------------------------------------------
97110-- | Create a custom route. This should almost always be used with
98111-- 'matchRoute'
99−--
100112customRoute :: (Identifier a -> FilePath) -> Routes
101113customRoute f = Routes $ Just . f . castIdentifier
102114
115+
116+--------------------------------------------------------------------------------
103117-- | A route that always gives the same result. Obviously, you should only use
104118-- this for a single compilation rule.
105119constRoute :: FilePath -> Routes
106120constRoute = customRoute . const
107121
122+
123+--------------------------------------------------------------------------------
108124-- | Create a gsub route
109125--
110126-- Example:
@@ -114,13 +130,14 @@ constRoute = customRoute . const
114130-- Result:
115131--
116132-- > Just "tags/bar.xml"
117−--
118133gsubRoute :: String -- ^ Pattern
119134 -> (String -> String) -- ^ Replacement
120135 -> Routes -- ^ Resulting route
121136gsubRoute pattern replacement = customRoute $
122137 replaceAll pattern replacement . toFilePath
123138
139+
140+--------------------------------------------------------------------------------
124141-- | Compose routes so that @f `composeRoutes` g@ is more or less equivalent
125142-- with @f >>> g@.
126143--
@@ -134,10 +151,9 @@ gsubRoute pattern replacement = customRoute $
134151-- > Just "tags/bar.xml"
135152--
136153-- If the first route given fails, Hakyll will not apply the second route.
137−--
138154composeRoutes :: Routes -- ^ First route to apply
139155 -> Routes -- ^ Second route to apply
140156 -> Routes -- ^ Resulting route
141157composeRoutes (Routes f) (Routes g) = Routes $ \i -> do
142158 p <- f i
143− g $ parseIdentifier p
159+ g $ fromFilePath p
src/Hakyll/Core/Rules.hs+18−19
@@ -31,7 +31,7 @@ module Hakyll.Core.Rules
3131
3232--------------------------------------------------------------------------------
3333import Control.Applicative ((<$>))
34−import Control.Arrow (arr, (***), (>>>))
34+import Control.Arrow ((***))
3535import Control.Monad.Reader (ask, local)
3636import Control.Monad.State (get, put)
3737import Control.Monad.Writer (tell)
@@ -64,14 +64,12 @@ tellRoute route' = RulesM $ tell $ RuleSet route' mempty mempty
6464--------------------------------------------------------------------------------
6565-- | Add a number of compilers
6666tellCompilers :: (Binary a, Typeable a, Writable a)
67− => [(Identifier a, Compiler () a)]
67+ => [(Identifier a, Compiler a)]
6868 -> Rules
6969tellCompilers compilers = RulesM $ do
7070 -- We box the compilers so they have a more simple type
71− let compilers' = map (castIdentifier *** boxCompiler) compilers
71+ let compilers' = map (castIdentifier *** fmap compiledItem) compilers
7272 tell $ RuleSet mempty compilers' mempty
73− where
74− boxCompiler = (>>> arr compiledItem)
7573
7674
7775--------------------------------------------------------------------------------
@@ -123,9 +121,9 @@ match pattern = RulesM . local addPredicate . unRulesM
123121-- This will put the compiler for the raw content in a separate group
124122-- (@\"raw\"@), which causes it to be compiled as well.
125123group :: String -> RulesM a -> RulesM a
126−group g = RulesM . local setGroup' . unRulesM
124+group g = RulesM . local setVersion' . unRulesM
127125 where
128− setGroup' env = env { rulesGroup = Just g }
126+ setVersion' env = env {rulesVersion = Just g}
129127
130128
131129--------------------------------------------------------------------------------
@@ -135,12 +133,12 @@ group g = RulesM . local setGroup' . unRulesM
135133-- no resources match the current selection, nothing will happen. In this case,
136134-- you might want to have a look at 'create'.
137135compile :: (Binary a, Typeable a, Writable a)
138− => Compiler () a -> RulesM (Pattern a)
136+ => Compiler a -> RulesM (Pattern a)
139137compile compiler = do
140138 ids <- resources
141139 tellCompilers [(castIdentifier id', compiler) | id' <- ids]
142140 tellResources ids
143− return $ list $ map castIdentifier ids
141+ return $ fromList $ map castIdentifier ids
144142
145143
146144--------------------------------------------------------------------------------
@@ -153,10 +151,10 @@ compile compiler = do
153151-- replaced by the group set via 'group' (or 'Nothing', if 'group' has not been
154152-- used).
155153create :: (Binary a, Typeable a, Writable a)
156− => Identifier a -> Compiler () a -> RulesM (Identifier a)
154+ => Identifier a -> Compiler a -> RulesM (Identifier a)
157155create id' compiler = RulesM $ do
158− group' <- rulesGroup <$> ask
159− let id'' = setGroup group' id'
156+ version' <- rulesVersion <$> ask
157+ let id'' = setVersion version' id'
160158 unRulesM $ tellCompilers [(id'', compiler)]
161159 return id''
162160
@@ -168,10 +166,11 @@ create id' compiler = RulesM $ do
168166route :: Routes -> Rules
169167route route' = RulesM $ do
170168 -- We want the route only to be applied if we match the current pattern and
171− -- group
172− pattern <- rulesPattern <$> ask
173− group' <- rulesGroup <$> ask
174− unRulesM $ tellRoute $ matchRoute (pattern `mappend` inGroup group') route'
169+ -- version
170+ pattern <- rulesPattern <$> ask
171+ version' <- rulesVersion <$> ask
172+ unRulesM $ tellRoute $ matchRoute
173+ (pattern `mappend` fromVersion version') route'
175174
176175
177176--------------------------------------------------------------------------------
@@ -181,8 +180,8 @@ resources :: RulesM [Identifier ()]
181180resources = RulesM $ do
182181 pattern <- rulesPattern <$> ask
183182 provider <- rulesResourceProvider <$> ask
184− g <- rulesGroup <$> ask
185− return $ filterMatches pattern $ map (setGroup g) $ resourceList provider
183+ g <- rulesVersion <$> ask
184+ return $ filterMatches pattern $ map (setVersion g) $ resourceList provider
186185
187186
188187--------------------------------------------------------------------------------
@@ -193,6 +192,6 @@ freshIdentifier :: String -- ^ Prefix
193192freshIdentifier prefix = RulesM $ do
194193 state <- get
195194 let index = rulesNextIdentifier state
196− id' = parseIdentifier $ prefix ++ "/" ++ show index
195+ id' = fromFilePath $ prefix ++ "/" ++ show index
197196 put $ state {rulesNextIdentifier = index + 1}
198197 return id'
src/Hakyll/Core/Rules/Internal.hs+3−3
@@ -35,7 +35,7 @@ data RuleSet = RuleSet
3535 { -- | Routes used in the compilation structure
3636 rulesRoutes :: Routes
3737 , -- | Compilation rules
38− rulesCompilers :: [(Identifier (), Compiler () CompiledItem)]
38+ rulesCompilers :: [(Identifier (), Compiler CompiledItem)]
3939 , -- | A set of the actually used files
4040 rulesResources :: Set (Identifier ())
4141 }
@@ -60,7 +60,7 @@ data RuleState = RuleState
6060data RuleEnvironment = RuleEnvironment
6161 { rulesResourceProvider :: ResourceProvider
6262 , rulesPattern :: forall a. Pattern a
63− , rulesGroup :: Maybe String
63+ , rulesVersion :: Maybe String
6464 }
6565
6666
@@ -88,7 +88,7 @@ runRules rules provider = do
8888 env = RuleEnvironment
8989 { rulesResourceProvider = provider
9090 , rulesPattern = mempty
91− , rulesGroup = Nothing
91+ , rulesVersion = Nothing
9292 }
9393
9494
tests/Hakyll/Core/Dependencies/Tests.hs+1−1
@@ -29,7 +29,7 @@ tests = testGroup "Hakyll.Core.Dependencies.Tests"
2929
3030
3131--------------------------------------------------------------------------------
32−oldUniverse :: [Identifier ()]
32+oldUniverse :: [Identifier]
3333oldUniverse = M.keys oldFacts
3434
3535