Skip to content

Repository files navigation

md2adf

⚠️ Work in Progress: This package is currently under active development and is not yet ready for production use. APIs may change without notice.

A Go package that converts Markdown to Atlassian Document Format (ADF).

Features

  • CommonMark Compliant: Built on top of goldmark, a strict CommonMark parser
  • GitHub Flavored Markdown: Full support for GFM extensions (tables, task lists, strikethrough)
  • Type-Safe: ADF structures are modeled as Go structs with full type safety
  • Extensible: Configurable via functional options pattern
  • Well-Tested: Comprehensive test coverage

Supported Markdown Elements

Block Elements

  • Paragraphs
  • Headings (levels 1-6)
  • Code blocks (fenced and indented)
  • Blockquotes
  • Horizontal rules
  • Ordered and unordered lists
  • Task lists (GFM)
  • Tables (GFM)

Inline Elements

  • Bold and italic text
  • Links (inline and autolinks)
  • Inline code
  • Strikethrough (GFM)
  • Hard line breaks

Installation

go get github.com/hrko/md2adf

Usage

Basic Usage

package main

import (
    "fmt"
    "log"

    "github.com/hrko/md2adf"
)

func main() {
    markdown := []byte(`# Hello, World!

This is a **bold** and *italic* text.

- Item 1
- Item 2
`)

    // Convert Markdown to ADF JSON
    adfJSON, err := md2adf.Convert(markdown)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(adfJSON))
}

With Options

// Disable GFM extensions
adfJSON, err := md2adf.Convert(markdown, md2adf.WithGFM(false))

// Custom handler for unsupported nodes
handler := func(nodeKind string) error {
    log.Printf("Warning: unsupported node type: %s", nodeKind)
    return nil // Continue conversion
}
adfJSON, err := md2adf.Convert(markdown, md2adf.WithUnsupportedHandler(handler))

Converting to Document Struct

// Get the ADF document as a Go struct
doc, err := md2adf.ConvertToDocument(markdown)
if err != nil {
    log.Fatal(err)
}

// Work with the document programmatically
for _, block := range doc.Content {
    // Process blocks
}

Examples

Task List

Input:

- [ ] Todo item
- [x] Done item

Output (ADF JSON):

{
  "version": 1,
  "type": "doc",
  "content": [
    {
      "type": "taskList",
      "content": [
        {
          "type": "taskItem",
          "attrs": {
            "localId": "task-1",
            "state": "TODO"
          },
          "content": [
            {
              "type": "paragraph",
              "content": [
                {
                  "type": "text",
                  "text": "Todo item"
                }
              ]
            }
          ]
        },
        {
          "type": "taskItem",
          "attrs": {
            "localId": "task-2",
            "state": "DONE"
          },
          "content": [
            {
              "type": "paragraph",
              "content": [
                {
                  "type": "text",
                  "text": "Done item"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Table

Input:

| Name  | Age |
|-------|-----|
| Alice | 30  |
| Bob   | 25  |

Output: Converted to ADF table structure with headers and cells.

Architecture

The package follows a pipeline architecture:

  1. Parse: goldmark parses Markdown into an AST
  2. Render: Custom ADF renderer traverses the AST and builds ADF structures
  3. Marshal: Go structs are marshaled to JSON

The custom renderer implements goldmark's renderer.Renderer interface, allowing it to directly translate the AST into ADF-compliant Go structs.

License

MIT

Contributing

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

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages