@@ -111,17 +111,18 @@ module Hakyll.Core.Compiler
111 , traceShowCompiler
111 , traceShowCompiler
112 , mapCompiler
112 , mapCompiler
113 , timedCompiler
113 , timedCompiler
114 , byExtension
115 , byExtension
117import Prelude hiding ((.), id)
118import Prelude hiding ((.), id)
118−import Control.Arrow ((>>>), (&&&), arr)
119+import Control.Arrow ((>>>), (&&&), arr, first)
119import Control.Applicative ((<$>))
120import Control.Applicative ((<$>))
120import Control.Monad.Reader (ask)
121import Control.Monad.Reader (ask)
121import Control.Monad.Trans (liftIO)
122import Control.Monad.Trans (liftIO)
122import Control.Monad.Error (throwError)
123import Control.Monad.Error (throwError)
123import Control.Category (Category, (.), id)
124import Control.Category (Category, (.), id)
124−import Data.Maybe (fromMaybe)
125+import Data.List (find)
125import System.FilePath (takeExtension)
126import System.FilePath (takeExtension)
127import Data.Binary (Binary)
128import Data.Binary (Binary)
@@ -342,33 +343,50 @@ timedCompiler msg (Compiler d j) = Compiler d $ \x -> CompilerM $ do
342 logger <- compilerLogger <$> ask
343 logger <- compilerLogger <$> ask
343 timed logger msg $ unCompilerM $ j x
344 timed logger msg $ unCompilerM $ j x
345−-- | Choose a compiler by extension
346+-- | Choose a compiler by identifier
349−-- > route "css/*" $ setExtension "css"
348+-- For example, assume that most content files need to be compiled
350−-- > compile "css/*" $ byExtension (error "Not a (S)CSS file")
349+-- normally, but a select few need an extra step in the pipeline:
351−-- > [ (".css", compressCssCompiler)
352−-- > , (".scss", sass)
355−-- This piece of code will select the @compressCssCompiler@ for @.css@ files,
351+-- > compile $ pageCompiler
356−-- and the @sass@ compiler (defined elsewhere) for @.scss@ files.
352+-- > >>> byIdentifier id
353+-- > [ ((=="projects.md") . toFilePath, addProjectListCompiler)
354+-- > , ((=="sitemap.md") . toFilePath, addSiteMapCompiler)
358−byExtension :: Compiler a b -- ^ Default compiler
357+byIdentifier :: Compiler a b -- ^ Default compiler
359− -> [(String, Compiler a b)] -- ^ Choices
358+ -> [(Identifier a -> Bool, Compiler a b)] -- ^ Choices
360− -> Compiler a b -- ^ Resulting compiler
359+ -> Compiler a b -- ^ Resulting compiler
361−byExtension defaultCompiler choices = Compiler deps job
360+byIdentifier defaultCompiler choices = Compiler deps job
363 -- Lookup the compiler, give an error when it is not found
362 -- Lookup the compiler, give an error when it is not found
364 lookup' identifier =
363 lookup' identifier =
365− let extension = takeExtension $ toFilePath identifier
366− in fromMaybe defaultCompiler $ lookup extension choices
364+ maybe defaultCompiler snd $ find (\(f,_) -> f identifier) choices
367 -- Collect the dependencies of the choice
365 -- Collect the dependencies of the choice
368 deps = do
366 deps = do
369− identifier <- dependencyIdentifier <$> ask
367+ identifier <- castIdentifier . dependencyIdentifier <$> ask
370 compilerDependencies $ lookup' identifier
368 compilerDependencies $ lookup' identifier
371 -- Collect the job of the choice
369 -- Collect the job of the choice
372 job x = CompilerM $ do
370 job x = CompilerM $ do
373− identifier <- compilerIdentifier <$> ask
371+ identifier <- castIdentifier . compilerIdentifier <$> ask
374 unCompilerM $ compilerJob (lookup' identifier) x
372 unCompilerM $ compilerJob (lookup' identifier) x
374+-- | Choose a compiler by extension
378+-- > match "css/*" $ do
379+-- > route $ setExtension "css"
380+-- > compile $ byExtension (error "Not a (S)CSS file")
381+-- > [ (".css", compressCssCompiler)
382+-- > , (".scss", sass)
385+-- This piece of code will select the @compressCssCompiler@ for @.css@ files,
386+-- and the @sass@ compiler (defined elsewhere) for @.scss@ files.
388+byExtension :: Compiler a b -- ^ Default compiler
389+ -> [(String, Compiler a b)] -- ^ Choices
390+ -> Compiler a b -- ^ Resulting compiler
391+byExtension defaultCompiler = byIdentifier defaultCompiler . map (first cmp)
392+ where cmp c = (==c) . takeExtension . toFilePath