A Python library for converting Atlassian Document Format (ADF) to Markdown
Project description
pyadf
A Python library for converting Atlassian Document Format (ADF) to Markdown.
Features
- Class-based API for clean, object-oriented usage
- Flexible input - accepts JSON strings, dictionaries, or any ADF node type
- Comprehensive node support:
- Text formatting (bold, italic, links)
- Headings (h1-h6)
- Lists (bullet, ordered, task lists)
- Tables with headers and column spans
- Code blocks with syntax highlighting
- Blockquotes and panels
- Status badges
- Inline cards
- Emoji (unicode and shortName)
- Type-safe with comprehensive type hints and Python 3.11+ support
- Extensible architecture with registry pattern for custom node types
- Robust error handling with detailed, context-aware error messages
- Debug mode for troubleshooting and development
Installation
pip install pyadf
Usage
Basic Usage
from pyadf import Document
# Convert ADF document to markdown
adf_data = {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{"type": "text", "text": "Hello, "},
{"type": "text", "text": "world!", "marks": [{"type": "strong"}]}
]
}
]
}
doc = Document(adf_data)
markdown_text = doc.to_markdown()
print(markdown_text)
# Output: Hello, **world!**
Converting from JSON String
from pyadf import Document
# Convert from JSON string
adf_json = '{"type": "doc", "content": [...]}'
doc = Document(adf_json)
markdown = doc.to_markdown()
Converting Individual Nodes
from pyadf import Document
# Convert a single node (any ADF node type)
node = {
"type": "heading",
"attrs": {"level": 2},
"content": [
{"type": "text", "text": "My Heading"}
]
}
doc = Document(node)
markdown = doc.to_markdown()
print(markdown)
# Output: ## My Heading
Error Handling
The library provides detailed error handling with specific exceptions:
from pyadf import Document, InvalidJSONError, UnsupportedNodeTypeError
try:
doc = Document('invalid json')
except InvalidJSONError as e:
print(f"Invalid JSON: {e}")
try:
doc = Document({"type": "unsupported_type"})
except UnsupportedNodeTypeError as e:
print(f"Unsupported node: {e}")
Debug Mode
Enable debug mode for detailed logging:
from pyadf import Document, set_debug_mode
set_debug_mode(True)
doc = Document(adf_data)
markdown = doc.to_markdown()
Customizing Markdown Output
Use MarkdownConfig to customize the generated markdown:
from pyadf import Document, MarkdownConfig
doc = Document(adf_data)
# Default bullet marker is +
doc.to_markdown() # "+ Item 1\n+ Item 2"
# Use * for bullet lists
config = MarkdownConfig(bullet_marker="*")
doc.to_markdown(config) # "* Item 1\n* Item 2"
# Use - for bullet lists
config = MarkdownConfig(bullet_marker="-")
doc.to_markdown(config) # "- Item 1\n- Item 2"
Available options:
| Option | Values | Default | Description |
|---|---|---|---|
bullet_marker |
+, -, * |
+ |
Character used for bullet list items |
Supported ADF Node Types
| ADF Node Type | Markdown Output | Notes |
|---|---|---|
doc |
Document root | Top-level container |
paragraph |
Plain text with newlines | |
text |
Text with optional formatting | Supports bold, italic, links |
heading |
# Heading (levels 1-6) |
|
bulletList |
+ Item |
|
orderedList |
1. Item |
|
taskList |
- [ ] Task |
Checkbox tasks |
codeBlock |
```language\ncode\n``` |
Optional language syntax |
blockquote |
> Quote |
|
panel |
> Panel content |
Info/warning/error boxes |
table |
Markdown table | Supports headers and colspan |
status |
**[STATUS]** |
Status badges |
inlineCard |
[link] or code block |
Link previews |
emoji |
Unicode emoji | |
hardBreak |
Line break |
Exception Types
The library provides specific exceptions for different error scenarios:
PyADFError- Base exception for all pyadf errorsInvalidJSONError- Raised when JSON parsing failsInvalidInputError- Raised when input type is incorrectInvalidADFError- Raised when ADF structure is invalidMissingFieldError- Raised when required fields are missingInvalidFieldError- Raised when field values are invalidUnsupportedNodeTypeError- Raised when encountering unsupported node typesNodeCreationError- Raised when node creation fails
All exceptions include detailed context about the error location in the ADF tree.
Development
Setting Up Development Environment
# Clone the repository
git clone https://github.com/YoungseokCh/pyadf.git
cd pyadf
# Install in development mode
pip install -e .
Running Tests
pytest
License
MIT License - see LICENSE file for details
Changelog
0.3.0 (Current)
- Added emoji node support
- Added configurable bullet markers via
MarkdownConfig
0.1.0
- Class-based API with
Documentclass - Better error handling with detailed exceptions and context
- Support for common ADF node types (doc, paragraph, text, headings, lists, tables, etc.)
- Type-safe architecture with comprehensive type hints (Python 3.11+)
- Registry pattern for extensibility
- Flexible input handling (JSON strings, dictionaries, individual nodes)
- Debug mode for troubleshooting
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyadf-0.3.0.tar.gz.
File metadata
- Download URL: pyadf-0.3.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3019659b26b8a15029078dc2ab9068c049c5e7fcaf84aec72d3092070725c98
|
|
| MD5 |
a51aa279430d7295261635a307f1a644
|
|
| BLAKE2b-256 |
63bd296ff255aa9c4183778cdb5a253ce4b28305c14140711f9df3e439194fd3
|
File details
Details for the file pyadf-0.3.0-py3-none-any.whl.
File metadata
- Download URL: pyadf-0.3.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3597ccb57857accc34ee3db6d2863b17c02b6a43d42c0c9dba563f6c6a9540a7
|
|
| MD5 |
d9882ae3fbcb32e70913fbaece1eae20
|
|
| BLAKE2b-256 |
64369813b4f17d9b1bfdc2334fb5103737508f6daa447bbeb9c49321627749b0
|