class TestToc: def setup_method(self): self.markdown = Markdown() self.markdown.use("toc") def test_render_toc(self): content = "# Foo\n## Foobar\n## Foofooz\n# Bar\n" result = self.markdown(content) assert '<h1 id="foo">Foo</h1>' in result toc = self.markdown.renderer.render_toc() assert '<ul>\n<li><a href="#foo">Foo</a></li>' in toc assert '<ul>\n<li><a href="#foobar">Foobar</a></li>' in toc def test_render_toc_exceeding_maxdepth(self): content = "#### Foobar\n" self.markdown(content) toc = self.markdown.renderer.render_toc() assert '<li><a href="#foobar">Foobar</a></li>' in toc content = "# Foo\n#### Foobar\n" self.markdown(content) toc = self.markdown.renderer.render_toc() assert '<li><a href="#foo">Foo</a></li>' in toc assert '<li><a href="#foobar">Foobar</a></li>' not in toc def test_render_toc_replace_tags(self): from marko.ext.toc import Toc markdown = Markdown(extensions=[Toc("<div>", "</div>")]) content = "#### Foobar\n" markdown(content) toc = markdown.renderer.render_toc() assert "<div>\n" in toc assert "</div>\n" in toc
class TestFootnote: def setup_method(self): self.markdown = Markdown() self.markdown.use("footnote") def test_footnote(self): result = self.markdown("this is a footnote[^1].\n\n[^1]: foo\n") assert '<sup class="footnote-ref"' in result assert 'foo<a href="#fnref-1" class="footnote">↩</a>' in result def test_non_footnote(self): result = self.markdown("foo[^1]") assert result.rstrip() == "<p>foo[^1]</p>"
def test_gemini_renderer_links() -> None: """ Test rendering links. """ gemini = Markdown(renderer=GeminiRenderer) assert (gemini.convert( """ This is a paragraph with [a link](https://example.com/). It is a good paragraph. This one [also has a link](https://example.net/). It also has some *emphasis* and **bold**. And this one is a special paragraph because it has not just [one](https://example.com/one), but [two](https://example.com/two) links. That is quite a lot. This other paragraph also has [a link][ref], using a reference. It's very fancy. [ref]: https://example.org/foo "This is foo" This one has an auto link <https://example.com/autolink>. That is it. """, ) == """ This is a paragraph with a link. It is a good paragraph. => https://example.com/ a link This one also has a link. It also has some emphasis and bold. => https://example.net/ also has a link And this one is a special paragraph because it has not just one, but two links. That is quite a lot. => https://example.com/one one => https://example.com/two two This other paragraph also has a link, using a reference. It's very fancy. => https://example.org/foo This is foo This one has an auto link https://example.com/autolink. => https://example.com/autolink https://example.com/autolink That is it. """)
class TestPangu: def setup_method(self): self.markdown = Markdown() self.markdown.use("pangu") def test_render_pangu(self): content = "中国2018年" result = self.markdown(content) assert ( result == '<p>中国<span class="pangu"></span>2018<span class="pangu"></span>年</p>\n' ) def test_chinese_punctuations(self): content = "你好:中国。" result = self.markdown(content) assert result == "<p>你好:中国。</p>\n"
def setUp(self): from marko import HTMLRenderer, Markdown from marko.ext.toc import TocRendererMixin class MyRenderer(TocRendererMixin, HTMLRenderer): pass self.markdown = Markdown(renderer=MyRenderer)
def setUp(self): from marko import Markdown, HTMLRenderer from marko.ext.pangu import PanguRendererMixin class MyRenderer(PanguRendererMixin, HTMLRenderer): pass self.markdown = Markdown(renderer=MyRenderer)
def test_gemini_renderer_link_ref_def() -> None: """ Test rendering a link definition reference. """ gemini = Markdown(renderer=GeminiRenderer) assert (gemini.convert( """ Hi, here's my [thing that I just casually mention][tt] sometimes. [tt]: gemini://my.boring/url "I like this link" """, ) == """ Hi, here's my thing that I just casually mention sometimes. => gemini://my.boring/url I like this link """)
def test_render_toc_replace_tags(self): from marko.ext.toc import Toc markdown = Markdown(extensions=[Toc("<div>", "</div>")]) content = "#### Foobar\n" markdown(content) toc = markdown.renderer.render_toc() assert "<div>\n" in toc assert "</div>\n" in toc
def compile_markdown(markdown_source: str) -> MarkdownRecipe: """ Compile a recipe grid flavoured markdown document, producing a :py:class:`MarkdownRecipe` which may be rescaled and rendered into the final HTML form as required. Internally calls :py:func:`recipe_grid.compiler.compile` and so may throw the same kinds of exceptions when syntax errors in the recipe sources are encountered. """ return cast(MarkdownRecipe, Markdown(extensions=[RecipeGrid])(markdown_source))
def setUp(self): from marko import Parser, HTMLRenderer, Markdown from marko.ext.footnote import FootnoteParserMixin, FootnoteRendererMixin class MyParser(FootnoteParserMixin, Parser): pass class MyRenderer(FootnoteRendererMixin, HTMLRenderer): pass self.markdown = Markdown(MyParser, MyRenderer)
def test_gemini_renderer_padding_after_link_ref_def() -> None: """ Test the padding after a link reference definition. Ideally we shouldn't be left with an empty line. """ gemini = Markdown(renderer=GeminiRenderer) assert (gemini.convert( """ This other paragraph also has [a link][ref], using a reference. It's very fancy. [ref]: https://example.org/foo "This is foo" That is it. """, ) == """ This other paragraph also has a link, using a reference. It's very fancy. => https://example.org/foo This is foo That is it. """)
def test_gemini_renderer_image() -> None: """ Test rendering images. """ gemini = Markdown(renderer=GeminiRenderer) assert (gemini.convert( """ This is a paragraph. ![Alt text](https://assets.digitalocean.com/articles/alligator/boo.svg "a title") ![Alt text](https://assets.digitalocean.com/articles/alligator/boo.svg) That is it. """, ) == """ This is a paragraph. => https://assets.digitalocean.com/articles/alligator/boo.svg a title => https://assets.digitalocean.com/articles/alligator/boo.svg Alt text That is it. """)
def main(): md = Markdown(parser=Parser, renderer=PptxRenderer) md_str = """ # slide title #1 slide body text slide body text slide body text slide body text # slide title #2 ## slide body paragraph #1 ## slide body paragraph #2 """ pres = md(md_str) with open("out.pptx", "wb") as f: pres.save(f)
def render_plain_text(self, element): if isinstance(element.children, str): return aguideEscape(element.children) return self.render_children(element) def render_raw_text(self, element): return aguideEscape(element.children) class AmigaGuide: elements = [HeadingTOC, ExternalLinkRef, Document, TableOfContents] renderer_mixins = [AmigaGuideMixin] markdown = Markdown(extensions=[AmigaGuide]) if len(sys.argv) != 2: print("usage: %s <foo.md>" % sys.argv[0]) sys.exit(1) infn = sys.argv[1] with open(infn, "r") as mdf: md = mdf.read() aguide = markdown.convert(md) #with open (OUTPUT_FN, "w", encoding="latin1") as outf: # outf.write(aguide)
class WikilinkRendererMixin(object): # This name is magic; it must match render_<class_name_in_snake_case>. def render_wikilink_element(self, element): return '<span class="wikilink-marker">[[</span><a href="{}">{}</a><span class="wikilink-marker">]]</span>'.format( # util.canonical_wikilink(self.escape_url(element.target)), self.render_children(element) util.canonical_wikilink(element.target), self.render_children(element)) class Wikilinks(): elements = [WikilinkElement] renderer_mixins = [WikilinkRendererMixin] markdown = Markdown(extensions=[Wikilinks]) # Org-mode -- simple but, well, bad for now. orgmode = to_html # Twitter embeds. def add_twitter_embeds(content): TWITTER_REGEX = '(https://twitter.com/\w+/status/[0-9]+)' TWITTER_EMBED = '<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><a href="\\1"></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>' return re.sub(TWITTER_REGEX, TWITTER_EMBED, content) # Trim front matter until we do something useful with it. def trim_front_matter(content): FRONT_MATTER_REGEX = '---(\n.*)*---'
""" Markdown class """ from marko import Markdown from .extensions import FlogParser, FlogRenderer markdown = Markdown(FlogParser, FlogRenderer)
def setup_method(self): self.markdown = Markdown() self.markdown.use("toc")
def setup_class(cls): cls.markdown = Markdown()
def test_codehilite_options(self): from marko.ext.codehilite import CodeHilite markdown = Markdown(extensions=[CodeHilite(linenos="table")]) content = '```python\nprint("hello")\n```' assert '<table class="highlighttable">' in markdown(content)
def get_code_emb(): markdown = Markdown(renderer=MarkdownEmbEodeRenderer) return markdown
""" Markdown class """ from marko import Markdown from marko.ext.gfm import GFMExtension from marko.ext.toc import TocExtension from marko.ext.pangu import PanguExtension from marko.ext.footnote import FootnoteExtension from .extensions import FlogExtension markdown = Markdown(extensions=[ GFMExtension, PanguExtension, TocExtension, FootnoteExtension, FlogExtension, ])
def _assert_latex(markdown: str, latex: str): md = Markdown(renderer=LatexRenderer) assert md.convert(dedent(markdown)) == dedent(latex)
"Extract a 'script' from a tutorial with commits, commands, and more.") parser.add_argument("tutorial", type=argparse.FileType("r"), help="Input tutorial") args = parser.parse_args() # Parse out the markdown header text = args.tutorial.readlines()[1:] meta = text[:text.index('---\n')] text = text[text.index('---\n') + 1:] text = ''.join(text) meta = ''.join(meta) meta = yaml.safe_load(meta) # Alternatively, you can register extensions later. markdown = Markdown(renderer=ASTRenderer) data = markdown(text) def dataKv(line): for m in re.findall('(?P<k>data-[a-z-]*)="(?P<v>[^"]*)"', line): yield (m[0][5:], m[1].strip('"')) def fixspoken(kids): text = "" for y in kids: if y['element'] != 'paragraph': continue for x in y['children']:
align = ' align="{}"'.format(element.align) return "<{tag}{align}>{children}</{tag}>\n".format( tag=tag, children=self.render_children(element), align=align ) def render_url(self, element): return self.render_link(element) class GFM(object): elements = [ elements.Paragraph, elements.ListItem, elements.Strikethrough, elements.Url, elements.Table, elements.TableRow, elements.TableCell, ] renderer_mixins = [GFMRendererMixin] GFMExtension = helpers._Deprecated(GFM) gfm = Markdown() gfm.use(GFM) def make_extension(): return GFM()
def setup_method(self): self.markdown = Markdown() self.markdown.use("footnote")
def test_gemini_renderer() -> None: """ Test ``GeminiRenderer``. """ double_space = " " gemini = Markdown(renderer=GeminiRenderer) assert (gemini.convert( f""" # Header 1 ## Header 2 ### Header 3 #### Header 4 - Mercury - Gemini - Apollo > This is{double_space} > A multiline{double_space} > blockquote{double_space} *This* is a **paragraph**. With `code`. This is an [inline link](https://example.com/). This is [another](https://example.org/). ``` This is some code. ``` End. """, ) == f""" # Header 1 ## Header 2 ### Header 3 ### Header 4 * Mercury * Gemini * Apollo > This is > A multiline > blockquote{double_space} This is a paragraph. With code. This is an inline link. This is another. => https://example.com/ inline link => https://example.org/ another ``` This is some code. ``` End. """)
def setup_method(self): self.markdown = Markdown() self.markdown.use("pangu")
""" Markdown class """ from marko import Markdown from .extensions import Flog markdown = Markdown( extensions=["gfm", "pangu", "toc", "footnote", "codehilite", Flog])
def setup_method(self): self.markdown = Markdown(extensions=["codehilite"])
def render_paragraph(self, element): children = self.render_children(element) return """<TextBlock Text="{}"/>\n""".format(children) def render_raw_text(self, element): return self.xml_escape(element.children) def render_line_break(self, element): return " " def render_literal(self, element): return self.xml_escape(element.children) @staticmethod def xml_escape(str): return _xml_escape(str, entities={"'": "'", "\"": """}) if __name__ == "__main__": __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) # Load help markdown with open(os.path.join(__location__, "help.md"), "r", encoding="utf8") as f: text = f.read() markdown = Markdown(renderer=XamlRenderer) print(markdown(text))