hakyll 4.13.4.1 → 4.14.0.0
raw patch · 15 files changed
+870/−93 lines, 15 filesdep +tasty-goldendep −pandoc-citeprocdep ~pandocdep ~randomPVP ok
version bump matches the API change (PVP)
Dependencies added: tasty-golden
Dependencies removed: pandoc-citeproc
Dependency ranges changed: pandoc, random
API changes (from Hackage documentation)
+ Hakyll.Web.Pandoc: renderPandocWithTransform :: ReaderOptions -> WriterOptions -> (Pandoc -> Pandoc) -> Item String -> Compiler (Item String)
+ Hakyll.Web.Pandoc: renderPandocWithTransformM :: ReaderOptions -> WriterOptions -> (Pandoc -> Compiler Pandoc) -> Item String -> Compiler (Item String)
+ Hakyll.Web.Pandoc.Biblio: [unBiblio] :: Biblio -> ByteString
- Hakyll.Web.Pandoc.Biblio: Biblio :: [Reference] -> Biblio
+ Hakyll.Web.Pandoc.Biblio: Biblio :: ByteString -> Biblio
Files
- CHANGELOG.md +9/−0
- hakyll.cabal +12/−6
- lib/Hakyll/Core/Item.hs +2/−17
- lib/Hakyll/Web/Pandoc.hs +30/−3
- lib/Hakyll/Web/Pandoc/Biblio.hs +54/−45
- lib/Hakyll/Web/Pandoc/Binary.hs +0/−12
- lib/Hakyll/Web/Template/Context.hs +1/−9
- src/Init.hs +6/−1
- tests/Hakyll/Web/Pandoc/Biblio/Tests.hs +66/−0
- tests/TestSuite.hs +2/−0
- tests/data/biblio/biblio01.golden +16/−0
- tests/data/biblio/chicago.csl +648/−0
- tests/data/biblio/default.html +11/−0
- tests/data/biblio/page.markdown +5/−0
- tests/data/biblio/refs.bib +8/−0
CHANGELOG.md view
@@ -4,6 +4,15 @@ # Releases +## Hakyll 4.14.0.0 (2021-03-14)++- Add `renderPandocWithTransform` and `renderPandocWithTransformM` (by Norman+ Liu)+- Make sure the initial project is writable (by Tobias Bora)+- Bump `pandoc` to 2.11.*+- Bump `file-embed` upper bound to 0.0.14+- Bump `random` upper bound to 1.2+ ## Hakyll 4.13.4.1 (2020-09-30) - Bump `pandoc` to 2.10.*
hakyll.cabal view
@@ -1,5 +1,5 @@ Name: hakyll-Version: 4.13.4.1+Version: 4.14.0.0 Synopsis: A static website compiler library Description:@@ -59,6 +59,11 @@ Extra-source-files: CHANGELOG.md+ tests/data/biblio/biblio01.golden+ tests/data/biblio/chicago.csl+ tests/data/biblio/default.html+ tests/data/biblio/page.markdown+ tests/data/biblio/refs.bib tests/data/embed.html tests/data/example.md tests/data/example.md.metadata@@ -174,7 +179,7 @@ data-default >= 0.4 && < 0.8, deepseq >= 1.3 && < 1.5, directory >= 1.2.7.0 && < 1.4,- file-embed >= 0.0.10.1 && < 0.0.12,+ file-embed >= 0.0.10.1 && < 0.0.14, filepath >= 1.0 && < 1.5, lrucache >= 1.1.1 && < 1.3, memory >= 0.14.18 && < 0.16,@@ -183,7 +188,7 @@ optparse-applicative >= 0.12 && < 0.16, parsec >= 3.0 && < 3.2, process >= 1.6 && < 1.7,- random >= 1.0 && < 1.2,+ random >= 1.0 && < 1.3, regex-tdfa >= 1.1 && < 1.4, resourcet >= 1.1 && < 1.3, scientific >= 0.3.4 && < 0.4,@@ -232,8 +237,7 @@ Other-Modules: Hakyll.Web.Pandoc.Binary Build-Depends:- pandoc >= 2.10 && < 2.11,- pandoc-citeproc >= 0.14 && < 0.18+ pandoc >= 2.11 && < 2.12 Cpp-options: -DUSE_PANDOC @@ -267,6 +271,7 @@ hakyll, QuickCheck >= 2.8 && < 2.15, tasty >= 0.11 && < 1.4,+ tasty-golden >= 2.3 && < 2.4, tasty-hunit >= 0.9 && < 0.11, tasty-quickcheck >= 0.8 && < 0.11, -- Copy pasted from hakyll dependencies:@@ -292,6 +297,7 @@ If flag(usePandoc) Other-modules:+ Hakyll.Web.Pandoc.Biblio.Tests Hakyll.Web.Pandoc.FileType.Tests Cpp-options: -DUSE_PANDOC@@ -327,4 +333,4 @@ base >= 4 && < 5, directory >= 1.0 && < 1.4, filepath >= 1.0 && < 1.5,- pandoc >= 2.10 && < 2.11+ pandoc >= 2.11 && < 2.12
lib/Hakyll/Core/Item.hs view
@@ -2,6 +2,7 @@ -- | An item is a combination of some content and its 'Identifier'. This way, we -- can still use the 'Identifier' to access metadata. {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveTraversable #-} module Hakyll.Core.Item ( Item (..) , itemSetBody@@ -25,23 +26,7 @@ data Item a = Item { itemIdentifier :: Identifier , itemBody :: a- } deriving (Show, Typeable)------------------------------------------------------------------------------------instance Functor Item where- fmap f (Item i x) = Item i (f x)------------------------------------------------------------------------------------instance Foldable Item where- foldr f z (Item _ x) = f x z------------------------------------------------------------------------------------instance Traversable Item where- traverse f (Item i x) = Item i <$> f x-+ } deriving (Show, Typeable, Functor, Foldable, Traversable) -------------------------------------------------------------------------------- instance Binary a => Binary (Item a) where
lib/Hakyll/Web/Pandoc.hs view
@@ -8,6 +8,8 @@ , writePandocWith , renderPandoc , renderPandocWith+ , renderPandocWithTransform+ , renderPandocWithTransformM -- * Derived compilers , pandocCompiler@@ -104,6 +106,32 @@ --------------------------------------------------------------------------------+-- | An extension of `renderPandocWith`, which allows you to specify a custom+-- Pandoc transformation on the input `Item`.+-- Useful if you want to do your own transformations before running +-- custom Pandoc transformations, e.g. using a `funcField` to transform raw content.+renderPandocWithTransform :: ReaderOptions -> WriterOptions+ -> (Pandoc -> Pandoc)+ -> Item String+ -> Compiler (Item String)+renderPandocWithTransform ropt wopt f = + renderPandocWithTransformM ropt wopt (return . f) +++--------------------------------------------------------------------------------+-- | Similar to `renderPandocWithTransform`, but the Pandoc transformation is+-- monadic. This is useful when you want the pandoc+-- transformation to use the `Compiler` information such as routes,+-- metadata, etc. along with your own transformations beforehand.+renderPandocWithTransformM :: ReaderOptions -> WriterOptions+ -> (Pandoc -> Compiler Pandoc)+ -> Item String+ -> Compiler (Item String)+renderPandocWithTransformM ropt wopt f i = + writePandocWith wopt <$> (traverse f =<< readPandocWith ropt i) +++-------------------------------------------------------------------------------- -- | Read a page render using pandoc pandocCompiler :: Compiler (Item String) pandocCompiler =@@ -137,9 +165,8 @@ pandocCompilerWithTransformM :: ReaderOptions -> WriterOptions -> (Pandoc -> Compiler Pandoc) -> Compiler (Item String)-pandocCompilerWithTransformM ropt wopt f =- writePandocWith wopt <$>- (traverse f =<< readPandocWith ropt =<< getResourceBody)+pandocCompilerWithTransformM ropt wopt f = + getResourceBody >>= renderPandocWithTransformM ropt wopt f --------------------------------------------------------------------------------
lib/Hakyll/Web/Pandoc/Biblio.hs view
@@ -12,6 +12,7 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-} module Hakyll.Web.Pandoc.Biblio ( CSL , cslCompiler@@ -23,34 +24,32 @@ ---------------------------------------------------------------------------------import Control.Monad (liftM, replicateM)-import Data.Binary (Binary (..))-import Data.Typeable (Typeable)+import Control.Monad (liftM)+import Data.Binary (Binary (..))+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.Map as Map+import qualified Data.Time as Time+import Data.Typeable (Typeable) import Hakyll.Core.Compiler import Hakyll.Core.Compiler.Internal import Hakyll.Core.Identifier import Hakyll.Core.Item-import Hakyll.Core.Provider import Hakyll.Core.Writable import Hakyll.Web.Pandoc-import Hakyll.Web.Pandoc.Binary ()-import qualified Text.CSL as CSL-import Text.CSL.Pandoc (processCites)-import Text.Pandoc (Pandoc, ReaderOptions (..),- enableExtension, Extension (..))+import Text.Pandoc (Extension (..), Pandoc,+ ReaderOptions (..),+ enableExtension)+import qualified Text.Pandoc as Pandoc+import qualified Text.Pandoc.Citeproc as Pandoc (processCitations) ---------------------------------------------------------------------------------data CSL = CSL- deriving (Show, Typeable)+newtype CSL = CSL {unCSL :: B.ByteString}+ deriving (Binary, Show, Typeable) ----------------------------------------------------------------------------------instance Binary CSL where- put CSL = return ()- get = return CSL - -------------------------------------------------------------------------------- instance Writable CSL where -- Shouldn't be written.@@ -59,21 +58,12 @@ -------------------------------------------------------------------------------- cslCompiler :: Compiler (Item CSL)-cslCompiler = makeItem CSL------------------------------------------------------------------------------------newtype Biblio = Biblio [CSL.Reference]- deriving (Show, Typeable)+cslCompiler = fmap (CSL . BL.toStrict) <$> getResourceLBS ---------------------------------------------------------------------------------instance Binary Biblio where- -- Ugly.- get = do- len <- get- Biblio <$> replicateM len get- put (Biblio rs) = put (length rs) >> mapM_ put rs+newtype Biblio = Biblio {unBiblio :: B.ByteString}+ deriving (Binary, Show, Typeable) --------------------------------------------------------------------------------@@ -84,12 +74,7 @@ -------------------------------------------------------------------------------- biblioCompiler :: Compiler (Item Biblio)-biblioCompiler = do- filePath <- getResourceFilePath- makeItem =<< unsafeCompiler (Biblio <$> CSL.readBiblioFile idpred filePath)- where- -- This is a filter on citations. We include all citations.- idpred = const True+biblioCompiler = fmap (Biblio . BL.toStrict) <$> getResourceLBS --------------------------------------------------------------------------------@@ -99,21 +84,45 @@ -> (Item String) -> Compiler (Item Pandoc) readPandocBiblio ropt csl biblio item = do- -- Parse CSL file, if given- provider <- compilerProvider <$> compilerAsk- style <- unsafeCompiler $- CSL.readCSLFile Nothing . (resourceFilePath provider) . itemIdentifier $ csl+ -- It's not straightforward to use the Pandoc API as of 2.11 to deal with+ -- citations, since it doesn't export many things in 'Text.Pandoc.Citeproc'.+ -- The 'citeproc' package is also hard to use.+ --+ -- So instead, we try treating Pandoc as a black box. Pandoc can read+ -- specific csl and bilbio files based on metadata keys.+ --+ -- So we load the CSL and Biblio files and pass them to Pandoc using the+ -- ersatz filesystem.+ Pandoc.Pandoc (Pandoc.Meta meta) blocks <- itemBody <$>+ readPandocWith ropt item - -- We need to know the citation keys, add then *before* actually parsing the- -- actual page. If we don't do this, pandoc won't even consider them- -- citations!- let Biblio refs = itemBody biblio- pandoc <- itemBody <$> readPandocWith ropt item- let pandoc' = processCites style refs pandoc+ let cslFile = Pandoc.FileInfo zeroTime . unCSL $ itemBody csl+ bibFile = Pandoc.FileInfo zeroTime . unBiblio $ itemBody biblio+ addBiblioFiles = \st -> st+ { Pandoc.stFiles =+ Pandoc.insertInFileTree "_hakyll/style.csl" cslFile .+ Pandoc.insertInFileTree "_hakyll/refs.bib" bibFile $+ Pandoc.stFiles st+ }+ biblioMeta = Pandoc.Meta .+ Map.insert "csl" (Pandoc.MetaString "_hakyll/style.csl") .+ Map.insert "bibliography" (Pandoc.MetaString "_hakyll/refs.bib") $+ meta+ errOrPandoc = Pandoc.runPure $ do+ Pandoc.modifyPureState addBiblioFiles+ Pandoc.processCitations $ Pandoc.Pandoc biblioMeta blocks - return $ fmap (const pandoc') item+ pandoc <- case errOrPandoc of+ Left e -> compilerThrow ["Error during processCitations: " ++ show e]+ Right x -> return x + return $ fmap (const pandoc) item++ where+ zeroTime = Time.UTCTime (toEnum 0) 0+ --------------------------------------------------------------------------------+-- | Compiles a markdown file via Pandoc. Requires the .csl and .bib files to be known to the compiler via match statements. pandocBiblioCompiler :: String -> String -> Compiler (Item String) pandocBiblioCompiler cslFileName bibFileName = do csl <- load $ fromFilePath cslFileName
lib/Hakyll/Web/Pandoc/Binary.hs view
@@ -4,9 +4,6 @@ import Data.Binary (Binary (..)) -import qualified Text.CSL as CSL-import qualified Text.CSL.Reference as REF-import qualified Text.CSL.Style as STY import Text.Pandoc --------------------------------------------------------------------------------@@ -18,7 +15,6 @@ instance Binary Cell instance Binary ColSpan instance Binary ColWidth-instance Binary CSL.Reference instance Binary Citation instance Binary CitationMode instance Binary Format@@ -27,17 +23,9 @@ instance Binary ListNumberStyle instance Binary MathType instance Binary QuoteType-instance Binary REF.CLabel-instance Binary REF.CNum-instance Binary REF.Literal-instance Binary REF.RefDate-instance Binary REF.RefType-instance Binary REF.Season instance Binary Row instance Binary RowHeadColumns instance Binary RowSpan-instance Binary STY.Agent-instance Binary STY.Formatted instance Binary TableBody instance Binary TableFoot instance Binary TableHead
lib/Hakyll/Web/Template/Context.hs view
@@ -60,8 +60,7 @@ import Data.Semigroup (Semigroup (..)) #endif import Data.Time.Clock (UTCTime (..))-import Data.Time.Format (formatTime)-import qualified Data.Time.Format as TF+import Data.Time.Format (formatTime, parseTimeM) import Data.Time.Locale.Compat (TimeLocale, defaultTimeLocale) import Hakyll.Core.Compiler import Hakyll.Core.Compiler.Internal@@ -463,10 +462,3 @@ missingField :: Context a missingField = Context $ \k _ _ -> noResult $ "Missing field '" ++ k ++ "' in context"--parseTimeM :: Bool -> TimeLocale -> String -> String -> Maybe UTCTime-#if MIN_VERSION_time(1,5,0)-parseTimeM = TF.parseTimeM-#else-parseTimeM _ = TF.parseTime-#endif
src/Init.hs view
@@ -11,7 +11,8 @@ import Data.List (foldl', intercalate, isPrefixOf) import Data.Version (Version (..)) import System.Directory (canonicalizePath, copyFile,- doesFileExist)+ doesFileExist,+ setPermissions, getPermissions, writable) import System.Environment (getArgs, getProgName) import System.Exit (exitFailure) import System.FilePath (splitDirectories, (</>))@@ -65,6 +66,10 @@ putStrLn $ "Creating " ++ dst makeDirectories dst copyFile src dst+ -- On some systems, the source folder may be readonly,+ -- and copyFile will therefore create a readonly project...+ p <- getPermissions dst+ setPermissions dst (p {writable = True}) putStrLn $ "Creating " ++ cabalPath createCabal cabalPath name
+ tests/Hakyll/Web/Pandoc/Biblio/Tests.hs view
@@ -0,0 +1,66 @@+--------------------------------------------------------------------------------+{-# LANGUAGE OverloadedStrings #-}+module Hakyll.Web.Pandoc.Biblio.Tests+ ( tests+ ) where+++--------------------------------------------------------------------------------+import System.FilePath ((</>))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Golden (goldenVsString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as LBS+++--------------------------------------------------------------------------------+import Hakyll+import Hakyll.Core.Runtime+import Hakyll.Web.Pandoc.Biblio+import qualified Hakyll.Core.Logger as Logger+import TestSuite.Util+++--------------------------------------------------------------------------------+tests :: TestTree+tests = testGroup "Hakyll.Web.Pandoc.Biblio.Tests" $+ [ goldenTest01+ ]++--------------------------------------------------------------------------------+goldenTestsDataDir :: FilePath+goldenTestsDataDir = "tests/data/biblio"++--------------------------------------------------------------------------------+goldenTest01 :: TestTree+goldenTest01 =+ goldenVsString+ "biblio01"+ (goldenTestsDataDir </> "biblio01.golden")+ (do+ -- Code lifted from https://github.com/jaspervdj/hakyll-citeproc-example.+ logger <- Logger.new Logger.Error+ let config = testConfiguration { providerDirectory = goldenTestsDataDir }+ _ <- run config logger $ do+ let myPandocBiblioCompiler = do+ csl <- load "chicago.csl"+ bib <- load "refs.bib"+ getResourceBody >>=+ readPandocBiblio defaultHakyllReaderOptions csl bib >>=+ return . writePandoc++ match "default.html" $ compile templateCompiler+ match "chicago.csl" $ compile cslCompiler+ match "refs.bib" $ compile biblioCompiler+ match "page.markdown" $ do+ route $ setExtension "html"+ compile $+ myPandocBiblioCompiler >>=+ loadAndApplyTemplate "default.html" defaultContext++ output <- fmap LBS.fromStrict $ B.readFile $+ destinationDirectory testConfiguration </> "page.html"++ cleanTestEnv++ return output)
tests/TestSuite.hs view
@@ -24,6 +24,7 @@ import qualified Hakyll.Web.Html.RelativizeUrls.Tests import qualified Hakyll.Web.Html.Tests #ifdef USE_PANDOC+import qualified Hakyll.Web.Pandoc.Biblio.Tests import qualified Hakyll.Web.Pandoc.FileType.Tests #endif import qualified Hakyll.Web.Template.Context.Tests@@ -48,6 +49,7 @@ , Hakyll.Web.Html.RelativizeUrls.Tests.tests , Hakyll.Web.Html.Tests.tests #ifdef USE_PANDOC+ , Hakyll.Web.Pandoc.Biblio.Tests.tests , Hakyll.Web.Pandoc.FileType.Tests.tests #endif , Hakyll.Web.Tags.Tests.tests
+ tests/data/biblio/biblio01.golden view
@@ -0,0 +1,16 @@+<!doctype html>+<html lang="en">+ <head>+ <meta charset="utf-8">+ <title>This page cites a paper.</title>+ </head>+ <body>+ <h1>This page cites a paper.</h1>+ <p>I would like to cite one of my favourite papers <span class="citation" data-cites="meijer1991functional">(Meijer, Fokkinga, and Paterson 1991)</span> here.</p>+<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">+<div id="ref-meijer1991functional" class="csl-entry" role="doc-biblioentry">+Meijer, Erik, Maarten Fokkinga, and Ross Paterson. 1991. <span>“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire.”</span> In <em>Conference on Functional Programming Languages and Computer Architecture</em>, 124–44. Springer.+</div>+</div>+ </body>+</html>
+ tests/data/biblio/chicago.csl view
@@ -0,0 +1,648 @@+<?xml version="1.0" encoding="utf-8"?>+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="display-and-sort" page-range-format="chicago">+ <info>+ <title>Chicago Manual of Style 17th edition (author-date)</title>+ <id>http://www.zotero.org/styles/chicago-author-date</id>+ <link href="http://www.zotero.org/styles/chicago-author-date" rel="self"/>+ <link href="http://www.chicagomanualofstyle.org/tools_citationguide.html" rel="documentation"/>+ <author>+ <name>Julian Onions</name>+ <email>julian.onions@gmail.com</email>+ </author>+ <contributor>+ <name>Sebastian Karcher</name>+ </contributor>+ <contributor>+ <name>Richard Karnesky</name>+ <email>karnesky+zotero@gmail.com</email>+ <uri>http://arc.nucapt.northwestern.edu/Richard_Karnesky</uri>+ </contributor>+ <contributor>+ <name>Andrew Dunning</name>+ <email>andrew.dunning@utoronto.ca</email>+ <uri>https://orcid.org/0000-0003-0464-5036</uri>+ </contributor>+ <contributor>+ <name>Matthew Roth</name>+ <email>matthew.g.roth@yale.edu</email>+ <uri> https://orcid.org/0000-0001-7902-6331</uri>+ </contributor>+ <category citation-format="author-date"/>+ <category field="generic-base"/>+ <summary>The author-date variant of the Chicago style</summary>+ <updated>2018-01-24T12:00:00+00:00</updated>+ <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>+ </info>+ <locale xml:lang="en">+ <terms>+ <term name="editor" form="verb-short">ed.</term>+ <term name="container-author" form="verb">by</term>+ <term name="translator" form="verb-short">trans.</term>+ <term name="editortranslator" form="verb">edited and translated by</term>+ <term name="translator" form="short">trans.</term>+ </terms>+ </locale>+ <macro name="secondary-contributors">+ <choose>+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="none">+ <group delimiter=". ">+ <names variable="editor translator" delimiter=". ">+ <label form="verb" text-case="capitalize-first" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ <names variable="director" delimiter=". ">+ <label form="verb" text-case="capitalize-first" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </group>+ </if>+ </choose>+ </macro>+ <macro name="container-contributors">+ <choose>+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">+ <group prefix=", " delimiter=", ">+ <names variable="container-author" delimiter=", ">+ <label form="verb" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ <names variable="editor translator" delimiter=", ">+ <label form="verb" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </group>+ </if>+ </choose>+ </macro>+ <macro name="editor">+ <names variable="editor">+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>+ <label form="short" prefix=", "/>+ </names>+ </macro>+ <macro name="translator">+ <names variable="translator">+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>+ <label form="short" prefix=", "/>+ </names>+ </macro>+ <macro name="recipient">+ <choose>+ <if type="personal_communication">+ <choose>+ <if variable="genre">+ <text variable="genre" text-case="capitalize-first"/>+ </if>+ <else>+ <text term="letter" text-case="capitalize-first"/>+ </else>+ </choose>+ </if>+ </choose>+ <names variable="recipient" delimiter=", ">+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </macro>+ <macro name="substitute-title">+ <choose>+ <if type="article-magazine article-newspaper review review-book" match="any">+ <text macro="container-title"/>+ </if>+ </choose>+ </macro>+ <macro name="contributors">+ <group delimiter=". ">+ <names variable="author">+ <name and="text" name-as-sort-order="first" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>+ <label form="short" prefix=", "/>+ <substitute>+ <names variable="editor"/>+ <names variable="translator"/>+ <names variable="director"/>+ <text macro="substitute-title"/>+ <text macro="title"/>+ </substitute>+ </names>+ <text macro="recipient"/>+ </group>+ </macro>+ <macro name="contributors-short">+ <names variable="author">+ <name form="short" and="text" delimiter=", " initialize-with=". "/>+ <substitute>+ <names variable="editor"/>+ <names variable="translator"/>+ <names variable="director"/>+ <text macro="substitute-title"/>+ <text macro="title"/>+ </substitute>+ </names>+ </macro>+ <macro name="interviewer">+ <names variable="interviewer" delimiter=", ">+ <label form="verb" prefix=" " text-case="capitalize-first" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </macro>+ <macro name="archive">+ <group delimiter=". ">+ <text variable="archive_location" text-case="capitalize-first"/>+ <text variable="archive"/>+ <text variable="archive-place"/>+ </group>+ </macro>+ <macro name="access">+ <group delimiter=". ">+ <choose>+ <if type="graphic report" match="any">+ <text macro="archive"/>+ </if>+ <else-if type="article-journal bill book chapter legal_case legislation motion_picture paper-conference" match="none">+ <text macro="archive"/>+ </else-if>+ </choose>+ <choose>+ <if type="webpage post-weblog" match="any">+ <date variable="issued" form="text"/>+ </if>+ </choose>+ <choose>+ <if variable="issued" match="none">+ <group delimiter=" ">+ <text term="accessed" text-case="capitalize-first"/>+ <date variable="accessed" form="text"/>+ </group>+ </if>+ </choose>+ <choose>+ <if type="legal_case" match="none">+ <choose>+ <if variable="DOI">+ <text variable="DOI" prefix="https://doi.org/"/>+ </if>+ <else>+ <text variable="URL"/>+ </else>+ </choose>+ </if>+ </choose>+ </group>+ </macro>+ <macro name="title">+ <choose>+ <if variable="title" match="none">+ <choose>+ <if type="personal_communication" match="none">+ <text variable="genre" text-case="capitalize-first"/>+ </if>+ </choose>+ </if>+ <else-if type="bill book graphic legislation motion_picture song" match="any">+ <text variable="title" text-case="title" font-style="italic"/>+ <group prefix=" (" suffix=")" delimiter=" ">+ <text term="version"/>+ <text variable="version"/>+ </group>+ </else-if>+ <else-if variable="reviewed-author">+ <choose>+ <if variable="reviewed-title">+ <group delimiter=". ">+ <text variable="title" text-case="title" quotes="true"/>+ <group delimiter=", ">+ <text variable="reviewed-title" text-case="title" font-style="italic" prefix="Review of "/>+ <names variable="reviewed-author">+ <label form="verb-short" text-case="lowercase" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </group>+ </group>+ </if>+ <else>+ <group delimiter=", ">+ <text variable="title" text-case="title" font-style="italic" prefix="Review of "/>+ <names variable="reviewed-author">+ <label form="verb-short" text-case="lowercase" suffix=" "/>+ <name and="text" delimiter=", "/>+ </names>+ </group>+ </else>+ </choose>+ </else-if>+ <else-if type="legal_case interview patent" match="any">+ <text variable="title"/>+ </else-if>+ <else>+ <text variable="title" text-case="title" quotes="true"/>+ </else>+ </choose>+ </macro>+ <macro name="edition">+ <choose>+ <if type="bill book graphic legal_case legislation motion_picture report song" match="any">+ <choose>+ <if is-numeric="edition">+ <group delimiter=" " prefix=". ">+ <number variable="edition" form="ordinal"/>+ <text term="edition" form="short" strip-periods="true"/>+ </group>+ </if>+ <else>+ <text variable="edition" text-case="capitalize-first" prefix=". "/>+ </else>+ </choose>+ </if>+ <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">+ <choose>+ <if is-numeric="edition">+ <group delimiter=" " prefix=", ">+ <number variable="edition" form="ordinal"/>+ <text term="edition" form="short"/>+ </group>+ </if>+ <else>+ <text variable="edition" prefix=", "/>+ </else>+ </choose>+ </else-if>+ </choose>+ </macro>+ <macro name="locators">+ <choose>+ <if type="article-journal">+ <choose>+ <if variable="volume">+ <text variable="volume" prefix=" "/>+ <group prefix=" (" suffix=")">+ <choose>+ <if variable="issue">+ <text variable="issue"/>+ </if>+ <else>+ <date variable="issued">+ <date-part name="month"/>+ </date>+ </else>+ </choose>+ </group>+ </if>+ <else-if variable="issue">+ <group delimiter=" " prefix=", ">+ <text term="issue" form="short"/>+ <text variable="issue"/>+ <date variable="issued" prefix="(" suffix=")">+ <date-part name="month"/>+ </date>+ </group>+ </else-if>+ <else>+ <date variable="issued" prefix=", ">+ <date-part name="month"/>+ </date>+ </else>+ </choose>+ </if>+ <else-if type="legal_case">+ <text variable="volume" prefix=", "/>+ <text variable="container-title" prefix=" "/>+ <text variable="page" prefix=" "/>+ </else-if>+ <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">+ <group prefix=". " delimiter=". ">+ <group>+ <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>+ <number variable="volume" form="numeric"/>+ </group>+ <group>+ <number variable="number-of-volumes" form="numeric"/>+ <text term="volume" form="short" prefix=" " plural="true"/>+ </group>+ </group>+ </else-if>+ <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">+ <choose>+ <if variable="page" match="none">+ <group prefix=". ">+ <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>+ <number variable="volume" form="numeric"/>+ </group>+ </if>+ </choose>+ </else-if>+ </choose>+ </macro>+ <macro name="locators-chapter">+ <choose>+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">+ <choose>+ <if variable="page">+ <group prefix=", ">+ <text variable="volume" suffix=":"/>+ <text variable="page"/>+ </group>+ </if>+ </choose>+ </if>+ </choose>+ </macro>+ <macro name="locators-article">+ <choose>+ <if type="article-newspaper">+ <group prefix=", " delimiter=", ">+ <group delimiter=" ">+ <text variable="edition"/>+ <text term="edition"/>+ </group>+ <group>+ <text term="section" form="short" suffix=" "/>+ <text variable="section"/>+ </group>+ </group>+ </if>+ <else-if type="article-journal">+ <choose>+ <if variable="volume issue" match="any">+ <text variable="page" prefix=": "/>+ </if>+ <else>+ <text variable="page" prefix=", "/>+ </else>+ </choose>+ </else-if>+ </choose>+ </macro>+ <macro name="point-locators">+ <choose>+ <if variable="locator">+ <choose>+ <if locator="page" match="none">+ <choose>+ <if type="bill book graphic legal_case legislation motion_picture report song" match="any">+ <choose>+ <if variable="volume">+ <group>+ <text term="volume" form="short" suffix=" "/>+ <number variable="volume" form="numeric"/>+ <label variable="locator" form="short" prefix=", " suffix=" "/>+ </group>+ </if>+ <else>+ <label variable="locator" form="short" suffix=" "/>+ </else>+ </choose>+ </if>+ <else>+ <label variable="locator" form="short" suffix=" "/>+ </else>+ </choose>+ </if>+ <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">+ <number variable="volume" form="numeric" suffix=":"/>+ </else-if>+ </choose>+ <text variable="locator"/>+ </if>+ </choose>+ </macro>+ <macro name="container-prefix">+ <text term="in" text-case="capitalize-first"/>+ </macro>+ <macro name="container-title">+ <choose>+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">+ <text macro="container-prefix" suffix=" "/>+ </if>+ </choose>+ <choose>+ <if type="webpage">+ <text variable="container-title" text-case="title"/>+ </if>+ <else-if type="legal_case" match="none">+ <group delimiter=" ">+ <text variable="container-title" text-case="title" font-style="italic"/>+ <choose>+ <if type="post-weblog">+ <text value="(blog)"/>+ </if>+ </choose>+ </group>+ </else-if>+ </choose>+ </macro>+ <macro name="publisher">+ <group delimiter=": ">+ <text variable="publisher-place"/>+ <text variable="publisher"/>+ </group>+ </macro>+ <macro name="date">+ <choose>+ <if variable="issued">+ <group delimiter=" ">+ <date variable="original-date" form="text" date-parts="year" prefix="(" suffix=")"/>+ <date variable="issued">+ <date-part name="year"/>+ </date>+ </group>+ </if>+ <else-if variable="status">+ <text variable="status" text-case="capitalize-first"/>+ </else-if>+ <else>+ <text term="no date" form="short"/>+ </else>+ </choose>+ </macro>+ <macro name="date-in-text">+ <choose>+ <if variable="issued">+ <group delimiter=" ">+ <date variable="original-date" form="text" date-parts="year" prefix="[" suffix="]"/>+ <date variable="issued">+ <date-part name="year"/>+ </date>+ </group>+ </if>+ <else-if variable="status">+ <text variable="status"/>+ </else-if>+ <else>+ <text term="no date" form="short"/>+ </else>+ </choose>+ </macro>+ <macro name="day-month">+ <date variable="issued">+ <date-part name="month"/>+ <date-part name="day" prefix=" "/>+ </date>+ </macro>+ <macro name="collection-title">+ <choose>+ <if match="none" type="article-journal">+ <choose>+ <if match="none" is-numeric="collection-number">+ <group delimiter=", ">+ <text variable="collection-title" text-case="title"/>+ <text variable="collection-number"/>+ </group>+ </if>+ <else>+ <group delimiter=" ">+ <text variable="collection-title" text-case="title"/>+ <text variable="collection-number"/>+ </group>+ </else>+ </choose>+ </if>+ </choose>+ </macro>+ <macro name="collection-title-journal">+ <choose>+ <if type="article-journal">+ <group delimiter=" ">+ <text variable="collection-title"/>+ <text variable="collection-number"/>+ </group>+ </if>+ </choose>+ </macro>+ <macro name="event">+ <group>+ <text term="presented at" suffix=" "/>+ <text variable="event"/>+ </group>+ </macro>+ <macro name="description">+ <choose>+ <if type="interview">+ <group delimiter=". ">+ <text macro="interviewer"/>+ <text variable="medium" text-case="capitalize-first"/>+ </group>+ </if>+ <else-if type="patent">+ <group delimiter=" " prefix=". ">+ <text variable="authority"/>+ <text variable="number"/>+ </group>+ </else-if>+ <else>+ <text variable="medium" text-case="capitalize-first" prefix=". "/>+ </else>+ </choose>+ <choose>+ <if variable="title" match="none"/>+ <else-if type="thesis personal_communication speech" match="any"/>+ <else>+ <group delimiter=" " prefix=". ">+ <text variable="genre" text-case="capitalize-first"/>+ <choose>+ <if type="report">+ <text variable="number"/>+ </if>+ </choose>+ </group>+ </else>+ </choose>+ </macro>+ <macro name="issue">+ <choose>+ <if type="legal_case">+ <text variable="authority" prefix=". "/>+ </if>+ <else-if type="speech">+ <group prefix=". " delimiter=", ">+ <group delimiter=" ">+ <text variable="genre" text-case="capitalize-first"/>+ <text macro="event"/>+ </group>+ <text variable="event-place"/>+ <text macro="day-month"/>+ </group>+ </else-if>+ <else-if type="article-newspaper article-magazine personal_communication" match="any">+ <date variable="issued" form="text" prefix=", "/>+ </else-if>+ <else-if type="patent">+ <group delimiter=", " prefix=", ">+ <group delimiter=" ">+ <!--Needs Localization-->+ <text value="filed"/>+ <date variable="submitted" form="text"/>+ </group>+ <group delimiter=" ">+ <choose>+ <if variable="issued submitted" match="all">+ <text term="and"/>+ </if>+ </choose>+ <!--Needs Localization-->+ <text value="issued"/>+ <date variable="issued" form="text"/>+ </group>+ </group>+ </else-if>+ <else-if type="article-journal" match="any"/>+ <else>+ <group prefix=". " delimiter=", ">+ <choose>+ <if type="thesis">+ <text variable="genre" text-case="capitalize-first"/>+ </if>+ </choose>+ <text macro="publisher"/>+ </group>+ </else>+ </choose>+ </macro>+ <citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="primary-name" collapse="year">+ <layout prefix="(" suffix=")" delimiter="; ">+ <group delimiter=", ">+ <choose>+ <if variable="issued accessed" match="any">+ <group delimiter=" ">+ <text macro="contributors-short"/>+ <text macro="date-in-text"/>+ </group>+ </if>+ <!---comma before forthcoming and n.d.-->+ <else>+ <group delimiter=", ">+ <text macro="contributors-short"/>+ <text macro="date-in-text"/>+ </group>+ </else>+ </choose>+ <text macro="point-locators"/>+ </group>+ </layout>+ </citation>+ <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="———" entry-spacing="0">+ <sort>+ <key macro="contributors"/>+ <key variable="issued"/>+ <key variable="title"/>+ </sort>+ <layout suffix=".">+ <group delimiter=". ">+ <text macro="contributors"/>+ <text macro="date"/>+ <text macro="title"/>+ </group>+ <text macro="description"/>+ <text macro="secondary-contributors" prefix=". "/>+ <text macro="container-title" prefix=". "/>+ <text macro="container-contributors"/>+ <text macro="edition"/>+ <text macro="locators-chapter"/>+ <text macro="collection-title-journal" prefix=", " suffix=", "/>+ <text macro="locators"/>+ <text macro="collection-title" prefix=". "/>+ <text macro="issue"/>+ <text macro="locators-article"/>+ <text macro="access" prefix=". "/>+ </layout>+ </bibliography>+</style>
+ tests/data/biblio/default.html view
@@ -0,0 +1,11 @@+<!doctype html>+<html lang="en">+ <head>+ <meta charset="utf-8">+ <title>$title$</title>+ </head>+ <body>+ <h1>$title$</h1>+ $body$+ </body>+</html>
+ tests/data/biblio/page.markdown view
@@ -0,0 +1,5 @@+---+title: This page cites a paper.+---++I would like to cite one of my favourite papers [@meijer1991functional] here.
+ tests/data/biblio/refs.bib view
@@ -0,0 +1,8 @@+@inproceedings{meijer1991functional,+ title={Functional programming with bananas, lenses, envelopes and barbed wire},+ author={Meijer, Erik and Fokkinga, Maarten and Paterson, Ross},+ booktitle={Conference on Functional Programming Languages and Computer Architecture},+ pages={124--144},+ year={1991},+ organization={Springer}+}