mdadf

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 27, 2026 License: MIT Imports: 7 Imported by: 0

README

mdadf

A Go library that converts Markdown to Atlassian Document Format (ADF) for use with Jira and Confluence APIs.

Installation

go get github.com/ericmason/mdadf

Usage

package main

import (
	"fmt"
	"log"

	adf "github.com/ericmason/mdadf"
)

func main() {
	markdown := `# Hello World

This is **bold** and *italic* text with a [link](https://example.com).

- Item 1
- Item 2

` + "```go\nfmt.Println(\"Hello\")\n```"

	// Convert to JSON bytes
	jsonBytes, err := adf.Convert(markdown)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(jsonBytes))

	// Or convert to Document struct
	doc, err := adf.ConvertToDoc(markdown)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Document has %d top-level nodes\n", len(doc.Content))
}

Supported Markdown Elements

Markdown ADF Output
# Heading heading (levels 1-6)
Paragraph paragraph
**bold** text with strong mark
*italic* text with em mark
`code` text with code mark
~~strike~~ text with strike mark
[link](url) text with link mark
- item bulletList > listItem
1. item orderedList > listItem
```lang codeBlock with language
> quote blockquote
--- rule
| table | table > tableRow > tableCell
![img](url) text with link mark (fallback)

ADF Output Example

Input:

# Hello

This is **bold** text.

Output:

{
  "version": 1,
  "type": "doc",
  "content": [
    {
      "type": "heading",
      "attrs": {"level": 1},
      "content": [{"type": "text", "text": "Hello"}]
    },
    {
      "type": "paragraph",
      "content": [
        {"type": "text", "text": "This is "},
        {"type": "text", "text": "bold", "marks": [{"type": "strong"}]},
        {"type": "text", "text": " text."}
      ]
    }
  ]
}

Helper Functions

The library provides helper functions to programmatically build ADF documents:

// Create nodes
para := adf.ParagraphNode(adf.TextNode("Hello"))
heading := adf.HeadingNode(1, adf.TextNode("Title"))
list := adf.BulletListNode(
	adf.ListItemNode(adf.ParagraphNode(adf.TextNode("Item 1"))),
	adf.ListItemNode(adf.ParagraphNode(adf.TextNode("Item 2"))),
)

// Create text with marks
bold := adf.TextNode("bold", adf.StrongMark())
italic := adf.TextNode("italic", adf.EmMark())
link := adf.TextNode("click here", adf.LinkMark("https://example.com", ""))
code := adf.TextNode("code", adf.CodeMark())

// Multiple marks
boldItalic := adf.TextNode("bold and italic", adf.StrongMark(), adf.EmMark())

Command Line Tool

The repository includes a command-line tool mdadf for converting markdown files:

# Build the tool
go build -o mdadf ./cmd/mdadf

# Convert a markdown file
./mdadf input.md > output.json

# Compact output (no indentation)
./mdadf -c input.md > output.json

# Read from stdin
echo "# Hello" | ./mdadf

Pre-built binaries are available in the Releases section.

Notes

  • Images are converted to links since ADF media requires Atlassian-specific IDs
  • HTML blocks are preserved as plain text
  • GFM extensions (tables, strikethrough) are supported via goldmark

Release Process

Releases are created automatically via GitHub Actions when a version tag is pushed.

Creating a Release
  1. Update version: Make any necessary code changes
  2. Commit changes:
    git add .
    git commit -m "Your commit message"
    git push
    
  3. Create and push tag:
    git tag v0.1.2
    git push origin v0.1.2
    

The release workflow will automatically:

  • Build binaries for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64, arm64)
  • Generate SHA256 checksums for all binaries
  • Create a GitHub release with all assets
  • Generate release notes from commits
Version Numbering

Follow Semantic Versioning:

  • MAJOR.MINOR.PATCH (e.g., v1.0.0)
  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)

Pre-release versions can use tags like v1.0.0-alpha.1 or v1.0.0-beta.1.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Convert

func Convert(markdown string) ([]byte, error)

Convert transforms markdown text to ADF JSON bytes

Types

type CodeBlockAttrs

type CodeBlockAttrs struct {
	Language string `json:"language,omitempty"`
}

CodeBlockAttrs holds attributes for code block nodes

type Document

type Document struct {
	Version int    `json:"version"`
	Type    string `json:"type"`
	Content []Node `json:"content"`
}

Document represents the root ADF document

func ConvertToDoc

func ConvertToDoc(markdown string) (*Document, error)

ConvertToDoc transforms markdown to an ADF Document struct

func NewDocument

func NewDocument() *Document

NewDocument creates a new ADF document with version 1

type HeadingAttrs

type HeadingAttrs struct {
	Level int `json:"level"`
}

HeadingAttrs holds attributes for heading nodes

type LinkAttrs

type LinkAttrs struct {
	Href  string `json:"href"`
	Title string `json:"title,omitempty"`
}

LinkAttrs holds attributes for link marks

type Mark

type Mark struct {
	Type  string          `json:"type"`
	Attrs json.RawMessage `json:"attrs,omitempty"`
}

Mark represents text formatting (bold, italic, code, link, etc.)

func CodeMark

func CodeMark() Mark

CodeMark creates an inline code mark

func EmMark

func EmMark() Mark

EmMark creates an italic/emphasis mark

func LinkMark

func LinkMark(href, title string) Mark

LinkMark creates a link mark with href and optional title

func StrikeMark

func StrikeMark() Mark

StrikeMark creates a strikethrough mark

func StrongMark

func StrongMark() Mark

StrongMark creates a bold/strong mark

func UnderlineMark

func UnderlineMark() Mark

UnderlineMark creates an underline mark

type MediaAttrs

type MediaAttrs struct {
	Type       string `json:"type"`
	ID         string `json:"id,omitempty"`
	Collection string `json:"collection,omitempty"`
	URL        string `json:"url,omitempty"`
	Alt        string `json:"alt,omitempty"`
	Width      int    `json:"width,omitempty"`
	Height     int    `json:"height,omitempty"`
}

MediaAttrs holds attributes for media nodes

type MediaSingleAttrs

type MediaSingleAttrs struct {
	Layout string `json:"layout,omitempty"`
}

MediaSingleAttrs holds attributes for mediaSingle nodes

type Node

type Node struct {
	Type    string          `json:"type"`
	Text    string          `json:"text,omitempty"`
	Content []Node          `json:"content,omitempty"`
	Marks   []Mark          `json:"marks,omitempty"`
	Attrs   json.RawMessage `json:"attrs,omitempty"`
}

Node represents any ADF node (block or inline)

func BlockquoteNode

func BlockquoteNode(content ...Node) Node

BlockquoteNode creates a blockquote node

func BulletListNode

func BulletListNode(items ...Node) Node

BulletListNode creates a bullet list node

func CodeBlockNode

func CodeBlockNode(language string, content ...Node) Node

CodeBlockNode creates a code block node

func HardBreakNode

func HardBreakNode() Node

HardBreakNode creates a hard break (line break) node

func HeadingNode

func HeadingNode(level int, content ...Node) Node

HeadingNode creates a heading node with the specified level

func ListItemNode

func ListItemNode(content ...Node) Node

ListItemNode creates a list item node

func OrderedListNode

func OrderedListNode(items ...Node) Node

OrderedListNode creates an ordered list node

func ParagraphNode

func ParagraphNode(content ...Node) Node

ParagraphNode creates a paragraph node with content

func RuleNode

func RuleNode() Node

RuleNode creates a horizontal rule node

func TableCellNode

func TableCellNode(content ...Node) Node

TableCellNode creates a table cell node

func TableHeaderNode

func TableHeaderNode(content ...Node) Node

TableHeaderNode creates a table header cell node

func TableNode

func TableNode(rows ...Node) Node

TableNode creates a table node

func TableRowNode

func TableRowNode(cells ...Node) Node

TableRowNode creates a table row node

func TextNode

func TextNode(text string, marks ...Mark) Node

TextNode creates a text node with optional marks

type OrderedListAttrs

type OrderedListAttrs struct {
	Order int `json:"order,omitempty"`
}

OrderedListAttrs holds attributes for ordered list nodes

type TableAttrs

type TableAttrs struct {
	IsNumberColumnEnabled bool   `json:"isNumberColumnEnabled,omitempty"`
	Layout                string `json:"layout,omitempty"`
}

TableAttrs holds attributes for table nodes

type TableCellAttrs

type TableCellAttrs struct {
	ColSpan int `json:"colspan,omitempty"`
	RowSpan int `json:"rowspan,omitempty"`
}

TableCellAttrs holds attributes for table cell/header nodes

Directories

Path Synopsis
cmd
mdadf command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL