Skip to content

Confluence / JIRA

Import and export Confluence Wiki Markup and JIRA markup as RelationalText documents. Both dialects share the same com.atlassian.wiki.facet namespace and are nearly identical in syntax.

Package: relational-text/confluenceNamespace: com.atlassian.wiki.facet

Functions

ts
import { from, to } from 'relational-text/registry'

from('confluence', input: string): Document

Parse a Confluence wiki markup string into a Document.

ts
const doc = from('confluence', 'h1. Hello\n\nA paragraph with *bold* and _italic_ text.\n\n* Item one\n* Item two')

Supported block constructs:

  • h1.h6. — headings
  • * item / ** nested — bullet lists (supports multi-level nesting with repeated *)
  • # item / ## nested — ordered lists (supports multi-level nesting with repeated #)
  • > text — blockquote (Confluence / Discord style)
  • bq. text — blockquote (JIRA style)
  • {code} / {code:language} ... {code} — fenced code block
  • {quote} ... {quote} — block-level quote region
  • {note} / {warning} / {tip} / {info} ... {closing tag} — admonition blocks
  • ---- (four or more dashes) — horizontal rule
  • Plain text line — paragraph

Supported inline constructs:

  • *bold* — bold
  • _italic_ — italic
  • +underline+ — underline
  • -strikethrough- — strikethrough
  • ^superscript^ — superscript
  • ~subscript~ — subscript
  • {{monospace}} — inline code (monospace)
  • [display text|url] — link with display text
  • [url] — bare link

to('confluence', doc: Document): string

Render a Document to a Confluence wiki markup string.

ts
import { from, to } from 'relational-text/registry'

const doc = from('markdown', '## Hello\n\nA paragraph with **bold** and `code`.')
const markup = to('confluence', doc)
// 'h2. Hello\nA paragraph with *bold* and {{code}}.\n'

Automatically applies any registered lenses targeting com.atlassian.wiki.facet via lensGraph.autoTransform(). Documents from CommonMark, HTML, and other formats convert automatically when their lexicons are registered.

from('confluence', input: string): Document

Parse a JIRA markup string into a Document. JIRA and Confluence share the same syntax. This is an alias for from('confluence', ...) that additionally handles the bq. text blockquote prefix (which from('confluence', ...) also handles).

ts
const doc = from('confluence', 'h2. Bug Report\n\nbq. Reproduction steps here.\n\n# Step one\n# Step two')

to('jira', doc: Document): string

Render a Document to a JIRA markup string. This is an alias for to('confluence', ...) — both formats produce identical output.

ensureConfluenceLexicon(): void

Register the com.atlassian.wiki.facet lexicon and the Confluence-to-RT lens with autoApply: true. Called automatically by all import/export functions on first use. Safe to call multiple times.

Feature Mapping

Inline Marks

SyntaxFeature nameNamespaceExpand
*text*boldcom.atlassian.wiki.facetboth sides
_text_italiccom.atlassian.wiki.facetboth sides
+text+underlinecom.atlassian.wiki.facetboth sides
-text-strikethroughcom.atlassian.wiki.facetboth sides
^text^superscriptcom.atlassian.wiki.facetneither side
~text~subscriptcom.atlassian.wiki.facetneither side
{{text}}monospacecom.atlassian.wiki.facetneither side
[text|url] / [url]link (attrs: uri, display?)com.atlassian.wiki.facetentity
!image.png!imagecom.atlassian.wiki.facetentity

Block Elements

SyntaxFeature nameattrs
h1.h6.heading{ level: 1–6 }
Plain paragraphparagraph
* itembullet-list-marker, list-item-marker, list-item-text{ level? } for nesting
# itemordered-list-marker, list-item-marker, list-item-text{ level? } for nesting
> text / bq. textblockquote-marker, paragraph (parents: ['blockquote'])
{quote} blockblockquote-marker, paragraph (parents: ['blockquote'])
{code} blockcode-block{ language? }
{note} / {warning} / {tip} / {info}admonition{ type: 'note'|'warning'|'tip'|'info' }
----horizontal-rule

Lens: Confluence → RT Hub

The lens com.atlassian.wiki.to.relationaltext.v1 is invertible: false because monospace maps to RT code (shared with inline code spans from other formats) and admonition collapses to blockquote-marker.

Confluence featureRT hub featurenotes
boldboldidentity
italicitalicidentity
underlineunderlineidentity
strikethroughstrikethroughidentity
superscriptsuperscriptidentity
subscriptsubscriptidentity
monospacecodename change
linklinkrenameAttrs: { uri → url }
imageimageidentity
paragraphparagraphidentity
headingheadingidentity (level attr preserved)
code-blockcode-blockidentity
blockquote-markerblockquote-markeridentity
bullet-list-markerbullet-list-markeridentity
ordered-list-markerordered-list-markeridentity
list-item-markerlist-item-markeridentity
list-item-textlist-item-textidentity
horizontal-rulehorizontal-ruleidentity
admonitionblockquote-markertype attr dropped

Examples

Import Confluence markup

ts
import { from } from 'relational-text/registry'

const doc = from('confluence', `
h1. Project Overview

A *bold* statement with a [link|https://example.com].

* First item
* Second item

{code:python}
def hello():
    print("world")
{code}
`)

Export to Confluence

ts
import { from, to } from 'relational-text/registry'

const doc = from('markdown', '# Title\n\nParagraph with **bold** and ~~strikethrough~~.')
const markup = to('confluence', doc)
// 'h1. Title\nParagraph with *bold* and -strikethrough-.\n'

Import JIRA markup

ts
import { from } from 'relational-text/registry'

const doc = from('confluence', `
h2. Bug Description

bq. Steps to reproduce the issue.

# Open the application
# Click the button
`)

Admonition blocks

ts
import { from, to } from 'relational-text/registry'

const doc = from('confluence', '{note}\nThis is a note.\n{note}')
// Stored as: com.atlassian.wiki.facet#admonition { type: 'note' }
// Lens maps to: org.relationaltext.facet#blockquote-marker

const out = to('confluence', doc)
// '{note}\nThis is a note.\n{note}\n'

Notes

  • JIRA vs Confluence: The two formats are syntactically identical for all constructs currently supported. from('confluence', ...) / to('confluence', ...) are direct aliases for from('confluence', ...) / to('confluence', ...). The only JIRA-specific construct parsed is bq. text, which from('confluence', ...) also handles.
  • Inline regex parser: Inline parsing uses a single regular expression. This means patterns like -strikethrough- will not match if the content contains a literal -. Confluence itself has similar limitations in its regex-based parser.
  • Admonitions: {note}, {warning}, {tip}, and {info} blocks are imported as admonition features with a type attr. The lens maps them to blockquote-marker in RT (the type attr is lost). On export from RT, admonition blocks that originated in RT will render as > paragraph blockquotes rather than {note} macro blocks, because the lens is not invertible.
  • Multi-level lists: Nesting depth is encoded by repeating the list character (**, ##). The importer records a level attr on list-item-text for levels deeper than 1 and builds the parents array to represent nesting.
  • Link attrs: The link feature stores uri (the URL) and optionally display (the explicit display text). The lens renames uri to url in RT. The renderer uses [inner|uri] when inner text differs from the URI, and [uri] for bare links.
  • Unclosed blocks: If a {code}, {quote}, or admonition block is not closed before EOF, the importer flushes its accumulated content as if the closing tag were present.