pandoc-utils
This package contains some useful functions for writing
Pandoc filters and integrating Pandoc into Haskell
applications such as Hakyll. It provides a
composable wrapper for filters acting on nodes of the Pandoc
AST.
Filter conversion/composition
As an example, let us look at the behead
and delink
filter from Pandoc's
tutorial.
behead :: Block -> Block
behead (Header n _ xs) | n >= 2 = Para [Emph xs]
behead x = x
delink :: Inline -> [Inline]
delink (Link _ txt _) = txt
delink x = [x]
Since behead
has type Block -> Block
, while delink
has type Inline -> [Inline]
, they are not naturally composable. However, this package provides a
utility function mkFilter
to convert them into a PandocFilter
.
import Text.Pandoc.Filter.Utils
beheadFilter :: PandocFilter
beheadFilter = mkFilter behead
delinkFilter :: PandocFilter
delinkFilter = mkFilter delink
PandocFilter
is an alias for PartialFilter Pandoc
, so you can also have
PartialFilter Inline
, etc. There is also a monadic version called
PartialFilterM
for encapsulating monadic filters.
The PandocFilter
is a monoid so you can do something like,
myFilter :: PandocFilter
myFilter = beheadFilter <> delinkFilter
where myFilter
would apply beheadFilter
first, then the delinkFilter
. You
can apply the filter using applyFilter
,
import Text.Pandoc
import Data.Default (def)
mdToHtml
:: Text -- ^ Input markdown string
-> Either PandocError Text -- ^ Html string or error
mdToHtml md = runPure $ do
doc <- readMarkdown def md
let doc' = applyFilter myFilter doc
writeHtml5String def doc'
or get an unwrapped Pandoc -> Pandoc
filter using getFilter
(this function
is also capable of doing implicit conversion from PartialFilter a
to b -> b
).
myPandocFilter :: Pandoc -> Pandoc
myPandocFilter = getFilter myFilter
For applying multiple filters, there is also a function called applyFilters
,
which takes a list of filters and apply it to a Pandoc
document (or subnode)
sequentially, from left to right.
myFilters :: [PandocFilter]
myFilters =
[ beheadFilter
, delinkFilter
]
mdToHtml'
:: Text -- ^ Input markdown string
-> Either PandocError Text -- ^ Html string or error
mdToHtml' md = runPure $ do
doc <- readMarkdown def md
let doc' = applyFilters myFilters doc
writeHtml5String def doc'
Attribute builder
pandoc-utils also provides an attribute builder for handling attributes. You
can create a new attributes by
ghci> import Text.Pandoc.Filter.Utils.AttrBuilder
ghci> import Text.Pandoc.Definition
ghci> nullAttr `setId` "id" `addClass` "class" `addKVPair` ("key","value")
("id",["class"],[("key","value")])
or modifying an existing attributes by
ghci> attr = ("id",[],[])
ghci> attr `setId` "newId"
("newId",[],[])
For more examples, please read the
spec.