
Convert Confluence Atlassian Document Format to Markdown and back; fetch and update pages or templates, manage attachments and comments, and customize node transformers/transcribers.
Transcribe is a library for programmatically interacting with Confluence. It converts between Atlassian Document Format and Markdown.
Supported use cases:
Configure Transcribe with a TranscribeConfiguration. You will typically provide:
your-site from https://your-site.atlassian.net/wiki/...)val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(
ConfluenceConfiguration(
siteName = "your-site",
authMaterial = AtlassianAuthMaterial(
email = "your-email@example.com",
apiToken = "your-api-token"
)
)
)
.build()
val transcribe = Transcribe(configuration)val result = transcribe.getPageMarkdown(pageUrl)
val markdown = result.markdown
val attachments = result.attachmentResults
val comments = result.commentResultThis returns a PageMarkdownResult containing:
AttachmentResult objects with downloaded image data. These will typically represent visual elements from the confluence page and are translated into image elements in the markdown body.CommentResult object containing inline comments and footer comments from the page, with each comment converted to Markdown format.Each AttachmentResult provides:
Each CommentResult provides:
Each Comment includes:
This allows you to optionally save images to disk and the recommended path to save them relative to the markdown (the image elements in markdown will reference these relative paths.)
For example, the returned markdown might look like:
# My Page
Here is some content with an image:
The corresponding AttachmentResult would have localRelativePath = "images/screenshot.png" and contain the image bytes in data.
val markdown = """
# My Page
Updated content goes here.
""".trimIndent()
val updatedPage = transcribe.updatePageMarkdown(
url = pageUrl,
markdown = markdown,
message = "Updated via Transcribe" // optional version message
)This converts the Markdown to ADF and updates the page. Returns a PageResponse with the updated page metadata.
Alternatively, if you already have the page ID, you can use updatePageMarkdownByPageId:
val updatedPage = transcribe.updatePageMarkdownByPageId(
pageId = "123456",
markdown = markdown,
message = "Updated via Transcribe" // optional version message
)val markdown = """
# Template Title
Template content goes here.
""".trimIndent()
val updatedTemplate = transcribe.updateTemplateMarkdown(
templateId = "template-id",
markdown = markdown,
name = "My Template"
)This converts the Markdown to ADF and updates the template. Returns a TemplateResponse with the updated template metadata.
There are two mechanisms for customizing transcription between Confluence and Markdown.
You can transform ADF nodes at two points in the pipeline using the ADFTransformer interface:
// Example transformer that filters out specific node types
class FilteringTransformer<Context> : ADFTransformer<Context> {
override fun transform(
nodes: List<ADFBlockNode>,
context: Context
): List<ADFBlockNode> {
return nodes.filter { node ->
// Filter out table nodes, for example
node !is TableNode
}
}
}
// Apply transformers in configuration
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.toMarkdownTransformer(FilteringTransformer())
.toConfluenceTransformer(FilteringTransformer())
.build()Translation between ADF and Markdown nodes is handled by Transcribers. You can override the default transcriber for any element type in either direction.
ADF to Markdown — Use adfCustomTranscribers to override how ADF nodes are converted to Markdown:
val customAdfTranscribers = adfNodeMapper {
// Override the paragraph transcriber
add<ParagraphNode> { mapper -> CustomParagraphNodeTranscriber(mapper) }
// Override the heading transcriber
add<HeadingNode> { mapper -> CustomHeadingNodeTranscriber(mapper) }
}
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.adfCustomTranscribers(customAdfTranscribers)
.build()Markdown to ADF — Use markdownCustomTranscribers to override how Markdown elements are converted to ADF:
val customMarkdownTranscribers = markdownNodeMapper {
// Override the paragraph transcriber
add(MarkdownElementTypes.PARAGRAPH) { mapper -> CustomParagraphTranscriber(mapper) }
// Override the code fence transcriber
add(MarkdownElementTypes.CODE_FENCE) { CustomCodeFenceTranscriber() }
}
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.markdownCustomTranscribers(customMarkdownTranscribers)
.build()See DefaultADFNodeMap.kt and DefaultMarkdownNodeMap.kt for the full list of default transcriber mappings.
Transcribe is a library for programmatically interacting with Confluence. It converts between Atlassian Document Format and Markdown.
Supported use cases:
Configure Transcribe with a TranscribeConfiguration. You will typically provide:
your-site from https://your-site.atlassian.net/wiki/...)val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(
ConfluenceConfiguration(
siteName = "your-site",
authMaterial = AtlassianAuthMaterial(
email = "your-email@example.com",
apiToken = "your-api-token"
)
)
)
.build()
val transcribe = Transcribe(configuration)val result = transcribe.getPageMarkdown(pageUrl)
val markdown = result.markdown
val attachments = result.attachmentResults
val comments = result.commentResultThis returns a PageMarkdownResult containing:
AttachmentResult objects with downloaded image data. These will typically represent visual elements from the confluence page and are translated into image elements in the markdown body.CommentResult object containing inline comments and footer comments from the page, with each comment converted to Markdown format.Each AttachmentResult provides:
Each CommentResult provides:
Each Comment includes:
This allows you to optionally save images to disk and the recommended path to save them relative to the markdown (the image elements in markdown will reference these relative paths.)
For example, the returned markdown might look like:
# My Page
Here is some content with an image:
The corresponding AttachmentResult would have localRelativePath = "images/screenshot.png" and contain the image bytes in data.
val markdown = """
# My Page
Updated content goes here.
""".trimIndent()
val updatedPage = transcribe.updatePageMarkdown(
url = pageUrl,
markdown = markdown,
message = "Updated via Transcribe" // optional version message
)This converts the Markdown to ADF and updates the page. Returns a PageResponse with the updated page metadata.
Alternatively, if you already have the page ID, you can use updatePageMarkdownByPageId:
val updatedPage = transcribe.updatePageMarkdownByPageId(
pageId = "123456",
markdown = markdown,
message = "Updated via Transcribe" // optional version message
)val markdown = """
# Template Title
Template content goes here.
""".trimIndent()
val updatedTemplate = transcribe.updateTemplateMarkdown(
templateId = "template-id",
markdown = markdown,
name = "My Template"
)This converts the Markdown to ADF and updates the template. Returns a TemplateResponse with the updated template metadata.
There are two mechanisms for customizing transcription between Confluence and Markdown.
You can transform ADF nodes at two points in the pipeline using the ADFTransformer interface:
// Example transformer that filters out specific node types
class FilteringTransformer<Context> : ADFTransformer<Context> {
override fun transform(
nodes: List<ADFBlockNode>,
context: Context
): List<ADFBlockNode> {
return nodes.filter { node ->
// Filter out table nodes, for example
node !is TableNode
}
}
}
// Apply transformers in configuration
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.toMarkdownTransformer(FilteringTransformer())
.toConfluenceTransformer(FilteringTransformer())
.build()Translation between ADF and Markdown nodes is handled by Transcribers. You can override the default transcriber for any element type in either direction.
ADF to Markdown — Use adfCustomTranscribers to override how ADF nodes are converted to Markdown:
val customAdfTranscribers = adfNodeMapper {
// Override the paragraph transcriber
add<ParagraphNode> { mapper -> CustomParagraphNodeTranscriber(mapper) }
// Override the heading transcriber
add<HeadingNode> { mapper -> CustomHeadingNodeTranscriber(mapper) }
}
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.adfCustomTranscribers(customAdfTranscribers)
.build()Markdown to ADF — Use markdownCustomTranscribers to override how Markdown elements are converted to ADF:
val customMarkdownTranscribers = markdownNodeMapper {
// Override the paragraph transcriber
add(MarkdownElementTypes.PARAGRAPH) { mapper -> CustomParagraphTranscriber(mapper) }
// Override the code fence transcriber
add(MarkdownElementTypes.CODE_FENCE) { CustomCodeFenceTranscriber() }
}
val configuration = TranscribeConfiguration.builder()
.confluenceConfiguration(confluenceConfig)
.markdownCustomTranscribers(customMarkdownTranscribers)
.build()See DefaultADFNodeMap.kt and DefaultMarkdownNodeMap.kt for the full list of default transcriber mappings.