Paragraph Options

ParagraphOptions collects the low-level layout rules for wrapped terminal paragraphs. The same object model is used by Terminal::printParagraph(), TextOptions, and Text, so one paragraph configuration can be reused for direct terminal output and buffer-based text rendering.

Details about the example output on this page

The examples below were rendered with the dedicated documentation helper doc/tools/paragraph-options-reference.cpp at a fixed width of 78 terminal columns. Each example starts with the same ruler line so it is easy to see exactly where the available width ends.

Usage

Building and Reusing Paragraph Presets

Keep one configured ParagraphOptions instance and reuse it for every paragraph with the same layout rules.

auto options = ParagraphOptions{Alignment::TopLeft};
options.setWrappedLineIndent(8);
options.setLineBreakStartMark(String{U"⤥"});
options.setLineBreakEndMark(String{U"⤦"});
options.setParagraphSpacing(ParagraphSpacing::DoubleLine);
options.setMaximumLineWraps(2);
options.setParagraphEllipsisMark(String{"…"});
options.setTabStops({18, 32, ParagraphOptions::cTabWrappedLineIndent});

terminal.printParagraph(paragraphText, options);

When the same content is rendered through Text, the same settings are available through the forwarding setters on Text and TextOptions.

Defaults at a Glance

Option group

Default

Purpose

Alignment

TopLeft

Left-align text, with top alignment when the paragraph is rendered inside a rectangle.

Indentation

0

No base indent, and both special indents inherit from lineIndent().

Background fill

Default

Leave untouched buffer cells outside the visible text.

Paragraph spacing

SingleLine

Render explicit newline-separated paragraphs without an extra blank row.

Word separators

U"\t "

Split words at spaces and tabs.

Word break mark

'-'

Mark a word that was split because it did not fit on one physical line.

Maximum line wraps

0

Allow unlimited automatic wraps.

Paragraph ellipsis mark

"…"

Mark clipped paragraphs after the configured wrap limit.

Tab stops

cTabWrappedLineIndent

Use the wrapped-line indent as the first configured tab stop.

Tab overflow

AddSpace

Replace a non-advancing tab with one space.

Error handling

PlainOutput

Fall back to plain terminal output if the layout cannot be built.

Alignment

The alignment() setting controls the horizontal placement of each physical line. For Text, the vertical component of the alignment is also used when the text is rendered inside a rectangle.

Alignment is the first setting most users reach for, so it is worth seeing the three layouts side by side.

Left

auto options = ParagraphOptions{};
options.setAlignment(Alignment::Left);
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
A paragraph can announce its theme at once: the winter lantern swung above the
harbor road while clerks, musicians, and late readers hurried homeward beneath
the same patient rain, each keeping a different pace and yet belonging to the
same line.

Center

auto options = ParagraphOptions{};
options.setAlignment(Alignment::Center);
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
A paragraph can announce its theme at once: the winter lantern swung above the
harbor road while clerks, musicians, and late readers hurried homeward beneath
the same patient rain, each keeping a different pace and yet belonging to the
                                  same line.

Right

auto options = ParagraphOptions{};
options.setAlignment(Alignment::Right);
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
A paragraph can announce its theme at once: the winter lantern swung above the
harbor road while clerks, musicians, and late readers hurried homeward beneath
 the same patient rain, each keeping a different pace and yet belonging to the
                                                                    same line.

Indentation

Indentation is only applied for left-aligned paragraphs. The three related settings work as a small inheritance chain:

  • lineIndent() is the base indent for all physical lines.

  • firstLineIndent() overrides only the first physical line.

  • wrappedLineIndent() overrides only wrapped continuation lines.

  • cUseLineIndent means “reuse lineIndent() here”.

lineIndent = 8

auto options = ParagraphOptions{};
options.setLineIndent(8);
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
        Indented paragraphs are excellent for guidance text: they let a short
        heading stand close to the margin while the calmer explanatory part
        settles slightly deeper, which keeps option descriptions, notes, and
        examples easy to scan in a crowded terminal.

firstLineIndent = 0

auto options = ParagraphOptions{};
options.setLineIndent(8);
options.setFirstLineIndent(0);
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Indented paragraphs are excellent for guidance text: they let a short heading
        stand close to the margin while the calmer explanatory part settles
        slightly deeper, which keeps option descriptions, notes, and examples
        easy to scan in a crowded terminal.

