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

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

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]

Properties

Versions 0.4.0, 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:46:48Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


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.