Markdown2
Markdown2 is a fast and complete Python implementation of Markdown, designed to closely match the behavior of the original Perl-implemented Markdown.pl. It offers a core Markdown parser and numerous extensions, known as 'extras,' for enhanced functionality like syntax highlighting, tables, and header IDs. The library is actively maintained with periodic releases and currently supports Python 3.9 and newer.
Common errors
-
ModuleNotFoundError: No module named 'markdown2'
cause The 'markdown2' library is not installed in the current Python environment or the environment where the script is being executed.fixInstall the library using pip: `pip install markdown2` -
AttributeError: 'NoneType' object has no attribute 'group'
cause This error occurs within `markdown2`'s internal parsing when it encounters malformed HTML or specific invalid Markdown syntax, leading to a regular expression match returning None instead of a match object.fixEnsure that the input Markdown text, especially any embedded HTML, is well-formed. Consider updating to the latest `markdown2` version, as some parsing issues may have been addressed. -
Markdown.convert() missing 2 required positional arguments: 'self' and 'text'
cause The `convert` method is being called directly on the `Markdown` class (`markdown2.Markdown.convert(...)`) instead of on an instance of the `Markdown` class.fixCreate an instance of the `Markdown` class first, then call the `convert` method on that instance, or use the module-level convenience function `markdown2.markdown()`: `import markdown2; markdowner = markdown2.Markdown(); html = markdowner.convert('*Hello*');` OR `html = markdown2.markdown('*Hello*')` -
HTML not rendering well when using markdown2 converted (in Django)
cause When using `markdown2` to generate HTML within a Django template, Django's default auto-escaping feature escapes the raw HTML output, preventing it from being rendered by the browser.fixMark the `markdown2` output as 'safe' in your Django template to instruct Django not to escape the HTML: `{{ markdown_output|safe }}` -
AttributeError: 'module' object has no attribute 'inlinepatterns'
cause This error arises when code designed for the `markdown` (Python-Markdown) library, which exposes an `inlinepatterns` attribute for custom extensions, is used with the `markdown2` library, which uses a different 'extras' system.fixIf using `markdown2`, leverage its 'extras' system (e.g., `markdown2.markdown(text, extras=['extra_name'])`) or `link_patterns` functionality instead of attempting to manipulate `inlinepatterns`. If `inlinepatterns` functionality is essential, consider using the `markdown` library instead of `markdown2`.
Warnings
- deprecated The 'code-color' extra (for Pygments-based syntax highlighting) is deprecated. Use the 'fenced-code-blocks' extra instead, which offers better and more modern syntax highlighting capabilities.
- gotcha Markdown2 directly outputs HTML, including any raw HTML present in the input Markdown. If processing untrusted user-generated content, ensure you sanitize the resulting HTML with a dedicated HTML sanitizer (e.g., 'Bleach') to prevent Cross-Site Scripting (XSS) vulnerabilities.
- gotcha Inconsistent or incorrect Markdown syntax can lead to unexpected rendering. Common pitfalls include missing blank lines between paragraphs or block-level elements, lack of space after heading hashes (`#`), or incorrect indentation for lists and code blocks.
Install
-
pip install markdown2 -
pip install markdown2[all]
Imports
- markdown
from markdown2 import markdown
- Markdown
from markdown2 import Markdown
Quickstart
import markdown2
markdown_text = """
# Hello, Markdown2!
This is a paragraph with *emphasis* and **strong emphasis**.
- List item 1
- List item 2
```python
print('Hello from a code block!')
```
Checkout the [Markdown2 GitHub page](https://github.com/trentm/python-markdown2).
"""
# Basic conversion
html = markdown2.markdown(markdown_text)
print("--- Basic Conversion ---")
print(html)
# Conversion with an extra (e.g., 'fenced-code-blocks' for syntax highlighting)
html_with_extras = markdown2.markdown(markdown_text, extras=["fenced-code-blocks", "footnotes"])
print("\n--- Conversion with Extras ---")
print(html_with_extras)
# Using the class-based API
markdowner = markdown2.Markdown(extras=["tables", "header-ids"])
html_from_class = markdowner.convert("| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |\n\n### My Section")
print("\n--- Class-based Conversion with Extras ---")
print(html_from_class)