Text Documents and Rendering

Text Document

Semantic Escaped Text

Use TextNode::addEscapedText() to insert untrusted text into a document. The method tolerantly decodes malformed input, groups ordinary characters into Text nodes, and creates one indivisible EscapeSequence node for every escaped character. This preserves wrapping and styling semantics while preventing raw control sequences from reaching a renderer.

JSON Values

Value Tree

JsonValue is a copy-on-write value tree for JSON nulls, booleans, signed 64-bit integers, finite floating-point numbers, Unicode strings, arrays, and objects. JsonArray and JsonObject use the regular Erbsland Core list and ordered string-map containers. Copying a tree is inexpensive; the first mutation detaches the changed value.

Parsing and Formatting

fromStringOrThrow() strictly parses one complete RFC 8259 value and reports syntax, duplicate-key, encoding, and configured-limit failures as ParseError. fromString() provides the optional-returning form. Default limits accept 16 MiB documents, 64 container levels, one million values, and 8 MiB decoded strings.

toString() produces deterministic compact JSON with object keys in StringMap order. JsonFormatOptions can enable space-indented output and non-ASCII escaping.

HTML Parser

Introduction

The HTML parser converts a tolerant subset of HTML fragments or documents into a TextDocument. Malformed tags and entities are recovered as text where possible, so user-facing parsers can accept imperfect input.

Usage

Create HtmlParser with an AnyString compatible value and call parse() for the default tolerant API. Use parseOrThrow() when future unrecoverable parser errors should be reported as ParseError.

Layout Rendering

The layout renderer compiles a deliberately small Jinja-like language into process-local bytecode and caches an immutable compiled generation for each logical layout name. The renderer supports exact source text, comments, explicit whitespace control, scalar expressions, conditionals, lexically scoped list and ordered-map iteration, assignments, static includes, static inheritance, blocks, super() calls, and registered value filters. Inserted scalar values are escaped automatically according to the logical layout-name suffix unless this behavior is disabled in EnvironmentOptions.

Setup and Thread Safety

Create an Environment, add one or more loaders, and optionally enable automatic reload before the first render. Loader, filter, and syntax setup is not thread-safe and becomes immutable at the first render. render() and setGlobalContext() are thread-safe.

Register application filters with addFilter() before the first render. A FilterFn receives one immutable ValueList and returns one Value. Item zero is the resolved piped value; items one and two, when present, are the optional positional arguments in source order. The compiler evaluates those arguments once from left to right, while each application callback validates the list size and all value types it accepts. Filter callbacks can run concurrently and must provide their own synchronization for captured mutable state. Filter names are ASCII identifiers. Application filters can replace ordinary built-ins, but duplicate application registrations are rejected. The names escape, e, and safe are reserved output modifiers.

The local Context supplied to render() takes precedence over the current global context snapshot. Missing names and missing dotted members become null; null renders as empty text and is false. Rendering a list or map directly is an error.

Loader Contract

A Loader receives a validated logical layout name and returns either one LayoutSource or std::nullopt. A source contains exact UTF-8 text, a diagnostic origin, and an opaque revision. Higher-priority loaders are queried first; equal priorities retain addition order.

FileSystemLoader accepts existing absolute directory roots. It canonicalizes each root, maps layout components below it, rejects symbolic-link traversal below the root and non-regular files, and reads strict UTF-8. Its revision changes with file content.

ResourceLoader maps a logical name exactly to one compiled-resource key. For identifier layouts and prefix application, email/body.html resolves to (layouts, application/email/body.html). No extension is added and the name is not made relative to the including layout. The identifier is a portable resource token. The optional prefix is empty or a normalized relative UTF-8 path with / separators and no empty, . or .. components.

An explicit resource provider is retained through its shared pointer. The convenience factory, or a null explicit provider, follows core::application().resources() and therefore the application lifetime. Do not create such an application-backed loader during unsafe static initialization. Missing keys return std::nullopt so later loaders can participate. Present data is transparently decompressed, must be valid UTF-8, and reports an error rather than being treated as missing when decoding fails. Resource origins use resource:<identifier>/<path> and revisions are derived from logical content.

The same layout tree can move from development to deployment without changing include names: use a FileSystemLoader rooted at <project>/data/layouts while developing, compile that tree as resources for deployment, then use ResourceLoader with its matching identifier and prefix. For customization, register both and give the external filesystem loader higher priority. Loader priority applies independently to the root and every included or inherited layout, so one external partial or parent can override its embedded counterpart.

Without automatic reload, a layout is loaded and compiled once. With reload enabled, every render recursively checks the current origin, revision, and dependency generations. A successfully compiled source or dependency change replaces the affected cache generations. An optional dependency appearing or disappearing also republishes its parents. A failed change reports an error; renders already holding the previous immutable generation remain valid.

Supported Syntax

Raw text, comments, whitespace markers, and expression, statement, and comment delimiters retain the behavior described for the running framework. Closing delimiters inside quoted expression strings are treated as literal text.

Expressions

Expressions support:

  • ASCII names and dotted lookup, such as name and user.profile.name;

  • signed decimal integers, finite decimal or scientific floats, true, false, and none/null;

  • single- and double-quoted UTF-8 strings;

  • nested list literals and string-keyed map literals, including empty collections and one trailing comma;

  • parentheses, unary +, -, and not, binary +, -, *, /, ~, and, and or;

  • ==, !=, >, >=, <, <=, in, not in, is, and is not; and

  • filter chains with zero, one, or two arguments, such as values | join(',').

String escapes are \\, \', \", \b, \f, \n, \r, \t, and \uXXXX. Unicode surrogate escapes must form a valid pair. Unescaped control characters and invalid Unicode escapes are rejected.

From tightest to loosest binding, precedence is primary/member/collection expressions, filter chains, unary + and -, * and /, +, -, and ~, comparisons and membership/tests, not, and, then or. and and or short-circuit and return the selected operand; not and comparisons return booleans. Only one comparison is accepted in each comparison expression; combine multiple comparisons with and.

Equality supports null, booleans, numbers, and text. Integers and floats compare numerically without first converting the integer to a float. Different scalar types compare unequal. Ordering requires two numbers or two text values; text uses exact decoded-code-point order. Comparing lists or maps is a runtime error.

Arithmetic accepts numbers only. Integer +, -, *, and / saturate to the signed 64-bit range using the math-domain saturating algorithms. Integer division truncates toward zero and returns an integer. Any floating-point operand selects double arithmetic and a floating-point result. An integer or floating-point zero divisor, including negative zero, produces null. The ~ operator converts null and scalars using renderer string conversion; containers are errors.

Membership supports text in text, a scalar in a list, and a text key in a map. The argument-free tests are none /null, true, false, boolean, integer, float, number, text /string, list /sequence, map /mapping, iterable, scalar, even, and odd. A test that does not apply to a value returns false.

Statements

if statements support nested elif and else branches and end with endif. Only conditions on the selected branch are evaluated. {% set name = expression %} stores a value in private render-local state without changing the supplied local or global context. A layout-level assignment is hoisted into that layout’s setup program and runs before body output, regardless of its source position. Across inheritance, setup programs run once from the ultimate base to the most-derived layout, so derived assignments override parent assignments. Assignments nested in blocks, conditions, or loops retain their normal execution order and lexical scope.

Iteration

{% for item in sequence %} iterates a list and {% for key, value in mapping %} iterates an ordered map. The iterable expression is evaluated and callbacks are resolved exactly once when the loop starts. One target requires a list; two distinct targets require a map. Map entries follow StringMap key order. Null, scalar values, mismatched target counts, duplicate targets, reserved keywords, and more than two targets are strict errors. An optional else branch runs only when the iterable produced no item. The loop’s private state and scope are removed before that branch executes.

Each iteration has a fresh lexical scope. Its target names and assignments disappear before the next iteration, and assignments never update an outer binding. Lookup proceeds through the innermost iteration scope, outer iteration scopes, render-local assignments, the caller’s local context, and finally the global context. Nested loops temporarily shadow loop and restore the outer value when the inner loop ends. The loop name cannot be an iteration or set target while a loop body is being compiled.

The immutable loop map contains:

  • index and index0: the one-based and zero-based current indexes;

  • revindex and revindex0: the one-based and zero-based remaining indexes;

  • first and last: booleans identifying the first and last item; and

  • length: the collection length.

Blocks and Inheritance

{% extends "layout/name" %} binds one exact static parent while compiling. The statement accepts one string and no modifiers; dynamic expressions, fallback lists, relative resolution, and added extensions are not supported. An extending layout may contain only one extends statement, layout-level set statements, block declarations, comments, and whitespace outside blocks. Other output, expressions, includes, or control statements outside a block are syntax errors.

{% block name %} declares an ASCII-identifier block and ends with {% endblock %}. Block names are unique within one layout, and a name after endblock is not supported. Blocks can nest inside other blocks and structurally valid control bodies. The renderer executes the ultimate base layout’s body and dispatches each declaration to the most-derived available implementation; an unoverridden declaration therefore renders its base fallback. Dispatched blocks retain visible iteration scopes, loop metadata, render-local values, caller context, and global context.

Inside a block, super() renders the next implementation in its resolved override chain and super.super() renders the implementation after that. A standalone {{ super() }} or {{ super.super() }} writes directly to the current output sink. When a super call participates in a filter, grouping, comparison, logic expression, or set assignment, its output is first captured as text and then processed as a normal value. Arguments, deeper chaining, and calls outside blocks are syntax errors; requesting a depth with no implementation is a runtime error.

Includes

{% include "layout/name" %} binds one exact static logical layout name while compiling. Dynamic expressions, relative names, fallback lists, and added extensions are not supported. ignore missing and either with context or without context may follow the name in either order, but each modifier is accepted at most once. The default is with context.

With context, an included layout sees the immediate parent’s active iteration scopes, private assignments, caller context, and global context. Assignments made by the child remain private to that child. Without context, the child sees only the global context and its own private assignments. A nested include always inherits from its immediate parent according to its own context modifier.

ignore missing suppresses only a missing-layout error. Invalid names, loader and resource failures, invalid UTF-8, syntax and runtime errors, cycles, and limits remain visible. A compiled graph can traverse at most the configured static-dependency depth below the root; the default is 32 edges. Direct, indirect, and mixed include/inheritance cycles are syntax errors.

Compiled generations retain their resolved immutable parents, block chains, include dependencies, and explicit empty descriptors for ignored missing layouts. Nested programs append to one shared output sink and the renderer joins the final output once.

Filters are resolved while compiling a layout, so an unknown filter is a syntax error. Filter chains run from left to right and apply normal callback resolution before and after each filter invocation. Arguments are evaluated once from left to right. A third argument is rejected while compiling.

The ordinary built-ins are:

  • text: capitalize, lower, upper, trim([characters]), and replace(old, new);

  • collections: first, last, join([separator [, member]]), length/count, reverse, sort([reverse [, case_sensitive]]), keys, values, and items;

  • numeric: abs, round([precision [, common|ceil|floor]]), sum([start]), min, and max; and

  • general/output: default/d([replacement [, use_false]]) and tojson([indent]).

Empty first, last, min, and max produce null. tojson accepts indentation from zero through 16 and returns ordinary unsafe text; use |tojson|safe for a raw JSON insertion.

Escaping

Automatic escaping is enabled by default. .html, .xml, .elcl, .md, and .json select Html, Xml, Config, Markdown, and Json respectively. Custom bounded suffix mappings use longest-match selection; unmatched names use None. The logical name of the program-owning layout selects the format, including included layouts and inherited block implementations.

All directly emitted scalars pass through Value::toString().toEscaped(selectedFormat). Null remains empty and containers remain non-renderable. safe suppresses automatic escaping for one insertion. escape and its Jinja compatibility alias e force escaping, with an optional canonical format argument. With no argument they use the suffix-selected format or HTML when no format was selected. These modifiers are accepted only as the final filter of a direct output expression; they are rejected in conditions, assignments, arguments, and expressions involving super(). Disabling automatic escaping does not disable explicit escape.

Direct block output and direct super() rendering are already layout-safe. Capturing and transforming super output turns it into ordinary unsafe text. Markdown escaping follows the CommonMark backslash-escape rules for normal Markdown text; it does not protect contexts in which CommonMark disables backslash escaping.

Limits

EnvironmentOptions::renderLimits() configures positive limits for total generated and captured output, executed instructions, runtime nesting, callback resolution, lexical scopes, call frames, value-stack depth, and static dependency depth. Defaults are 64 MiB, 10,000,000 instructions, 128 nesting levels, 32 callback levels, 128 scopes, 128 call frames, 1,024 stack values, and 32 static dependency edges. Exceeding a limit raises a Limit render error.

