Process Markdown Inside HTML Blocks which have been stored in the `HtmlStash`.
| 309 | |
| 310 | |
| 311 | class MarkdownInHtmlProcessor(BlockProcessor): |
| 312 | """Process Markdown Inside HTML Blocks which have been stored in the `HtmlStash`.""" |
| 313 | |
| 314 | def test(self, parent: etree.Element, block: str) -> bool: |
| 315 | # Always return True. `run` will return `False` it not a valid match. |
| 316 | return True |
| 317 | |
| 318 | def parse_element_content(self, element: etree.Element) -> None: |
| 319 | """ |
| 320 | Recursively parse the text content of an `etree` Element as Markdown. |
| 321 | |
| 322 | Any block level elements generated from the Markdown will be inserted as children of the element in place |
| 323 | of the text content. All `markdown` attributes are removed. For any elements in which Markdown parsing has |
| 324 | been disabled, the text content of it and its children are wrapped in an `AtomicString`. |
| 325 | """ |
| 326 | |
| 327 | md_attr = element.attrib.pop('markdown', 'off') |
| 328 | |
| 329 | if md_attr == 'block': |
| 330 | # Parse the block elements content as Markdown |
| 331 | if element.text: |
| 332 | block = element.text.rstrip('\n') |
| 333 | element.text = '' |
| 334 | self.parser.parseBlocks(element, block.split('\n\n')) |
| 335 | |
| 336 | elif md_attr == 'span': |
| 337 | # Span elements need to be recursively processed for block elements and raw HTML |
| 338 | # as their content is not normally accessed by block processors, so expand stashed |
| 339 | # HTML under the span. Span content itself will not be parsed here, but will await |
| 340 | # the inline parser. |
| 341 | block = element.text if element.text is not None else '' |
| 342 | element.text = '' |
| 343 | child = None |
| 344 | start = 0 |
| 345 | |
| 346 | # Search the content for HTML placeholders and process the elements |
| 347 | for m in util.HTML_PLACEHOLDER_RE.finditer(block): |
| 348 | index = int(m.group(1)) |
| 349 | el = self.parser.md.htmlStash.rawHtmlBlocks[index] |
| 350 | end = m.start() |
| 351 | |
| 352 | if isinstance(el, etree.Element): |
| 353 | # Replace the placeholder with the element and process it. |
| 354 | # Content after the placeholder should be attached to the tail. |
| 355 | if child is None: |
| 356 | element.text += block[start:end] |
| 357 | else: |
| 358 | child.tail += block[start:end] |
| 359 | element.append(el) |
| 360 | self.parse_element_content(el) |
| 361 | child = el |
| 362 | if child.tail is None: |
| 363 | child.tail = '' |
| 364 | self.parser.md.htmlStash.rawHtmlBlocks.pop(index) |
| 365 | self.parser.md.htmlStash.rawHtmlBlocks.insert(index, '') |
| 366 | |
| 367 | else: |
| 368 | # Not an element object, so insert content back into the element |