pandoc-utils: Utility functions to work with Pandoc in Haskell applications.

[ library, mit, text ] [ Propose Tags ]

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.

For more examples, please see the README on GitHub.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.4.0, 0.5.0, 0.5.1, 0.6.0, 0.6.1, 0.7.0, 0.7.1
Change log CHANGELOG.md
Dependencies base (>=4.10 && <4.15), pandoc-types (>=1.17.2 && <1.18 || >=1.20 && <1.21), text (>=1.2 && <1.3) [details]
License MIT
Copyright Copyright (c) 2020 Krasjet
Author Krasjet
Maintainer Krasjet
Category Text
Home page https://github.com/Krasjet/pandoc-utils
Bug tracker https://github.com/Krasjet/pandoc-utils/issues
Source repo head: git clone git://github.com/Krasjet/pandoc-utils.git
Uploaded by Krasjet at 2020-05-24T10:49:17Z
Distributions
Downloads 1069 total (16 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for pandoc-utils-0.4.0

[back to package description]

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.