Arbitrary function calls, assignments to dotted names, recursive loops, block capture, dynamic dependencies, macros, and persisted bytecode remain unsupported. A whitespace marker removes adjacent ASCII whitespace; no other source whitespace is changed.

Layout names use lowercase ASCII letters, digits, -, _, ., and /. They are relative, contain no empty, . or .. component, and contain at most 200 characters.

Errors

RenderError reports a category, title, description, logical layout, origin, source location, optional source snippet, and nested render frames. A nested failure preserves the leaf layout, origin, and location and records outer include or inheritance call sites in outermost-first order as one-based layout:line:column frames. Loading and callback exceptions are kept as nested causes. Invalid supported operations are strict; only missing value lookup is silent.

Interface

struct CodeSnippet

A line-oriented excerpt of source code.

The line index is zero-based; renderers present it in the customary one-based form.

Public Members

StringList lines

The source lines without line endings.

unit::LineIndex startLine = {unit::LineIndex::zero()}

The zero-based index of the first source line.

String language

The optional language identifier.

class CodeSnippetMarker

A marker range for a line-oriented code snippet.

Public Functions

CodeSnippetMarker() = default

Create an empty code-snippet marker.

inline CodeSnippetMarker(unit::LineIndex line, unit::ColumnIndex column, unit::ColumnCount length = unit::ColumnCount::one(), String label = {}, String style = {}) noexcept

Create a marker for a snippet line.

Parameters:
  • line – The original zero-based line index.

  • column – The zero-based logical source-code-point column.

  • length – The marker length in logical source code points, or zero for a point marker.

  • label – Optional label rendered after the marker.

  • style – Optional style token for renderers.

inline unit::LineIndex line() const noexcept

Get the original zero-based line index.

inline unit::ColumnIndex column() const noexcept

Get the zero-based logical source-code-point column.

inline unit::ColumnCount length() const noexcept

Get the marker length in logical source code points.

inline String label() const noexcept

Get the optional marker label.

inline String style() const noexcept

Get the optional marker style token.

using erbsland::text::CodeSnippetMarkerList = util::List<CodeSnippetMarker>

A list of code snippet markers.

class HtmlParser

A tolerant HTML parser that converts HTML fragments into text documents.

Public Functions

explicit HtmlParser(AnyString html)

Create a parser for the given HTML text.

Parameters:

html – The HTML fragment or document to parse.

HtmlParser &operator=(HtmlParser&&) noexcept

Move parser state into this instance.

TextDocument parse() noexcept

Parse the HTML text into a document.

Returns:

The parsed text document, or a best-effort document if a parser error is recovered.

TextDocument parseOrThrow()

Parse the HTML text into a document.

Throws:

err::ParseError – If a future unrecoverable parser condition is detected.

Returns:

The parsed text document.

typedef util::List<JsonValue> erbsland::text::json::JsonArray

Ordered JSON array storage.

typedef StringMap<JsonValue> erbsland::text::json::JsonObject

Ordered JSON object storage.

class JsonFormatOptions

Options for serializing a JSON value.

Public Functions

inline constexpr unit::CpLength indentation() const noexcept

Get the spaces used for each indentation level; zero selects compact output.

inline constexpr JsonFormatOptions &setIndentation(const unit::CpLength value) noexcept

Set the spaces used for each indentation level.

inline constexpr EscapeAmount escapeAmount() const noexcept

Get the JSON string escape amount.

inline constexpr JsonFormatOptions &setEscapeAmount(const EscapeAmount value) noexcept

Set the JSON string escape amount.

Public Static Functions

static inline constexpr JsonFormatOptions compact() noexcept

Create compact formatting options.

static inline constexpr JsonFormatOptions pretty() noexcept

Create pretty formatting options using two spaces.

class JsonParseOptions

Safety limits for parsing JSON documents.

Public Functions

inline constexpr unit::ByteLength maximumInputLength() const noexcept

Get the maximum source length in bytes.

inline constexpr JsonParseOptions &setMaximumInputLength(const unit::ByteLength value) noexcept

Set the maximum source length in bytes.

inline constexpr unit::ItemCount maximumNesting() const noexcept

Get the maximum number of open container levels.

inline constexpr JsonParseOptions &setMaximumNesting(const unit::ItemCount value) noexcept

Set the maximum number of open container levels.

inline constexpr unit::ItemCount maximumValueCount() const noexcept

Get the maximum value count, including the root.

inline constexpr JsonParseOptions &setMaximumValueCount(const unit::ItemCount value) noexcept

Set the maximum value count, including the root.

inline constexpr unit::CpLength maximumStringLength() const noexcept

Get the maximum decoded key or string length in bytes.

inline constexpr JsonParseOptions &setMaximumStringLength(const unit::CpLength value) noexcept

Set the maximum decoded key or string length in bytes.

Public Static Attributes

static constexpr auto cDefaultMaximumInputLength = unit::ByteLength{16U * 1024U * 1024U}

Input limit.

static constexpr auto cDefaultMaximumNesting = unit::ItemCount{64U}

Nesting limit.

static constexpr auto cDefaultMaximumValueCount = unit::ItemCount{1'000'000U}

Value limit.

static constexpr auto cDefaultMaximumStringLength = unit::CpLength{8U * 1024U * 1024U}

String limit.

enum class erbsland::text::json::JsonType : uint8_t

The semantic type of a JSON value.

Values:

enumerator Null

The null value.

enumerator Bool

A boolean value.

enumerator Number

An integer or floating-point number.

enumerator Text

A Unicode string.

enumerator Array

An ordered array.

enumerator Object

A string-keyed object.

class JsonValue

A copy-on-write JSON value tree.

See: Text Documents and Rendering

Public Functions

JsonValue() noexcept = default

Create the null value.

JsonValue(bool value)

Create a boolean value.

JsonValue(int64_t value)

Create an integer number.

JsonValue(double value)

Create a floating-point number.

Throws:

err::ParameterError – If value is not finite.

JsonValue(String value)

Create a text value.

JsonValue(JsonArray value)

Create an array value.

JsonValue(JsonObject value)

Create an object value.

template<std::integral T>
inline JsonValue(const T value)

Create an integer number from another integral type.

Throws:

err::ParameterError – If value does not fit into int64_t.

JsonType type() const noexcept

Get the semantic JSON type.

bool is(JsonType expected) const noexcept

Test whether this value has the requested type.

bool isPrimitive() const noexcept

Test whether this value is null, boolean, number, or text.

unit::ItemCount itemCount() const noexcept

