12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- # Copyright 2015 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Implements Gitiles' notification, aside and promotion blocks.
- This extention makes the Markdown parser recognize the Gitiles' extended
- blocks notation. The syntax is explained at:
- https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md#Notification_aside_promotion-blocks
- """
- from markdown.blockprocessors import BlockProcessor
- from markdown.extensions import Extension
- from markdown.util import etree
- import re
- class _GitilesExtBlockProcessor(BlockProcessor):
- """Process Gitiles' notification, aside and promotion blocks."""
- RE_START = re.compile(r'^\*\*\* (note|aside|promo) *\n')
- RE_END = re.compile(r'\n\*\*\* *\n?$')
- def __init__(self, *args, **kwargs):
- self._last_parent = None
- BlockProcessor.__init__(self, *args, **kwargs)
- def test(self, parent, block):
- return self.RE_START.search(block) or self.RE_END.search(block)
- def run(self, parent, blocks):
- raw_block = blocks.pop(0)
- match_start = self.RE_START.search(raw_block)
- if match_start:
- # Opening a new block.
- rest = raw_block[match_start.end():]
- if self._last_parent:
- # Inconsistent state (nested starting markers). Ignore the marker
- # and keep going.
- blocks.insert(0, rest)
- return
- div = etree.SubElement(parent, 'div')
- # Setting the class name is sufficient, because doc.css already has
- # styles for these classes.
- div.set('class', match_start.group(1))
- self._last_parent = parent
- blocks.insert(0, rest)
- self.parser.parseBlocks(div, blocks)
- return
- match_end = self.RE_END.search(raw_block)
- if match_end:
- # Ending an existing block.
- # Process the text preceding the ending marker in the current context
- # (i.e. within the div block).
- rest = raw_block[:match_end.start()]
- self.parser.parseBlocks(parent, [rest])
- if not self._last_parent:
- # Inconsistent state (the ending marker is found but there is no
- # matching starting marker).
- # Let's continue as if we did not see the ending marker.
- return
- last_parent = self._last_parent
- self._last_parent = None
- self.parser.parseBlocks(last_parent, blocks)
- return
- class _GitilesExtBlockExtension(Extension):
- """Add Gitiles' extended blocks to Markdown."""
- def extendMarkdown(self, md):
- md.parser.blockprocessors.add('gitilesextblocks',
- _GitilesExtBlockProcessor(md.parser),
- '_begin')
- def makeExtension(*args, **kwargs):
- return _GitilesExtBlockExtension(*args, **kwargs)
|