wrappedLineIndent = 14

auto options = ParagraphOptions{};
options.setLineIndent(8);
options.setWrappedLineIndent(14);
terminal.printParagraph(textWithNewline, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
        First line: A wrapped continuation should move to the deeper
              continuation indent so the reader can tell that the sentence is
              still flowing forward.
        After newline: A hard line break starts again at the normal line
              indent before any later wraps move back to the deeper
              wrapped-line indent.

Wrap Marks

lineBreakStartMark() and lineBreakEndMark() decorate automatic wraps.

Use them when you want readers to immediately see where a continuation begins and where the previous line ran out of space.

lineBreakStartMark = “⤥”

auto options = ParagraphOptions{};
options.setLineBreakStartMark(String{U"⤥"});
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Visible wrap markers turn layout into something the reader can trust: theyshow exactly where the sentence continues, which is especially helpful inpreviews, manuals, and teaching material where the shape of the paragraphmatters as much as the words.

lineBreakEndMark = “⤦”

auto options = ParagraphOptions{};
options.setLineBreakEndMark(String{U"⤦"});
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Visible wrap markers turn layout into something the reader can trust: theyshow exactly where the sentence continues, which is especially helpful inpreviews, manuals, and teaching material where the shape of the paragraphmatters as much as the words.

both marks with wrappedLineIndent = 8

auto options = ParagraphOptions{};
options.setWrappedLineIndent(8);
options.setLineBreakStartMark(String{U"⤥"});
options.setLineBreakEndMark(String{U"⤦"});
terminal.printParagraph(text, options);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Visible wrap markers turn layout into something the reader can trust: they   ⤦
        ⤥show exactly where the sentence continues, which is especially      ⤦
        ⤥helpful in previews, manuals, and teaching material where the shape ⤦
        ⤥of the paragraph matters as much as the words.

Paragraph Spacing

ParagraphSpacing controls the vertical gap between explicit paragraphs.

For Text, each newline starts a new paragraph. For Terminal::printParagraph(), paragraph spacing is applied after the call finishes.

ParagraphSpacing::SingleLine

auto text = Text{paragraphs, buffer.rect(), Alignment::TopLeft};
text.setParagraphSpacing(ParagraphSpacing::SingleLine);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Synopsis: The watchman trimmed the lamp, checked the gate, and listened for
the returning carriage.
Examples: Use double spacing when neighboring paragraphs should read like
separate steps instead of one continuous argument.

ParagraphSpacing::DoubleLine

auto text = Text{paragraphs, buffer.rect(), Alignment::TopLeft};
text.setParagraphSpacing(ParagraphSpacing::DoubleLine);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Synopsis: The watchman trimmed the lamp, checked the gate, and listened for
the returning carriage.

Examples: Use double spacing when neighboring paragraphs should read like
separate steps instead of one continuous argument.

Word Separators

wordSeparators() defines which characters split a source line into words. Consecutive separators collapse into one rendered space.

Default separators

auto text = Text{pathLikeText, buffer.rect(), Alignment::TopLeft};
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
docs/reference/paragraph-options/with/illustrated/examples/for/layout/choices-
/and/friendly/terminal/output/that/readers/can/skim/without/guesswork

wordSeparators = U” /”

auto text = Text{pathLikeText, buffer.rect(), Alignment::TopLeft};
text.setWordSeparators(U" /");
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
docs reference paragraph-options with illustrated examples for layout choices
and friendly terminal output that readers can skim without guesswork

Word Break Mark

If a single word still does not fit, the layout engine splits it at display-cell boundaries and appends wordBreakMark() to each wrapped chunk except the last one.

Default ‘-’

auto text = Text{longIdentifier, buffer.rect(), Alignment::TopLeft};
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
ParagraphLayoutDemonstrationIdentifierForReadersWhoPreferVeryLongNamesThatSti-
llNeedPredictableWrappingInReferenceManualsAndTerminalPreviews

wordBreakMark = ‘~’

auto text = Text{longIdentifier, buffer.rect(), Alignment::TopLeft};
text.setWordBreakMark(Char{U'~'});
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
ParagraphLayoutDemonstrationIdentifierForReadersWhoPreferVeryLongNamesThatSti~
llNeedPredictableWrappingInReferenceManualsAndTerminalPreviews

Maximum Wraps and Ellipsis

maximumLineWraps() limits how many automatic wraps a single source line may produce. Once the limit is reached, the paragraph stops and appends paragraphEllipsisMark().

Unlimited wraps

auto text = Text{summaryText, buffer.rect(), Alignment::TopLeft};
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Sometimes a paragraph should stop politely instead of taking over the screen:
for release notes, narrow side panels, or compact popovers, a short ellipsis
can admit that more text exists without forcing the entire chapter into a
space meant for a summary.

maximumLineWraps = 1

auto text = Text{summaryText, buffer.rect(), Alignment::TopLeft};
text.setMaximumLineWraps(1);
text.setParagraphEllipsisMark(String{" (more)"});
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Sometimes a paragraph should stop politely instead of taking over the screen:
for release notes, narrow side panels, or compact popovers, a short (more)

Tab Stops and Overflow Behavior

Tabs receive special handling only in left-aligned paragraphs. In centered or right-aligned paragraphs, tabs are handled through wordSeparators().

tabStops = {14}

auto text = Text{tabbedRows, buffer.rect(), Alignment::TopLeft};
text.setTabStops({14});
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
build         Compile the project tree and refresh the generated headers
test          Run the unit tests and inspect the failing cases while the logs
are still fresh
publish       Create the release archive and attach the changelog for the

TabOverflowBehavior::AddSpace

auto text = Text{tableLikeRows, buffer.rect(), Alignment::TopLeft};
text.setTabStops({10, 20, 30, 40, 50, 60, 70});
text.setTabOverflowBehavior(TabOverflowBehavior::AddSpace);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Name      Start     Middle    Finish    Notes     Owner     State
River     Stone     Candlelight Map     Ink       Rope      Ready
Harbor    Lantern   Weatherproof Clock  Seal      Ledger    Waiting
Garden    Gate      Silverthread Bell   Twine     Packet    Queued

TabOverflowBehavior::LineBreak

auto text = Text{optionDescriptions, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(15);
text.setTabStops({15});
text.setTabOverflowBehavior(TabOverflowBehavior::LineBreak);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
--color        Choose the accent colors for the preview panels and the footer
               hints
--maximum-description-column
               Cap the description tab stop so narrow terminals still wrap
               cleanly
--paragraph-ellipsis-mark
               Show a compact marker when the preview summary had to be
               clipped

Background Fill Modes

ParagraphBackgroundMode controls whether the background color of the last visible character is extended into cells that do not contain visible text.

These modes behave slightly differently depending on the rendering path:

  • With Text and WritableBuffer::drawText(), untouched cells remain whatever is already stored in the target buffer unless the selected mode fills them from the wrapped text.

  • With CursorWriter::printParagraph(), indentation and trailing padding must be written as space characters. Cells not filled from wrapped-text background therefore use the writer’s current background color.

If paragraph padding should blend into a panel when using CursorWriter::printParagraph(), set the writer background before printing the paragraph.

The following examples use buffer-based text rendering. The paragraph is blue and the surrounding buffer is dark grey.

ParagraphBackgroundMode::Default

In buffer-based rendering, the continuation indent and the right side keep the existing buffer background. With CursorWriter::printParagraph(), the same cells use the current writer background instead.

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::Default);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

ParagraphBackgroundMode::WrappedLeft

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::WrappedLeft);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