Get the number of array elements or object entries, or zero for a primitive.

JsonValue get(unit::ItemIndex index) const

Get an array element, or null if this is not an array or the index is invalid.

JsonValue getOrThrow(unit::ItemIndex index) const

Get an array element.

Throws:
JsonValue get(const String &key) const

Get an object member, or null if this is not an object or the key is missing.

JsonValue getOrThrow(const String &key) const

Get an object member.

Throws:
template<typename T>
std::optional<T> get() const

Get this value as a supported native type.

template<typename T>
T get(T fallback) const

Get this value as a supported native type, or return a fallback.

template<typename T>
T getOrThrow() const

Get this value as a supported native type.

Throws:

err::LogicError – If the value cannot be represented as T.

std::optional<bool> getBool() const noexcept

Get a boolean value.

bool getBool(bool fallback) const noexcept

Get a boolean value or a fallback.

bool getBoolOrThrow() const

Get a boolean value.

Throws:

err::LogicError – If this is not a boolean.

std::optional<double> getNumber() const noexcept

Get a number as a double.

double getNumber(double fallback) const noexcept

Get a number as a double or a fallback.

double getNumberOrThrow() const

Get a number as a double.

Throws:

err::LogicError – If this is not a number.

std::optional<String> getText() const noexcept

Get a text value.

String getText(String fallback) const noexcept

Get a text value or a fallback.

String getTextOrThrow() const

Get a text value.

Throws:

err::LogicError – If this is not text.

JsonValue &set(unit::ItemIndex index, JsonValue value)

Replace an array element, or append when index == itemCount().

Throws:
JsonValue &set(const String &key, JsonValue value)

Insert or replace an object member.

Throws:

err::LogicError – If this is not an object.

JsonValue &append(JsonValue value)

Append an array element.

Throws:

err::LogicError – If this is not an array.

String toString(JsonFormatOptions options = {}) const

Serialize this value as valid JSON.

Public Static Functions

static std::optional<JsonValue> fromString(const String &text, JsonParseOptions options = {}) noexcept

Parse one complete JSON value.

Note

UTF-8 errors are ignored, validate the string before parsing if this is relevant.

static JsonValue fromStringOrThrow(const String &text, JsonParseOptions options = {})

Parse one complete JSON value.

Note

UTF-8 errors are ignored, validate the string before parsing if this is relevant.

Throws:

err::ParseError – If the document is invalid or exceeds configured limits.

class PlainTextRenderer

Render a text document as plain UTF-8 text.

Public Functions

explicit PlainTextRenderer(const TextDocument &document)

Create a plain-text renderer for a document.

Parameters:

document – The document to render.

~PlainTextRenderer()

Destroy the renderer implementation.

String build()

Build a new UTF-8 string from the document.

Returns:

The rendered plain text string.

AnyStringBuilder &appendTo(AnyStringBuilder &builder)

Append the rendered plain text to an existing builder.

Parameters:

builder – The builder to append to.

Returns:

The same builder.

class Context

A named collection of values exposed while rendering a layout.

See: Text Documents and Rendering

Public Functions

Context() = default

Create an empty context.

inline explicit Context(ValueMap values) noexcept

Create a context from named values.

inline bool contains(const String &name) const noexcept

Test whether a value with name exists.

inline Value get(const String &name) const

Get a named value, or null when it does not exist.

inline Context &set(const String &name, Value value)

Insert or replace a named value.

inline const ValueMap &values() const noexcept

Access all named values.

class Delimiters

One configurable pair of layout delimiters.

Public Functions

inline Delimiters(String begin, String end, String line = {})

Create a new set of delimiters.

inline const String &begin() const noexcept

Get the begin delimiter.

inline const String &end() const noexcept

Get the end delimiter.

inline const String &line() const noexcept

Get the line delimiter.

class Environment

A text rendering environment.

layout is a path like identifier only accepting ASCII lowercase letters, digits, the underscore, minus character and the / as path separator [-._/a-z0-9]. It must never start or end with /, and must not contain two consecutive /. The maximum length is 200 code-points.

Multithreading: The setup methods are not thread-safe. The manage and render methods are thread-safe.

See: Text Documents and Rendering

Subclassed by erbsland::text::render::impl::Environment

Public Functions

virtual void addLayoutLoader(const LoaderPtr &loader, int priority) = 0

Add a layout loader to this environment.

Loaders are tested in the order of priority, or in the order of addition if priorities are equal.

Note

Not thread-safe. Must not be called after the first manage or render call.

Parameters:
  • loader – The loader to add. Must not be null.

  • priority – The priority of the loader. Higher values have higher priority.

inline void addLayoutLoader(const LoaderPtr &loader)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

virtual void addFilter(const String &name, FilterFn filter) = 0

Add a value filter to this environment.

Filter names use ASCII identifiers. Registered filters can be invoked concurrently while rendering. The callback list contains the piped value at index zero followed by up to two positional arguments. The callback validates its own accepted list size and value types.

Note

Not thread-safe. Must not be called after the first render call.

Parameters:
  • name – The unique filter name.

  • filter – The filter callback. Must not be empty.

virtual void enableAutoReload() = 0

Enable automatic reload of layouts.

This option mainly makes sense while development, as it can impact performance. Each time a layout is rendered, all loaders are queried and the last modification date/time of the found layout is compared with the compiled version. If a newer version is found, the layout is reloaded and compiled. Once enabled, auto reload cannot be disabled.

Note

Not thread-safe. Must not be called after the first manage or render call.

virtual void setGlobalContext(Context context) = 0

Replace the global context snapshot.

The global context is the fallback if a variable is not found in the local context, or if no local context is provided.

Parameters:

context – The new global context.

virtual String render(const String &layout, const Context &context) = 0

Renders the given layout using the given context.

Parameters:
  • layout – The path to the layout to render. Must not be empty.

  • context – The local context to use for rendering; it overrides global names.

Throws:

RenderError – on any failure.

Returns:

The rendered layout.

inline String render(const String &layout)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Public Static Functions

static EnvironmentPtr create(EnvironmentOptions options = {})

Create a new empty environment.

class EnvironmentOptions

Options controlling layout syntax.

Public Functions

EnvironmentOptions()

Create the default environment options.

inline const Delimiters &expressionDelimiters() const noexcept

Get the expression delimiters.

inline EnvironmentOptions &setExpressionDelimiters(const Delimiters &delimiters) noexcept

Set the expression delimiters.

inline const Delimiters &statementDelimiters() const noexcept

