1

I want to use Pandoc to merge multiple Markdown files. While doing so, I want each file's frontmatter or metadata to generate custom Markdown at the top of the document before merging. I found this SO post answer which appears to do what I want, but I don't sufficiently understand Pandoc filters or the Haskell for the proposed filter. My attempt to translate the Haskell into Python is this:

from pandocfilters import Header
from pandocfilters import toJSONFilter


def insertMeta(key, value, format, meta):
    if ???:
        return Header(meta['title'], [], [])


if __name__ == "__main__":
    toJSONFilter(insertMeta)

I understand that toJSONFilter will walk the AST of the document, but I have no idea how to write a condition to only insert header information at the top of the document. What am I conditioning on? I tried to dir(pandocfilters) but do not see an object that looks like metadata or file headers. Thanks for any help.

jds
  • 7,910
  • 11
  • 63
  • 101

1 Answers1

2

Yes, it is a bit hard to get your head over toJSONFilter, because it involves understanding Haskell type classes (and this type class is also not very usual as its instances are functions). But the good news is that you don't really need to understand it, because it is a helper function that wraps your custom logic into a proper Pandoc filter.

So, skipping all the details you need start with

import Text.Pandoc.JSON

main :: IO ()
main = toJSONFilter myFunc

And implement myFunc, a function that take some Walkable thing and produce the same altered thing. In your example that thing was Pandoc, a top-level AST node, IIRC.

You can lookup a whole list of Walkable things here: https://hackage.haskell.org/package/pandoc-types/docs/Text-Pandoc-Walk.html#t:Walkable

Since Pandoc contains a list of document Blocks, and you want to prepend some block at the beginning, your myFunc should also operate on Pandoc, just like your example.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • Thanks for the help. Unfortunately, this doesn't really solve my issue because `pandocfilters` does not appear to have an object called `Pandoc`, representing the top-level AST node. I'll accept this answer anyway in a few days if I don't get any other help. – jds May 20 '20 at 01:15
  • Why not implement it in Haskell? I believe, it is easier than you think. Reach me out by email or at IRC `#haskell-FreeBSD` on Freenode and I'll gladly help you. – arrowd May 20 '20 at 06:20