ParagraphBackgroundMode::WrappedRight

The continuation indent still keeps the existing buffer background in the examples below. When printed through CursorWriter::printParagraph(), it uses the current writer background instead.

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::WrappedRight);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

ParagraphBackgroundMode::WrappedBoth

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::WrappedBoth);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

ParagraphBackgroundMode::FullRight

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::FullRight);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

ParagraphBackgroundMode::FullBoth

auto text = Text{paragraph, buffer.rect(), Alignment::TopLeft};
text.setWrappedLineIndent(10);
text.setBackgroundMode(ParagraphBackgroundMode::FullBoth);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
Background fill is easier to judge with a sentence that keeps moving: the blue
          paper lantern glowed at the window while the final line faded into  
          the dim grey hall beyond it.                                        

Reusable Indents and Separator Sets

ParagraphIndents and FastCharSet are useful when you want to reuse the same low-level paragraph mechanics across several rendering presets.

auto indents = ParagraphIndents{2};
indents.setFirstLineIndent(0);
indents.setWrappedLineIndent(6);
indents.setMargins(Margins{1, 1, 0, 1});

auto options = ParagraphOptions{};
options.setIndents(indents);
options.setWordSeparatorSet(FastCharSet::create(U" \t/"));

terminal.printParagraph("path/to/the/current/document section", options);