Get the statement delimiters.

inline EnvironmentOptions &setStatementDelimiters(const Delimiters &delimiters) noexcept

Set the statement delimiters.

inline const Delimiters &commentDelimiters() const noexcept

Get the comment delimiters.

inline EnvironmentOptions &setCommentDelimiters(const Delimiters &delimiters) noexcept

Set the comment delimiters.

inline bool automaticEscapingEnabled() const noexcept

Test if automatic escaping is enabled.

EnvironmentOptions &setAutomaticEscapingEnabled(bool enabled) noexcept

Enable or disable automatic escaping.

EnvironmentOptions &setEscapeFormatForSuffix(const String &suffix, EscapeFormat format)

Assign an escape format to a layout-name suffix.

bool removeEscapeFormatForSuffix(const String &suffix)

Remove the escape format assigned to a suffix.

void clearEscapeFormats()

Remove all suffix escape-format assignments.

EscapeFormat escapeFormatForLayout(const String &layoutName) const noexcept

Look up the escape format for a logical layout name using longest-suffix matching.

inline const RenderLimits &renderLimits() const noexcept

Access the rendering limits.

EnvironmentOptions &setRenderLimits(const RenderLimits &limits) noexcept

Replace the rendering limits.

class FileSystemLoader : public erbsland::text::render::Loader

A loader that loads layouts from a directory on the file system.

  • All directories must be absolute and exist at the time of construction.

  • It does not follow symlinks.

  • It does map layout paths 1:1 to relative file paths.

  • It searches for layouts in the given search directories in the specified order.

    See: Text Documents and Rendering

Subclassed by erbsland::text::render::impl::FileSystemLoader

Public Static Functions

static LoaderPtr create(path::Path searchPath, FileSystemLoaderOptions options = {})

Create a new file system loader, with a single path and the given options.

Parameters:
  • searchPath – The path to the directory to search for layouts.

  • options – The options for the file system loader.

Returns:

A new file system loader.

static LoaderPtr create(util::List<path::Path> searchPaths, FileSystemLoaderOptions options = {})

Create a new file system loader, with a single path and the given options.

Parameters:
  • searchPaths – The search paths to directories to be searched in this order for layouts.

  • options – The options for the file system loader.

Returns:

A new file system loader.

class FileSystemLoaderOptions

Options for the file system layout loader.

class LayoutSource

One loaded layout source and its cache identity.

See: Text Documents and Rendering

Public Functions

inline LayoutSource(String text, String origin, String revision) noexcept

Create a loaded source.

Parameters:
  • text – The UTF-8 layout text.

  • origin – A stable diagnostic origin, such as an absolute path.

  • revision – An opaque token that changes whenever the source changes.

inline const String &text() const noexcept

Access the UTF-8 source text.

inline const String &origin() const noexcept

Access the diagnostic source origin.

inline const String &revision() const noexcept

Access the opaque source revision.

class Loader

Loads layout sources by logical name.

All methods must be thread-safe.

See: Text Documents and Rendering

Subclassed by erbsland::text::render::FileSystemLoader, erbsland::text::render::ResourceLoader

Public Functions

virtual std::optional<LayoutSource> load(const String &layout) = 0

Load a layout.

Parameters:

layout – The validated logical layout name.

Returns:

The loaded source, or no value when this loader has no matching layout.

class RenderError : public erbsland::err::RuntimeError

The primary error type for the layout renderer.

See: Text Documents and Rendering

Public Functions

explicit RenderError(RenderErrorContext context, const std::exception_ptr &cause = {})

Create a new render error from the given context.

Parameters:
  • context – The context of the error.

  • cause – The optional cause of the error.

inline const RenderErrorContext &context() const noexcept

Access the context of the error.

virtual err::DiagnosticConstPtr diagnostic() const override

Create a standard diagnostic view of this render error.

enum class erbsland::text::render::RenderErrorCategory : uint8_t

The category of a layout-rendering failure.

Values:

enumerator InvalidLayoutName

A logical layout name is invalid.

enumerator LayoutNotFound

No loader found the requested layout.

enumerator Load

Loading a layout failed.

enumerator Syntax

Layout syntax is invalid or unsupported.

enumerator Runtime

Program execution failed.

enumerator Limit

A renderer safety limit was exceeded.

enumerator Internal

Compiled bytecode or an internal invariant is invalid.

class RenderErrorContext

Complete user-facing context for a render error.

Public Functions

inline RenderErrorContext(RenderErrorCategory category, String title, String description) noexcept

Create a new error context with a title and description.

inline RenderErrorCategory category() const noexcept

Access the error category.

inline const String &title() const noexcept

The title of the error. What went wrong.

inline const String &description() const noexcept

The description of the error. Why it went wrong.

inline const String &layout() const noexcept

Access the logical layout name.

inline RenderErrorContext &setLayout(String layout) noexcept

Set the logical layout name.

inline const String &origin() const noexcept

Access the optional source origin.

inline RenderErrorContext &setOrigin(String origin) noexcept

Set the source origin.

inline const unit::CodeLocation &location() const noexcept

An optional location in the file/resource that caused the error.

inline RenderErrorContext &setLocation(const unit::CodeLocation location) noexcept

Set the location in the file/resource that caused the error.

inline const std::optional<CodeSnippet> &codeSnippet() const noexcept

Access the optional source snippet.

inline RenderErrorContext &setCodeSnippet(CodeSnippet codeSnippet) noexcept

Set the source snippet.

inline const StringList &frames() const noexcept

Access the nested layout frames, outermost first.

inline RenderErrorContext &addFrame(String frame)

Append a nested layout frame.

inline RenderErrorContext &addOuterFrame(String frame)

Prepend an outer nested layout frame.

class RenderLimits

Limits protecting a rendering operation from excessive resource use.

Public Functions

inline uint64_t generatedOutputBytes() const noexcept

Get the maximum combined generated and captured output in bytes.

RenderLimits &setGeneratedOutputBytes(uint64_t value)

Set the maximum combined generated and captured output in bytes.

inline uint64_t executedInstructions() const noexcept

Get the maximum number of executed instructions.

RenderLimits &setExecutedInstructions(uint64_t value)

Set the maximum number of executed instructions.

inline uint64_t nestingDepth() const noexcept

Get the maximum runtime nesting depth.

RenderLimits &setNestingDepth(uint64_t value)

Set the maximum runtime nesting depth.

inline uint64_t callbackDepth() const noexcept

