def md2node(text): md = Markdown() md.serializer = Serializer(md) md.stripTopLevelTags = False md.postprocessors = OrderedDict() md.postprocessors['section'] = SectionPostprocessor() md.postprocessors['strip'] = StripPostprocessor() return md.convert(text)
def extendMarkdown(self, md, md_globals): """Create a dict of inline replace patterns and add to the tree processor.""" configs = self.getConfigs() self.patterns = OrderedDict() for k, v in REPL.items(): if configs[k]: self.add_pattern(v, md) inline_processor = InlineProcessor(md) inline_processor.inlinePatterns = self.patterns md.treeprocessors.add('smart-symbols', inline_processor, '_end') if "smarty" in md.treeprocessors.keys(): md.treeprocessors.link('smarty', '_end')
def reset(self): """ Clear literature references on reset, and prepare for distinct document. """ self.literatures = OrderedDict() self.unique_prefix += 1
class LiteratureExtension(Extension): """ Literature Extension. """ def __init__(self, *args, **kwargs): """ Setup configs. """ self.config = { 'PLACE_MARKER': [ "///Literature Goes Here///", "The text string that marks where the literature references go" ], 'UNIQUE_IDS': [ False, "Avoid name collisions across " "multiple calls to reset()." ], "BACKLINK_TEXT": [ "↩", "The text string that links from the literature reference " "to the reader's place." ] } super(LiteratureExtension, self).__init__(*args, **kwargs) # In multiple invocations, emit links that don't get tangled. self.unique_prefix = 0 self.reset() def extendMarkdown(self, md, md_globals): """ Add pieces to Markdown. """ md.registerExtension(self) self.parser = md.parser self.md = md # Insert a preprocessor before ReferencePreprocessor md.preprocessors.add("literature", LiteraturePreprocessor(self), "<reference") # Insert an inline pattern before ImageReferencePattern LITERATURE_RE = r'\[\=([^\]]*)\]' # blah blah [^1] blah md.inlinePatterns.add("literature", LiteraturePattern(LITERATURE_RE, self), "<reference") # Insert a tree-processor that would actually add the literatures div # This must be before all other treeprocessors (i.e., inline and # codehilite) so they can run on the the contents of the div. md.treeprocessors.add("literature", LiteratureTreeprocessor(self), "_begin") # Insert a postprocessor after amp_substitute oricessor md.postprocessors.add("literature", LiteraturePostprocessor(self), ">amp_substitute") def reset(self): """ Clear literature references on reset, and prepare for distinct document. """ self.literatures = OrderedDict() self.unique_prefix += 1 def findLiteraturesPlaceholder(self, root): """ Return ElementTree Element that contains Literature placeholder. """ def finder(element): for child in element: if child.text: if child.text.find(self.getConfig("PLACE_MARKER")) > -1: return child, element, True if child.tail: if child.tail.find(self.getConfig("PLACE_MARKER")) > -1: return child, element, False child_res = finder(child) if child_res is not None: return child_res return None res = finder(root) return res def setLiterature(self, id, text): """ Store a literature for later retrieval. """ self.literatures[id] = text def get_separator(self): if self.md.output_format in ['html5', 'xhtml5']: return '-' return ':' def makeLiteratureId(self, id): """ Return literature link id. """ if self.getConfig("UNIQUE_IDS"): return 'lit%s%d-%s' % (self.get_separator(), self.unique_prefix, id) else: return 'lit%s%s' % (self.get_separator(), id) def makeLiteratureRefId(self, id): """ Return literature back-link id. """ if self.getConfig("UNIQUE_IDS"): return 'litref%s%d-%s' % (self.get_separator(), self.unique_prefix, id) else: return 'litref%s%s' % (self.get_separator(), id) def makeLiteraturesDiv(self, root): """ Return div of literatures as et Element. """ if not list(self.literatures.keys()): return None div = etree.Element("div") div.set('class', 'literature') etree.SubElement(div, "hr") ol = etree.SubElement(div, "ol") for id in self.literatures.keys(): li = etree.SubElement(ol, "li") li.set("id", self.makeLiteratureId(id)) self.parser.parseChunk(li, self.literatures[id]) backlink = etree.Element("a") backlink.set("href", "#" + self.makeLiteratureRefId(id)) if self.md.output_format not in ['html5', 'xhtml5']: backlink.set("rev", "literature") # Invalid in HTML5 backlink.set("class", "literature-backref") backlink.set( "title", "Jump back to literature %d in the text" % (self.literatures.index(id) + 1)) backlink.text = LIT_BACKLINK_TEXT if list(li): node = li[-1] if node.tag == "p": node.text = node.text + NBSP_PLACEHOLDER node.append(backlink) else: p = etree.SubElement(li, "p") p.append(backlink) return div
def reset(self): """ Clear footnotes on reset, and prepare for distinct document. """ self.footnotes = OrderedDict() self.unique_prefix += 1
class UniqueFootnoteExtension(Extension): """ Unique Footnote Extension. """ def __init__(self, *args, **kwargs): """ Setup configs. """ self.config = { 'PLACE_MARKER': ["///Footnotes Go Here///", "The text string that marks where the footnotes go"], "BACKLINK_TEXT": ["⬏", "The text string that links from the footnote " "to the reader's place."] } super(UniqueFootnoteExtension, self).__init__(*args, **kwargs) self.reset() def extendMarkdown(self, md, md_globals): """ Add pieces to Markdown. """ md.registerExtension(self) self.parser = md.parser self.md = md # Insert a preprocessor before ReferencePreprocessor md.preprocessors.add( "footnote", FootnotePreprocessor(self), "<reference" ) # Insert an inline pattern before ImageReferencePattern FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah md.inlinePatterns.add( "footnote", FootnotePattern(FOOTNOTE_RE, self), "<reference" ) # Insert a tree-processor that would actually add the footnote div # This must be before all other treeprocessors (i.e., inline and # codehilite) so they can run on the the contents of the div. md.treeprocessors.add( "footnote", FootnoteTreeprocessor(self), "_begin" ) # Insert a postprocessor after amp_substitute oricessor md.postprocessors.add( "footnote", FootnotePostprocessor(self), ">amp_substitute" ) def reset(self): """ Clear footnotes on reset, and prepare for distinct document. """ self.footnotes = OrderedDict() def findFootnotesPlaceholder(self, root): """ Return ElementTree Element that contains Footnote placeholder. """ def finder(element): for child in element: if child.text: if child.text.find(self.getConfig("PLACE_MARKER")) > -1: return child, element, True if child.tail: if child.tail.find(self.getConfig("PLACE_MARKER")) > -1: return child, element, False finder(child) return None res = finder(root) return res def setFootnote(self, id, text): """ Store a footnote for later retrieval. """ self.footnotes[id] = _unique_id(), text def get_separator(self): if self.md.output_format in ['html5', 'xhtml5']: return '-' return ':' def makeFootnoteId(self, id): """ Return footnote link id. """ return 'fn%s%s' % (self.get_separator(), self.footnotes[id][0]) def makeFootnoteRefId(self, id): """ Return footnote back-link id. """ return 'fnref%s%s' % (self.get_separator(), self.footnotes[id][0]) def makeFootnotesDiv(self, root): """ Return div of footnotes as et Element. """ if not list(self.footnotes.keys()): return None div = etree.Element("div") div.set('class', 'post-footnote') ol = etree.SubElement(div, "ol") for id in self.footnotes.keys(): li = etree.SubElement(ol, "li") li.set("id", self.makeFootnoteId(id)) self.parser.parseChunk(li, self.footnotes[id][1]) backlink = etree.Element("a") backlink.set("href", "#" + self.makeFootnoteRefId(id)) if self.md.output_format not in ['html5', 'xhtml5']: backlink.set("rev", "footnote") # Invalid in HTML5 backlink.set("class", "footnote-backref") backlink.set( u'title', u'Назад к сноске %d' % (self.footnotes.index(id)+1) ) backlink.text = FN_BACKLINK_TEXT if li.getchildren(): node = li[-1] if node.tag == "p": node.text = node.text + NBSP_PLACEHOLDER node.append(backlink) else: p = etree.SubElement(li, "p") p.append(backlink) return div