Getting h1 from markdown via python's pandoc library

Viewed 391

I'm writing a python batch script to process many markdown files to get h1-like text to generate 'title' metadata variable (I forgot to add 'title' into frontmatter). I'm not using this as pandoc filter.

Thus I was thinking to process those files via pandoc-python, but I'm not familiar with that and I cannot figure out how to get only h1.

content = pandoc.read(post.content)

'content' is pandoc native format. And I see something like this

(Pdb) content                                                                                                                                                                                                                                 
Pandoc(Meta({}), [Header(1, ('foobar', [], []), [Str('foobar:')]), Para(...

I would like to get h1 as simple text.

2 Answers

I have the following snippet that works for headers both with # or =======.

import pandoc
from pandoc.types import *

with open('README.md') as f:
    content = pandoc.read(f.read()) 
# But you can use your content.
headers = []

for elt in pandoc.iter(content):
     if isinstance(elt, Header):
         if elt[0] == 1: # this is header 1, remove this if statement if you want all headers.
             headers.append(elt[1][0])

Or if you want the exact string with upper case etc.:

for elt in pandoc.iter(content):
    if isinstance(elt, Header):
        if elt[0] == 1: # this is header 1, remove this if statement if you want all headers.
            header.append(pandoc.write(elt[-1]).strip())

One could also try to configure pandoc to do that for us. Here's what the manual has to say about the --shift-heading-level-by option:

--shift-heading-level-by=NUMBER

Shift heading levels by a positive or negative integer. For example, with --shift-heading-level-by=-1, level 2 headings become level 1 headings, and level 3 headings become level 2 headings. Headings cannot have a level less than 1, so a heading that would be shifted below level 1 becomes a regular paragraph. Exception: with a shift of -N, a level-N heading at the beginning of the document replaces the metadata title. --shift-heading-level-by=-1 is a good choice when converting HTML or Markdown documents that use an initial level-1 heading for the document title and level-2+ headings for sections. --shift-heading-level-by=1 may be a good choice for converting Markdown documents that use level-1 headings for sections to HTML, since pandoc uses a level-1 heading to render the document title.

So running pandoc with --shift-heading-level-by=-1 might be enough to suit your needs.

Related