Get the maximum callback resolution depth.

RenderLimits &setCallbackDepth(uint64_t value)

Set the maximum callback resolution depth.

inline uint64_t lexicalScopeDepth() const noexcept

Get the maximum lexical scope depth.

RenderLimits &setLexicalScopeDepth(uint64_t value)

Set the maximum lexical scope depth.

inline uint64_t callFrameDepth() const noexcept

Get the maximum call-frame depth.

RenderLimits &setCallFrameDepth(uint64_t value)

Set the maximum call-frame depth.

inline uint64_t valueStackDepth() const noexcept

Get the maximum value-stack depth.

RenderLimits &setValueStackDepth(uint64_t value)

Set the maximum value-stack depth.

inline uint64_t staticDependencyDepth() const noexcept

Get the maximum static dependency depth.

RenderLimits &setStaticDependencyDepth(uint64_t value)

Set the maximum static dependency depth.

class ResourceLoader : public erbsland::text::render::Loader

A layout loader backed by one compiled-resource identifier and optional path prefix.

A null resource provider selects the application resource manager. Do not create an application-backed loader during unsafe static initialization.

See: Text Documents and Rendering

Subclassed by erbsland::text::render::impl::ResourceLoader

Public Static Functions

static LoaderPtr create(String identifier, String pathPrefix = {})

Create a loader using the application resource manager.

Parameters:
  • identifier – The exact portable resource identifier.

  • pathPrefix – The optional normalized relative resource path prefix.

Returns:

A new resource layout loader.

static LoaderPtr create(resource::ResourcesConstPtr resources, String identifier, String pathPrefix = {})

Create a loader retaining an explicit provider, or using application resources when it is null.

Parameters:
  • resources – The retained resource provider, or null for application resources.

  • identifier – The exact portable resource identifier.

  • pathPrefix – The optional normalized relative resource path prefix.

Returns:

A new resource layout loader.

class Value

An immutable value exposed to the layout renderer.

See: Text Documents and Rendering

Public Functions

Value() noexcept = default

Create a null value.

Value(bool value)

Create a boolean value.

Value(String text)

Create a text value.

inline Value(StringLiteral text)

Create a text value from an Erbsland Core string literal.

Value(int64_t value)

Create an integer value.

template<std::integral T>
inline Value(const T value)

Create an integer value from another integral type.

Throws:

err::ParameterError – If value does not fit into int64_t.

Value(double value)

Create a float value.

template<std::floating_point T>
inline Value(const T value)

Create a floating-point value from another floating-point type.

Value(const util::List<Value> &value)

Create a list value.

Value(const StringMap<Value> &value)

Create a map value.

Value(ValueCallbackFn value)

Create a lazily evaluated callback value.

ValueType type() const noexcept

The type of the value.

bool isNull() const noexcept

Test if this is a null value.

bool isBoolean() const noexcept

Test if this is a boolean value.

bool isInteger() const noexcept

Test if this is an integer value.

bool isFloat() const noexcept

Test if this is a floating-point value.

bool isText() const noexcept

Test if this is a text value.

bool isList() const noexcept

Test if this is a list value.

bool isMap() const noexcept

Test if this is a map.

bool isCallback() const noexcept

Test if this is a callback.

unit::ItemCount itemCount() const noexcept

Get the number of list or map items, or zero for other types.

bool isTruthy() const noexcept

Test this value using the renderer truth rules.

bool asBoolean() const

Get the stored boolean.

Throws:

err::LogicError – If this is not a boolean value.

int64_t asInteger() const

Get the stored integer.

Throws:

err::LogicError – If this is not an integer value.

double asFloat() const

Get the stored floating-point number.

Throws:

err::LogicError – If this is not a floating-point value.

String asText() const

Get the stored text.

Throws:

err::LogicError – If this is not a text value.

const ValueList &asList() const

Get the stored list.

Throws:

err::LogicError – If this is not a list value.

const ValueMap &asMap() const

Get the stored map.

Throws:

err::LogicError – If this is not a map value.

Value get(unit::ItemIndex index) const

Get a list item, or null if this is not a list or the index is invalid.

Value get(const String &name) const

Get a map item, or null if this is not a map or the name is missing.

Value evaluate() const

Evaluate one callback layer, or return this value unchanged when it is not a callback.

String toString() const

Convert this value into a string.

This convert all types into a default text representation. Null and Callback are converted into an empty string. Lists and maps are converted into compact diagnostic placeholders.

using erbsland::text::render::ValueList = util::List<Value>

A list of render values.

using erbsland::text::render::ValueMap = StringMap<Value>

A string-keyed map of render values.

using erbsland::text::render::ValueCallbackFn = std::function<Value()>

A callback that lazily produces a render value.

using erbsland::text::render::FilterFn = std::function<Value(const ValueList&)>

An application filter receiving the piped value followed by zero, one, or two positional arguments.

enum class erbsland::text::render::ValueType : uint8_t

The semantic type of a render value.

Values:

enumerator Null

A null value.

enumerator Boolean

A boolean value.

enumerator Text

A text value.

enumerator Integer

A signed integer value.

enumerator Float

A floating point value.

enumerator List

A list of values.

enumerator Map

A map of values.

enumerator Callback

A lazily evaluated callback value.

class TextDocument

A mutable text document with a valid document root node.

Public Functions

TextDocument()

Create an empty text document.

TextNodePtr add(TextNodeType type)

Add a child node with the given type to the document root.

TextNodePtr addParagraph()

Add a paragraph to the document root.

TextNodePtr addSection()

Add a section to the document root.

TextNodePtr addBlockquote()

Add a blockquote to the document root.

TextNodePtr addLineBreak()

Add an explicit line break to the document root.

TextNodePtr addHeading(TextNode::Level level)

Add a heading to the document root.

Parameters:

level – The heading level.

TextNodePtr addBulletList(TextNode::Level level = 0)

Add a bullet list to the document root.

Parameters:

level – The nesting level.

TextNodePtr addNumberedList(TextNode::Level level = 0)

Add a numbered list to the document root.

Parameters:

level – The nesting level.

TextNodePtr addDefinitionList()

Add a definition list to the document root.

TextNodePtr addCodeBlock(String language = {})

Add a code block to the document root.

Parameters:

language – The optional language identifier.

TextNodePtr addCodeSnippet(CodeSnippet snippet, CodeSnippetMarkerList markers = {})

Add a line-oriented code snippet to the document root.

