mistune Documentation
repository·main·Indexed 25 days ago
https://github.com/lepture/mistuneA fast, powerful, and extensible Python Markdown parser compatible with the CommonMark 0.31.2 specification. It features a plugin system for adding custom block and inline patterns, support for multiple renderers (HTML, Markdown, and reStructuredText), and the ability to parse Markdown into an Abstract Syntax Tree (AST). Includes a CLI for conversion and utilities for text processing and escaping.
What's inside mistune
- Mistune is a fast and powerful Python Markdown parser. It is compatible with CommonMark 0.31.2 and supports various renderers and plugins.
Customize HTMLRenderer for custom syntax
mainYou can extend
mistune.HTMLRendererto handle custom syntax by overriding specific rendering methods. For example, to wrap text enclosed in$in a specific HTML span, override thecodespanmethod.To use your custom renderer, pass an instance of it to
mistune.create_markdown(renderer=...).from mistune import HTMLRenderer, create_markdown from markupsafe import escape class MyRenderer(HTMLRenderer): def codespan(self, text): if text.startswith('$') and text.endswith('$'): return '<span class="math">' + escape(text) + '</span>' return '<code>' + escape(text) + '</code>' # use customized renderer markdown = create_markdown(renderer=MyRenderer()) print(markdown('hi `$a^2=4$`'))Enable built-in plugins in Mistune
mainMistune provides several built-in plugins for extended Markdown syntax. You can enable them using two primary methods:
- Using
mistune.create_markdown(): Pass a list of plugin names to thepluginsargument. - Using
mistune.Markdown(): Manually instantiate the class with a renderer and a list of plugin objects imported frommistune.plugins.
Note: The
speedupplugin is deprecated and ignored as its functionality is now part of the core parser.- Using
Migrate HTMLRenderer from v2 to v3
mainWhen upgrading custom renderers from Mistune v2 to v3, several method signatures in
HTMLRendererhave changed. Ensure your custom implementations match the new parameter orders and names:link: Now uses(self, text, url, title=None)instead of(self, link, text=None, title=None).image: Now uses(self, text, url, title=None)instead of(self, src, alt="", title=None).heading: Now accepts**attrsas(self, text, level, **attrs).list: Now accepts**attrsinstead of(self, text, ordered, level, start=None).list_item: Now uses(self, text)instead of(self, text, level).table_cell: Theis_headparameter is renamed toheadin(self, text, align=None, head=False).
Use community extensions for Mistune
mainBeyond the core library, the community provides specialized plugins for specific output formats:
- mistune-telegram: Converts Markdown into Telegram-compatible format.
- mistune-json: Converts Markdown into HTML-based JSON objects.
You can find these extensions on GitHub to extend Mistune's capabilities.
Use the Mistune CLI to convert Markdown
mainYou can use Mistune as a command-line tool to convert Markdown content into HTML or other formats. You can provide input via a message string, a file, or through a Unix pipe.Customize the output using a custom Renderer
mainYou can customize the generated output by subclassing
mistune.HTMLRendererand passing the instance tocreate_markdown(renderer=...). This allows you to override specific methods, such asblock_code, to implement features like syntax highlighting.import mistune from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import html class HighlightRenderer(mistune.HTMLRenderer): def block_code(self, code, info=None): if info: lexer = get_lexer_by_name(info, stripall=True) formatter = html.HtmlFormatter() return highlight(code, lexer, formatter) return '<pre><code>' + mistune.escape(code) + '</code></pre>' markdown = mistune.create_markdown(renderer=HighlightRenderer()) print(markdown('```python\nassert 1 == 1\n```'))Convert Markdown to HTML with mistune.html()
mainFor a quick and easy conversion of Markdown text to HTML with all common features enabled by default (including strikethrough, tables, and footnotes, and without HTML escaping), use the
mistune.html()function.import mistune mistune.html(YOUR_MARKDOWN_TEXT)Customize MarkdownRenderer with plugins
mainThe standardMarkdownRendereronly supports basic Markdown syntax. If you are using plugins, you must subclassMarkdownRendererand implement the corresponding rendering methods to handle the plugin tokens. Note thatMarkdownRenderermethods take(self, token, state)as arguments, unlikeHTMLRendererwhich often takes raw text.Use directives in mistune v3
mainIn mistune v3, directives are implemented using two distinct styles: reStructuredText style and fenced style. Because of these multiple styles, you cannot pass directive classes directly into the
pluginsparameter ofmistune.create_markdown. Instead, you must wrap your desired directives in eitherRSTDirectiveorFencedDirective.reStructuredText style
Inspired by reStructuredText, the syntax uses
.. directive-type:::.. directive-type:: title :option-key: option value content text hereFenced style
Inspired by
markdown-it-docutils, the syntax uses fenced code blocks:```{directive-type} title :option-key: option value content text hereimport mistune from mistune.directives import FencedDirective, RSTDirective from mistune.directives import Admonition, TableOfContents
To use Fenced style directives
markdown = mistune.create_markdown(plugins=[ 'math', 'footnotes', FencedDirective([ Admonition(), TableOfContents(), ]), ])
To use reStructuredText style directives
markdown = mistune.create_markdown(plugins=[ 'math', 'footnotes', RSTDirective([ Admonition(), TableOfContents(), ]), ])
Install Mistune via pip
mainInstall Mistune usingpip. The package has no external dependencies.Create a Mistune plugin
mainTo create a plugin in Mistune, write a function that accepts a
Markdowninstance (md) as its argument. Within this function, you can register block-level patterns, inline-level patterns, and HTML renderers.Example structure:
def my_plugin(md): # Register block level pattern md.block.register('my_block_type', BLOCK_PATTERN, parse_block_func, before='list') # Register inline level pattern md.inline.register('my_inline_type', INLINE_PATTERN, parse_inline_func, before='link') # Register HTML renderers if using the HTML renderer if md.renderer and md.renderer.NAME == 'html': md.renderer.register('my_block_type', render_block_func) md.renderer.register('my_inline_type', render_inline_func)def math(md): md.block.register('block_math', BLOCK_MATH_PATTERN, parse_block_math, before='list') md.inline.register('inline_math', INLINE_MATH_PATTERN, parse_inline_math, before='link') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('block_math', render_block_math) md.renderer.register('inline_math', render_inline_math)