MCPcopy Create free account
hub / github.com/ronreiter/interactive-tutorials / HeaderIdProcessor

Class HeaderIdProcessor

markdown/extensions/headerid.py:77–163  ·  view source on GitHub ↗

Replacement BlockProcessor for Header IDs.

Source from the content-addressed store, hash-verified

75
76
77class HeaderIdProcessor(markdown.blockprocessors.BlockProcessor):
78 """ Replacement BlockProcessor for Header IDs. """
79
80 # Detect a header at start of any line in block
81 RE = re.compile(r"""(^|\n)
82 (?P<level>\#{1,6}) # group('level') = string of hashes
83 (?P<header>.*?) # group('header') = Header text
84 \#* # optional closing hashes
85 (?:[ \t]*\{[ \t]*\#(?P<id>[-_:a-zA-Z0-9]+)[ \t]*\})?
86 (\n|$) # ^^ group('id') = id attribute
87 """,
88 re.VERBOSE)
89
90 IDs = []
91
92 def test(self, parent, block):
93 return bool(self.RE.search(block))
94
95 def run(self, parent, blocks):
96 block = blocks.pop(0)
97 m = self.RE.search(block)
98 if m:
99 before = block[:m.start()] # All lines before header
100 after = block[m.end():] # All lines after header
101 if before:
102 # As the header was not the first line of the block and the
103 # lines before the header must be parsed first,
104 # recursively parse this lines as a block.
105 self.parser.parseBlocks(parent, [before])
106 # Create header using named groups from RE
107 start_level, force_id = self._get_meta()
108 level = len(m.group('level')) + start_level
109 if level > 6:
110 level = 6
111 h = markdown.etree.SubElement(parent, 'h%d' % level)
112 h.text = m.group('header').strip()
113 if m.group('id'):
114 h.set('id', self._unique_id(m.group('id')))
115 elif force_id:
116 h.set('id', self._create_id(m.group('header').strip()))
117 if after:
118 # Insert remaining lines as first block for future parsing.
119 blocks.insert(0, after)
120 else:
121 # This should never happen, but just in case...
122 message(CRITICAL, "We've got a problem header!")
123
124 def _get_meta(self):
125 """ Return meta data suported by this ext as a tuple """
126 level = int(self.config['level'][0]) - 1
127 force = self._str2bool(self.config['forceid'][0])
128 if hasattr(self.md, 'Meta'):
129 if 'header_level' in self.md.Meta:
130 level = int(self.md.Meta['header_level'][0]) - 1
131 if 'header_forceid' in self.md.Meta:
132 force = self._str2bool(self.md.Meta['header_forceid'][0])
133 return level, force
134

Callers 1

extendMarkdownMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected