Fast Markdown to HTML renderer - GFM tables, code highlighting, XSS-safe, extensible
Project description
markdown-fast-py
Fast Markdown to HTML renderer — GFM tables, syntax highlighting, XSS-safe, extensible.
Pure Python. Zero dependencies. Production-ready.
Install
pip install markdown-fast-py
Quick Start
import markdown_fast_py as md
html = md.convert("# Hello\n\nThis is **bold** and _italic_.")
print(html)
# <h1 id="hello">Hello</h1>
# <p>This is <strong>bold</strong> and <em>italic</em>.</p>
Features
- CommonMark-compatible block and inline parsing
- GFM tables with per-column alignment
- Syntax highlighting for 15+ languages — pure Python, no external deps
- XSS sanitization — allowlist-based, strips event handlers and
javascript:URIs - Task lists (
- [x] done/- [ ] todo) - Strikethrough (
~~text~~) - Autolinks (bare URLs and
<angle-bracket>style) - Setext and ATX headings with automatic slug
idattributes - Blockquotes, fenced and indented code blocks
- Ordered and unordered lists with nesting
- Hard line breaks (
\n) - Reference-style links and images
- Extension system: footnotes, math, anchors, TOC, definition lists
- Command-line tool (
markdown-fast)
Usage
One-shot conversion
from markdown_fast_py import convert
html = convert(source)
Reusable instance
from markdown_fast_py import Markdown
md = Markdown(
highlight_code=True, # syntax-highlight fenced code blocks
sanitize=True, # strip dangerous HTML (XSS-safe)
heading_ids=True, # add id="slug" to headings
safe_links=True, # block javascript: URLs
breaks=False, # treat single newline as <br>
xhtml=False, # emit XHTML-style void elements
table_class="", # optional CSS class on <table>
extensions=[], # see Extensions section
)
html = md.render(source)
# or equivalently:
html = md.convert(source)
html = md(source) # callable
API reference
convert(text, **options) -> str
One-shot Markdown-to-HTML conversion.
| Parameter | Type | Default | Description |
|---|---|---|---|
text |
str |
— | Markdown source |
highlight_code |
bool |
True |
Syntax-highlight fenced code blocks |
sanitize |
bool |
True |
XSS-sanitize the output |
heading_ids |
bool |
True |
Add id attributes to headings |
safe_links |
bool |
True |
Block javascript: / data: hrefs |
breaks |
bool |
False |
Newlines become <br> |
xhtml |
bool |
False |
Self-closing void elements |
smart_quotes |
bool |
False |
Curly quotes |
table_class |
str |
"" |
CSS class on <table> |
extensions |
list |
[] |
Extensions to enable |
sanitize(html) -> str
Standalone XSS sanitizer — works on HTML from any source.
from markdown_fast_py import sanitize
clean = sanitize('<a href="javascript:alert(1)">click</a>')
# <a href="#">click</a>
highlight(code, language) -> str
Standalone syntax highlighter returning HTML with hl-* CSS classes.
from markdown_fast_py import highlight
html = highlight("def foo(): pass", "python")
parse(text) -> Node
Low-level AST parser. Returns a Node tree you can traverse or transform.
from markdown_fast_py import parse, NodeType
doc = parse("# Hello\n\n- item")
for child in doc.children:
print(child.type, child.level if child.type == NodeType.HEADING else "")
Syntax Highlighting
Fenced code blocks are highlighted when a language tag is provided:
```python
def hello(name: str) -> str:
return f"Hello, {name}!"
```
Supported languages
| Language | Tags |
|---|---|
| Python | python, py |
| JavaScript | javascript, js, jsx |
| TypeScript | typescript, ts, tsx |
| HTML/XML | html, xml |
| CSS/SCSS | css, scss, sass |
| JSON | json |
| SQL | sql |
| Bash/Shell | bash, sh, shell, zsh |
| Go | go, golang |
| Rust | rust, rs |
| YAML | yaml, yml |
| Diff | diff, patch |
The highlighter emits <span class="hl-*"> markup. Include the bundled theme
or write your own CSS:
from markdown_fast_py import CSS_THEME_DARK, CSS_THEME_LIGHT
# Embed in a <style> tag:
print(f"<style>{CSS_THEME_DARK}</style>")
XSS Sanitization
The sanitizer uses a strict allowlist of safe tags and attributes. Event handlers
(onclick, onload, …), <script>, <iframe>, and javascript: / data: URIs
are stripped automatically.
dangerous = '<p onclick="steal()">Hi <script>alert(1)</script></p>'
safe = convert(dangerous)
# <p>Hi </p>
Extensions
Enable built-in extensions by name or instance:
md = Markdown(extensions=["footnotes", "anchors", "toc"])
Available extensions
| Name | Class | Description |
|---|---|---|
footnotes |
FootnotesExtension |
[^1] references and definitions |
math |
MathExtension |
$inline$ and $$block$$ pass-through for MathJax/KaTeX |
anchors |
AnchorExtension |
Self-link ¶ on every heading |
toc |
TableOfContentsExtension |
Replace [TOC] with a nested <nav> |
deflist |
DefinitionListExtension |
term\n: definition → <dl> |
Custom extensions
from markdown_fast_py import Extension, Markdown
class MyExtension(Extension):
name = "mine"
def preprocess(self, text: str) -> str:
return text.replace(":rocket:", "🚀")
def postprocess_html(self, html: str) -> str:
return html.replace("TODO", '<mark>TODO</mark>')
md = Markdown(extensions=[MyExtension()])
GFM Tables
| Name | Age | City |
|---------|:---:|----------:|
| Alice | 30 | New York |
| Bob | 25 | London |
Column alignment: :--- left, ---: right, :---: centre.
Command Line
# Convert from stdin
echo "# Hello" | markdown-fast
# Convert a file
markdown-fast README.md
# Output a full HTML page with dark theme
markdown-fast --page --theme dark --title "Docs" README.md > docs.html
# Disable highlighting and sanitization
markdown-fast --no-highlight --no-sanitize input.md
# Enable extensions
markdown-fast --extensions anchors toc footnotes README.md
usage: markdown-fast [-h] [-o FILE] [--no-highlight] [--no-sanitize]
[--no-heading-ids] [--breaks] [--xhtml]
[--page] [--title TITLE] [--theme {dark,light,none}]
[--extensions [EXT ...]] [--version]
[FILE]
License
MIT © Vladyslav Zaiets
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markdown_fast_py-1.0.0.tar.gz.
File metadata
- Download URL: markdown_fast_py-1.0.0.tar.gz
- Upload date:
- Size: 25.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1100823ffdd3afaeb3f629fd263e991c7afe2b1061a4ea53d82d0a6b8d6cc02
|
|
| MD5 |
21f435f7b495c4d9f8fd95ed6369a9b7
|
|
| BLAKE2b-256 |
a76bac6fac1e2c23f10ae914211a10c6dd62388e897bae8546a3faba5d41a6ce
|
File details
Details for the file markdown_fast_py-1.0.0-py3-none-any.whl.
File metadata
- Download URL: markdown_fast_py-1.0.0-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e9e50dd0338b9ed4696432fbbe00264b9aa649dddd316ad3bf606a8e80f88d1
|
|
| MD5 |
602932ce3ceaa3e98d381116ff8af66a
|
|
| BLAKE2b-256 |
f51b366a8821ed66a31fbc0fbd46d6a4fa9c01fc96410b5096ad16d852b93178
|