Help us shape the future of Go! Take the 2026 Go Developer Survey

rst

package
v0.141.1 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: BSD-3-Clause Imports: 14 Imported by: 2

Documentation

Overview

Package rst is a reStructuredText parser producing a doctree.Element document tree, modeled on docutils.parsers.rst.states.

SCOPE (v1 — see [[go-docutils-org]] for the plan): sections (over/under lined titles), paragraphs, transitions, bullet lists, enumerated lists (all five of docutils' own sequences — arabic, loweralpha/upperalpha, lowerroman/upperroman — in all three formats, see enum.go), field lists, definition lists, line blocks (nested by relative indentation, see lineblock.go), doctest blocks, block quotes, literal blocks, comments, directives (captured structurally only, except "raw", "table", "list-table" (see Options and tabledirective.go), and the nine generic admonitions plus "admonition" itself (see admonitions.go) — there is still no general per-directive registry beyond those), hyperlink targets with reference resolution (named, indirect, and anonymous — see explicit.go), footnotes, citations, substitution definitions, docinfo promotion, simple tables and GRID tables (see table.go and gridtable.go), and the inline markup in inline.go. Section titles (both overlined and underline-only), their consistency-tracking (title_styles, real docutils' check_subsection — a title style's LEVEL is fixed by the order it's first seen in the whole document, and skipping more than one level deeper than the current nesting is an error), and their various diagnostics (too-short overline/underline, missing/mismatched underline, incomplete title, invalid title-or-transition) are ported — see matchTitle/titleDiagnostic/checkSubsectionLevel in parser.go. Not yet ported: the match_titles=false diagnostics for a title-looking construct found somewhere titles aren't allowed (inside a block quote or list item — real docutils still errors there, "Unexpected section title[. / or transition.]"; this parser currently treats it as plain text silently), and enumerator-sequence validation (docutils errors on a non-consecutive ordinal; this parser doesn't check).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ColumnWidth added in v0.116.0

func ColumnWidth(s string) int

ColumnWidth is docutils' utils.column_width: how many columns s occupies, counting an East Asian Wide or Fullwidth character as two and a combining character as none.

It is NOT TableColumnWidth, and the difference is deliberate on docutils' side: a table's geometry comes from pad_double_width, which doubles wide characters and says nothing about combining ones, while column_width subtracts them. The two are a column count for different purposes and this package now has both, each named for its own.

func MakeID added in v0.58.0

func MakeID(s string) string

MakeID returns the identifier reStructuredText derives from a name — docutils' own nodes.make_id, and the exact rule this package uses for a section's implicit target, a hyperlink target's anchor and every other generated id.

It is exported for consumers that need to ask "would this id be produced anyway?" — go-richdoc/rst's writer, for one, emits an explicit ".. _id:" target before a heading only when the heading's own title would NOT already slug to that id, since emitting it regardless produces a genuine duplicate-name diagnostic on reparse (see dupnames.go). Reimplementing the rule downstream would duplicate this package's asciiFold table and drift from it.

func Parse

func Parse(source string) *doctree.Element

Parse parses reStructuredText source into a document tree, using DefaultOptions.

func ParseWithOptions added in v0.15.0

func ParseWithOptions(source string, opts Options) *doctree.Element

ParseWithOptions is Parse with explicit control over the behaviors Options exposes.

func TableColumnWidth added in v0.110.0

func TableColumnWidth(s string) int

TableColumnWidth returns how many columns of a reST table s occupies: one per code point, two for each East Asian Wide or Fullwidth character. It is the metric this package's own grid-table geometry uses, and the only metric under which a table's borders and its rows agree.

It is exported because a WRITER needs the identical rule and had gotten it wrong in the mirror image: go-richdoc/rst padded its cells by rune count, so a CJK cell overflowed its column and a table this package had just parsed did not survive being written back out. Two implementations of one rule is what put the byte/code-point version of this bug here in the first place, so there is one, here, and the consumer calls it.

Types

type Options added in v0.15.0