FastCharSet keeps separator lookups cheap when the same character set is reused across many paragraphs. The shared factories FastCharSet::onlySpace() and FastCharSet::spaceAndTab() cover the most common cases directly.

Error Handling

Some combinations of width and paragraph settings are impossible to render. Typical causes are:

  • wrap markers or ellipsis markers that leave no room for visible text

  • indentation that consumes the whole available width

  • a very narrow rectangle combined with aggressive wrap decoration

ParagraphOnError controls the fallback.

ParagraphOnError::PlainOutput

auto text = Text{String{"AA BB"}, Rectangle{0, 0, 2, 2}, Alignment::TopLeft};
text.setLineBreakEndMark(String{U"⤦⤦"});
text.setOnError(ParagraphOnError::PlainOutput);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
AA
BB

ParagraphOnError::Empty

auto text = Text{String{"AA BB"}, Rectangle{0, 0, 2, 2}, Alignment::TopLeft};
text.setLineBreakEndMark(String{U"⤦⤦"});
text.setOnError(ParagraphOnError::Empty);
buffer.drawText(text);
012345678901234567890123456789012345678901234567890123456789012345678901234567
··············································································
··············································································

Interface

class ParagraphOptions

Options that control paragraph wrapping, indentation, tab handling, and fallback behavior.

These settings are used by Terminal::printParagraph() and by TextOptions / Text when text is laid out inside a rectangle.

Note

Creating and copying paragraph options is expensive. Please keep and reuse created instances.

Public Functions

inline explicit ParagraphOptions(const Alignment alignment) noexcept

Create paragraph options with the given alignment.

Alignment alignment() const noexcept

The alignment of the paragraph.

For the Terminal::printParagraph calls, vertical alignment is ignored. For the drawText(Text) calls, the vertical alignment is used to align the text in the given rectangle.

void setAlignment(Alignment alignment) noexcept

Set the alignment of the paragraph.

const ParagraphIndents &indents() const noexcept

Get the configured indents and margins.

void setIndents(const ParagraphIndents &indents) noexcept

Replace the configured indents and margins.

Parameters:

indents – The new indent and margin settings.

int lineIndent() const noexcept

The line indent for all lines.

Only valid if the alignment is set to Alignment::Left. This indent can be overridden by firstLineIndent and wrappedLineIndent.

void setLineIndent(int indent) noexcept

Set the line indent for all lines.

Parameters:

indent – The new indent value. >=0

int firstLineIndent() const noexcept

Get the first line indent.

This is the indent for the first line of the paragraph. Only valid if the alignment is set to Alignment::Left.

1:| <first indent> A long text that is broken   |
2:| into multiple lines.                        |

void setFirstLineIndent(int indent) noexcept

Set the first line indent.

Parameters:

indent – The new indent value. >=0 or cUseLineIndent to use lineIndent

int wrappedLineIndent() const noexcept

Get the indent for wrapped lines.

This is the indent for all lines that are wrapped at the terminal width. Only valid if the alignment is set to Alignment::Left.

1:| <first indent> A long text that is broken   |
2:| into multiple lines.                        |

void setWrappedLineIndent(int indent) noexcept

Set the indent for wrapped lines.

Parameters:

indent – The new indent value. >=0 or cUseLineIndent to use lineIndent

const Margins &margins() const noexcept

Get the margins around the paragraph.

void setMargins(Margins margins) noexcept

Set the margins around the paragraph.

Parameters:

margins – The margins around the paragraph area.

ParagraphBackgroundMode backgroundMode() const noexcept

Get the background mode.

The background mode determines how the background of the paragraph is handled when lines are wrapped. It also controls how the background is extended for the last line in the paragraph.

With Text / drawText(...), cells outside the wrapped text keep the existing buffer background unless the selected mode fills them from the wrapped text. With CursorWriter::printParagraph(), indentation and padding are written as spaces, so cells not covered by wrapped-text background use the writer’s current background.

void setBackgroundMode(ParagraphBackgroundMode backgroundMode) noexcept

Set the background mode.

When using CursorWriter::printParagraph(), configure the writer background before printing if indentation or trailing padding should visually match a surrounding panel.

const String &lineBreakEndMark() const noexcept

Get the line break end mark.

The line break end mark is appended to wrapped physical lines. The mark is aligned to the right edge of the available paragraph area. If the mark contains color information, it will override the background color.

1:| A long text that is broken  <end mark> |
2:| into multiple lines.                   |

Returns:

The current line break end mark. Empty for no line break end mark.

void setLineBreakEndMark(String mark)

Set the line break end mark.

Parameters:

mark – The new line break end mark. Must not exceed two characters.

const String &lineBreakStartMark() const noexcept

Get the line break start mark.

The line break start mark prepends wrapped continuation lines in left-aligned paragraphs. The mark is inserted after the continuation indentation. If the mark contains color information, it will override the background color.

1:| A long text that is broken           |
2:| <start mark> into multiple lines.    |

Returns:

The current line break start mark. Empty for no line break start mark.

void setLineBreakStartMark(String mark)

Set the line break start mark.

Parameters:

mark – The new line break start mark. Must not exceed two characters.

ParagraphSpacing paragraphSpacing() const noexcept

The spacing between paragraphs.

The behavior of the paragraph spacing depends on the used interface. For Terminal::printParagraph() and CursorBuffer::printParagraph(), embedded newlines are hard line breaks inside one printed paragraph, and the configured spacing is appended once after the whole call. For drawText(Text) calls, each newline starts a new paragraph and spacing is inserted between paragraphs.

void setParagraphSpacing(ParagraphSpacing spacing) noexcept

Set the paragraph spacing.

const std::u32string &wordSeparators() const noexcept

Get the configured word separators as a canonicalized character string.

Word separators split a source line into words. Consecutive separators are rendered as a single space between words. Tabs use special tab-stop handling in left-aligned paragraphs before separator handling is applied. The returned string is duplicate-free and normalized for comparison and display.

const FastCharSetPtr &wordSeparatorSet() const noexcept

Access the shared separator lookup used internally for paragraph layout.

The returned set can be reused by callers that need repeated separator membership checks.

void setWordSeparators(std::u32string separators) noexcept

Set the word separators.

Tabs remain special tab stops in left-aligned paragraphs and act as regular word separators in other alignments when included here. The provided string is canonicalized automatically and mapped to shared defaults for common patterns.

Parameters:

separators – A string of Unicode characters that are used to split words.

const Char &wordBreakMark() const noexcept

Get the word break mark.

The word break mark is used when a long word had to be split in a paragraph.

void setWordBreakMark(Char mark) noexcept

Set the word break mark.

int maximumLineWraps() const noexcept

Get the maximum line wraps.

A value >0 limits the automatic wraps for one source line. Once the limit is reached, the current source line is truncated and paragraphEllipsisMark() is appended if configured. Embedded line breaks start a new source line and therefore reset the wrap counter.

Returns:

The maximum number of line wraps, or zero for unlimited line wraps.

void setMaximumLineWraps(int lines) noexcept

Set the maximum number of line wraps.

Parameters:

lines – The maximum number of line wraps, or zero for unlimited line wraps.

const String &paragraphEllipsisMark() const noexcept

Get the paragraph ellipsis mark.

This string is used to indicate that a paragraph would have to be wrapped over even more lines to be displayed completely. A single character can be used, but a short text like (more…) works as well. Please note that the width of this mark further reduces the available space for the paragraph text.

Returns:

The paragraph ellipsis mark or an empty string if no ellipsis mark shall be used.

void setParagraphEllipsisMark(String mark) noexcept

Set the paragraph ellipsis mark.

We recommend using a single character or a very short text. Longer texts quickly make paragraph rendering impossible.

Parameters:

mark – The paragraph ellipsis mark. If empty, no ellipsis mark will be used.

const std::vector<int> &tabStops() const noexcept

Get the tab stops for the paragraph.

Only valid if the alignment is set to Alignment::Left. If a line (text up to a newline character) contains TAB characters, each tab character will pick the next tab-stop columns value from this array. If the column is larger than the current column, spacing is inserted until the cursor reaches the tab-stop column. If the tab column is smaller, or there is no further tab stop in the sequence, tabOverflowBehavior() is used to decide whether the tab becomes a single space or starts a wrapped continuation line. In centered or right-aligned paragraphs, tabs use wordSeparators instead of these tab stops. The special value cTabWrappedLineIndent can be used to use the same indent as for wrapped lines.

