Skip to main content

adf-bridge

adf-bridge is a small, pure-Python bridge between portable GFM Markdown and a focused Jira-oriented subset of Atlassian Document Format (ADF). It returns ordinary JSON-compatible dictionaries rather than model classes.

from adf_bridge import adf_to_markdown, markdown_to_adf

created = markdown_to_adf("Hello [~accountId:557057:User-AbC]")
assert created.value["type"] == "doc"
assert adf_to_markdown(created.value).value == "Hello [~accountId:557057:User-AbC]"

API and behavior

  • markdown_image_urls(markdown, *, strict=False) -> ConversionResult[tuple[str, ...]]
  • markdown_to_adf(markdown, *, strict=False, resolved_images=()) -> ConversionResult[AdfDocument]
  • adf_to_markdown(document, *, strict=False) -> ConversionResult[str]
  • validate_adf(document) -> None
  • verify_jira_media_readback(submitted, persisted, *, resolved_images) -> None

A ConversionResult holds value and an ordered tuple of structured Diagnostic values. strict=True converts any readable-degradation warning into LossyConversionError after conversion completes. Invalid ADF, unknown constructs, and out-of-profile features always raise project-owned errors.

Blank CommonMark Markdown becomes the canonical sole empty root paragraph. Empty ADF documents also render as an empty string. GFM output is canonicalized and has no terminal newline; exact source spelling is not round-tripped.

v0.1 profile

Direct support covers paragraphs, headings, blockquotes, lists, code blocks, hard breaks, rules, tables, text, strong/emphasis/strike/code/link marks, and canonical Jira account-ID mentions. Mention IDs remain opaque; &, <, and > are source-encoded safely. Adjacent marked text uses a local mark stack, so shared presentation marks stay open across supported overlaps. Basic table-cell paragraphs and hard breaks are flattened through exact lowercase <br> with one warning per affected cell. Dates, emoji, inline cards, status, expand/panel, and unmarked media have readable warning-producing fallbacks. Inline-code line endings normalize to spaces with a diagnostic; code-block text canonicalizes to LF with one trailing newline when nonempty and warns only when that changes its semantic text.

Link, image, and card labels entity-encode their nested literal syntax, so URL labels with Markdown punctuation round-trip without retained escape backslashes. Inside table cells, nested syntax-owned values including mention IDs and link titles entity-encode pipes before GFM table parsing. Form feed is entity-encoded losslessly. Bridge-generated direct link, card, and external-media destinations are opaque values: a reversible CommonMark entity encoding preserves their exact supported characters without URL normalization. Caller-authored Markdown autolinks and used reference links instead use CommonMark/Mistune URL normalization; their raw source spelling is not an opaque-destination preservation contract and produces no diagnostic. Ordinary and readable-fallback text containing U+0000 normalizes to U+FFFD with a warning; mention IDs containing U+0000 are rejected to preserve their opaque identity. Markdown consisting only of reference definitions produces no visible ADF content and warns with markdown.reference_definitions_discarded. Values containing a character that HTML5 character references cannot preserve (such as NUL) are fatal at the bridge-generated destination attribute. Presentation marks with an unrepresentable Unicode-whitespace boundary (such as VT or NEL) preserve their text but are discarded with a warning. Ordinary/root VT and NEL text remains exact; at list or table edges a reversible source entity is used when available, or adf.boundary_whitespace_normalized documents unavoidable loss. Empty link titles and titles containing control characters are intentionally omitted with an attribute-discard warning.

Block alignment and indentation marks, and every mark on media, mediaSingle, or mediaGroup, are fatal because v0.1 has no unambiguous GFM placement for them. Linked inline code containing [ or ] is also fatal: Mistune/CommonMark cannot preserve those code-label characters exactly. A nonterminal heading hard break and an ordered list whose generated sequence exceeds nine-digit markers are rejected rather than silently changing block structure. Every break in a terminal paragraph or heading hard-break run is discarded with a warning because portable GFM has no semantic representation for it; table-cell breaks retain their <br> flattening policy. A heading's literal ATX closing-hash candidate is source-encoded to preserve trailing # text. Only the canonical sole root empty paragraph represents empty visible Markdown; other ordinary empty ADF paragraphs are fatal. The exact empty paragraph shapes produced by GFM empty list items and table cells render as canonical empty list markers and cells. Adjacent same-kind lists use equivalent alternating GFM markers to remain distinct. Empty Markdown link labels, linked images, images in headings or table cells, and unsupported table-cell shapes are rejected rather than silently dropped.

See the support matrix and diagnostics guide for details. markdown_image_urls() uses the same focused parser as conversion and returns supported image destinations in source order. Callers can supply immutable ResolvedJiraImage(source_url, media_id, collection) values to convert exact matching image URLs into Jira file media; unmapped URLs remain external. Mappings are data only: invalid, unused, duplicate-source, or duplicate Jira media-identity (media_id, collection) entries fail, and no URL normalization or Jira enrichment is performed. Markdown owns alt text for every occurrence. Managed media cannot render back to its original attachment-content URL. verify_jira_media_readback() narrowly checks persisted managed media at the same ADF paths, permitting only known Jira local IDs, sizing, occurrence keys, and nonnegative media dimensions. This package does not perform Jira lookups, network operations, CLI work, or plugin registration.

Schema and licenses

The wheel bundles the exact unmodified @atlaskit/adf-schema 57.3.4 full JSON Schema. It is checksum-verified, requires local-only $ref values, and is compiled once with defaults disabled using fastjsonschema. Project code is MIT licensed. The bundled Atlassian schema is Apache-2.0; its attribution and full license are in THIRD_PARTY_NOTICES.md.

Development

Use uv:

uv sync --all-groups
make check-ci

See CONTRIBUTING.md for the focused validation commands.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

adf_bridge-0.1.0.tar.gz (62.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

adf_bridge-0.1.0-py3-none-any.whl (47.0 kB view details)

Uploaded Python 3

File details

Details for the file adf_bridge-0.1.0.tar.gz.

File metadata

  • Download URL: adf_bridge-0.1.0.tar.gz
  • Upload date:
  • Size: 62.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for adf_bridge-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a53845a16b11f03b3ae023959c3992a069a1fe92fa6a8f697452dd7c34a143f7
MD5 534b80708e4c0ee2b863a11f35d13428
BLAKE2b-256 5e467ded60efc982686f932e3a2a6168394b7c0a0d5972881a59b5c0d09d0a6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for adf_bridge-0.1.0.tar.gz:

Publisher: publish.yml on en-ver/adf-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file adf_bridge-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: adf_bridge-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 47.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for adf_bridge-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d789f2ea2f6159f86aaa34cbc34abec34179a14e2a971626bff41c132449a3a7
MD5 7bf5448be4800c90cca54f0f488ede12
BLAKE2b-256 ed17987eaaa49cc110487bd24b986b5377e86d031f3ecd51f4e8ca74dac5c026

See more details on using hashes here.

Provenance

The following attestation bundles were made for adf_bridge-0.1.0-py3-none-any.whl:

Publisher: publish.yml on en-ver/adf-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page