adf

package
v0.20.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package adf inspects Atlassian Document Format (ADF) JSON without importing Jira types, so store, origin, and CLI can share it without crossing the store/jira firewall (docs/ARCHITECTURE.md).

PlainText flattens a document for FTS. IsSimple is the format-loss gate (doc / paragraph / text / hardBreak, no marks) ported from web/src/lib/adf.ts isSimpleAdf; FormatLoss names what a plain-text replace would destroy, for the refusal that prints it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatLoss added in v0.19.0

func FormatLoss(raw string) []string

FormatLoss lists what a markdown replace of raw would destroy: node types and mark names outside the markdown subset (panel, media, status, mention, textColor, …), deduped in first-appearance order — edit -m's refusal prints them so the user sees what the replace would drop (GDK-1001). Empty means the body round-trips through markdown and a replace loses nothing. A bare string (the older wiki-markup shape PlainText passes through) is already plain. A document that does not parse is reported, never waved through.

func FromMarkdown added in v0.20.1

func FromMarkdown(src string) json.RawMessage

FromMarkdown parses markdown text into an ADF document.

func HasPlaceholders added in v0.20.1

func HasPlaceholders(src string) bool

HasPlaceholders reports whether src carries at least one placeholder — the gate's question when a body has preserved nodes: none in the draft means a plain replace, which stays refused without force.

It reads the markdown the way the substituting parser does — a marker is an HTML block or a raw-HTML run — so a marker quoted inside a code fence or a code span is the text it is, not a placeholder. A line regex called this documentation of the markers itself unpublishable (GDK-1398).

func IsSimple added in v0.17.0

func IsSimple(raw string) bool

IsSimple reports a document made of typed text only — doc / paragraph / text / hardBreak / codeBlock, no marks: what an older jira.Doc or a migration built from a string. Markdown() returns such a document's text as typed (its `**` is the author's markdown); anything richer is serialized. The format-loss gate is FormatLoss, not this.

func Markdown added in v0.20.1

func Markdown(raw json.RawMessage) string

Markdown recovers the editing source of an ADF document. A simple document (IsSimple: paragraphs, text, hardBreak, codeBlock, no marks) is what an older jira.Doc or a migration made of text a person typed — that text is returned as it was typed, markdown syntax included, so what looked like a wall of `**` and `##` edits as the markdown it always was. Anything richer is serialized with escaping, so a literal `*` in a Jira-authored body stays literal when it comes back through FromMarkdown. A bare string body is returned as-is.

func MarkdownDoc added in v0.20.1

func MarkdownDoc(src string) map[string]any

MarkdownDoc is FromMarkdown before marshalling: the doc as a tree of map[string]any, for a caller that adds nodes (mentions, media) before sending it.

func PlainText

func PlainText(raw json.RawMessage) string

PlainText flattens an ADF document to plain text: it is what FTS indexes and what makes a repro-steps custom field searchable. A field that holds a bare string (the older wiki-markup shape) passes through unchanged.

func RefusePlaceholders added in v0.20.1

func RefusePlaceholders(text string) error

RefusePlaceholders is the check every text→ADF entry point without a body to substitute from makes (create, comment, page create/comment, --append): a marker there has nothing behind it and would be stored as visible text.

func Source added in v0.20.1

func Source(raw json.RawMessage) string

Source is the markdown an editor opens with: Markdown() for a body that round-trips, and Markdown() with a placeholder standing in for every node it cannot carry otherwise. Present.Source is this.

Types

type Kept added in v0.20.1

type Kept struct {
	// N is the 1-based position among the document's preserved nodes, in
	// document order — the number the placeholder carries.
	N int
	// Hash pins the node's JSON; a placeholder whose hash differs from the
	// current body's is refused.
	Hash string
	// Type is the ADF node type (panel, mention, …); for a text run kept for
	// its mark it is the mark's type.
	Type string
	// Parent is the type of the node it sat under. A block placeholder may
	// stand under the document root or under a node of this type, nowhere
	// else — Jira rejects a panel inside a list item, and this is the check
	// that says so before the origin does.
	Parent string
	// Container: the node's content is editable markdown between an open
	// and a close marker.
	Container bool
	// Inline: the node sat in inline content (a paragraph, a heading, a cell
	// paragraph) and its placeholder is inline.
	Inline bool
	// Node is the node itself.
	Node node
}

Kept is one preserved node of a document.

func FromMarkdownWith added in v0.20.1

func FromMarkdownWith(src string, base json.RawMessage) (json.RawMessage, []Kept, error)

FromMarkdownWith is MarkdownDocWith marshalled.

func MarkdownDocWith added in v0.20.1

func MarkdownDocWith(src string, base json.RawMessage) (map[string]any, []Kept, error)

MarkdownDocWith is MarkdownDoc with the body currently on the origin as the source of every placeholder's node. It returns the document, the preserved nodes of base that no placeholder referenced (deleted by the edit), and an error when a placeholder cannot be honoured: a number base does not have, a hash that no longer matches (the body changed since it was read), a marker used twice, a close without its open, a block node in inline position, or a block node under a parent it did not sit under. A nil base with any placeholder in src is an error too — a marker with nothing behind it is never text.

func Preserved added in v0.20.1

func Preserved(raw json.RawMessage) []Kept

Preserved lists the nodes of raw that markdown cannot carry, numbered the way Source() numbers their placeholders — the same writer pass produces both, so the two cannot disagree.

type PlaceholderError added in v0.20.1

type PlaceholderError struct {
	N   int
	Msg string
}

PlaceholderError is a placeholder the draft carries that the current body cannot honour. Callers print Error(); the fields are for tests and for a UI that wants to point at the marker.

func (*PlaceholderError) Error added in v0.20.1

func (e *PlaceholderError) Error() string

type Presented added in v0.20.1

type Presented struct {
	// Display is the document to render. For a body whose ADF is simple
	// (typed text — an older jira.Doc, a migration) and for a markdown-only
	// body it is FromMarkdown of the text, so the `##` and `**` a person or
	// an agent typed become headings and emphasis. A rich ADF is displayed
	// as it is.
	Display json.RawMessage
	// Source is the markdown an editor opens with: the typed text for a
	// simple body, an escaped serialization for a rich one — with a
	// placeholder standing in for each node markdown cannot carry.
	Source string
	// Loss names what a markdown edit of this body would destroy — the
	// nodes and marks outside the markdown subset. Empty when the body
	// round-trips.
	Loss []string
}

Presented is one body as a reader and an editor need it, derived from what the mirror holds (GDK-1385). The mirror keeps the origin's shape — ADF for Jira, Confluence and the Built-in tracker, markdown text for Linear — and never a converted copy; the conversion happens here, on the way out.

func Present added in v0.20.1

func Present(raw json.RawMessage, text string) Presented

Present derives the reader's and editor's view of a body from the mirror's two columns: the ADF (empty on Linear) and the text.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL