A fast and complete Python implementation of Markdown with extensive extras support
npx @tessl/cli install tessl/pypi-markdown2@2.5.0markdown2 is a fast and complete Python implementation of Markdown that translates easy-to-read, easy-to-write structured text format into HTML. It closely matches the behavior of the original Perl-implemented Markdown.pl while providing extensive customization through 25+ built-in extras (extensions) for enhanced functionality like syntax highlighting, tables, footnotes, header IDs, and many advanced features.
pip install markdown2 or pip install markdown2[all] (with optional dependencies)import markdown2For class-based usage:
from markdown2 import MarkdownFor specific components:
from markdown2 import Markdown, MarkdownWithExtras, UnicodeWithAttrs, MarkdownErrorimport markdown2
# Simple conversion
html = markdown2.markdown("**bold text** and *italic text*")
print(html) # <p><strong>bold text</strong> and <em>italic text</em></p>
# Convert a file
html = markdown2.markdown_path("document.md")
# With extras (extensions)
html = markdown2.markdown(
"```python\nprint('hello')\n```",
extras=["fenced-code-blocks", "code-friendly"]
)
# Reusable processor
markdowner = Markdown(extras=["footnotes", "tables", "header-ids"])
html1 = markdowner.convert(text1)
html2 = markdowner.convert(text2)
# Pre-configured processor with common extras
from markdown2 import MarkdownWithExtras
markdowner = MarkdownWithExtras() # includes footnotes, fenced-code-blocks
html = markdowner.convert(markdown_text)markdown2 uses a processing pipeline with defined stages and an extensible extras system:
markdown() and markdown_path() for simple conversionsEssential functions for converting markdown text and files to HTML, with support for various output formats and processing options.
def markdown(
text: str,
html4tags: bool = False,
tab_width: int = 4,
safe_mode: Optional[Literal['replace', 'escape']] = None,
extras: Optional[Union[list[str], dict[str, Any]]] = None,
link_patterns: Optional[Iterable[tuple[re.Pattern, Union[str, Callable[[re.Match], str]]]]] = None,
footnote_title: Optional[str] = None,
footnote_return_symbol: Optional[str] = None,
use_file_vars: bool = False,
cli: bool = False
) -> UnicodeWithAttrs: ...
def markdown_path(
path: str,
encoding: str = "utf-8",
html4tags: bool = False,
tab_width: int = 4,
safe_mode: Optional[Literal['replace', 'escape']] = None,
extras: Optional[Union[list[str], dict[str, Any]]] = None,
link_patterns: Optional[Iterable[tuple[re.Pattern, Union[str, Callable[[re.Match], str]]]]] = None,
footnote_title: Optional[str] = None,
footnote_return_symbol: Optional[str] = None,
use_file_vars: bool = False
) -> UnicodeWithAttrs: ...Reusable markdown processor classes for efficient batch processing and advanced configuration.
class Markdown:
def __init__(
self,
html4tags: bool = False,
tab_width: int = 4,
safe_mode: Optional[Literal['replace', 'escape']] = None,
extras: Optional[Union[list[str], dict[str, Any]]] = None,
link_patterns: Optional[Iterable[tuple[re.Pattern, Union[str, Callable[[re.Match], str]]]]] = None,
footnote_title: Optional[str] = None,
footnote_return_symbol: Optional[str] = None,
use_file_vars: bool = False,
cli: bool = False
): ...
def convert(self, text: str) -> UnicodeWithAttrs: ...
def reset(self) -> None: ...
class MarkdownWithExtras(Markdown):
# Pre-configured with: footnotes, fenced-code-blocks
passExtensions that modify how text elements are processed, including line breaks, emphasis handling, and typography enhancements.
# Key extras: breaks, code-friendly, middle-word-em, smarty-pants, strike, underline
extras = ["breaks", "smarty-pants", "strike"]
html = markdown2.markdown(text, extras=extras)Extensions for enhanced code block processing, syntax highlighting, and developer-friendly features.
# Key extras: fenced-code-blocks, highlightjs-lang, pyshell
extras = ["fenced-code-blocks", "code-friendly"]
html = markdown2.markdown(code_text, extras=extras)Extensions for advanced link processing, auto-linking, and reference management.
# Key extras: link-patterns, link-shortrefs, markdown-file-links, nofollow
link_patterns = [(re.compile(r'bug #(\d+)'), r'http://bugs.example.com/\1')]
extras = {"link-patterns": link_patterns}
html = markdown2.markdown(text, extras=extras)Extensions for enhanced document structure including tables, footnotes, headers, and table of contents generation.
# Key extras: tables, footnotes, header-ids, toc, html-classes
extras = ["tables", "footnotes", "header-ids", "toc"]
html = markdown2.markdown(text, extras=extras)
# Access TOC: html.toc_htmlExtensions for specialized content types including mathematical expressions, diagrams, and interactive elements.
# Key extras: latex, mermaid, wavedrom, spoiler, admonitions, alerts
extras = ["latex", "mermaid", "admonitions"]
html = markdown2.markdown(content, extras=extras)class UnicodeWithAttrs(str):
"""Enhanced string return type with optional attributes."""
metadata: Optional[dict[str, str]] # From 'metadata' extra
toc_html: Optional[str] # From 'toc' extra
class MarkdownError(Exception):
"""Base exception for markdown processing errors."""
pass
# Type aliases
SafeMode = Literal['replace', 'escape']
ExtrasDict = dict[str, Any]
ExtrasParam = Union[list[str], ExtrasDict]
LinkPatterns = Iterable[tuple[re.Pattern, Union[str, Callable[[re.Match], str]]]]__version__: str # Package version (e.g., "2.5.4")
__version_info__: tuple[int, int, int] # Version tuple (e.g., (2, 5, 4))
__author__: str # "Trent Mick"
DEFAULT_TAB_WIDTH: int # 4def main(argv: Optional[list[str]] = None) -> None:
"""CLI entry point for markdown2 command."""
passThe package provides a markdown2 console script when installed via pip.
Basic Usage:
# Convert from file to stdout
markdown2 document.md
# Convert from stdin
echo "**bold text**" | markdown2
# Convert to file
markdown2 document.md --output document.html
# Convert multiple files
markdown2 doc1.md doc2.md doc3.mdCommand Line Options:
markdown2 [options] [files...]
Options:
--version Show version and exit
-v, --verbose More verbose output
--encoding ENCODING Specify encoding of text content (default: utf-8)
--html4tags Use HTML 4 style for empty element tags
-s MODE, --safe MODE Sanitize literal HTML ('escape' or 'replace')
-x EXTRA, --extras EXTRA
Turn on specific extras (can be used multiple times)
--use-file-vars Look for Emacs-style file variables to enable extras
--link-patterns-file FILE
Path to a link patterns file
--output FILE Output to file instead of stdout
--self-test Run internal self-tests
--compare Run against Markdown.pl for testingExamples with Extras:
# Enable multiple extras
markdown2 -x fenced-code-blocks -x tables -x footnotes document.md
# With output file
markdown2 --extras fenced-code-blocks --extras tables document.md --output doc.html
# Safe mode with HTML escaping
markdown2 --safe escape document.md
# Custom encoding
markdown2 --encoding latin-1 document.md