type Options struct {
	// RawEnabled allows the "raw" directive (`.. raw:: FORMAT`) to pass
	// its content through completely unprocessed, tagged with the target
	// format it's meant for — real docutils' own real security surface
	// for untrusted input, since the content is never parsed as reST at
	// all. Real docutils defaults this true (its own --no-raw flag's
	// help text: "Enable the raw directive. (default)"), matched here;
	// disabled, the directive falls back to this project's existing
	// structural capture, the same as any other unimplemented directive.
	RawEnabled bool

	// SourcePath is the path of the document being parsed, and it is what
	// makes the "include" directive work: a relative include resolves
	// against this file's directory, exactly as the reference resolves one
	// against its own current_source.
	//
	// EMPTY DISABLES INCLUDES, and that is the safe default rather than an
	// omission. A caller that handed this parser nothing but a string has
	// not asked it to read the filesystem, and docutils gates the same
	// directive behind its own file_insertion_enabled setting for the same
	// reason. With no path, an ".. include::" reports the reference's own
	// `"include" directive disabled.` warning and parses on.
	SourcePath string

	// LineLengthLimit refuses a document containing a line longer than this,
	// which is the reference's own denial-of-service guard: rst.Parser.parse
	// checks every line BEFORE parsing and, on the first one over the limit,
	// appends `Line N exceeds the line-length-limit.` as an ERROR and parses
	// nothing at all. docutils added it because reST's inline grammar has
	// pathological cases, and 10000 is its default, matched here.
	//
	// ZERO MEANS NO LIMIT, so a bare Options{} does not refuse every line;
	// DefaultOptions sets 10000. A caller handling untrusted input should keep
	// the default or lower it.
	LineLengthLimit int

	// IncludeRootPrefix is the directory an ABSOLUTE path in an "include"
	// directive resolves against -- docutils' own root_prefix setting, whose
	// help text is "Base directory for absolute paths when reading from the
	// local filesystem".
	//
	// It is the confinement knob for a caller that must parse untrusted reST
	// with SourcePath set: without it, ".. include:: /etc/passwd" reads that
	// file. It does NOT confine a RELATIVE path that climbs with "..", because
	// the reference does not either; a caller that needs that guarantee should
	// leave SourcePath empty, which disables inclusion entirely.
	IncludeRootPrefix string

	// ReportDanglingReferences rewrites a reference with no matching
	// target into a <problematic>, and appends one trailing
	// "Docutils System Messages" section collecting every such
	// diagnostic.
	//
	// It defaults to FALSE, because that rewriting is not parsing: real
	// docutils does it in the DanglingReferences and Messages TRANSFORMS,
	// which run after the parser and which a caller may never run at all.
	// A bare Parse therefore leaves an unresolved reference exactly as
	// docutils' own bare parse does — a <reference> carrying its refname
	// and no refuri — and a consumer that wants the diagnostics opts in.
	//
	// Whether a reference that DOES resolve gains its refuri is a
	// separate question, and a separate option: see ResolveReferences.
	ReportDanglingReferences bool

	// ResolveReferences fills a reference's refuri in from the target it
	// names -- turning `link`_ plus ".. _link: http://x" into a
	// <reference refname="link" refuri="http://x">, and a reference to an
	// internal name into "#its-id".
	//
	// It defaults FALSE, by the same rule as ReportDanglingReferences,
	// PromoteDocInfo and NumberAutoFootnotes: docutils resolves
	// hyperlinks in transforms.references.Hyperlinks, a TRANSFORM, so its
	// bare parse leaves a reference carrying only the refname it points
	// at. Set it true to have this package do the resolution too -- the
	// html and latex writers here do, and so does go-richdoc/rst, since a
	// renderer needs somewhere to send the reader.
	//
	// The refname is written either way, so a consumer can always resolve
	// for itself; what this option controls is only whether this package
	// does it eagerly.
	ResolveReferences bool

	// ReportUnknownDirectives emits docutils' own pair of diagnostics for a
	// directive this parser has no implementation for: an INFO
	// ("No directive entry for ... Trying ... as canonical directive
	// name.") and an ERROR ("Unknown directive type ...") carrying the
	// directive's whole source as a <literal_block>, in place of the
	// structural <directive> capture.
	//
	// Unlike ReportDanglingReferences this defaults TRUE, because the
	// asymmetry is real: Body.unknown_directive lives in the PARSER, so
	// emitting it is what a faithful parse does. A consumer that would
	// rather keep an unrecognized directive's content — a Sphinx
	// ".. toctree::" in a document this package was not told about, say —
	// sets it false and gets the structural capture back.
	ReportUnknownDirectives bool

	// PromoteDocInfo turns a document's own LEADING field list into a
	// typed <docinfo> — author, date, version and friends becoming typed
	// children, with dedication/abstract split off as sibling <topic>s.
	//
	// It defaults FALSE for the same reason ReportDanglingReferences does:
	// docutils performs it in the DocInfo TRANSFORM, so its bare parse
	// leaves an ordinary <field_list> in place. Set it true to get the
	// promoted shape — go-richdoc/rst does, because its Document.Meta is
	// built from it.
	PromoteDocInfo bool

	// NumberAutoFootnotes assigns numbers to auto-numbered footnotes
	// ("[#]_", "[#name]_") and symbols to auto-symbol ones ("[*]_"),
	// giving each footnote its <label> and matching every reference to its
	// definition.
	//
	// It defaults FALSE: docutils does all of it in
	// transforms.references.Footnotes, so its bare parse leaves an auto
	// footnote with no label and no number at all. Set it true for the
	// numbered shape -- go-richdoc/rst does, since it renders footnotes.
	NumberAutoFootnotes bool

	// ReportUnknownRoles emits docutils' diagnostics for interpreted text
	// whose role this parser does not know: an INFO for the failed lookup,
	// then an ERROR carrying the whole construct as a <problematic>.
	//
	// Like ReportUnknownDirectives — and for the same reason — this
	// defaults TRUE: Inliner.interpreted raises it in the PARSER, not in a
	// transform. A consumer that would rather keep the text of a role it
	// has never heard of (a Sphinx ":doc:" reference, say) sets it false
	// and gets the lenient <inline role="..."> back.
	//
	// It ALSO gates the eleven roles docutils registers and then refuses
	// to run (roles.unimplemented_role: index, target, uri-reference and
	// friends -- see unimplementedRoles). Strictly those are a different
	// thing: the lookup SUCCEEDS and the role function itself errors. They
	// share the flag because a consumer that turns it off wants the same
	// outcome for both -- ":index:`word`" rendering as "word" rather than
	// as the raw ":index:`word`" a <problematic> would carry.
	ReportUnknownRoles bool

	// ReportUnknownDirectiveOptions emits the ERROR docutils raises for an
	// option a directive does not declare -- sphinx's ":caption:" on a
	// code block, its ":label:" on an equation -- which REPLACES the
	// directive with the message and a <literal_block> of its source.
	//
	// It defaults TRUE, and for the same reason its two neighbours do:
	// Body.parse_directive_options raises it in the PARSER
	// (states.py, "unknown option: ..."), so emitting it is what a
	// faithful parse does.
	//
	// The cost is paid by a consumer RENDERING sphinx: 32 of this
	// project's 1564 real-world corpus files carry such an option, and
	// each one loses its code block or its equation to an error
	// paragraph. A consumer that would rather keep the block and ignore
	// the option it has no use for sets this false -- go-richdoc/rst
	// does, alongside the two flags above.
	ReportUnknownDirectiveOptions bool
}

Options configures Parse's behavior. The zero value is NOT what Parse itself uses — see DefaultOptions — so a caller building one by hand should start from DefaultOptions and override specific fields, not construct Options{} directly (its RawEnabled would silently come out false, the opposite of what Parse/DefaultOptions actually do).

func DefaultOptions added in v0.15.0

func DefaultOptions() Options

DefaultOptions returns the Options Parse itself uses, matching real docutils' own defaults.

Jump to

Keyboard shortcuts

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