tomd
Convert HTML to Markdown.
tomd is a small Python library that takes an HTML string and returns the
Markdown that produced it (or an approximation, when the HTML wasn't
originally Markdown). Handy for archiving articles, scraped blog posts, or
anything else where you'd rather work with plain text than DOM trees.
Install
pip install tomd
Requires Python 3.10+.
Quickstart
import tomd
tomd.convert("<h1>Hello, world!</h1>")
# => '\n# Hello, world!\n'
Or via the class:
from tomd import Tomd
Tomd("<h1>Hello, world!</h1>").markdown
What it supports
| Markdown | HTML |
|---|---|
| Headings | <h1>–<h6> |
| Bold / italic | <b>, <strong>, <i>, <em> |
| Inline code | <code> |
| Strikethrough | <del> |
| Links | <a href="https://..."> |
| Images | <img src="..." alt="..."/> |
| Unordered lists | <ul><li>...</li></ul> |
| Ordered lists | <ol><li>...</li></ol> |
| Blockquotes | <blockquote>...</blockquote> |
| Horizontal rule | <hr/> |
| Code blocks | <pre><code>...</code></pre> |
| Tables | <table><thead>...<tbody>...</table> |
If your HTML can't be cleanly expressed in Markdown (nested layouts,
floating divs, etc.), the output will lose some structure — tomd aims at
the round-trip Markdown → HTML → Markdown case, not arbitrary HTML.
Example
from tomd import Tomd
html = """
<h1>Heading</h1>
<p><b>bold</b> and <i>italic</i> and <a href="https://example.com">a link</a></p>
<ul>
<li>one</li>
<li>two</li>
</ul>
<blockquote>a quote</blockquote>
"""
print(Tomd(html).markdown)
# Heading
**bold** and *italic* and [a link](https://example.com)
- one
- two
> a quote
Development
git clone https://github.com/elliotgao2/tomd.git
cd tomd
uv sync # install deps into .venv
uv run pytest # run tests
uv run ruff check . # lint
We use uv for packaging and ruff for lint + format. Install the pre-commit hooks:
uv run pre-commit install
Roadmap
- Headings, emphasis, links, images, lists, blockquotes, tables, HR, code blocks
- Nested lists
- CLI (
tomd < input.html > output.md)
Contributing
Pull requests are welcome. For non-trivial changes, please open an issue
first to discuss. Make sure uv run pytest and uv run ruff check . pass
before submitting.
License
MIT © Elliot Gao
Metadata
Release files for tomd 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| tomd-1.1.0.tar.gz | 12.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tomd-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.5 kB
Release files / tomd-1.1.0.tar.gz
| Download URL | tomd-1.1.0.tar.gz |
|---|---|
| Size | 12.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c810e6cd370ceebedee547cdcd776382787126ac0dc0afaa3ba0b78891b45256
|
|
BLAKE2b-256 checksum How to use checksums |
3040a8e3e2eb9e2046bfc342baa445077454921aaebfd9e7ad2c9c67ee3b0c68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.9
|
Release files / tomd-1.1.0-py3-none-any.whl
| Download URL | tomd-1.1.0-py3-none-any.whl |
|---|---|
| Size | 7.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de66beb25670e49055402927d3d36abfea144fd597fcfb793acec57c36b8eb70
|
|
BLAKE2b-256 checksum How to use checksums |
3f626da8a58520e3c7bbfe286993e1075fe2c8b1d81b22ee07981c32adc96325
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.9
|
Security for tomd 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.