Meziantou.Framework.AtlassianDataFormat 1.0.1

Prefix Reserved
dotnet add package Meziantou.Framework.AtlassianDataFormat --version 1.0.1
                    
NuGet\Install-Package Meziantou.Framework.AtlassianDataFormat -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Meziantou.Framework.AtlassianDataFormat" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Meziantou.Framework.AtlassianDataFormat" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Meziantou.Framework.AtlassianDataFormat" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Meziantou.Framework.AtlassianDataFormat --version 1.0.1
                    
#r "nuget: Meziantou.Framework.AtlassianDataFormat, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Meziantou.Framework.AtlassianDataFormat@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Meziantou.Framework.AtlassianDataFormat&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Meziantou.Framework.AtlassianDataFormat&version=1.0.1
                    
Install as a Cake Tool

Meziantou.Framework.AtlassianDataFormat

Meziantou.Framework.AtlassianDataFormat provides:

  • A typed object model for the Atlassian Document Format (ADF), the JSON rich-text format used by Jira, Confluence, and Bitbucket (AdfDocument, AdfNode, AdfMark, ...)
  • A Markdown converter with per-node options for the ADF constructs Markdown cannot express (AdfToMarkdown)

Convert a document to Markdown

using Meziantou.Framework.AtlassianDataFormat;

var json = """
    {
      "version": 1,
      "type": "doc",
      "content": [
        { "type": "heading", "attrs": { "level": 1 }, "content": [ { "type": "text", "text": "Title" } ] },
        { "type": "paragraph", "content": [ { "type": "text", "text": "Hello", "marks": [ { "type": "strong" } ] } ] }
      ]
    }
    """;

var markdown = AdfToMarkdown.Convert(json);

// # Title
//
// **Hello**

Convert also accepts a JsonElement or a JsonNode, which avoids a round trip when the document comes from an API response you already parsed.

Configure the conversion

Defaults produce plain CommonMark/GitHub-Flavored Markdown; HTML output is opt-in.

var markdown = AdfToMarkdown.Convert(json, new AdfToMarkdownOptions
{
    PanelStyle = AdfPanelStyle.GitHubAlert,      // > [!WARNING]
    ExpandStyle = AdfExpandStyle.HtmlDetails,    // <details><summary>…</summary>
    TableStyle = AdfTableStyle.Auto,             // pipe table, or HTML when cells span rows/columns
    MediaRendering = AdfMediaRendering.Link,
    EmojiRendering = AdfEmojiRendering.ShortName,
    TaskListStyle = AdfTaskListStyle.Checkbox,
    DecisionListStyle = AdfDecisionListStyle.BulletList,
    UnknownNodeHandling = AdfUnknownNodeHandling.KeepContent,
    MentionFormat = "@{text}",
    StatusFormat = "**[{text}]**",
    DateFormat = "yyyy-MM-dd",
    HeadingStyle = AdfHeadingStyle.Atx,
    EmphasisMarker = AdfEmphasisMarker.Asterisk,
    CodeBlockStyle = AdfCodeBlockStyle.Fenced,
    LineBreakStyle = AdfLineBreakStyle.Backslash,
});

Resolving media and mentions

Only media of type external carries a URL. Files stored by Atlassian carry an identifier and a collection, and turning those into a URL needs an authenticated call to the media API. Documents returned by the APIs also often omit the display name of a mention. Both can be supplied by a callback:

var markdown = AdfToMarkdown.Convert(json, new AdfToMarkdownOptions
{
    MediaUrlResolver = media => $"https://media.example.com/{media.Collection}/{media.Id}",
    MentionResolver = mention => directory.GetDisplayName(mention.Id),
});

Work with the object model

var document = AdfDocument.Parse(json);

foreach (var mention in document.Descendants().OfType<AdfMention>())
{
    Console.WriteLine(mention.Id);
}

var heading = (AdfHeading)document.Content[0];
Console.WriteLine(heading.Level); // 1

var markdown = document.ToMarkdown();
var roundTripped = document.ToJsonString();

Documents can also be built from scratch:

var document = new AdfDocument
{
    Content =
    [
        new AdfHeading { Level = 1, Content = [new AdfText { Text = "Title" }] },
        new AdfParagraph { Content = [new AdfText { Text = "Hello", Marks = [new AdfStrongMark()] }] },
    ],
};

Console.WriteLine(document.ToJsonString());

Unknown nodes

Atlassian adds node types regularly, and real documents contain nodes such as unsupportedBlock. Parsing never fails on an unknown type: it produces an AdfUnknownNode that keeps the original JSON, so the document round-trips unchanged. AdfToMarkdownOptions.UnknownNodeHandling controls whether such a node is skipped, has its content converted, or throws.

Supported nodes and marks

Nodes: blockCard, blockquote, bodiedExtension, bulletList, caption, codeBlock, date, decisionItem, decisionList, embedCard, emoji, expand, extension, hardBreak, heading, inlineCard, inlineExtension, layoutColumn, layoutSection, listItem, media, mediaGroup, mediaInline, mediaSingle, mention, nestedExpand, orderedList, panel, paragraph, placeholder, rule, status, table, tableCell, tableHeader, tableRow, taskItem, taskList, text.

Marks: alignment, annotation, backgroundColor, border, breakout, code, em, indentation, link, strike, strong, subsup, textColor, underline.

Marks with no Markdown equivalent — underline, textColor, backgroundColor, annotation, border, alignment, indentation, breakout — are dropped, and the text they carry is kept. subsup becomes <sub> or <sup>.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net11.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 94 9/6/2026
1.0.0 96 8/28/2026