Skip to main content

Bidirectional converter between GitHub Flavored Markdown and Atlassian Document Format

Project description

marklas

Bidirectional conversion library between GFM (GitHub Flavored Markdown) and ADF (Atlassian Document Format).

Converts between Markdown and ADF via an intermediate AST representation.

ADF ──parser──▶ AST ──renderer──▶ Markdown
Markdown ──parser──▶ AST ──renderer──▶ ADF

Installation

pip install marklas

Usage

Markdown → ADF

from marklas.parser.md import parse
from marklas.renderer.adf import render

doc = parse("**Hello** world")
adf = render(doc)
# {
#   "type": "doc",
#   "version": 1,
#   "content": [
#     {
#       "type": "paragraph",
#       "content": [
#         {"type": "text", "text": "Hello", "marks": [{"type": "strong"}]},
#         {"type": "text", "text": " world"}
#       ]
#     }
#   ]
# }

ADF → Markdown

from typing import Any

from marklas.parser.adf import parse
from marklas.renderer.md import render

adf: dict[str, Any] = {
    "type": "doc",
    "version": 1,
    "content": [
        {
            "type": "paragraph",
            "content": [
                {"type": "text", "text": "Hello", "marks": [{"type": "strong"}]},
                {"type": "text", "text": " world"},
            ],
        }
    ],
}
doc = parse(adf)
md = render(doc)
# "**Hello** world\n"

Conversion Rules

Block

ADF AST Markdown
paragraph Paragraph(children) inline content
heading (level 1-6) Heading(level, children) # ~ ######
codeBlock (language?) CodeBlock(code, language?) ```lang\ncode\n```
blockquote BlockQuote(children) > text
bulletList > listItem BulletList(items) > ListItem(children) - item
orderedList > listItem OrderedList(items, start) > ListItem(children) 1. item
taskList > taskItem BulletList > ListItem(checked=bool) - [x] / - [ ]
decisionList > decisionItem BulletList > ListItem(checked=bool) - [x] / - [ ]
rule ThematicBreak ---
table > tableRow > tableHeader/tableCell Table(head, body, alignments) GFM table
mediaSingle > media (external) Paragraph > Image(url, alt) ![alt](url)
mediaSingle > media (non-external) Paragraph > Text("[Image: id]") [Image: id]
mediaGroup > media Paragraph > Image/Text ![alt](url) / [Image: id]
panel BlockQuote(children) > text
expand / nestedExpand (title?) BlockQuote(children) (title prepended) > title\n> text
layoutSection > layoutColumn flattened blocks columns flattened
blockCard (url) Paragraph > Link(url) [url](url)
embedCard (url) Paragraph > Link(url) [url](url)

Inline

ADF AST Markdown
text Text(text) plain text
text + strong mark Strong(children) **text**
text + em mark Emphasis(children) *text*
text + strike mark Strikethrough(children) ~~text~~
text + code mark CodeSpan(code) `code`
text + link mark Link(url, children, title?) [text](url)
hardBreak HardBreak \ + newline
SoftBreak newline
mention CodeSpan(code) `@user`
emoji Text(text) :shortName:
date CodeSpan(code) `2024-01-01`
status CodeSpan(code) `status text`
inlineCard (url) Link(url) [url](url)
Image(url, alt, title?) ![alt](url)

Not Supported

Element Behavior
ADF marks: underline, textColor, backgroundColor, subsup silently ignored
ADF blocks: extension, bodiedExtension, syncBlock, bodiedSyncBlock [type] placeholder
ADF inlines: placeholder, inlineExtension, mediaInline [type] placeholder
ADF table: colspan, rowspan expanded with empty cells
ADF table: background, colwidth attributes ignored
ADF table: non-paragraph cell content [type] placeholder
Markdown: raw HTML (block, inline) silently ignored

Development

uv sync --extra dev
uv run pytest -v
uv run black src/ tests/

Project details


Download files

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

Source Distribution

marklas-0.1.0.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

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

marklas-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: marklas-0.1.0.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for marklas-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b7f7c814eb79aea82b4038915e21c85150422c9b63341a045703a4bd956f81a0
MD5 4ab91dc9ddb3d8e70427668006a35086
BLAKE2b-256 e48b741067fa66945dcbbcc40d7e28384b5828d3090a1f2b0e13571059fcc504

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on byExist/marklas

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

File details

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

File metadata

  • Download URL: marklas-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for marklas-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57af3a6074dfd43c077bd03890e70987d62acefa5ced678e3b770181e8d4b0ba
MD5 c89a95a23f9475adc7bccfe6e3a1be35
BLAKE2b-256 38bc6146e7a6e4e5936e0cdee895dffd118c0cd41d32bd13f112845333c0c31c

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on byExist/marklas

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page