void setTabStops(std::vector<int> tabStops) noexcept

Set the tab stops.

TabOverflowBehavior tabOverflowBehavior() const noexcept

Get the overflow handling for non-advancing tab stops.

This mode is used if a TAB resolves to a tab-stop column that is not larger than the current column, or if there is no further configured tab stop.

void setTabOverflowBehavior(TabOverflowBehavior behavior) noexcept

Set the overflow handling for non-advancing tab stops.

Parameters:

behavior – The behavior to use for tabs that do not advance the current line.

ParagraphOnError onError() const noexcept

Get the error resolution if a paragraph cannot be rendered with the given settings.

If the screen layout and the given parameters do not allow the paragraph to be rendered properly, this error resolution is used.

Returns:

The error resolution to use when a paragraph cannot be rendered.

void setOnError(ParagraphOnError onError) noexcept

Set the error resolution.

Parameters:

onError – The error resolution to use when a paragraph cannot be rendered.

Public Static Functions

static const ParagraphOptions &defaultOptions() noexcept

Globally shared default options.

Returns:

A reusable default instance with the library defaults for all paragraph settings.

Public Static Attributes

static constexpr auto cUseLineIndent = ParagraphIndents::cUseLineIndent

Special value that makes firstLineIndent() or wrappedLineIndent() reuse lineIndent().

static constexpr auto cTabWrappedLineIndent = -1

Special tab-stop value that resolves to the configured wrappedLineIndent().

class ParagraphIndents

Shared indentation and margin settings for paragraph-like text rendering.

Public Functions

constexpr ParagraphIndents() noexcept = default

Create default indents without margins.

inline explicit constexpr ParagraphIndents(const int lineIndent) noexcept

Create indents with the same value for all paragraph lines.

Parameters:

lineIndent – The indent to use for all lines.

inline constexpr ParagraphIndents(const int lineIndent, const int firstLineIndent, const int wrappedLineIndent, const Margins margins) noexcept

Create indents and margins with explicit values.

Parameters:
  • lineIndent – The indent for all lines.

  • firstLineIndent – The indent for the first line, or cUseLineIndent.

  • wrappedLineIndent – The indent for wrapped lines, or cUseLineIndent.

  • margins – The margins around the rendered paragraph area.

inline constexpr int lineIndent() const noexcept

Get the indent for all lines.

inline constexpr void setLineIndent(const int indent) noexcept

Set the indent for all lines.

Parameters:

indent – The new indent value. >=0

inline constexpr int firstLineIndent() const noexcept

Get the indent for the first line.

Returns:

The resolved first-line indent.

inline constexpr void setFirstLineIndent(const int indent) noexcept

Set the indent for the first line.

Parameters:

indent – The new indent value. >=0 or cUseLineIndent to use lineIndent().

inline constexpr int wrappedLineIndent() const noexcept

Get the indent for wrapped lines.

Returns:

The resolved wrapped-line indent.

inline constexpr void setWrappedLineIndent(const int indent) noexcept

Set the indent for wrapped lines.

Parameters:

indent – The new indent value. >=0 or cUseLineIndent to use lineIndent().

inline constexpr const Margins &margins() const noexcept

Get the margins around the paragraph.

inline constexpr void setMargins(const Margins margins) noexcept

Set the margins around the paragraph.

Parameters:

margins – The new margins.

Public Static Attributes

static constexpr auto cUseLineIndent = -1

Special value that makes firstLineIndent() or wrappedLineIndent() reuse lineIndent().

enum class erbsland::cterm::ParagraphBackgroundMode : uint8_t

How paragraph rendering extends the background color beyond the visible text.

These modes are most visible when the rendered text uses a non-default background color and the paragraph wraps across multiple physical lines. Depending on the chosen mode, the renderer can extend that background into the unused cells on the right side of a wrapped line, into the indentation area of the continuation line, or both.

For buffer-based text rendering such as Text and WritableBuffer::drawText(), untouched cells keep the existing buffer background. For cursor-writer output such as CursorWriter::printParagraph(), indentation and padding must be materialized as spaces, so cells not covered by wrapped-text background use the writer’s current background.

Values:

enumerator Default

