Documentation
¶
Overview ¶
Package richdoc defines a neutral, format-agnostic and widget-agnostic model for rich text documents.
The model is a typed tree, not a generic attribute bag. A Document is an ordered slice of Block nodes; blocks and inlines are closed interface sets (each concrete type carries an unexported marker method), so consumers such as converters and editor widgets can exhaustively type-switch over them.
The package is deliberately small and orthogonal. On top of the model it provides four utilities:
- Walk with a Visitor performs a depth-first traversal.
- Builder (via New) offers fluent, ergonomic construction.
- PlainText extracts the textual content of a document.
- Clone returns a deep copy.
The package has no dependencies beyond the standard library and is safe to build with CGO disabled.
Index ¶
- func PlainText(d *Document) string
- func Walk(d *Document, v Visitor)
- type Alignment
- type Anchor
- type Block
- type BlockQuote
- type Builder
- func (b *Builder) Add(blocks ...Block) *Builder
- func (b *Builder) CodeBlock(language, text string) *Builder
- func (b *Builder) Doc() *Document
- func (b *Builder) H(level int, inlines ...Inline) *Builder
- func (b *Builder) HR() *Builder
- func (b *Builder) MathBlock(tex string) *Builder
- func (b *Builder) Meta(key, value string) *Builder
- func (b *Builder) OList(start int, tight bool, items ...ListItem) *Builder
- func (b *Builder) P(inlines ...Inline) *Builder
- func (b *Builder) Quote(blocks ...Block) *Builder
- func (b *Builder) RawBlock(format, text string) *Builder
- func (b *Builder) Table(align []Alignment, header []Cell, rows [][]Cell) *Builder
- func (b *Builder) UList(tight bool, items ...ListItem) *Builder
- type Cell
- type Code
- type CodeBlock
- type CrossRef
- type Document
- type Emph
- type Footnote
- type Heading
- type Image
- type Inline
- type LineBreak
- type Link
- type List
- type ListItem
- type Math
- type MathBlock
- type Paragraph
- type RawBlock
- type RawInline
- type RefKind
- type Strikethrough
- type Strong
- type Table
- type Text
- type ThematicBreak
- type Visitor
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func PlainText ¶
PlainText returns the textual content of d with block-level nodes separated by newlines. It is intended for search, previews and tests, not for faithful rendering.
It concatenates the values of Text and Code inlines and of CodeBlock blocks, descending through every container (headings, lists, quotes, table cells, and emphasis-like inlines). A Footnote contributes its body text inline at the position it occurs, because footnotes are document text a search should find; an Anchor and a CrossRef contribute their visible inlines but not their identifiers. Nodes that carry no literal text in that sense contribute nothing: ThematicBreak, LineBreak, Image, Math, MathBlock, RawInline and RawBlock. It returns "" for a nil document.
Types ¶
type Anchor ¶ added in v0.2.0
Anchor is a labeled target attached to inline content: the destination a CrossRef points at (a LaTeX \label, an ODF bookmark, a Markdown heading anchor target). ID is the label; Inlines is the content the label marks and may be empty for a point target that carries no visible text of its own.
type Block ¶
type Block interface {
// contains filtered or unexported methods
}
Block is a top-level or nested block-level node. The set of concrete block types is closed: only types defined in this package satisfy Block, which lets consumers type-switch exhaustively.
type BlockQuote ¶
BlockQuote is a quotation containing nested blocks.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder incrementally assembles a Document with a fluent, chainable API. Every method appends a top-level block and returns the receiver, and New starts an empty builder:
doc := richdoc.New().
H(1, richdoc.Txt("Title")).
P(richdoc.Bold(richdoc.Txt("bold")), richdoc.Txt(" and "), richdoc.Italic(richdoc.Txt("italic"))).
Doc()
Inline and structural values are produced by the constructor helpers in this file (Txt, Bold, Italic, Item, Td, ...); the plain struct literals remain available for anything the helpers do not cover.
A Builder is not safe for concurrent use.
func (*Builder) Add ¶
Add appends arbitrary pre-built blocks, an escape hatch for constructs the typed methods below do not cover.
func (*Builder) OList ¶
OList appends an ordered List starting at start (clamped to a minimum of 1).
func (*Builder) Quote ¶
Quote appends a BlockQuote wrapping the given blocks.
type Cell ¶
Cell is a single table cell.
Inlines and Blocks ¶
A cell can hold real block content: a list, a literal block, several paragraphs, even another table. Blocks carries it. Inlines carries the same content FLATTENED to a line of inlines, and remains what a consumer that does not know about Blocks reads.
Both are filled for a cell whose content is more than one paragraph, and that duplication is the point: a converter written before Blocks existed keeps rendering the cell's words instead of silently rendering an empty cell. The contract is therefore
- a producer that sets Blocks MUST also set Inlines, to whatever degraded rendering it would have produced before;
- a consumer reads Blocks when it can represent them and Inlines when it cannot, which is what Cell.Content expresses in one call;
- the two must say the same thing. Nothing enforces it, so a producer that edits one edits the other.
A cell holding exactly one paragraph — the overwhelming common case — sets Inlines alone and leaves Blocks nil, so nothing about the simple case changes.
Spans ¶
ColSpan and RowSpan are the number of columns/rows this cell occupies. Zero, the default — what an existing Cell{Inlines: ...} literal or a Td call already produces, with no field for either — means the same as 1: an ordinary cell spanning nothing extra. A converter that has no notion of spanning cells at all (a plain CommonMark table, say) never needs to touch these fields to keep working correctly.
func (Cell) Content ¶ added in v0.5.0
Content returns the cell's content as blocks: Blocks when the producer filled it, and otherwise the Inlines wrapped in a single Paragraph. It returns nil for an empty cell.
It exists so that a consumer able to render block content in a cell needs one call rather than a branch at every use, and so that the preference order is written down once.
type Code ¶
Code is an inline code span. Value is the verbatim code.
Classes are the author's own presentational names for it; see [Classes].
type CodeBlock ¶
CodeBlock is a block of preformatted code. Language is an optional informational language tag (for example "go"); Text is the verbatim source including its internal newlines.
type CrossRef ¶ added in v0.2.0
CrossRef is a reference to an Anchor/label or a bibliographic citation. Target is the label or citation key it resolves to and Kind selects between the two. Inlines is the visible text; when it is empty the renderer or writer supplies the resolved number or label.
type Document ¶
Document is a rich text document: an ordered sequence of top-level blocks together with format-agnostic metadata (title, author, and similar).
Meta is an optional, unstructured string map; converters decide how to map its keys onto their target format. A nil Meta is valid and means "no metadata".
type Emph ¶
type Emph struct {
Inlines []Inline
}
Emph is emphasized (conventionally italic) inline content.
type Footnote ¶ added in v0.2.0
type Footnote struct {
Blocks []Block
}
Footnote is a footnote placed inline, whose content is block-level (LaTeX \footnote, an ODF footnote, a Markdown [^id] reference with its definition). Blocks holds the note body; it appears at the position the note is referenced, and a writer is free to relocate the body to the page or document end.
type Heading ¶
Heading is a section heading. Level is 1..6, following the common HTML/ Markdown convention (1 is the most prominent).
ID is an optional anchor identifier for the heading (a Markdown heading anchor, a LaTeX \section immediately followed by \label). An empty ID means the heading carries no explicit anchor.
type Image ¶
type Image struct {
URL string
Alt string
Title string
Width string
Height string
Scale int
Align Alignment
Classes []string
}
Image is an inline image reference. Alt is the textual alternative and Title an optional advisory title.
Width and Height are the requested display size as the author wrote it, including its unit: "200" (no unit, meaning pixels or big points depending on the target), "50%", "4em". Scale is a percentage applied to the intrinsic size, 0 meaning "not given" — a zero-percent image being meaningless, there is no need for a pointer. Align is the horizontal placement; AlignDefault leaves it to the renderer.
These four are not decoration. Every format that can size an image at all needs them — reST's ":width:"/":align:", LaTeX's \includegraphics[width=,height=,scale=], HTML's width/height — and a model without them forces each converter to drop what the author asked for. 43 of the 79 standalone images in go-richdoc/rst's 1564-document corpus carry at least one.
A converter whose format cannot express them ignores them, exactly as it already ignores Title: CommonMark has no syntax for a size, so go-richdoc/markdown emits the same "" it always did.
type Inline ¶
type Inline interface {
// contains filtered or unexported methods
}
Inline is an inline-level node. Like Block, the set of concrete inline types is closed, so consumers can type-switch exhaustively.
type Link ¶
Link is a hyperlink wrapping inline content. Title is an optional advisory title (for example a tooltip).
type List ¶
List is an ordered or unordered list.
When Ordered is true, Start is the number of the first item (1 when unset). Tight indicates a list whose items should render without inter-item spacing, mirroring the CommonMark tight/loose distinction.
type ListItem ¶
type ListItem struct {
Blocks []Block
}
ListItem is a single entry of a List. Items hold blocks, which makes arbitrary nesting (paragraphs, sub-lists, quotes, ...) possible.
type Math ¶
type Math struct {
TeX string
}
Math is inline mathematics, carrying its TeX source.
func InlineMath ¶
InlineMath builds a Math inline carrying TeX source.
type MathBlock ¶
type MathBlock struct {
TeX string
}
MathBlock is display (block-level) mathematics, carrying its TeX source.
type Paragraph ¶
Paragraph is a run of inline content forming a single logical paragraph.
Classes are the author's own presentational names for it; see [Classes].
type RawBlock ¶
RawBlock is a verbatim, format-specific block passthrough used to preserve round-trip fidelity for constructs the model does not represent natively. Format names the target format the Text belongs to (for example "latex" or "html"); a converter for a different format is free to drop it.
type RawInline ¶
RawInline is a verbatim, format-specific inline passthrough used to preserve round-trip fidelity, analogous to RawBlock. Format names the target format the Text belongs to.
type RefKind ¶ added in v0.2.0
type RefKind int
RefKind distinguishes the two kinds of reference a CrossRef can be.
type Strikethrough ¶
type Strikethrough struct {
Inlines []Inline
}
Strikethrough is struck-out inline content.
type Strong ¶
type Strong struct {
Inlines []Inline
}
Strong is strongly emphasized (conventionally bold) inline content.
type Table ¶
type Table struct {
Caption []Inline
Align []Alignment
Header []Cell
Rows [][]Cell
Classes []string
}
Table is a simple grid with an optional header row.
Align gives the per-column alignment; a shorter Align slice leaves the remaining columns at AlignDefault. Header may be empty for a headerless table. Rows is a list of rows, each a slice of cells.
Caption is the table's own title — reST's ".. table:: Caption", HTML's <caption>, LaTeX's \caption — and is empty for a table that has none. It is inline content because every format that has a caption renders it as a line of text, not as a sequence of blocks.
type ThematicBreak ¶
type ThematicBreak struct{}
ThematicBreak is a horizontal rule separating content.
type Visitor ¶
Visitor observes a depth-first traversal driven by Walk.
For every node Walk calls Enter before descending into that node's children and Leave once its subtree has been fully visited. Returning false from Enter skips the node's children (Leave is still called), which lets a visitor prune whole subtrees.
Nodes are passed as any. The concrete dynamic types are the Document (passed as *Document), every Block and Inline, and the structural ListItem and Cell containers, so a visitor can recover the full tree structure by type-switching.