md-adf
Typed Python implementation of the Markdown-ADF converter.
Install
pip install md-adf
Requires Python 3.10 or newer.
API
from md_adf import (
adf_to_markdown,
markdown_to_adf,
parse_adf,
validate_adf,
)
markdown_result = adf_to_markdown(adf_document)
print(markdown_result.value)
print(markdown_result.diagnostics)
adf_result = markdown_to_adf("## Hello\n\nThis is **ADF**.")
print(adf_result.value)
Results have this shape:
@dataclass(frozen=True)
class ConversionResult(Generic[T]):
value: T
diagnostics: list[Diagnostic]
Current ConversionOptions support:
markdown_dialect: onlygfmis supported; other values are rejected. Dict options may also usemarkdownDialect.profile:jira,confluence, andportableMarkdownare accepted for API and CLI parity, but do not change Phase 1 conversion behavior yet.validate_adf: defaults toTrue; set toFalseto skip pinned schema validation for ADF-to-Markdown input. Dict options may also usevalidateAdf.normalize_adf: accepted for future normalization controls. It is currently a no-op because Phase 1 Markdown-to-ADF output is already normalized where supported. Dict options may also usenormalizeAdf.
ADF-to-Markdown returns a string with trailing whitespace trimmed and no final newline. The CLI writes that string exactly.
CLI
md-adf to-md input.adf.json --output output.md
md-adf to-adf input.md --output output.adf.json
md-adf validate-adf input.adf.json
cat input.md | md-adf to-adf --profile jira
Supported profiles are jira, confluence, and portableMarkdown. Diagnostics are emitted as JSON lines to stderr.
Current Support
- ADF validation/parsing against a pinned ADF schema.
- ADF to Markdown for
doc,paragraph,heading,blockquote,bulletList,orderedList,listItem,codeBlock,rule, simple GFM tables, task lists, panel blockquotes, expand flattening, card link/text fallback, media link/text fallback, rich inline text fallback formention,emoji,date, andstatus,text, andhardBreak. - Markdown to ADF for paragraphs, headings, block quotes, lists, GFM task lists, code blocks, thematic breaks, GFM tables, simple
<details>/<summary>blocks as expands, text, hard breaks, soft breaks, links, images as link text fallback, and raw HTML as text fallback. - Marks for
strong,em,strike,code, andlink. - Structured diagnostics for invalid ADF roots, unsupported ADF nodes/marks, invalid containers, invalid link marks, complex table omission, task-list fallback, malformed details fallback, panel/expand/card fallback, image/media fallback, rich inline fallback, and dropped rich inline attributes.
Known Limitations
- ADF to Markdown only renders simple rectangular tables as GFM pipe tables; complex tables are omitted with diagnostics.
- Media is represented as Markdown link/text fallback; no media URL resolver or image emission exists yet.
- Markdown to ADF maps images to linked text fallback instead of ADF media nodes.
- Mixed or complex GFM task lists may fall back to ordinary list items with diagnostics.
- ADF to Markdown renders mentions, emoji, dates, and statuses as text fallbacks; Markdown to ADF keeps that text as normal text and does not recreate rich inline node IDs.
- ADF to Markdown renders panels, expands, nested expands, and cards as conservative Markdown fallbacks; Markdown to ADF supports simple raw HTML
<details>/<summary>blocks as ADF expands but keeps other fallback blockquotes, headings, text, and links as ordinary Markdown structures. - ADF to Markdown does not yet render layout nodes, extensions, or color/underline/subscript/superscript marks.
- Markdown raw HTML is preserved as text fallback except for simple supported
<details>/<summary>expand blocks; general raw HTML preservation is not available. - Unsupported ADF nodes are omitted with diagnostics.
- Markdown parser AST access is not exposed as public API yet; conversion uses real Markdown parsers internally.
Development
poetry -C packages/python run python ../../tools/conformance/run-python.py
poetry -C packages/python run pytest
poetry -C packages/python run ruff check --config ../../pyproject.toml src tests ../../tools/conformance/run-python.py
poetry -C packages/python run mypy --config-file ../../pyproject.toml src tests ../../tools/conformance/run-python.py
npm run test:packages
Shared conformance fixtures live in ../../fixtures and are run by the root just test-python command.
Metadata
Release files for md-adf 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| md_adf-0.2.2.tar.gz | 30.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| md_adf-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 84.1 kB
Release files / md_adf-0.2.2.tar.gz
| Download URL | md_adf-0.2.2.tar.gz |
|---|---|
| Size | 30.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
34f9412d2592b063d8bcd7c414a4dbaa267385ab974d66c9790e2bb4e3c3e08f
|
|
BLAKE2b-256 checksum How to use checksums |
af5bc7ebbfb7927464c569ff54e4dc231e58d8e9d1a4183b941e48a084a8b3b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.1 CPython/3.11.4 Darwin/25.5.0
|
Release files / md_adf-0.2.2-py3-none-any.whl
| Download URL | md_adf-0.2.2-py3-none-any.whl |
|---|---|
| Size | 53.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
14ab43d069a96a30e5e3d8cc88dc20d57105500b83fdffdeb15ef3730cfe2ca3
|
|
BLAKE2b-256 checksum How to use checksums |
4d0255d51ac61ffaccb92b9aa82edc9fbe9848aadd7b570975180c2ee2368a2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.1 CPython/3.11.4 Darwin/25.5.0
|