Parameters:
  • snippet – The source excerpt to include.

  • markers – Optional marker ranges.

TextNodePtr addHorizontalLine()

Add a horizontal line to the document root.

TextNodePtr addText(String text)

Add plain text to the document root.

Parameters:

text – The text content.

TextNodePtr addUnsupported(String text = {})

Add an unsupported-content block to the document root.

Parameters:

text – The preserved content text.

TextNodePtr addError(String text = {})

Add an error-content block to the document root.

Parameters:

text – The preserved error text.

bool isEmpty() const noexcept

Test if the document root has no children.

inline TextNodePtr root() noexcept

Access the document root node.

inline TextNodePtr root() const noexcept

Access the document root node.

String toString() const

Render the document tree as plain UTF-8 text.

class TextNode : public std::enable_shared_from_this<TextNode>

A mutable node in a text document tree.

Public Types

using Type = TextNodeType

The node type wrapper.

using Level = int

Heading or nesting level.

Public Functions

TextNodePtr add(Type type)

Add a child node with the given type.

Parameters:

type – The child node type.

Returns:

The added child node.

TextNodePtr add(TextNodePtr child)

Add an existing detached child node.

Parameters:

child – The child node to add. Must not be null.

Returns:

The added child node.

TextNodePtr addParagraph()

Add a paragraph child.

TextNodePtr addSection()

Add a section child.

TextNodePtr addBlockquote()

Add a blockquote child.

TextNodePtr addLineBreak()

Add an explicit line-break child.

TextNodePtr addHeading(Level level)

Add a heading child.

Parameters:

level – The heading level.

TextNodePtr addBulletList(Level level = 0)

Add a bullet-list child.

Parameters:

level – The nesting level.

TextNodePtr addNumberedList(Level level = 0)

Add a numbered-list child.

Parameters:

level – The nesting level.

TextNodePtr addListItem()

Add a list-item child matching this list node type.

TextNodePtr addBulletListItem()

Add a bullet-list-item child.

TextNodePtr addNumberedListItem()

Add a numbered-list-item child.

TextNodePtr addDefinitionList()

Add a definition-list child.

TextNodePtr addDefinitionTerm()

Add a definition-term child.

TextNodePtr addDefinitionDescription()

Add a definition-description child.

TextNodePtr addCodeBlock(String language = {})

Add a code-block child.

Parameters:

language – The optional language identifier.

TextNodePtr addCodeSnippet(CodeSnippet snippet, CodeSnippetMarkerList markers = {})

Add a line-oriented code snippet child.

Parameters:
  • snippet – The source excerpt to include.

  • markers – Optional marker ranges.

TextNodePtr addHorizontalLine()

Add a horizontal-line child.

TextNodePtr addText(String text)

Add a plain-text child.

Parameters:

text – The text content.

TextNode &addEscapedText(const String &text, EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced)

Add safely escaped text as plain-text and escape-sequence children.

Parameters:
  • text – The potentially unsafe text to append.

  • format – The escape format to use.

  • amount – The amount of text to escape.

Returns:

This node.

TextNodePtr addEmphasis()

Add an emphasis child.

TextNodePtr addStrong()

Add a strong-emphasis child.

TextNodePtr addUnderline()

Add an underline child.

TextNodePtr addSpan()

Add a generic span child.

TextNodePtr addLink(String url = {})

Add a link child.

Parameters:

url – The link target.

TextNodePtr addCode()

Add an inline-code child.

TextNodePtr addUnsupported(String text = {})

Add an unsupported-content child.

Parameters:

text – The preserved content text.

TextNodePtr addError(String text = {})

Add an error-content child.

Parameters:

text – The preserved error text.

TextNode &setText(String text) noexcept

Replace the text payload.

TextNode &setIdentifier(String identifier) noexcept

Replace the identifier.

TextNode &setStyle(String style) noexcept

Replace the style/class information.

TextNode &setData(TextNodeDataPtr data) noexcept

Replace the node-specific metadata.

TextNode &setLevel(Level level) noexcept

Replace the heading or nesting level.

inline Type type() const noexcept

Get the node type.

bool hasChildren() const noexcept

Test if this node has child nodes.

inline const TextNodeList &children() const noexcept

Access the child nodes.

A text node guarantees that this list never contains null pointers. Child pointers can only be added through the node API, and null children are rejected before they can enter the tree.

bool hasParent() const noexcept

Test if this node has a parent.

TextNodePtr parent() const noexcept

Access the parent node, or an empty pointer for roots.

inline String text() const noexcept

Access the text payload.

inline String identifier() const noexcept

Access the identifier.

inline String style() const noexcept

Access the style/class information.

inline const TextNodeDataPtr &data() const noexcept

Access the optional node-specific metadata.

inline Level level() const noexcept

Access the heading or nesting level.

template<typename Fn>
TextWalkResult walk(Fn nodeFn) const

Walk this node and all descendants in pre-order.

Parameters:

nodeFn – The function called for every node.

Returns:

The final walk result.

template<typename Fn>
bool anyOf(Fn nodeFn) const

Test if any node in this tree matches a predicate.

Parameters:

nodeFn – The predicate called for every node.

Returns:

true if any node matches.

bool contains(Type type) const

Test if this node tree contains a node with the given type.

Parameters:

type – The node type to search for.

Returns:

true if this node or any descendant has the given type.

TextNodePtr clone() const

Create a deep copy of this node and all descendants.

Returns:

The cloned node tree.

StringTree toDiagnosticTree() const

Convert this node tree into a diagnostic tree.

Public Static Functions

static TextNodePtr create(Type type)

Create a node with the given type.

Parameters:

type – The node type.

Returns:

The created node.

static TextNodePtr createDocument()

Create a document root node.

static TextNodePtr createParagraph()

Create a paragraph node.

static TextNodePtr createSection()

Create a section node.

static TextNodePtr createBlockquote()

Create a blockquote node.

static TextNodePtr createLineBreak()

Create an explicit line-break node.

static TextNodePtr createHeading(Level level)

Create a heading node.

Parameters:

level – The heading level.

static TextNodePtr createBulletList(Level level)

Create a bullet-list node.

Parameters:

level – The nesting level.

static TextNodePtr createNumberedList(Level level)

Create a numbered-list node.

Parameters:

level – The nesting level.

static TextNodePtr createBulletListItem()

Create a bullet-list-item node.

static TextNodePtr createNumberedListItem()

Create a numbered-list-item node.

static TextNodePtr createDefinitionList()

Create a definition-list node.

