Skip to content

Commit

Permalink
Refactor to Postprocessor
Browse files Browse the repository at this point in the history
Other processors/extensions may generate headings, that might need to be
downgraded. A prime example is the built-in raw HTML processing, that
removes inline HTML processes the actual markdown, and then -- in a
preprocessor -- puts the removed raw HTML back.

To avoid this, the header downgrade logic has been moved to a
postprocessor with a low priority (5) to make sure it's the last thing
running.
  • Loading branch information
fancsali committed Mar 23, 2020
1 parent 6b29403 commit 671f59d
Showing 1 changed file with 20 additions and 24 deletions.
44 changes: 20 additions & 24 deletions mdx_headdown/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,30 @@
heading levels to offset by. This will automatically be absolutised and
integerised.
(c) 2018, Sascha Cowley under the MIT Licence.
(c) 2018-2020, Sascha Cowley and contributors under the MIT Licence.
"""

# Import relevant modules.
from markdown.extensions import Extension
from markdown.treeprocessors import Treeprocessor
from markdown.postprocessors import Postprocessor
import re

name = "mdx_headdown"

class DowngradeHeadingsTreeprocessor(Treeprocessor):
""" Downgrade headings via the Treeprocessor interface. """
def run(self, root):
class DowngradeHeadingsPostprocessor(Postprocessor):
""" Downgrade headings via the Preprocessor interface. """
def run(self, text):
# Ensure the offset value is a positive (or zero) integer.
offset = abs(int(self.config['offset']))

# Match headings 1-6 case insensitively if they're the entirety of the
# string, and capture the heading number.
heading_pattern = re.compile('^h([1-6])$', re.I)

for element in root:
# Attempt matching each tag against the heading pattern.
match = heading_pattern.match(element.tag)
if match:
# For all headings, increase their heading number by `offset`.
# If the new heading number is > 6, use 6 instead.
element.tag = 'h%d' % min(6, int(match.group(1))+offset)
self.offset = abs(int(self.config['offset']))

# Match headings 1-6 case insensitively, and capture the heading number.
heading_pattern = re.compile(r'<h([1-6])>([^<]*)</h\1>', re.I)

return re.sub(heading_pattern, self.downgrade, text)

def downgrade(self, mo):
return '<h%(level)d>%(content)s</h%(level)d>' % \
{'level': min(6, int(mo.group(1)) + self.offset), 'content': mo.group(2) }

class DowngradeHeadingsExtension(Extension):
""" Setup the extension for usage. """
Expand All @@ -45,15 +41,15 @@ def __init__(self, **kwargs):
super(DowngradeHeadingsExtension, self).__init__(**kwargs)

def extendMarkdown(self, md):
# Register the plugin as a Treeprocessor. """
md.treeprocessors.register(
DowngradeHeadingsTreeprocessor(md),
'downgradeheadings', 200
# Register the plugin as a Postprocessor. """
md.postprocessors.register(
DowngradeHeadingsPostprocessor(md),
'downgradeheadings', 5
)
# And give the actual processor access to the configuration.
DowngradeHeadingsTreeprocessor.config = self.getConfigs()
DowngradeHeadingsPostprocessor.config = self.getConfigs()


def makeExtension(*args, **kwargs):
# Tell Markdown to make this an extension.
return DowngradeHeadingsExtension(*args, **kwargs)
return DowngradeHeadingsExtension(*args, **kwargs)

0 comments on commit 671f59d

Please sign in to comment.