diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Hakyll/Core/Metadata.hs | 11 | ||||
-rw-r--r-- | src/Hakyll/Core/Provider/Metadata.hs | 37 | ||||
-rw-r--r-- | src/Hakyll/Core/Rules/Default.hs | 24 | ||||
-rw-r--r-- | src/Hakyll/Core/Runtime.hs | 5 |
4 files changed, 73 insertions, 4 deletions
diff --git a/src/Hakyll/Core/Metadata.hs b/src/Hakyll/Core/Metadata.hs index 7902b94..a123c18 100644 --- a/src/Hakyll/Core/Metadata.hs +++ b/src/Hakyll/Core/Metadata.hs @@ -5,6 +5,7 @@ module Hakyll.Core.Metadata , getMetadataField , getMetadataField' , makePatternDependency + , metadataFiles ) where @@ -12,6 +13,7 @@ module Hakyll.Core.Metadata import Control.Monad (forM) import Data.Map (Map) import qualified Data.Map as M +import System.FilePath.Posix ((</>), takeDirectory) -------------------------------------------------------------------------------- @@ -61,3 +63,12 @@ makePatternDependency :: MonadMetadata m => Pattern -> m Dependency makePatternDependency pattern = do matches' <- getMatches pattern return $ PatternDependency pattern matches' + +-------------------------------------------------------------------------------- +-- | Returns a list of all directory-wise metadata files, subdir first, global last +metadataFiles :: Identifier -> [Identifier] +metadataFiles identifier = local : go (takeDirectory $ toFilePath identifier) where + go "." = [fromFilePath "metadata"] + go dir = fromFilePath (dir </> "metadata") : go (takeDirectory dir) + local = fromFilePath $ toFilePath identifier ++ ".metadata" + diff --git a/src/Hakyll/Core/Provider/Metadata.hs b/src/Hakyll/Core/Provider/Metadata.hs index 7e4d7ed..889291f 100644 --- a/src/Hakyll/Core/Provider/Metadata.hs +++ b/src/Hakyll/Core/Provider/Metadata.hs @@ -20,6 +20,8 @@ import System.IO as IO import Text.Parsec ((<?>)) import qualified Text.Parsec as P import Text.Parsec.String (Parser) +import System.FilePath.Posix +import Control.Monad (liftM) -------------------------------------------------------------------------------- @@ -28,7 +30,7 @@ import Hakyll.Core.Metadata import Hakyll.Core.Provider.Internal import Hakyll.Core.Util.Parser import Hakyll.Core.Util.String - +import Hakyll.Core.Identifier.Pattern -------------------------------------------------------------------------------- loadMetadata :: Provider -> Identifier -> IO (Metadata, Maybe String) @@ -42,7 +44,9 @@ loadMetadata p identifier = do Nothing -> return M.empty Just mi' -> loadMetadataFile $ resourceFilePath p mi' - return (M.union md emd, body) + gmd <- loadGlobalMetadata p identifier + + return (M.unions [md, gmd], body) where normal = setVersion Nothing identifier fp = resourceFilePath p identifier @@ -133,3 +137,32 @@ page = do metadata' <- P.option [] metadataBlock body <- P.many P.anyChar return (metadata', body) + + +-------------------------------------------------------------------------------- +-- | Load directory-wise metadata +loadGlobalMetadata :: Provider -> Identifier -> IO Metadata +loadGlobalMetadata p fp = liftM M.fromList $ loadgm fp where + loadgm :: Identifier -> IO [(String, String)] + loadgm = liftM concat . mapM loadOne . reverse . filter (resourceExists p) . metadataFiles + loadOne mfp = + let path = resourceFilePath p mfp + dir = takeDirectory $ toFilePath mfp + -- TODO: It might be better to print warning and continue + in either (error.show) (findMetadata dir) . P.parse namedMetadata path <$> readFile path + findMetadata dir = + concatMap snd . filter (flip matches fp . fromGlob . normalise . combine dir . fst) + +namedMetadata :: Parser [(String, [(String, String)])] +namedMetadata = liftA2 (:) (namedMetadataBlock False) $ P.many $ namedMetadataBlock True + +namedMetadataBlock :: Bool -> Parser (String, [(String, String)]) +namedMetadataBlock isNamed = do + name <- if isNamed + then P.many1 (P.char '-') *> P.many inlineSpace *> P.manyTill P.anyChar newline + else pure "**" + metadata' <- metadata + P.skipMany P.space + return (name, metadata') + + diff --git a/src/Hakyll/Core/Rules/Default.hs b/src/Hakyll/Core/Rules/Default.hs new file mode 100644 index 0000000..fee78c5 --- /dev/null +++ b/src/Hakyll/Core/Rules/Default.hs @@ -0,0 +1,24 @@ +{-# LANGUAGE OverloadedStrings #-} +module Hakyll.Core.Rules.Default + ( internalRules + , addMetadataDependencies + ) +where +import Hakyll.Core.Rules +import Hakyll.Core.Compiler +import Hakyll.Core.Compiler.Internal (compilerTellDependencies) +import Hakyll.Core.Metadata (getMatches, metadataFiles) +import Hakyll.Core.Identifier.Pattern(fromList) + +internalRules :: Rules () +internalRules = do + match "metadata" $ compile $ makeItem () + match "**/metadata" $ compile $ makeItem () + match "**.metadata" $ compile $ makeItem () + +-------------------------------------------------------------------------------- +addMetadataDependencies :: Compiler () +addMetadataDependencies = + compilerTellDependencies . map IdentifierDependency =<< getMatches . fromList =<< fmap metadataFiles getUnderlying + + diff --git a/src/Hakyll/Core/Runtime.hs b/src/Hakyll/Core/Runtime.hs index 824d11b..12285ad 100644 --- a/src/Hakyll/Core/Runtime.hs +++ b/src/Hakyll/Core/Runtime.hs @@ -35,6 +35,7 @@ import qualified Hakyll.Core.Logger as Logger import Hakyll.Core.Provider import Hakyll.Core.Routes import Hakyll.Core.Rules.Internal +import Hakyll.Core.Rules.Default import Hakyll.Core.Store (Store) import qualified Hakyll.Core.Store as Store import Hakyll.Core.Util.File @@ -53,7 +54,7 @@ run config verbosity rules = do provider <- newProvider store (shouldIgnoreFile config) $ providerDirectory config Logger.message logger "Running rules..." - ruleSet <- runRules rules provider + ruleSet <- runRules (rules >> internalRules) provider -- Get old facts mOldFacts <- Store.get store factsKey @@ -186,7 +187,7 @@ chase trail id' config <- runtimeConfiguration <$> ask Logger.debug logger $ "Processing " ++ show id' - let compiler = todo M.! id' + let compiler = addMetadataDependencies >> todo M.! id' read' = CompilerRead { compilerConfig = config , compilerUnderlying = id' |