Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

zuri.doc

import zuri

zuri exposes this as zuri.doc, so import zuri is enough and the names are called as zuri.doc.*. import zuri.doc reaches the same definitions directly.

Reads Zuri’s documentation comments: the doc blocks a zuri.parse() tree keeps as DocBlock nodes, turned into prose and a list of @tag entries, and paired with the declarations they document.

A doc block is markdown prose followed by a run of tags. Each tag starts a line with @ and its name, and its text may wrap onto the lines below it, which are recognised by their indentation. A blank line ends the run of tags.

import zuri

# Spelled in pieces so this example can sit inside a doc block.
var open = '/' + '**'
var close = '*' + '/'

var source = '${open}
 * Adds two numbers.
 *
 * @param number a: The first number
 * @returns number
 ${close}
def add(a, b) {
  return a + b
}'

for attached in zuri.doc.attach(zuri.parse(source)) {
  echo attached.node.fields.name           # add
  echo attached.block.summary()            # Adds two numbers.
  echo attached.block.first('param').name  # a
}

Fenced code inside a block is kept as it is, with no line of it read as a tag, and since Zuri block comments nest, an example that opens a comment of its own does not end the block it sits in.

Several tags have a second spelling, read as the first: @return as @returns, @raises as @throws, @params as @param, and @number as @numeric.

Functions

parse_lines()

zuri.doc.parse_lines(lines: list) -> Block

Parses the lines of a doc block into its prose and tags; the same as parse() for text already split into lines.

Everything before the first tag is prose. Once tags start, a line beginning with whitespace continues the tag above it, a line beginning with @ starts a new one, and a blank line ends the run.

Each line is read from just after the * that starts a line of a doc block, dropping that * and the one space after it, so whatever indentation follows is what marks a continuation. A line with no * is read from its first character that is not whitespace, and so never continues a tag.

Parameters

  • lines (list) — The block’s text, one string per line

Returns Block

parse()

zuri.doc.parse(text: string) -> Block

Parses the text of a doc block, the text a DocBlock node carries, into its prose and tags.

import zuri

var block = zuri.doc.parse('Opens the file.\n\n@param string path\n@returns file')

echo block.summary()               # Opens the file.
echo block.first('returns').type   # file

Parameters

  • text (string) — The block’s text, as a DocBlock node carries it

Returns Block

empty()

zuri.doc.empty() -> Block

A block with neither prose nor tags, for a declaration that has no documentation.

Returns Block

module_block()

zuri.doc.module_block(nodes: list) -> ?Block

The module’s own documentation among the top-level nodes of a file: the first doc block carrying an @module tag, parsed, or nil when the file has none.

Parameters

  • nodes (list) — The file’s top-level nodes, as zuri.parse() returns them

Returns ?Block

attach()

zuri.doc.attach(nodes: list) -> list[Attached]

Pairs every node in a list of siblings with the doc block written directly above it.

A doc block documents the node that follows it and nothing else: anything in between, a plain # comment included, breaks the pairing. The module’s own doc block, the first carrying an @module tag, documents the module rather than the node after it, so it is paired with nothing. Every node other than a doc block comes back, in order, documented or not.

nodes is any list of siblings: a file’s top-level nodes, a block’s statements, or a class’s properties or methods. A top-level declaration that is a statement comes back as the Stmt node wrapping it, exactly as it sits in the list.

Parameters

  • nodes (list) — A list of sibling nodes from zuri.parse()

Returns list[Attached]

Classes

Tag

class zuri.doc.Tag

One @tag from a doc block, its wrapped lines already joined into one string.

kind is the tag’s name without its @, under its main spelling: an @return is a 'returns' tag. type is the type the tag names, written as {type} or as a type word leading its text, and name is the name an @param or @property tag names. Both are empty strings, never nil, when the tag carries none. text is what remains: the description.

import zuri

var block = zuri.doc.parse('@param {string} name: Who to greet')
var tag = block.tags[0]

echo tag.kind  # param
echo tag.type  # string
echo tag.name  # name
echo tag.text  # Who to greet
  • printable — has a @to_string(), so echo and print() show something useful

Constructor

zuri.doc.Tag(kind: string, type: string, name: string, text: string)

Returns a new Tag. Ordinary code receives these from parse() rather than building them.

Parameters

  • kind (string) — The tag’s name without its @
  • type (string) — The type it names, or ''
  • name (string) — The name it names, or ''
  • text (string) — Its description

Tag.to_string()

zuri.doc.Tag.to_string() -> string

This tag as Tag(@kind type name).

Returns string

Block

class zuri.doc.Block

A parsed doc block: body, its markdown prose as a list of lines, and tags, every @tag in the order it was written.

Blank lines at the start and end of the prose are dropped. Each line keeps the indentation it had after the * that starts it, so code blocks and nested lists read as they were written.

  • printable — has a @to_string(), so echo and print() show something useful

Constructor

zuri.doc.Block(body: list, tags: list)

Returns a new Block. Ordinary code receives these from parse() and attach() rather than building them.

Parameters

  • body (list) — The prose, one string per line
  • tags (list) — The block’s {Tag}s, in source order

Block.all()

zuri.doc.Block.all(kind: string) -> list[Tag]

Every tag of one kind, in source order; an empty list when the block has none. kind is a tag’s main spelling, such as 'returns'.

Parameters

  • kind (string)

Returns list[Tag]

Block.first()

zuri.doc.Block.first(kind: string) -> ?Tag

The first tag of one kind, or nil when the block has none.

Parameters

  • kind (string)

Returns ?Tag

Block.has()

zuri.doc.Block.has(kind: string) -> bool

True when the block carries at least one tag of this kind.

Parameters

  • kind (string)

Returns bool

Block.summary()

zuri.doc.Block.summary() -> string

The block’s first paragraph of prose as one line, for a one-line summary in an index. It stops at the first blank line, heading or code fence, and is an empty string for a block that opens with one of those.

Returns string

Block.is_empty()

zuri.doc.Block.is_empty() -> bool

True when the block has neither prose nor tags.

Returns bool

Block.to_string()

zuri.doc.Block.to_string() -> string

This block as Block(n lines, m tags).

Returns string

Attached

class zuri.doc.Attached

One node from a list of siblings, with the doc block written directly above it, as attach() pairs them.

block is an empty Block when there is no doc block above the node, and documented says which: a doc block that holds nothing still counts as documenting its node.

  • printable — has a @to_string(), so echo and print() show something useful

Constructor

zuri.doc.Attached(node, block: instance, documented: bool)

Returns a new Attached. Ordinary code receives these from attach() rather than building them.

Parameters

  • node (Node) — The node, exactly as it sits in the list
  • block (Block) — Its documentation
  • documented (bool) — Whether a doc block was written above it

Attached.to_string()

zuri.doc.Attached.to_string() -> string

This pairing as Attached(kind, documented).

Returns string


2026, Richard Ore and Zuri contributors