Skip to content

Formats Overview

RelationalText supports 40+ input/output formats. All formats are accessible through the generic from / to dispatcher or via their dedicated module functions.

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

const doc = from('markdown', '**Hello** world')
const html = to('html', doc)

Rich Text Editors

Editor formats use a JSON wire format representing the editor's internal document state. Each editor has its own node/mark type system; RelationalText uses the editor's native type strings as feature names (transliteration principle). All editor adapters register both their lexicon and a lens to CommonMark via ensureXxxLexicon().

Format keyfromtoWire typeNotes
prosemirrorJSON stringProseMirror doc JSON, org.prosemirror.facet namespace
tiptapJSON stringTipTap doc JSON, dev.tiptap.facet namespace
quillJSON stringQuill Delta JSON, org.quilljs.delta.facet namespace
lexicalJSON stringLexical editor JSON, io.lexical.facet namespace
slateJSON stringSlate editor JSON, rocks.slate.facet namespace

Markup Languages

Markup language adapters work with string wire formats. All formats use ensureXxxLexicon() for registration. Extended markup formats (MDX, MyST, GitLab, etc.) additionally register a lens to CommonMark.

Format keyfromtoWire typeNotes
markdownstringCommonMark 0.31, org.commonmark.facet namespace
gfmstringAlias for markdown; GFM extensions auto-registered
htmlstringWHATWG HTML, org.w3c.html.facet namespace
mdxstringMDX (Markdown + JSX), org.mdx.facet namespace
myststringMyST Markdown, org.myst.facet namespace
pandocstringPandoc markdown, org.pandoc.facet namespace
multimarkdownstringMultiMarkdown
gitlabstringGitLab Flavored Markdown, org.gitlab.facet namespace
markdocstringMarkdoc, com.markdoc.facet namespace

Social Platforms

Social platform adapters handle platform-specific wire formats (constrained HTML, custom markdown dialects, or structured JSON). Each registers its lexicon and a lens to CommonMark, enabling seamless cross-platform conversion.

Format keyfromtoWire typeNotes
blueskyJSON stringatproto { text, facets } wire format
mastodonstringActivityPub constrained HTML, org.joinmastodon.facet
slackstringSlack mrkdwn, com.slack.mrkdwn.facet
discordstringDiscord markdown, com.discord.facet
telegramstringTelegram Bot API entities, org.telegram.facet
whatsappstringWhatsApp formatting, com.whatsapp.facet
linkedinstringLinkedIn markdown, com.linkedin.facet
threadsstringThreads / Instagram, com.threads.facet

Note-Taking & Wikis

Note-taking and wiki adapters support a wide range of formats — from proprietary app exports (Notion, Roam) to open wiki syntaxes (DokuWiki, MediaWiki). Import-only formats (roam, logseq) do not support export; use a lens to convert to a supported output format.

Format keyfromtoWire typeNotes
notionJSON stringNotion blocks, com.notion.facet
confluencestringConfluence wiki markup
jirastringJIRA wiki markup (alias for confluence)
obsidianstringObsidian markdown, md.obsidian.facet
roamJSON stringRoam Research export. Import only.
logseqstringLogseq Markdown export. Import only.
orgstringOrg-mode, org.orgmode.facet
dokuwikistringDokuWiki markup, org.dokuwiki.facet
mediawikistringMediaWiki markup, org.mediawiki.facet
jupyterJSON stringJupyter notebook, org.jupyter.facet

Publishing & CMS

CMS and publishing adapters cover headless CMS platforms (Contentful, Sanity), structured document formats (OPML), and specialized markup languages (BBCode, Textile, Fountain/screenplay).

Format keyfromtoWire typeNotes
contentfulJSON stringContentful Rich Text, com.contentful.richtext.facet
sanityJSON stringSanity Portable Text, io.sanity.portabletext.facet
bbcodestringBBCode markup, org.bbcode.facet
textilestringTextile markup, org.textile.facet
fountainstringFountain screenplay, com.fountain.facet
opmlstringOPML outline, org.opml.facet

Collaboration

Collaboration formats are designed for real-time or asynchronous multi-user editing. The Automerge adapter works with CRDT document snapshots and change streams, making it suitable for peer-to-peer and local-first applications.

Format keyfromtoWire typeNotes
automergeAutomerge CRDTSnapshot + change-stream; peer dependency

Import-Only Formats

roam and logseq are import-only. Calling to('roam', doc) throws:

Format 'roam' does not support export (import only).
Use a lens to convert to a supported output format first.

JSON-Format Inputs and Outputs

Formats that use JSON as their wire format (quill, prosemirror, tiptap, lexical, slate, contentful, sanity, notion, jupyter, bluesky) accept and return JSON strings when used through the from / to dispatcher.

ts
// ProseMirror round-trip
const pmJson = '{"type":"doc","content":[...]}'
const doc = from('prosemirror', pmJson)
const out = to('prosemirror', doc)  // JSON string

Lexicon Namespaces

Every format module registers its features under a stable NSID (namespace identifier). The namespace is used to:

  1. Match features in lens rules (source / target fields)
  2. Identify which renderer to use when calling to('markdown', ...) / to('html', ...)
  3. Filter features by namespace (e.g., filter_facets_by_namespace for Bluesky export)

Lenses provide automatic conversion between namespaces — see Lenses.

Lexicon Registration

All format modules use the ensureXxxLexicon() pattern for registration. This function:

  • Registers the WASM lexicon (feature classes and Peritext expand semantics)
  • Registers the format's conversion lens with autoApply: true (where applicable)
  • Is idempotent — subsequent calls are no-ops
ts
import { ensureMarkdownLexicon } from 'relational-text/markdown'
import { ensureHtmlLexicon }     from 'relational-text/html'
import { ensureMastodonLexicon } from 'relational-text/mastodon'
import { ensureQuillLexicon }    from 'relational-text/quill'

ensureMarkdownLexicon()  // registers org.commonmark.facet + org.gfm.facet feature classes
ensureHtmlLexicon()      // registers org.w3c.html.facet feature classes
ensureMastodonLexicon()  // registers org.joinmastodon.facet + lens → org.commonmark.facet
ensureQuillLexicon()     // registers org.quilljs.delta.facet + lens → org.commonmark.facet

These are called automatically by from() and to() on first use. You do not need to call them manually unless you want to pre-register at startup (e.g., to avoid cold-start latency on a server).

When lenses enter the graph

Lenses enter the global lensGraph when ensureXxxLexicon() is first called. Because from() / to() call ensureXxxLexicon() automatically, lenses are registered lazily on first use of a format function.

If you call lensGraph.findPath() or autoTransform() before using any format function, no lenses will be registered yet. In server environments, pre-register all formats at startup:

ts
import { ensureMastodonLexicon }  from 'relational-text/mastodon'
import { ensureQuillLexicon }     from 'relational-text/quill'
import { ensureProseMirrorLexicon } from 'relational-text/prosemirror'

ensureMastodonLexicon()
ensureQuillLexicon()
ensureProseMirrorLexicon()