Do not extend the wrapped-text background into additional cells.

No extra cells are painted on the right side of wrapped lines. Continuation indents keep the existing
background in buffer-based rendering, or use the current cursor-writer background when the paragraph is printed
as streamed output.
enumerator WrappedLeft

Extend the wrapped-line background into the left indentation area only.

The indentation area of each wrapped continuation line uses the background color of the last visible
character on the previous physical line. The right side of the line keeps the existing buffer background in
buffer-based rendering, or the current cursor-writer background in streamed output.
@code
| This is a very long               |
| <fill here> wrapped line.         |
@endcode
enumerator WrappedRight

Extend the wrapped-line background into the remaining cells on the right side only.

Each wrapped physical line fills the unused cells up to the available width with the background color of its
last visible character. Indentation keeps the existing buffer background in buffer-based rendering, or the
current cursor-writer background in streamed output.
@code
| This is a very long <filled here> |
|     wrapped line.                 |
@endcode
enumerator WrappedBoth

Extend the wrapped-line background on both sides of wrapped lines.

Wrapped lines fill the remaining cells on the right side, and the continuation indent on the next physical
line uses that same background color.
@code
| This is a very long <filled here> |
| <and here> wrapped line.          |
@endcode
enumerator FullRight

Extend the background into the right-side remainder on every physical line.

This behaves like `WrappedRight`, but also fills the last physical line of the paragraph.
@code
| This is a very long  <filled here> |
|     wrapped line.       <and here> |
@endcode
enumerator FullBoth

Extend the background on both sides for every physical line.

This behaves like `WrappedBoth`, but also keeps filling the right-side remainder on the last physical line.
@code
| This is a very long   <filled here> |
| <and here> wrapped line. <and here> |
@endcode
enum class erbsland::cterm::ParagraphOnError : uint8_t

The fallback to use when paragraph layout becomes impossible.

This can happen when the available width is too small for the chosen indentation, wrap markers, ellipsis marker, or other paragraph settings.

Values:

enumerator PlainOutput

Fallback to plain text output and let the terminal handle wrapping.

enumerator Empty

Do not output the paragraph at all.

enum class erbsland::cterm::ParagraphSpacing : uint8_t

The spacing between explicit newline-separated paragraphs.

Values:

enumerator SingleLine

Render the next paragraph directly below the previous paragraph.

enumerator DoubleLine

Insert one empty row between paragraphs.

enum class erbsland::cterm::TabOverflowBehavior : uint8_t

The handling for tabs whose configured tab stop does not advance the current line.

This mode is used when a left-aligned paragraph encounters a tab stop that is less than or equal to the current column, or when there is no further configured tab stop.

Values:

enumerator AddSpace

Replace the tab with a single space character.

enumerator LineBreak

End the current physical line and continue after the tab on the next wrapped line.

using erbsland::cterm::FastCharSetPtr = std::shared_ptr<FastCharSet>

Shared pointer for FastCharSet.

class FastCharSet

Shared immutable character set with optimized lookup for common separator patterns.

Instances are intended to be created once and reused across many paragraph layouts.

Public Types

enum class FastTrack : uint8_t

Fast-track mode for common separator patterns.

Values:

enumerator Space

Match only U+0020 SPACE.

enumerator SpaceTab

Match U+0020 SPACE and U+0009 TAB.

Public Functions

inline const std::u32string &characters() const noexcept

Access the canonicalized characters of this set.

The returned string is duplicate-free and sorted by code point.

bool contains(char32_t character) const noexcept

Test whether the given character is part of the set.

Parameters:

character – The Unicode code point to test.

Returns:

true if character is contained in this set.

inline bool contains(const Char &character) const noexcept

Test whether the given terminal character is part of the set.

Only single-code-point characters can match.

Parameters:

character – The terminal character to test.

Returns:

true if character is a single-code-point member of this set.

Public Static Functions

static FastCharSetPtr create(std::u32string characters)

Create a shared immutable character set for the given characters.

Duplicate characters are removed automatically. If the given characters match a fast-track pattern, a shared instance is returned.

Parameters:

characters – The characters to include in the set.

Returns:

A shared immutable character set.

static FastCharSetPtr onlySpace()

Shared set that only contains U+0020 SPACE.

static FastCharSetPtr spaceAndTab()

Shared set that contains U+0020 SPACE and U+0009 TAB.