packages feed

hakyll 4.10.0.0 → 4.11.0.0

raw patch · 14 files changed

+279/−79 lines, 14 filesdep +file-embeddep −system-filepathdep ~QuickCheckdep ~basedep ~binarynew-component:exe:hakyll-websitePVP ok

version bump matches the API change (PVP)

Dependencies added: file-embed

Dependencies removed: system-filepath

Dependency ranges changed: QuickCheck, base, binary, http-types, pandoc, pandoc-citeproc, tasty, tasty-hunit

API changes (from Hackage documentation)

+ Hakyll.Web.Template: readTemplateElems :: String -> [TemplateElement]
+ Hakyll.Web.Template: template :: [TemplateElement] -> Template

Files

CHANGELOG.md view
@@ -4,6 +4,21 @@  # Releases +## Hakyll 4.11.0.0++- Bump binary to 0.9+- Bump pandoc to 2.1+- Bump pandoc-citeproc to 0.13+- Bump http-types to 0.11+- Bump QuickCheck to 2.11+- Bump tasty to 1.0+- Bump tasty-hunit to 0.10+- Remove system-filepath dependency+- Embed feed templates rather than using data-files (contribution by Roman+  Kuznetsov)+- Fix pthread link error on GHC-8.2.2 (contribution by Shinya Yamaguchi)+- Extend capture with Regex handling (contribution by frederik-h)+ ## Hakyll 4.10.0.0  - Bump Pandoc to 2.0 (contribution by Vaibhav Sagar)
hakyll.cabal view
@@ -1,5 +1,5 @@ Name:    hakyll-Version: 4.10.0.0+Version: 4.11.0.0  Synopsis: A static website compiler library Description:@@ -37,7 +37,7 @@ License-File: LICENSE Category:     Web -Cabal-Version: >= 1.8+Cabal-Version: >= 1.10 Build-Type:    Simple Data-Dir:      data @@ -56,10 +56,6 @@   example/index.html   example/about.rst   example/contact.markdown-  templates/atom-item.xml-  templates/atom.xml-  templates/rss-item.xml-  templates/rss.xml  Extra-source-files:   CHANGELOG.md@@ -77,6 +73,10 @@   tests/data/strip.html.out   tests/data/template.html   tests/data/template.html.out+  data/templates/atom-item.xml+  data/templates/atom.xml+  data/templates/rss-item.xml+  data/templates/rss.xml  Source-Repository head   Type:     git@@ -94,9 +94,15 @@   Description: Include external link checking   Default:     True +Flag buildWebsite+  Description: Build the hakyll website+  Default:     False+  Manual:      True+ Library-  Ghc-Options:    -Wall-  Hs-Source-Dirs: lib+  Ghc-Options:      -Wall+  Hs-Source-Dirs:   lib+  Default-language: Haskell2010    Exposed-Modules:     Hakyll@@ -154,7 +160,7 @@    Build-Depends:     base                 >= 4.8      && < 5,-    binary               >= 0.5      && < 0.9,+    binary               >= 0.5      && < 0.10,     blaze-html           >= 0.5      && < 0.10,     blaze-markup         >= 0.5.1    && < 0.9,     bytestring           >= 0.9      && < 0.11,@@ -168,8 +174,8 @@     mtl                  >= 1        && < 2.3,     network              >= 2.6      && < 2.7,     network-uri          >= 2.6      && < 2.7,-    pandoc               >= 2.0.5    && < 2.1,-    pandoc-citeproc      >= 0.12.1.1 && < 0.13,+    pandoc               >= 2.0.5    && < 2.2,+    pandoc-citeproc      >= 0.13     && < 0.14,     parsec               >= 3.0      && < 3.2,     process              >= 1.6      && < 1.7,     random               >= 1.0      && < 1.2,@@ -184,16 +190,16 @@     unordered-containers >= 0.2      && < 0.3,     vector               >= 0.11     && < 0.13,     yaml                 >= 0.8.11   && < 0.9,-    optparse-applicative >= 0.12     && < 0.15+    optparse-applicative >= 0.12     && < 0.15,+    file-embed           >= 0.0.10.1 && < 0.0.11    If flag(previewServer)     Build-depends:       wai             >= 3.2   && < 3.3,       warp            >= 3.2   && < 3.3,       wai-app-static  >= 3.1   && < 3.2,-      http-types      >= 0.9   && < 0.10,-      fsnotify        >= 0.2   && < 0.3,-      system-filepath >= 0.4.6 && <= 0.5+      http-types      >= 0.9   && < 0.12,+      fsnotify        >= 0.2   && < 0.3     Cpp-options:       -DPREVIEW_SERVER     Other-modules:@@ -202,8 +208,7 @@    If flag(watchServer)     Build-depends:-      fsnotify        >= 0.2   && < 0.3,-      system-filepath >= 0.4.6 && <= 0.5+      fsnotify        >= 0.2   && < 0.3     Cpp-options:       -DWATCH_SERVER     Other-modules:@@ -212,15 +217,16 @@   If flag(checkExternal)     Build-depends:       http-conduit >= 2.2    && < 2.3,-      http-types   >= 0.7    && < 0.10+      http-types   >= 0.7    && < 0.12     Cpp-options:       -DCHECK_EXTERNAL  Test-suite hakyll-tests-  Type:           exitcode-stdio-1.0-  Hs-source-dirs: tests-  Main-is:        TestSuite.hs-  Ghc-options:    -Wall+  Type:             exitcode-stdio-1.0+  Hs-source-dirs:   tests+  Main-is:          TestSuite.hs+  Ghc-options:      -Wall -threaded+  Default-language: Haskell2010    Other-modules:     Hakyll.Core.Dependencies.Tests@@ -243,13 +249,13 @@    Build-Depends:     hakyll,-    QuickCheck                 >= 2.8  && < 2.11,-    tasty                      >= 0.11 && < 0.12,-    tasty-hunit                >= 0.9  && < 0.10,+    QuickCheck                 >= 2.8  && < 2.12,+    tasty                      >= 0.11 && < 1.1,+    tasty-hunit                >= 0.9  && < 0.11,     tasty-quickcheck           >= 0.8  && < 0.10,     -- Copy pasted from hakyll dependencies:     base                 >= 4.8      && < 5,-    binary               >= 0.5      && < 0.9,+    binary               >= 0.5      && < 0.10,     blaze-html           >= 0.5      && < 0.10,     blaze-markup         >= 0.5.1    && < 0.9,     bytestring           >= 0.9      && < 0.11,@@ -263,8 +269,8 @@     mtl                  >= 1        && < 2.3,     network              >= 2.6      && < 2.7,     network-uri          >= 2.6      && < 2.7,-    pandoc               >= 2.0.5    && < 2.1,-    pandoc-citeproc      >= 0.12.1.1 && < 0.13,+    pandoc               >= 2.0.5    && < 2.2,+    pandoc-citeproc      >= 0.13     && < 0.14,     parsec               >= 3.0      && < 3.2,     process              >= 1.6      && < 1.7,     random               >= 1.0      && < 1.2,@@ -286,30 +292,29 @@       wai             >= 3.2   && < 3.3,       warp            >= 3.2   && < 3.3,       wai-app-static  >= 3.1   && < 3.2,-      http-types      >= 0.9   && < 0.10,-      fsnotify        >= 0.2   && < 0.3,-      system-filepath >= 0.4.6 && <= 0.5+      http-types      >= 0.9   && < 0.12,+      fsnotify        >= 0.2   && < 0.3     Cpp-options:       -DPREVIEW_SERVER    If flag(watchServer)     Build-depends:-      fsnotify        >= 0.2   && < 0.3,-      system-filepath >= 0.4.6 && <= 0.5+      fsnotify        >= 0.2   && < 0.3     Cpp-options:       -DWATCH_SERVER    If flag(checkExternal)     Build-depends:       http-conduit >= 2.2    && < 2.3,-      http-types   >= 0.7    && < 0.10+      http-types   >= 0.7    && < 0.12     Cpp-options:       -DCHECK_EXTERNAL  Executable hakyll-init-  Ghc-options:    -Wall-  Hs-source-dirs: src-  Main-is:        Init.hs+  Main-is:          Init.hs+  Ghc-options:      -Wall -threaded+  Hs-source-dirs:   src+  Default-language: Haskell2010    Other-modules:     Paths_hakyll@@ -319,3 +324,21 @@     base      >= 4   && < 5,     directory >= 1.0 && < 1.4,     filepath  >= 1.0 && < 1.5++Executable hakyll-website+  Main-is:          site.hs+  Ghc-options:      -Wall -threaded+  Hs-source-dirs:   web+  Default-language: Haskell2010++  If flag(buildWebsite)+    Buildable: True+  Else+    Buildable: False++  Build-depends:+    hakyll,+    base      >= 4     && < 5,+    directory >= 1.0   && < 1.4,+    filepath  >= 1.0   && < 1.5,+    pandoc    >= 2.0.5 && < 2.2
lib/Hakyll/Core/Identifier/Pattern.hs view
@@ -27,7 +27,7 @@ -- * @\"foo\/*.html\"@ will match all HTML files in the @\"foo\/\"@ directory. -- -- The 'capture' function allows the user to get access to the elements captured--- by the capture elements in the pattern.+-- by the capture elements in a glob or regex pattern. module Hakyll.Core.Identifier.Pattern     ( -- * The pattern type       Pattern@@ -260,9 +260,11 @@   ----------------------------------------------------------------------------------- | Match a glob against a pattern, generating a list of captures+-- | Match a glob or regex pattern against an identifier, generating a list of captures capture :: Pattern -> Identifier -> Maybe [String] capture (Glob p) i = capture' p (toFilePath i)+capture (Regex pat) i = Just groups+  where (_, _, _, groups) = ((toFilePath i) =~ pat) :: (String, String, String, [String]) capture _        _ = Nothing  
lib/Hakyll/Web/Feed.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE TemplateHaskell #-}+ -------------------------------------------------------------------------------- -- | A Module that allows easy rendering of RSS feeds. --@@ -25,19 +27,38 @@  -------------------------------------------------------------------------------- import           Hakyll.Core.Compiler-import           Hakyll.Core.Compiler.Internal import           Hakyll.Core.Item-import           Hakyll.Core.Util.String (replaceAll)+import           Hakyll.Core.Util.String     (replaceAll) import           Hakyll.Web.Template import           Hakyll.Web.Template.Context import           Hakyll.Web.Template.List   ---------------------------------------------------------------------------------import           Paths_hakyll+import           Data.FileEmbed              (embedFile)+import qualified Data.Text                   as T+import qualified Data.Text.Encoding          as T   --------------------------------------------------------------------------------+rssTemplate :: String+rssTemplate = T.unpack $+    T.decodeUtf8 $(embedFile "data/templates/rss.xml")++rssItemTemplate :: String+rssItemTemplate = T.unpack $+    T.decodeUtf8 $(embedFile "data/templates/rss-item.xml")++atomTemplate :: String+atomTemplate = T.unpack $+    T.decodeUtf8 $(embedFile "data/templates/atom.xml")++atomItemTemplate :: String+atomItemTemplate = T.unpack $+    T.decodeUtf8 $(embedFile "data/templates/atom-item.xml")+++-------------------------------------------------------------------------------- -- | This is a data structure to keep the configuration of a feed. data FeedConfiguration = FeedConfiguration     { -- | Title of the feed.@@ -55,15 +76,15 @@  -------------------------------------------------------------------------------- -- | Abstract function to render any feed.-renderFeed :: FilePath                -- ^ Feed template-           -> FilePath                -- ^ Item template+renderFeed :: String                  -- ^ Default feed template+           -> String                  -- ^ Default item template            -> FeedConfiguration       -- ^ Feed configuration            -> Context String          -- ^ Context for the items            -> [Item String]           -- ^ Input items            -> Compiler (Item String)  -- ^ Resulting item-renderFeed feedPath itemPath config itemContext items = do-    feedTpl <- loadTemplate feedPath-    itemTpl <- loadTemplate itemPath+renderFeed defFeed defItem config itemContext items = do+    feedTpl <- readTemplateFile defFeed+    itemTpl <- readTemplateFile defItem      protectedItems <- mapM (applyFilter protectCDATA) items     body <- makeItem =<< applyTemplateList itemTpl itemContext' protectedItems@@ -73,10 +94,6 @@     applyFilter tr str = return $ fmap tr str     protectCDATA :: String -> String     protectCDATA = replaceAll "]]>" (const "]]&gt;")-    -- Auxiliary: load a template from a datafile-    loadTemplate path = do-        file <- compilerUnsafeIO $ getDataFileName path-        unsafeReadTemplateFile file      itemContext' = mconcat         [ itemContext@@ -105,7 +122,10 @@             ListField _ _ -> fail "Hakyll.Web.Feed.renderFeed: Internal error"             StringField s -> return s +    readTemplateFile :: String -> Compiler Template+    readTemplateFile value = pure $ template $ readTemplateElems value + -------------------------------------------------------------------------------- -- | Render an RSS feed with a number of items. renderRss :: FeedConfiguration       -- ^ Feed configuration@@ -113,7 +133,7 @@           -> [Item String]           -- ^ Feed items           -> Compiler (Item String)  -- ^ Resulting feed renderRss config context = renderFeed-    "templates/rss.xml" "templates/rss-item.xml" config+    rssTemplate rssItemTemplate config     (makeItemContext "%a, %d %b %Y %H:%M:%S UT" context)  @@ -124,7 +144,7 @@            -> [Item String]           -- ^ Feed items            -> Compiler (Item String)  -- ^ Resulting feed renderAtom config context = renderFeed-    "templates/atom.xml" "templates/atom-item.xml" config+    atomTemplate atomItemTemplate config     (makeItemContext "%Y-%m-%dT%H:%M:%SZ" context)  
lib/Hakyll/Web/Pandoc/Biblio.hs view
@@ -84,7 +84,10 @@ biblioCompiler :: Compiler (Item Biblio) biblioCompiler = do     filePath <- toFilePath <$> getUnderlying-    makeItem =<< unsafeCompiler (Biblio <$> CSL.readBiblioFile filePath)+    makeItem =<< unsafeCompiler (Biblio <$> CSL.readBiblioFile idpred filePath)+  where+    -- This is a filter on citations.  We include all citations.+    idpred = const True   --------------------------------------------------------------------------------
lib/Hakyll/Web/Template.hs view
@@ -140,6 +140,8 @@ -- module Hakyll.Web.Template     ( Template+    , template+    , readTemplateElems     , templateBodyCompiler     , templateCompiler     , applyTemplate
lib/Hakyll/Web/Template/Internal.hs view
@@ -200,4 +200,3 @@ unsafeReadTemplateFile file = do     tpl <- unsafeCompiler $ readFile file     pure $ template $ readTemplateElemsFile file tpl-
tests/Hakyll/Core/Identifier/Tests.hs view
@@ -42,6 +42,7 @@     , Just ["lol", "fun/large"] @=? capture "*cat/**.jpg" "lolcat/fun/large.jpg"     , Just []                   @=? capture "\\*.jpg" "*.jpg"     , Nothing                   @=? capture "\\*.jpg" "foo.jpg"+    , Just ["xyz","42"]              @=? capture (fromRegex "cat-([a-z]+)/foo([0-9]+).jpg") "cat-xyz/foo42.jpg"     ]  
tests/Hakyll/Core/Provider/Tests.hs view
@@ -9,7 +9,7 @@ import           Hakyll.Core.Metadata import           Hakyll.Core.Provider import           Test.Tasty           (TestTree, testGroup)-import           Test.Tasty.HUnit     (Assertion, assert, testCase, (@=?))+import           Test.Tasty.HUnit     (Assertion, testCase, (@=?)) import           TestSuite.Util  @@ -25,7 +25,7 @@ case01 = do     store    <- newTestStore     provider <- newTestProvider store-    assert $ resourceExists provider "example.md"+    True @=? resourceExists provider "example.md"      metadata <- resourceMetadata provider "example.md"     Just "An example"    @=? lookupString "title"    metadata
tests/Hakyll/Core/Rules/Tests.hs view
@@ -20,7 +20,7 @@ import           Hakyll.Web.Pandoc import           System.FilePath                ((</>)) import           Test.Tasty                     (TestTree, testGroup)-import           Test.Tasty.HUnit               (Assertion, assert, (@=?))+import           Test.Tasty.HUnit               (Assertion, (@=?)) import           TestSuite.Util  @@ -50,7 +50,7 @@     checkRoute "example.mv1"     (sv "mv1" "example.md")     checkRoute "example.mv2"     (sv "mv2" "example.md")     checkRoute "food/example.md" (sv "metadataMatch" "example.md")-    readIORef ioref >>= assert+    readIORef ioref >>= (True @=?)     cleanTestEnv   where     sv g     = setVersion (Just g)
tests/Hakyll/Core/Store/Tests.hs view
@@ -63,11 +63,11 @@     -- Store a string and try to fetch an int     Store.set store ["foo", "bar"] ("qux" :: String)     value <- Store.get store ["foo", "bar"] :: IO (Store.Result Int)-    H.assert $ case value of-        Store.WrongType e t ->-            e == typeOf (undefined :: Int) &&-            t == typeOf (undefined :: String)-        _                   -> False+    case value of+        Store.WrongType e t -> do+            typeOf (undefined :: Int)    H.@=? e+            typeOf (undefined :: String) H.@=? t+        _ -> H.assertFailure "Expecting WrongType"     cleanTestEnv  @@ -78,6 +78,6 @@     Store.set store ["foo", "bar"] ("qux" :: String)     good <- Store.isMember store ["foo", "bar"]     bad  <- Store.isMember store ["foo", "baz"]-    H.assert good-    H.assert (not bad)+    True  H.@=? good+    False H.@=? bad     cleanTestEnv
tests/Hakyll/Core/UnixFilter/Tests.hs view
@@ -39,7 +39,7 @@     provider <- newTestProvider store     output   <- testCompilerDone store provider testMarkdown compiler     expected <- testCompilerDone store provider testMarkdown getResourceString-    H.assert $ rev (itemBody expected) == lines (itemBody output)+    rev (itemBody expected) H.@=? lines (itemBody output)     cleanTestEnv   where     compiler = getResourceString >>= withItemBody (unixFilter "rev" [])@@ -52,9 +52,9 @@     store    <- newTestStore     provider <- newTestProvider store     result   <- testCompiler store provider testMarkdown compiler-    H.assert $ case result of-        CompilerError es -> any ("exit code" `isInfixOf`) es-        _                -> False+    case result of+        CompilerError es -> True H.@=? any ("exit code" `isInfixOf`) es+        _                -> H.assertFailure "Expecting CompilerError"     cleanTestEnv   where     compiler = getResourceString >>= withItemBody (unixFilter "false" [])@@ -66,9 +66,9 @@     store    <- newTestStore     provider <- newTestProvider store     result   <- testCompiler store provider testMarkdown compiler-    H.assert $ case result of-        CompilerError es -> any ("invalid option" `isInfixOf`) es-        _                -> False+    case result of+        CompilerError es -> True H.@=? any ("invalid option" `isInfixOf`) es+        _                -> H.assertFailure "Expecting CompilerError"     cleanTestEnv   where     compiler = getResourceString >>= withItemBody (unixFilter "head" ["-#"])
tests/Hakyll/Web/Html/Tests.hs view
@@ -7,7 +7,7 @@ -------------------------------------------------------------------------------- import           Data.Char        (toUpper) import           Test.Tasty       (TestTree, testGroup)-import           Test.Tasty.HUnit (assert, (@=?))+import           Test.Tasty.HUnit ((@=?))   --------------------------------------------------------------------------------@@ -64,11 +64,11 @@         ]      , fromAssertions "isExternal"-        [ assert (isExternal "http://reddit.com")-        , assert (isExternal "https://mail.google.com")-        , assert (isExternal "//ajax.googleapis.com")-        , assert (not (isExternal "../header.png"))-        , assert (not (isExternal "/foo/index.html"))+        [ True  @=? isExternal "http://reddit.com"+        , True  @=? isExternal "https://mail.google.com"+        , True  @=? isExternal "//ajax.googleapis.com"+        , False @=? isExternal "../header.png"+        , False @=? isExternal "/foo/index.html"         ]      , fromAssertions "stripTags"
+ web/site.hs view
@@ -0,0 +1,135 @@+--------------------------------------------------------------------------------+{-# LANGUAGE OverloadedStrings #-}+import           Control.Arrow    (second)+import           Control.Monad    (forM_)+import           Data.Char        (isDigit)+import           Data.List        (isPrefixOf, sortBy)+import           Data.Monoid      ((<>))+import           Data.Ord         (comparing)+import           Hakyll+import           System.Directory (copyFile)+import           System.FilePath  (dropTrailingPathSeparator, splitPath)+import           Text.Pandoc+++--------------------------------------------------------------------------------+main :: IO ()+main = hakyllWith config $ do+    -- Copy CHANGELOG.md here.+    preprocess $ copyFile "../CHANGELOG.md" "releases.markdown"++    -- CSS+    match "css/*" $ do+        route   idRoute+        compile compressCssCompiler++    -- Static directories+    forM_ ["images/*", "examples/*"] $ \f -> match f $ do+        route   idRoute+        compile copyFileCompiler++    -- Haddock stuff+    match "reference/**.html" $ do+        route   idRoute+        compile $ fmap (withUrls hackage) <$> getResourceString++    -- Haddock stuff+    match ("reference/**" `mappend` complement "**.html") $ do+        route   idRoute+        compile copyFileCompiler++    -- Pages+    match "*.markdown" $ do+        route   $ setExtension "html"+        compile $ pandocCompiler+            >>= loadAndApplyTemplate "templates/default.html" defaultContext+            >>= relativizeUrls++    -- Tutorials+    match "tutorials/*" $ do+        route   $ setExtension "html"+        compile $ pandocCompilerWith defaultHakyllReaderOptions withToc+            >>= loadAndApplyTemplate "templates/tutorial.html" defaultContext+            >>= loadAndApplyTemplate "templates/default.html" defaultContext+            >>= relativizeUrls++    -- Tutorial list+    create ["tutorials.html"] $ do+        route idRoute+        compile $ do+            tuts <-+                sortBy (comparing itemIdentifier) <$> loadAll "tutorials/*"++            let tutorialsCtx =+                    constField "title" "Tutorials"  `mappend`+                    listField "tutorials"   tutorialCtx (return tuts) `mappend`+                    defaultContext++            makeItem ""+                >>= loadAndApplyTemplate "templates/tutorials.html" tutorialsCtx+                >>= loadAndApplyTemplate "templates/default.html" tutorialsCtx+                >>= relativizeUrls++    -- Templates+    match "templates/*" $ compile templateCompiler+  where+    withToc = defaultHakyllWriterOptions+        { writerTableOfContents = True+        , writerTemplate        = Just "$toc$\n$body$"+        }+++--------------------------------------------------------------------------------+config :: Configuration+config = defaultConfiguration+    { deployCommand = "rsync --checksum -ave 'ssh -p 2222' \+                      \_site/* \+                      \jaspervdj@jaspervdj.be:jaspervdj.be/hakyll/"+    }+++--------------------------------------------------------------------------------+-- | Turns+--+-- > /usr/share/doc/ghc/html/libraries/base-4.6.0.0/Data-String.html+--+-- into+--+-- > http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/Data-String.html+hackage :: String -> String+hackage url+    | "/usr" `isPrefixOf` url =+        "http://hackage.haskell.org/packages/archive/" +++        packageName ++ "/" ++ version' ++ "/doc/html/" ++ baseName+    | otherwise               = url+  where+    (packageName, version')  = second (drop 1) $ break (== '-') package+    (baseName : package : _) = map dropTrailingPathSeparator $+        reverse $ splitPath url+++--------------------------------------------------------------------------------+data TutorialType = SeriesTutorial | ArticlesTutorial | ExternalTutorial+    deriving (Eq)+++--------------------------------------------------------------------------------+-- | Partition tutorials into tutorial series, other articles, external articles+tutorialCtx :: Context String+tutorialCtx =+    field "isSeries"   (isTutorialType SeriesTutorial)   <>+    field "isArticle"  (isTutorialType ArticlesTutorial) <>+    field "isExternal" (isTutorialType ExternalTutorial) <>+    defaultContext+  where+    getTutorialType item = do+        mbExternal <- getMetadataField (itemIdentifier item) "external"+        return $ case mbExternal of+            Just _ -> ExternalTutorial+            _      -> case splitPath (toFilePath $ itemIdentifier item) of+                [_, (x : _)] -> if isDigit x then SeriesTutorial else ArticlesTutorial+                _            -> ArticlesTutorial++    isTutorialType ty0 item = do+        ty1 <- getTutorialType item+        if ty0 == ty1 then return "yes" else fail "no"