def _build_block_parser(md, **kwargs): """ Build the default block parser used by Markdown. """ parser = BlockParser(md) parser.blockprocessors.register(EmptyBlockProcessor(parser), 'empty', 100) parser.blockprocessors.register(ListIndentProcessor(parser), 'indent', 90) parser.blockprocessors.register(CodeBlockProcessor(parser), 'code', 80) parser.blockprocessors.register(BudouXHashHeaderProcessor(parser), 'hashheader', 70) parser.blockprocessors.register(SetextHeaderProcessor(parser), 'setextheader', 60) parser.blockprocessors.register(HRProcessor(parser), 'hr', 50) parser.blockprocessors.register(OListProcessor(parser), 'olist', 40) parser.blockprocessors.register(UListProcessor(parser), 'ulist', 30) parser.blockprocessors.register(BlockQuoteProcessor(parser), 'quote', 20) parser.blockprocessors.register(ReferenceProcessor(parser), 'reference', 15) parser.blockprocessors.register(BudouXParagraphProcessor(parser), 'paragraph', 10) return parser
class CustomHtmlListBuilder(HierarchyBuilderWithQueue): class Level: def __init__(self, char, element): self.char = char self.element = element def __init__(self, parser, root): super(CustomHtmlListBuilder, self).__init__() self._root = root self._hrProcessor = HRProcessor(parser) rootUl = property(lambda self: None if not self._levels else self._levels[0].element) @staticmethod def _parseLine(line, level=None): assert line and not line[0].isspace() if level is not None: if line[0] == level.char: char = level.char text = line[1:].lstrip() else: char = None text = line else: if line[0] in '*-|': char = line[0] text = line[1:].lstrip() else: char = None text = line return (char, text) def _createUl(self, parent, char): if char is None or char == '*': return etree.SubElement(parent, 'ul') elif char == '-': return etree.SubElement(parent, 'ol') elif char == '|': return etree.SubElement(parent, 'ul', { 'class': 'details' }) else: raise Exception("Invalid char") def _createLi(self, parent, text): # Кастомная обработка: если текст соответствует Markdown-разметке горизонтальной линии, # вместо использования этого текста добавляем элементу списка класс "separator" shouldBeSeparator = self._hrProcessor.test(parent, text) li = etree.SubElement(parent, 'li') if shouldBeSeparator: li.set('class', 'separator') else: li.text = text return li def push(self, line): char, text = self._parseLine(line, level=None) parentElement = self._root if not self._levels else \ self._levels[-1].element[-1] # последний LI текущего UL ul = self._createUl(parentElement, char) self._createLi(ul, text) self._levels.append(self.Level(char, ul)) def put(self, line): level = self._levels[-1] unused_char, text = self._parseLine(line, level) self._createLi(level.element, text)
def __init__(self, parser, root): super(CustomHtmlListBuilder, self).__init__() self._root = root self._hrProcessor = HRProcessor(parser)