static TextNodePtr createDefinitionTerm()

Create a definition-term node.

static TextNodePtr createDefinitionDescription()

Create a definition-description node.

static TextNodePtr createCodeBlock(String language = {})

Create a code-block node.

Parameters:

language – The optional language identifier.

static TextNodePtr createCodeSnippet(CodeSnippet snippet, CodeSnippetMarkerList markers = {})

Create a line-oriented code snippet node.

Parameters:
  • snippet – The source excerpt to include.

  • markers – Optional marker ranges.

static TextNodePtr createHorizontalLine()

Create a horizontal-line node.

static TextNodePtr createText(String text)

Create a plain text node.

Parameters:

text – The text content.

static TextNodePtr createEmphasis()

Create an emphasis node.

static TextNodePtr createStrong()

Create a strong-emphasis node.

static TextNodePtr createUnderline()

Create an underline node.

static TextNodePtr createSpan()

Create a generic span node.

static TextNodePtr createLink(String url = {})

Create a link node.

Parameters:

url – The link target.

static TextNodePtr createCode()

Create an inline code node.

static TextNodePtr createUnsupported(String text = {})

Create an unsupported-content node.

Parameters:

text – The preserved content text.

static TextNodePtr createError(String text = {})

Create an error-content node.

Parameters:

text – The preserved error text.

class TextNodeData

Extensible metadata attached to a text-document node.

Applications may derive their own data types and attach them to nodes with TextNode::setData(). The string representation is used by diagnostic trees.

Subclassed by erbsland::text::impl::CodeBlockData, erbsland::text::impl::CodeLineMarkerData, erbsland::text::impl::CodeSnippetData, erbsland::text::impl::LinkData

Public Functions

virtual ~TextNodeData() = 0

Destroy the metadata object.

virtual String toString() const = 0

Convert the metadata to a diagnostic string.

class TextNodeType

The semantic type of a text document node.

Public Types

enum Value

The raw semantic node type.

Values:

enumerator Document

The root node of a document.

enumerator Paragraph

A paragraph containing inline content.

enumerator Section

A structural section containing blocks.

enumerator Blockquote

A quoted block containing blocks.

enumerator LineBreak

An explicit line break.

enumerator Heading

A heading containing inline content.

enumerator BulletList

A bullet list containing list items.

enumerator NumberedList

A numbered list containing list items.

enumerator BulletListItem

A bullet-list item containing inline content and nested blocks.

enumerator NumberedListItem

A numbered-list item containing inline content and nested blocks.

enumerator DefinitionList

A definition list containing terms and descriptions.

enumerator DefinitionTerm

A definition term.

enumerator DefinitionDescription

A definition description.

enumerator TermList

A semantic term list with names and descriptions.

enumerator TermItem

A semantic term-list item.

enumerator TermName

A semantic term name.

enumerator TermDescription

A semantic term description.

enumerator FieldList

A form-like list of labeled fields.

enumerator FieldItem

One field-list item.

enumerator FieldLabel

The label of a field.

enumerator FieldContent

The primary content of a field.

enumerator CodeBlock

A block of code.

enumerator CodeSnippet

A line-oriented code snippet.

enumerator CodeLine

A line in a code snippet.

enumerator CodeLineNumber

A code snippet line number.

enumerator CodeLineText

A code snippet source text.

enumerator CodeLineMarker

A marker attached to one code snippet source line.

enumerator HorizontalLine

A horizontal separator.

enumerator Text

Plain inline text.

enumerator Emphasis

Emphasized inline content.

enumerator Strong

Strong inline content.

enumerator Underline

Underlined inline content.

enumerator Span

Generic inline span.

enumerator Link

Link inline content.

enumerator Code

Inline code.

enumerator OptionExecutable

Option output executable name.

enumerator OptionModule

Option output module name.

enumerator OptionName

Option output complete option name.

enumerator OptionShort

Option output short option name.

enumerator OptionLong

Option output long option name.

enumerator OptionMeta

Option output meta value.

enumerator OptionOptional

Option output optional placeholder.

enumerator OptionDetails

Option output inline details.

enumerator Separator

A semantic inline separator and wrapping opportunity.

enumerator EscapeSequence

An indivisible inline escape sequence.

enumerator Unsupported

Unsupported content preserved as text.

enumerator Error

Error content preserved as text.

enumerator None

No node type.

enumerator _count
enum class RenderClass : uint8_t

The broad rendering class of a node type.

Values:

enumerator Empty

Does not render visible content directly.

enumerator Structure

Contains structural children.

enumerator Block

Renders as a block.

enumerator Inline

Renders inline.

Public Functions

constexpr TextNodeType() noexcept = default

Create the empty node type.

inline constexpr TextNodeType(Value value) noexcept

Create a node type from a raw value.

constexpr bool operator==(const TextNodeType &other) const noexcept = default

Test if two node types are equal.

inline constexpr bool operator==(Value value) const noexcept

Test if this node type is the given raw value.

inline constexpr bool operator!=(Value value) const noexcept

Test if this node type is not the given raw value.

inline constexpr Value raw() const noexcept

Get the raw value.

String toString() const noexcept

Get the display name of this node type.

RenderClass renderClass() const noexcept

Get the broad rendering class of this node type.

bool isInline() const noexcept

Test if this type renders inline.

bool isTextContainer() const noexcept

Test if this type can directly contain text while parsing or building documents.

bool isListContainer() const noexcept

Test if this type is a list container.

bool isListItem() const noexcept

Test if this type is a list item.

bool isTermListElement() const noexcept

Test if this type is a term-list element.

bool isFieldListElement() const noexcept

Test if this type is a field-list element.

bool preserveWhitespace() const noexcept

Test if this type preserves whitespace when rendered as a paragraph-like block.

class TextWalkResult : public erbsland::util::Result

The result of a text node walk call.

Public Functions

inline constexpr Result(const Value value)

Create a new result.

Parameters:

value – The value of the result.

Public Static Attributes

static const TextWalkResult Success = Value::success<0>()

Successfully completed the walk.

static const TextWalkResult Stopped = Value::success<1>()

The user early stopped the walk successfully.

static const TextWalkResult Failure = Value::failure<0>()

The walk was stopped because of a failure.

enum class erbsland::text::TextWalkStatus : uint8_t

The returned status of a text node walk function.

Values:

enumerator Continue

Continue with the next node.

enumerator Stop

Stop the walk successfully.

enumerator Failure

Stop the walk because of a failure.