pandoccommonmark

Keep custom code block attributes in pandoc when converting to Markdown


I am converting an org file to Markdown (specifically commonmark). I am adding a custom attribute to my code blocks, which the commonmark writer does not support, and strips them from the code block during conversion. I am trying to find a way to keep my custom attributes.

This is what I have:

#+begin_src python :hl_lines "2"
def some_function():
    print("foo bar")
    return
#+end_src

This is what I want in my .md file:

``` python hl_lines="2"
def some_function():
    print("foo bar")
    return
```

After doing some research, I think a filter can solve my issue: I am now playing with panflute, a python lib for writing pandoc filters.

I found some relevant questions, but they apply to other conversions (rST -> html, rst -> latex) and I don't know enough Lua to translate the code into Python and the org -> md conversion.

Thanks for any help.


Solution

  • I was able to write a script, posting it here for future Python-based questions about pandoc filters.

    The filter below requires panflute, but there are other libs for pandoc filters in Python.

    import panflute
    
    
    def keep_attributes_markdown(elem, doc, format="commonmark"):
        """Keep custom attributes specified in code block headers when exporting to Markdown"""
        if type(elem) == panflute.CodeBlock:
            language = "." + elem.classes[0]
            attributes = ""
            attributes = " ".join(
                [key + "=" + value for key, value in elem.attributes.items()]
            )
            header = "``` { " + " ".join([language, attributes]).strip() + " }"
            panflute.debug(header)
    
            code = elem.text.strip()
    
            footer = "```"
    
            content = [
                panflute.RawBlock(header, format=format),
                panflute.RawBlock(code, format=format),
                panflute.RawBlock(footer, format=format),
            ]
            return content
    
    
    def main(doc=None):
        return panflute.run_filter(keep_attributes_markdown, doc=doc)
    
    
    if __name__ == "__main__":
        main()
    

    You can now run the following command:

    pandoc --from=org --to=commonmark --filter=/full/path/to/keep_attributes_markdown.py --output=target_file.md your_file.org