@@ -111,17 +111,18 @@ module Hakyll.Core.Compiler
111111 , traceShowCompiler
112112 , mapCompiler
113113 , timedCompiler
114+ , byIdentifier
114115 , byExtension
115116 ) where
116117
117118import Prelude hiding ((.), id)
118−import Control.Arrow ((>>>), (&&&), arr)
119+import Control.Arrow ((>>>), (&&&), arr, first)
119120import Control.Applicative ((<$>))
120121import Control.Monad.Reader (ask)
121122import Control.Monad.Trans (liftIO)
122123import Control.Monad.Error (throwError)
123124import Control.Category (Category, (.), id)
124−import Data.Maybe (fromMaybe)
125+import Data.List (find)
125126import System.FilePath (takeExtension)
126127
127128import Data.Binary (Binary)
@@ -342,33 +343,50 @@ timedCompiler msg (Compiler d j) = Compiler d $ \x -> CompilerM $ do
342343 logger <- compilerLogger <$> ask
343344 timed logger msg $ unCompilerM $ j x
344345
345−-- | Choose a compiler by extension
346−--
347−-- Example:
346+-- | Choose a compiler by identifier
348347--
349−-- > route "css/*" $ setExtension "css"
350−-- > compile "css/*" $ byExtension (error "Not a (S)CSS file")
351−-- > [ (".css", compressCssCompiler)
352−-- > , (".scss", sass)
353−-- > ]
348+-- For example, assume that most content files need to be compiled
349+-- normally, but a select few need an extra step in the pipeline:
354350--
355−-- This piece of code will select the @compressCssCompiler@ for @.css@ files,
356−-- and the @sass@ compiler (defined elsewhere) for @.scss@ files.
351+-- > compile $ pageCompiler
352+-- > >>> byIdentifier id
353+-- > [ ((=="projects.md") . toFilePath, addProjectListCompiler)
354+-- > , ((=="sitemap.md") . toFilePath, addSiteMapCompiler)
355+-- > ]
357356--
358−byExtension :: Compiler a b -- ^ Default compiler
359− -> [(String, Compiler a b)] -- ^ Choices
360− -> Compiler a b -- ^ Resulting compiler
361−byExtension defaultCompiler choices = Compiler deps job
357+byIdentifier :: Compiler a b -- ^ Default compiler
358+ -> [(Identifier a -> Bool, Compiler a b)] -- ^ Choices
359+ -> Compiler a b -- ^ Resulting compiler
360+byIdentifier defaultCompiler choices = Compiler deps job
362361 where
363362 -- Lookup the compiler, give an error when it is not found
364363 lookup' identifier =
365− let extension = takeExtension $ toFilePath identifier
366− in fromMaybe defaultCompiler $ lookup extension choices
364+ maybe defaultCompiler snd $ find (\(f,_) -> f identifier) choices
367365 -- Collect the dependencies of the choice
368366 deps = do
369− identifier <- dependencyIdentifier <$> ask
367+ identifier <- castIdentifier . dependencyIdentifier <$> ask
370368 compilerDependencies $ lookup' identifier
371369 -- Collect the job of the choice
372370 job x = CompilerM $ do
373− identifier <- compilerIdentifier <$> ask
371+ identifier <- castIdentifier . compilerIdentifier <$> ask
374372 unCompilerM $ compilerJob (lookup' identifier) x
373+
374+-- | Choose a compiler by extension
375+--
376+-- Example:
377+--
378+-- > match "css/*" $ do
379+-- > route $ setExtension "css"
380+-- > compile $ byExtension (error "Not a (S)CSS file")
381+-- > [ (".css", compressCssCompiler)
382+-- > , (".scss", sass)
383+-- > ]
384+--
385+-- This piece of code will select the @compressCssCompiler@ for @.css@ files,
386+-- and the @sass@ compiler (defined elsewhere) for @.scss@ files.
387+--
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