1
0
Fork
You've already forked mf2dom
0
Microformats2 (mf2) parser and deterministic renderer powered by JustHTML.
  • Python 70%
  • TypeScript 29.2%
  • JavaScript 0.5%
  • Makefile 0.3%
2026年05月18日 15:01:31 +02:00
src chore: release 0.2.1 2026年05月18日 09:00:53 -04:00
tests feat: show pronouns after name 2026年05月18日 08:58:30 -04:00
.gitignore Remove old file 2025年12月16日 14:40:57 -05:00
.gitmodules chore: use submodule for tests 2025年12月21日 20:03:48 -05:00
.pre-commit-config.yaml Initial version 2025年12月16日 11:43:00 -05:00
LICENSE.md First version 2025年12月16日 14:37:34 -05:00
Makefile feat: npm package 2026年01月11日 16:45:51 -05:00
pyproject.toml chore: release 0.2.1 2026年05月18日 09:00:53 -04:00
README.md Update docs 2026年01月10日 17:10:52 -05:00
uv.lock chore: release 0.2.1 2026年05月18日 09:00:53 -04:00

mf2dom

Microformats2 (mf2) parser and deterministic renderer powered by JustHTML.

mf2dom focuses on:

  • Correct mf2 parsing (validated against the official microformats-tests suite)
  • Deterministic HTML rendering and stable round-trips (HTML -> mf2 -> HTML)
  • A small runtime surface area (no network I/O, no BeautifulSoup)

Installation

pip install mf2dom

Requires Python 3.11+.

Quickstart

Parse mf2 JSON from HTML:

import mf2dom
html = '<a class="h-card u-url p-name" href="/me">Alice</a>'
doc = mf2dom.parse(html, base_url="https://example.com/")
print(doc["items"])

The parsed document is a dict with items, rels, and rel-urls keys (mf2 JSON shape).

Render mf2 JSON back into canonical HTML:

html2 = mf2dom.render(doc)

Async parsing (offloads to a thread):

doc = await mf2dom.parse_async(html, base_url="https://example.com/")

API

  • mf2dom.parse(html, *, base_url=None, url=None) -> dict
    • html can be a string/bytes, a justhtml.JustHTML instance, or a JustHTML root node.
    • base_url controls resolution of relative URLs (preferred). url is a deprecated alias.
  • mf2dom.parse_async(...) is parse(...) via asyncio.to_thread(...).
  • mf2dom.render(doc) -> str renders a deterministic HTML representation of an mf2 document.

JavaScript/TypeScript Renderer

A TypeScript implementation of the renderer is available in src/mf2dom-ts/ for client-side rendering (e.g., with sql-wasm.js).

Installation

cd src/mf2dom-ts
npm install
npm run build

Usage

ES Module:

import { render, renderItemElement, renderItems } from './dist/mf2dom.esm.js';
// Render full document to HTML string
const html = render(mf2Document);
// Render to DOM element (most efficient for client-side)
const main = render(mf2Document, { asElement: true });
document.body.appendChild(main);
// Render single item
const card = renderItemElement(hCard);
// Batch render with DocumentFragment (efficient for lists)
const fragment = renderItems(entries);
container.appendChild(fragment);

Browser script tag:

<script src="dist/mf2dom.min.js"></script>
<script>
 const html = mf2dom.render(doc);
 // or
 const el = mf2dom.render(doc, { asElement: true });
</script>

Build Output

File Size Use Case
dist/mf2dom.esm.js 5.2kb ES modules (bundlers, modern browsers)
dist/mf2dom.cjs 5.7kb CommonJS (Node.js)
dist/mf2dom.min.js 5.7kb Browser <script> tag

Why mf2dom vs mf2py?

Both libraries parse microformats, but they optimize for different use cases:

  • Choose mf2dom if you need deterministic rendering, stable round-trips, and a smaller/no-network runtime surface (useful for normalization, caching, and "canonical mf2 HTML" fixtures).
  • Choose mf2py if you need URL fetching, microformats1 compatibility, metaformats support, or wider Python version support.

Testing & correctness

  • Official parsing fixtures: tests/test_official_microformats_suite.py runs the upstream microformats-tests JSON fixtures.
  • Coverage gate: pyproject.toml enforces 100% branch coverage.

To run the official fixture suite locally, check out microformats-tests as a sibling directory:

git clone https://github.com/microformats/microformats-tests ../microformats-tests

Development (uv)

uv sync --group dev
uv run pytest
uv run coverage run -m pytest && uv run coverage report
uv run pre-commit install

License

AGPL 3