packages feed

hakyll 1.2 → 1.3

raw patch · 8 files changed

+146/−42 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Text.Hakyll.File: sortByBaseName :: [FilePath] -> [FilePath]
+ Text.Hakyll.Renderables: createListing :: (Renderable a) => String -> FilePath -> [a] -> [(String, String)] -> CustomPage
+ Text.Hakyll.Renderables: createListingWith :: (Renderable a) => ContextManipulation -> String -> FilePath -> [a] -> [(String, String)] -> CustomPage
+ Text.Hakyll.Renderables: instance Binary PagePath
+ Text.Hakyll.Tags: readCategoryMap :: String -> [PagePath] -> Hakyll TagMap
+ Text.Hakyll.Tags: type TagMap = Map String [PagePath]
- Text.Hakyll.Tags: readTagMap :: String -> [FilePath] -> Hakyll (Map String [FilePath])
+ Text.Hakyll.Tags: readTagMap :: String -> [PagePath] -> Hakyll TagMap
- Text.Hakyll.Tags: renderTagCloud :: Map String [FilePath] -> (String -> String) -> Float -> Float -> String
+ Text.Hakyll.Tags: renderTagCloud :: TagMap -> (String -> String) -> Float -> Float -> String

Files

hakyll.cabal view
@@ -1,5 +1,5 @@ Name:           hakyll-Version:        1.2+Version:        1.3  Synopsis:       A simple static site generator library. Description:
src/Text/Hakyll/Context.hs view
@@ -24,9 +24,9 @@ -- | Type for context manipulating functions. type ContextManipulation = Context -> Context --- | Do something with a value in a "Context", but keep the old value as well.+-- | Do something with a value in a @Context@, but keep the old value as well. --   This is probably the most common function to construct a---   "ContextManipulation".+--   @ContextManipulation@. renderValue :: String -- ^ Key of which the value should be copied.             -> String -- ^ Key the value should be copied to.             -> (String -> String) -- ^ Function to apply on the value.@@ -35,7 +35,7 @@     Nothing      -> context     (Just value) -> M.insert dst (f value) context --- | Change a value in a "Context".+-- | Change a value in a @Context@. -- --   > import Data.Char (toUpper) --   > changeValue "title" (map toUpper)
src/Text/Hakyll/File.hs view
@@ -8,6 +8,7 @@     , removeSpaces     , makeDirectories     , getRecursiveContents+    , sortByBaseName     , havingExtension     , isMoreRecent     , directory@@ -16,7 +17,7 @@ import System.Directory import System.FilePath import Control.Monad-import Data.List (isPrefixOf)+import Data.List (isPrefixOf, sortBy) import Control.Monad.Reader (liftIO)  import Text.Hakyll.Hakyll@@ -99,6 +100,12 @@     return (concat paths)   where     isProper = not . (== '.') . head++-- | Sort a list of filenames on the basename.+sortByBaseName :: [FilePath] -> [FilePath]+sortByBaseName = sortBy compareBaseName+  where+    compareBaseName f1 f2 = compare (takeFileName f1) (takeFileName f2)  -- | A filter that takes all file names with a given extension. Prefix the --   extension with a dot:
src/Text/Hakyll/Internal/Template.hs view
@@ -12,6 +12,7 @@ import Data.Char (isAlphaNum) import Data.Binary import Control.Monad (liftM, liftM2, replicateM)+import Control.Applicative ((<$>)) import Data.Maybe (fromMaybe) import System.FilePath ((</>)) import Control.Monad.Reader (liftIO)@@ -29,7 +30,7 @@               | End               deriving (Show, Read, Eq) --- | Construct a "Template" from a string.+-- | Construct a @Template@ from a string. fromString :: String -> Template fromString [] = End fromString string@@ -41,7 +42,7 @@   where     tail' = tail string --- | Read a "Template" from a file. This function might fetch the "Template"+-- | Read a @Template@ from a file. This function might fetch the @Template@ --   from the cache, if available. readTemplate :: FilePath -> Hakyll Template readTemplate path = do@@ -54,7 +55,7 @@   where      fileName = "templates" </> path --- | Substitutes @$identifiers@ in the given "Template" by values from the given+-- | Substitutes @$identifiers@ in the given @Template@ by values from the given --   "Context". When a key is not found, it is left as it is. You can specify --   the characters used to replace escaped dollars (@$$@) here. substitute :: String -> Template -> Context -> String @@ -68,12 +69,12 @@     escaper ++ substitute escaper template context substitute _ End _ = [] --- | "substitute" for use during a chain. This will leave escaped characters as+-- | @substitute@ for use during a chain. This will leave escaped characters as --   they are. regularSubstitute :: Template -> Context -> String regularSubstitute = substitute "$$" --- | "substitute" for the end of a chain (just before writing). This renders+-- | @substitute@ for the end of a chain (just before writing). This renders --   escaped characters. finalSubstitute :: Template -> Context -> String finalSubstitute = substitute "$"@@ -95,10 +96,10 @@ arbitraryTemplate :: Int -> Gen Template arbitraryTemplate 0 = return End arbitraryTemplate length' = oneof [ do chunk <- chunk'-                                       template' >>= return . Chunk chunk+                                       Chunk chunk <$> template'                                   , do key <- key'-                                       template' >>= return . Identifier key-                                  , template' >>= return . EscapeCharacter+                                       Identifier key <$> template'+                                  , EscapeCharacter <$> template'                                   ]   where     template' = arbitraryTemplate (length' - 1)@@ -111,7 +112,7 @@                 return $ if null sanitized then "foo"                                            else sanitized --- | Make "Template" testable.+-- | Make @Template@ testable. instance Arbitrary Template where     arbitrary = choose (0, 20) >>= arbitraryTemplate 
src/Text/Hakyll/Page.hs view
@@ -1,4 +1,4 @@--- | A module for dealing with "Page"s. This module is mostly internally used.+-- | A module for dealing with @Page@s. This module is mostly internally used. module Text.Hakyll.Page      ( Page     , fromContext@@ -13,14 +13,14 @@ import Data.Maybe (fromMaybe) import Control.Monad (liftM, replicateM) import Control.Monad.Reader (liftIO)-import System.FilePath (takeExtension, (</>))+import System.FilePath  import Test.QuickCheck import Text.Pandoc import Data.Binary  import Text.Hakyll.Internal.Cache-import Text.Hakyll.Hakyll (Hakyll)+import Text.Hakyll.Hakyll import Text.Hakyll.File import Text.Hakyll.Util (trim) import Text.Hakyll.Context (Context)@@ -127,6 +127,7 @@     let sections = splitAtDelimiters $ lines contents         context = concat $ zipWith ($) sectionFunctions sections         page = fromContext $ M.fromList $+            category ++             [ ("url", url)             , ("path", path)             ] ++ context@@ -134,6 +135,8 @@     return page   where     url = toURL path+    category = let dirs = splitDirectories $ takeDirectory path+               in [("category", last dirs) | not (null dirs)]  -- | Read a page. Might fetch it from the cache if available. Otherwise, it will --   read it from the file given and store it in the cache.
src/Text/Hakyll/Render.hs view
@@ -71,8 +71,8 @@ renderAndConcat = renderAndConcatWith id  -- | Render each renderable with the given templates, then concatenate the---   result. This function allows you to specify a "ContextManipulation" to---   apply on every "Renderable".+--   result. This function allows you to specify a @ContextManipulation@ to+--   apply on every @Renderable@. renderAndConcatWith :: Renderable a                     => ContextManipulation                     -> [FilePath]@@ -97,7 +97,7 @@ renderChain = renderChainWith id  -- | A more custom render chain that allows you to specify a---   "ContextManipulation" which to apply on the context when it is read first.+--   @ContextManipulation@ which to apply on the context when it is read first. renderChainWith :: Renderable a                 => ContextManipulation -> [FilePath] -> a -> Hakyll () renderChainWith manipulation templatePaths renderable =
src/Text/Hakyll/Renderables.hs view
@@ -1,6 +1,8 @@ module Text.Hakyll.Renderables     ( CustomPage     , createCustomPage+    , createListing+    , createListingWith     , PagePath     , createPagePath     , CombinedRenderable@@ -9,11 +11,17 @@     ) where  import qualified Data.Map as M+import Control.Arrow (second)+import Control.Monad (liftM) +import Data.Binary+ import Text.Hakyll.Hakyll (Hakyll) import Text.Hakyll.Page import Text.Hakyll.Renderable import Text.Hakyll.File+import Text.Hakyll.Context+import Text.Hakyll.Render  -- | A custom page. data CustomPage = CustomPage @@ -35,6 +43,46 @@                  -> CustomPage createCustomPage = CustomPage +-- | A @createCustomPage@ function specialized in creating listings.+--+--   This function creates a listing of a certain list of @Renderable@s. Every+--   item in the list is created by applying the given template to every+--   renderable. You can also specify additional context to be included in the+--   @CustomPage@.+--+--   > let customPage = createListingWith +--   >                      "index.html" -- Destination of the page.+--   >                      "templates/postitem.html" -- Path to template to+--   >                                                -- render the items with.+--   >                      posts -- ^ Renderables to create the list with.+--   >                      [("title", "Home")] -- ^ Additional context+createListing :: (Renderable a)+              => String -- ^ Destination of the page.+              -> FilePath -- ^ Template to render all items with.+              -> [a] -- ^ Renderables in the list.+              -> [(String, String)] -- ^ Additional context.+              -> CustomPage+createListing = createListingWith id++-- | A @createCustomPage@ function specialized in creating listings.+--+--   In addition to @createListing@, this function allows you to specify an+--   extra @ContextManipulation@ for all @Renderable@s given.+createListingWith :: (Renderable a)+                  => ContextManipulation -- ^ Manipulation for the renderables.+                  -> String -- ^ Destination of the page.+                  -> FilePath -- ^ Template to render all items with.+                  -> [a] -- ^ Renderables in the list.+                  -> [(String, String)] -- ^ Additional context.+                  -> CustomPage+createListingWith manipulation url template renderables additional =+    createCustomPage url dependencies context+  where+    dependencies = template : concatMap getDependencies renderables+    context = ("body", Right concatenation) : additional'+    concatenation = renderAndConcatWith manipulation [template] renderables+    additional' = map (second Left) additional+ instance Renderable CustomPage where     getDependencies = customPageDependencies     getURL = customPageURL@@ -57,20 +105,25 @@     getURL (PagePath path) = toURL path     toContext (PagePath path) = readPage path >>= toContext +-- We can serialize filepaths+instance Binary PagePath where+    put (PagePath path) = put path+    get = liftM PagePath get+ -- | A combination of two other renderables. data CombinedRenderable a b = CombinedRenderable a b                             | CombinedRenderableWithURL FilePath a b  -- | Combine two renderables. The url will always be taken from the first---   "Renderable". Also, if a `$key` is present in both renderables, the---   value from the first "Renderable" will be taken as well.+--   @Renderable@. Also, if a `$key` is present in both renderables, the+--   value from the first @Renderable@ will be taken as well. -- --   Since renderables are always more or less key-value maps, you can see --   this as a @union@ between two maps. combine :: (Renderable a, Renderable b) => a -> b -> CombinedRenderable a b combine = CombinedRenderable --- | Combine two renderables and set a custom URL. This behaves like "combine",+-- | Combine two renderables and set a custom URL. This behaves like @combine@, --   except that for the @url@ field, the given URL is always chosen. combineWithURL :: (Renderable a, Renderable b)                => FilePath
src/Text/Hakyll/Tags.hs view
@@ -13,38 +13,62 @@ --   > The novel is set in a post-apocalyptic near future, where the Earth and --   > its populations have been damaged greatly by Nuclear... -----   All the following functions would work with such a format.+--   All the following functions would work with such a format. In addition to+--   tags, Hakyll also supports categories. The convention when using categories+--   is to place pages in subdirectories.+--+--   An example, the page @posts\/coding\/2010-01-28-hakyll-categories.markdown@+--   would be placed under the `coding` category.+--+--   Tags or categories are read using the @readTagMap@ and @readCategoryMap@+--   functions. Because categories are implemented using tags - categories can+--   be seen as tags, with the restriction that a page can only have one+--   category - all functions for tags also work with categories.+--+--   When reading a @TagMap@ (which is also used for category maps) using the+--   @readTagMap@ or @readCategoryMap@ function, you also have to give a unique+--   identifier to it. This identifier is simply for caching reasons, so Hakyll+--   can tell different maps apart; it has no other use. module Text.Hakyll.Tags-    ( readTagMap+    ( TagMap+    , readTagMap+    , readCategoryMap     , renderTagCloud     , renderTagLinks     ) where  import qualified Data.Map as M import Data.List (intercalate)+import Data.Maybe (fromMaybe, maybeToList) import Control.Monad (foldM) import Control.Arrow (second) import Control.Applicative ((<$>))-import System.FilePath ((</>))+import System.FilePath -import Text.Hakyll.Hakyll (Hakyll)-import Text.Hakyll.Context (ContextManipulation, changeValue)+import Text.Hakyll.Hakyll+import Text.Hakyll.Context import Text.Hakyll.Regex+import Text.Hakyll.Renderable+import Text.Hakyll.Renderables import Text.Hakyll.Util-import Text.Hakyll.Page import Text.Hakyll.Internal.Cache import Text.Hakyll.Internal.Template --- | Read a tag map. This creates a map from tags to page paths.+-- | Type for a tag map. -----   You also have to give a unique identifier for every tagmap. This is for---   caching reasons, so the tagmap will be stored in---   @_cache/_tagmap/identifier@.-readTagMap :: String -- ^ Unique identifier for the tagmap.-           -> [FilePath]-           -> Hakyll (M.Map String [FilePath])-readTagMap identifier paths = do-    isCacheMoreRecent' <- isCacheMoreRecent fileName paths+--   This is a map associating tags or categories to the appropriate pages+--   using that tag or category. In the case of categories, each path will only+--   appear under one category - this is not the case with tags.+type TagMap = M.Map String [PagePath]++-- | Read a tag map. This is a internally used function that can be used for+--   tags as well as for categories.+readMap :: (Context -> [String]) -- ^ Function to get tags from a context.+        -> String -- ^ Unique identifier for the tagmap.+        -> [PagePath]+        -> Hakyll TagMap+readMap getTagsFunction identifier paths = do+    isCacheMoreRecent' <- isCacheMoreRecent fileName (getDependencies =<< paths)     if isCacheMoreRecent' then M.fromAscList <$> getFromCache fileName                           else do tagMap <- readTagMap'                                   storeInCache (M.toAscList tagMap) fileName@@ -54,12 +78,28 @@      readTagMap' = foldM addPaths M.empty paths     addPaths current path = do-        page <- readPage path-        let tags = map trim $ splitRegex "," $ getValue "tags" page-        return $ foldr (flip (M.insertWith (++)) [path]) current tags+        context <- toContext path+        let tags = getTagsFunction context+            addPaths' = flip (M.insertWith (++)) [path]+        return $ foldr addPaths' current tags +-- | Read a @TagMap@, using the @tags@ metadata field.+readTagMap :: String -- ^ Unique identifier for the map.+           -> [PagePath] -- ^ Paths to get tags from.+           -> Hakyll TagMap+readTagMap = readMap  getTagsFunction+  where+    getTagsFunction = map trim . splitRegex ","+                    . fromMaybe [] . M.lookup "tags"++-- | Read a @TagMap@, using the subdirectories the pages are placed in.+readCategoryMap :: String -- ^ Unique identifier for the map.+                -> [PagePath] -- ^ Paths to get tags from.+                -> Hakyll TagMap+readCategoryMap = readMap $ maybeToList . M.lookup "category"+ -- | Render a tag cloud.-renderTagCloud :: M.Map String [FilePath] -- ^ Map as produced by "readTagMap".+renderTagCloud :: TagMap -- ^ Map as produced by @readTagMap@.                -> (String -> String) -- ^ Function to produce an url for a tag.                -> Float -- ^ Smallest font size, in percent.                -> Float -- ^ Biggest font size, in percent.