table.dhover×314all
#!/usr/bin/env dub
/+ dub.sdl:
    name "table"
    dependency "sparkles:core-cli" path="../../.."
    targetPath "build"
    // Optimised, assertions live, `debug {}` blocks out — the build every nix
    // artifact uses. Neither `debug` (which compiles those blocks in) nor
    // `release` (which deletes assert *expressions*, side effects included).
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/

// A gallery of every `drawTable` feature: spans, sparse placement, per-column
// horizontal & vertical alignment, glyph presets & custom glyphs, separator
// toggles, width caps & wrapping, and the `validateTable` error posture.
//
// Every section deliberately mixes ANSI-styled text (`styledText`), wide/CJK
// glyphs, and emoji + combining marks, so each feature simultaneously proves it
// measures content in *terminal cells* (via `sparkles.base.text`) rather than
// bytes — a misaligned column would be immediately visible.

import 
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.demo

Demo runner utilities for showcasing UI components.

Provides a structured way to display multiple sections with headers, useful for examples and demonstrations.

demo
:
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
,
(alias) table.runDemo = void sparkles.ui.components.demo.runDemo(string header, sparkles.ui.components.demo.Section[] content, sparkles.ui.components.demo.DemoProps props = DemoProps(67LU, "Demo Complete")) @safe

Runs a demo by printing a header banner, sections, and closing banner.

Example

runDemo(
    header: "My Demo",
    content: [
        Section(header: "First", content: "Some content here"),
        Section(header: "Second", content: "More content"),
    ],
);
@paramheader The demo header shown in the opening banner@paramcontent Array of sections to display@paramprops Configuration options
runDemo
;
import
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.table

The span-capable table: pure model resolution in sparkles.ui.components.table.grid, the content-agnostic layout core (configuration, width/height solving, junction glyphs, line ordering) in sparkles.ui.components.table.layout, and the string view in sparkles.ui.components.table.render, re-exported here under the historical module name. Nothing else lives in this file — the test runner does not discover unittests in package.d modules.

The widget view (sparkles.ui.components.table.widgets) is deliberately not re-exported: it imports the whole toolkit — canvas, chrome, state, widget, wrap — where the three modules above reach no further than sparkles:base. Re-exporting it would put that closure on every consumer of drawTable, including the wasm playground, which compiles a hand-listed set of source directories and fails outright when the closure widens. Import it by its own module path where the widget view is actually wanted.

table
:
(alias) table.drawTable = string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
,
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
,
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
,
(struct) sparkles.ui.components.table.layout.TableGlyphs

The configurable box-drawing glyph set. Defaults are the rounded frame plus the square interior corners spans create; every field is a caller-overridable dchar.

TableGlyphs
,
(enum) sparkles.ui.components.table.grid.VAlign

Vertical alignment of a cell's content within its (possibly multi-line or rowspan) height. inherit defers to the column/table default. (Model-side so per-cell overrides can carry it; the renderer applies it.)

VAlign
,
(alias thread local global) table.stylePresets = sparkles.ui.components.table.layout.TableGlyphs[string] sparkles.ui.components.table.layout.stylePresets

Named glyph presets, selectable as TableProps(glyphs: stylePresets["ascii"]). Seeded from presetGlyphs with rounded (the default, == TableGlyphs.init), square, ascii, double, and heavy; callers may register or override their own entries. Thread local (each thread gets the built-ins), so reads stay @safe. Prefer presetGlyphs(name) where a pure lookup that needs no module ctor helps (e.g. a wasm build).

stylePresets
,
(alias template) table.validateTable = sparkles.ui.components.table.grid.validateTable(T)(in T[] cells) if (is(T == Cell[]) || is(T == Placement))

Validate a table's cell placement, returning the first table-model error (overlap or an over-long rowspan) or true when the table is well-formed. drawTable renders either way; call this first when a malformed table should be rejected. Works with the dense Cell[][] or sparse Placement[] form.

validateTable
,
(struct) sparkles.ui.components.table.grid.TableError

A table-model error. drawTable renders a malformed table deterministically anyway (first-writer-wins on overlap, rowspans clamped); validateTable surfaces these for callers that want to reject one. row/col locate the offending slot or anchor.

TableError
;
import
(package) sparkles
sparkles
.
(package) sparkles.base
base
.
(module) sparkles.base.styled_template

Style template processing for IES (Interpolated Expression Sequences).

Provides a template syntax for applying terminal styles to IES strings:

import sparkles.base.styled_template;

int cpu = 75;
styledWriteln(i"CPU: {red $(cpu)%} Status: {green OK}");

Supported syntax:

  • {red text} — Apply single style

  • {bold.red text} — Chain multiple styles

  • {bold outer {red nested}} — Nested blocks (inner inherits outer)

  • {red text {~red normal}} — Negation with ~ removes a style

  • #{ — Escaped literal {

  • #} — Escaped literal }

styled_template
:
(alias template) table.styledText = sparkles.base.styled_template.styledText(Args...)(ColorDepth depth, InterpolationHeader header, Args args, InterpolationFooter footer)

Returns styled IES as a string; depth folds colors to the terminal's tier.

styledText
;
import
(package) sparkles
sparkles
.
(package) sparkles.base
base
.
(package) sparkles.base.text
text
.
(module) sparkles.base.text.width

Display (terminal cell) width of code points and grapheme clusters.

Width follows the kitty Text Sizing Protocol (the modern terminal consensus; see docs/specs/base/text/), not legacy wcwidth. codepointWidth assigns, in decreasing priority: regional indicators 2 (EAW marks them neutral, but a flag half is 2); noncharacters and controls 0; all Marks (Mn | Mc | Me) and Cf 0; East-Asian Wide/Fullwidth (UAX #11) 2 (this also covers emoji-presentation bases and skin-tone modifiers); everything else (incl. ambiguous) 1.

The crucial rule: codepointWidth is the width of a code point in isolation and must NOT be summed across a cluster. A grapheme cluster occupies one cell whose width is that of its leading code point, adjusted only by the UTS #51 variation selectors (VS16 promotes an emoji base to 2, VS15 demotes it to 1); combining members never add width. So a flag (two regional indicators), a ZWJ sequence, or base+VS16 each occupy one cell. Use graphemeClusterWidth (or visibleWidth, in sparkles.base.text.grapheme) for strings.

The East-Asian-Width and emoji-VS-base tables live in the generated sparkles.base.text.unicode_tables; the zero-width set is built from std.uni's Mn | Mc | Me | Cf plus the few conjoining ranges Phobos's categories miss. Pinned to Unicode 17.0 (see the generator).

width
:
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
;
void
void D main()
main
()
{ // Shared samples reused across the preset and toggle galleries.
(alias) object.string = string
string
[][]
(local variable) string[][] sample
sample
= [
[
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Node}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Node}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold Node}"
i
"{bold Node}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}"
i
"{bold 地域}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Status}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Status}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold Status}"
i
"{bold Status}")],
["api", "日本 🇯🇵",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}"
i
"{green ✅ up}")],
["web", "eu-west",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}"
i
"{yellow ⚠ warn}")],
];
(alias) object.string = string
string
[][]
(local variable) string[][] toggleSample
toggleSample
= [
["a", "日本"], ["b", "🚀"], ["c", "café"], ]; // Preset helper: render `sample` under a named glyph set from `stylePresets`.
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
(
(alias) object.string = string
string
(parameter) string name
name
) =>
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: `Preset: "` ~
(parameter) string name
name
~ `"`,
content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] sample
sample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(glyphs:
(local variable) sparkles.ui.components.table.layout.TableGlyphs* __aaget507
stylePresets
[
(parameter) string name
name
])),
); // A deliberately malformed layout for the validation section: cell B lands on // a slot already covered by A's colspan.
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
[]
(local variable) sparkles.ui.components.table.grid.Placement[] overlapping
overlapping
= [
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
(0, 0,
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold A}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold A}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold A}"
i
"{bold A}"), colSpan: 2),
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
(0, 1,
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{red B}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{red B}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{red B}"
i
"{red B}")), // overlaps A's second slot
]; auto
(local variable) expected.Expected!(bool, TableError, Abort) validation
validation
=
expected.Expected!(bool, TableError, Abort) sparkles.ui.components.table.grid.validateTable!(sparkles.ui.components.table.grid.Placement)(in sparkles.ui.components.table.grid.Placement[] cells) pure nothrow @safe

Validate a table's cell placement, returning the first table-model error (overlap or an over-long rowspan) or true when the table is well-formed. drawTable renders either way; call this first when a malformed table should be rejected. Works with the dense Cell[][] or sparse Placement[] form.

validateTable
(
(local variable) sparkles.ui.components.table.grid.Placement[] overlapping
overlapping
);
const
(local variable) const(string) validationNote
validationNote
=
(local variable) expected.Expected!(bool, TableError, Abort) validation
validation
.
bool expected.Expected!(bool, sparkles.ui.components.table.grid.TableError, expected.Abort).hasError!()() const pure nothrow @nogc @property @safe

Checks if Expected has error

hasError
? "⚠ validateTable: " ~
(local variable) expected.Expected!(bool, TableError, Abort) validation
validation
.
inout(sparkles.ui.components.table.grid.TableError) expected.Expected!(bool, sparkles.ui.components.table.grid.TableError, expected.Abort).error() inout nothrow @nogc @property ref @safe

Returns the error value. May only be called when hasValue returns false.

If there is no error value, it calls hook's onAccessEmptyError.

It returns E.init when hook doesn't provide onAccessEmptyError.

error
.
(field) string sparkles.ui.components.table.grid.TableError.message
message
: "✓ validateTable: no model errors";
void sparkles.ui.components.demo.runDemo(string header, sparkles.ui.components.demo.Section[] content, sparkles.ui.components.demo.DemoProps props = DemoProps(67LU, "Demo Complete")) @safe

Runs a demo by printing a header banner, sections, and closing banner.

Example

runDemo(
    header: "My Demo",
    content: [
        Section(header: "First", content: "Some content here"),
        Section(header: "Second", content: "More content"),
    ],
);

Examples

Section initialization

const section = Section(header: "Title", content: "Body text");
assert(section.header == "Title");
assert(section.content == "Body text");

DemoProps defaults

const props = DemoProps.init;
assert(props.width == 67);
assert(props.endTitle == "Demo Complete");
@paramheader The demo header shown in the opening banner@paramcontent Array of sections to display@paramprops Configuration options
runDemo
(
header: "drawTable Demo — Every Feature", content: [ // // 1. Basics — backward-compatible string[][] //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Basic table (plain string[][], byte-identical baseline)", content: [ ["Service", "Region", "Status"], ["api", "us-east", "up"], ["web", "eu-west", "up"], ["db", "ap-south", "down"], ].
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
,
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Styled + i18n content (ANSI SGR, CJK, emoji, flags)", content: [ [
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Service}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Service}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold Service}"
i
"{bold Service}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold \xe5\x9c\xb0\xe5\x9f\x9f}"
i
"{bold 地域}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Status}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Status}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold Status}"
i
"{bold Status}")],
["api 🚀", "us-east",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}"
i
"{green ✅ up}")],
["web", "日本 🇯🇵",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}"
i
"{yellow ⚠ warn}")],
["db", "eu-west",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{red \xe2\x9c\x97 down}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{red \xe2\x9c\x97 down}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{red \xe2\x9c\x97 down}"
i
"{red ✗ down}")],
].
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
,
), // // 2. Column spans //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Column span (colSpan banner; right-aligned numeric columns)", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Cell[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a dense Cell[][] (cells may carry colSpan/rowSpan) as a boxed table. Covered slots are omitted from the following cells (rows may be ragged); the placement cursor recovers their positions. Malformed tables (overlap, over-long rowspans) still render deterministically — use validateTable to detect them. See Cell.

drawTable
([
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold.underline \xe5\x9b\x9b\xe5\x8d\x8a\xe6\x9c\x9f\xe5\xa3\xb2\xe4\xb8\x8a (Quarterly Sales)}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold.underline \xe5\x9b\x9b\xe5\x8d\x8a\xe6\x9c\x9f\xe5\xa3\xb2\xe4\xb8\x8a (Quarterly Sales)}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold.underline \xe5\x9b\x9b\xe5\x8d\x8a\xe6\x9c\x9f\xe5\xa3\xb2\xe4\xb8\x8a (Quarterly Sales)}"
i
"{bold.underline 四半期売上 (Quarterly Sales)}"), colSpan: 3)],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Region"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Q1"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Q2")],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("North 🌎"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("1200"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("1350")],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("日本"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("980"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("1100")],
],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnAligns: [
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.left = 1
left
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
])),
), // // 3. Row spans (with row separators) //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Row span (rowSpan label + rowSeparators → rule breaks, ┌┐└┘ corners)", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Cell[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a dense Cell[][] (cells may carry colSpan/rowSpan) as a boxed table. Covered slots are omitted from the following cells (rows may be ragged); the placement cursor recovers their positions. Malformed tables (overlap, over-long rowspans) still render deterministically — use validateTable to detect them. See Cell.

drawTable
([
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("地域\nAsia", rowSpan: 2),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Tokyo"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85 up}"
i
"{green ✅ up}"))],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Osaka"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{yellow \xe2\x9a\xa0 warn}"
i
"{yellow ⚠ warn}"))],
],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(rowSeparators: true)),
), // // 4. Row × column block span //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Block span (colSpan: 2, rowSpan: 2)", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Cell[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a dense Cell[][] (cells may carry colSpan/rowSpan) as a boxed table. Covered slots are omitted from the following cells (rows may be ragged); the placement cursor recovers their positions. Malformed tables (overlap, over-long rowspans) still render deterministically — use validateTable to detect them. See Cell.

drawTable
([
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold.inverse CORE}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold.inverse CORE}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold.inverse CORE}"
i
"{bold.inverse CORE}"), colSpan: 2, rowSpan: 2),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("edge-1")],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("edge-2")],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("a"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("b"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("c 🚀")],
]), ), // // 5. Sparse Placement[] (order-independent) //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Sparse Placement[] (out-of-order; uncovered slots blank)", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Placement[] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a sparse Placement[] (order-independent cells naming their own (row, col) and extent) as a boxed table. Lowers to the same slot grid as the dense forms, so it renders identically. See Placement.

drawTable
([
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
(2, 2,
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{cyan cells}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{cyan cells}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{cyan cells}"
i
"{cyan cells}")),
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
(0, 0, "diagonal 🚀"),
(struct) sparkles.ui.components.table.grid.Placement

A cell for the sparse authoring form ``Placement[]: it names its own (row, col) and extent, so placements are order-independent and never need filler for the gaps (uncovered slots become implicit blanks). Equivalent in power to Cell[][].

Placement
(1, 1, "日本語"),
]), ), // // 6. Horizontal alignment //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Per-column horizontal alignment (left / center / right)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["left", "center", "right"], ["a",
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{green \xe2\x9c\x85}"
i
"{green ✅}"), "1"],
["日本語", "mid", "4200"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnAligns: [
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.left = 1
left
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.center = 2
center
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
])),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "defaultAlign: right, with a single Align.left override on col 0", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["metric", "v1", "v2"], ["cpu", "45", "80"], ["mem 💾", "1200", "980"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(defaultAlign:
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
, columnAligns: [
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.left = 1
left
])),
), // // 7. Vertical alignment //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Per-column vertical alignment (top / middle / bottom in a tall row)", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Cell[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a dense Cell[][] (cells may carry colSpan/rowSpan) as a boxed table. Covered slots are omitted from the following cells (rows may be ragged); the placement cursor recovers their positions. Malformed tables (overlap, over-long rowspans) still render deterministically — use validateTable to detect them. See Cell.

drawTable
([
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("line 1\nline 2\nline 3\nline 4"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{green \xe2\x96\xb2 top}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{green \xe2\x96\xb2 top}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{green \xe2\x96\xb2 top}"
i
"{green ▲ top}")),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{yellow \xe2\x97\x8f middle}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{yellow \xe2\x97\x8f middle}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{yellow \xe2\x97\x8f middle}"
i
"{yellow ● middle}")),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
(
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{red \xe2\x96\xbc bottom}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{red \xe2\x96\xbc bottom}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{red \xe2\x96\xbc bottom}"
i
"{red ▼ bottom}")),
], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnVAligns: [
(enum) sparkles.ui.components.table.grid.VAlign

Vertical alignment of a cell's content within its (possibly multi-line or rowspan) height. inherit defers to the column/table default. (Model-side so per-cell overrides can carry it; the renderer applies it.)

VAlign
.
(enum value) sparkles.ui.components.table.grid.VAlign.top = 1
top
,
(enum) sparkles.ui.components.table.grid.VAlign

Vertical alignment of a cell's content within its (possibly multi-line or rowspan) height. inherit defers to the column/table default. (Model-side so per-cell overrides can carry it; the renderer applies it.)

VAlign
.
(enum value) sparkles.ui.components.table.grid.VAlign.top = 1
top
,
(enum) sparkles.ui.components.table.grid.VAlign

Vertical alignment of a cell's content within its (possibly multi-line or rowspan) height. inherit defers to the column/table default. (Model-side so per-cell overrides can carry it; the renderer applies it.)

VAlign
.
(enum value) sparkles.ui.components.table.grid.VAlign.middle = 2
middle
,
(enum) sparkles.ui.components.table.grid.VAlign

Vertical alignment of a cell's content within its (possibly multi-line or rowspan) height. inherit defers to the column/table default. (Model-side so per-cell overrides can carry it; the renderer applies it.)

VAlign
.
(enum value) sparkles.ui.components.table.grid.VAlign.bottom = 3
bottom
])),
), // // 8. Glyph presets (all five) //
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
("rounded"),
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
("square"),
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
("ascii"),
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
("double"),
sparkles.ui.components.demo.Section table.main.preset(string name) @system
preset
("heavy"),
// // 9. Custom glyphs //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Custom TableGlyphs (dotted rules — fields are individually overridable)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
[
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold x}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold x}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold x}"
i
"{bold x}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold y}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold y}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold y}"
i
"{bold y}")],
["1", "日本"], ["2", "🚀"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(glyphs:
(struct) sparkles.ui.components.table.layout.TableGlyphs

The configurable box-drawing glyph set. Defaults are the rounded frame plus the square interior corners spans create; every field is a caller-overridable dchar.

TableGlyphs
(
topLeft: '·', topRight: '·', bottomLeft: '·', bottomRight: '·', horizontalLine: '┈', verticalLine: '┊', teeDown: '·', teeUp: '·', teeRight: '·', teeLeft: '·', cross: '·', cornerTL: '·', cornerTR: '·', cornerBL: '·', cornerBR: '·'))), ), // // 10. Separator toggles //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Toggle: border off", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] toggleSample
toggleSample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(border: false)),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Toggle: column separators off", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] toggleSample
toggleSample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnSeparators: false)),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Toggle: row separators on", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] toggleSample
toggleSample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(rowSeparators: true)),
), // // 10b. Header row & stub column separators (distinct emphasis rules) //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Header row separator (headerRows: 1 — distinct heavy rule under the header)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] sample
sample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(headerRows: 1)),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Stub column separator (headerCols: 1, columnSeparators off — heavy ┃ after the stub)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] sample
sample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(headerCols: 1, columnSeparators: false)),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Header row + stub column (headerRows: 1, headerCols: 1 — ╋ where the rules cross)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
(
(local variable) string[][] sample
sample
,
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(headerRows: 1, headerCols: 1)),
), // // 11. Width caps & wrapping — sparkles.base.text robustness //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Wrap (a): total maxWidth: 40 — shrink largest-first to fit", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["id", "description"], ["1", "A fairly long description that will not fit a narrow terminal and must wrap"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(maxWidth: 40)),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Wrap (b): per-column columnMaxWidths: [0, 20] — cap one column", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["id", "note"], ["1", "wrap this column at twenty cells while the id column stays untouched"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnMaxWidths: [0, 20])),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Width floor: columnMinWidths: [12, 0] — stable geometry for live re-renders", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["name", "value"], ["cpu", "45%"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnMinWidths: [12, 0])),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Wrap (c): explicit \\n in content — hard break", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["key", "value"], ["PATH", "/usr/local/bin\n/opt/app/bin\n/home/user/bin"], ]), ),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Wrap (d): Unicode width — full-width CJK (2 cells each) + emoji graphemes", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["lang", "sample"], ["ja", "日本語のテキストは全角文字で構成されています"], ["mix", "🚀 ✅ 🎉 🇯🇵 café résumé"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnMaxWidths: [0, 14])),
),
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Wrap (e): ANSI-safe wrapping — SGR style re-opened on each line", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["level", "message"], [
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{red ERR}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{red ERR}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{red ERR}"
i
"{red ERR}"),
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold.green A long styled message whose bold-green SGR style must be re-emitted on every wrapped continuation line, never split mid-escape}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold.green A long styled message whose bold-green SGR style must be re-emitted on every wrapped continuation line, never split mid-escape}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold.green A long styled message whose bold-green SGR style must be re-emitted on every wrapped continuation line, never split mid-escape}"
i
"{bold.green A long styled message whose bold-green SGR style must be re-emitted on every wrapped continuation line, never split mid-escape}"),
], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(columnMaxWidths: [0, 26])),
), // // 12. validateTable — detect + render anyway //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "validateTable (overlap): reports the error AND still renders deterministically", content:
(local variable) const(string) validationNote
validationNote
~ "\n\n" ~
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Placement[] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a sparse Placement[] (order-independent cells naming their own (row, col) and extent) as a boxed table. Lowers to the same slot grid as the dense forms, so it renders identically. See Placement.

drawTable
(
(local variable) sparkles.ui.components.table.grid.Placement[] overlapping
overlapping
),
), // // 13. Title & footer — spliced into the frame like drawBox's //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Title/footer: spliced into the borders (truncated with … when narrow)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["item", "qty"], ["nuts", "12"], ["bolts", "7"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(title:
string sparkles.base.styled_template.styledText!(core.interpolation.InterpolatedLiteral!"{bold Inventory}")(core.interpolation.InterpolationHeader header, core.interpolation.InterpolatedLiteral!"{bold Inventory}" __param_1, core.interpolation.InterpolationFooter footer) nothrow @safe

ditto — defaults to ColorDepth.trueColor (no folding).

styledText
(
(template instance) core.interpolation.InterpolatedLiteral!"{bold Inventory}"
i
"{bold Inventory}"),
footer: "2 kinds", headerRows: 1, columnAligns: [
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.left = 1
left
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
])),
), // // 14. Align.decimal — a column of numbers sharing a dot position //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Align.decimal: values align on the last '.' (dotless sit left of it)", content:
string sparkles.ui.components.table.render.drawTable(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a rectangular string[][] as a boxed table. With the default TableProps the output is byte-identical to the pre-overhaul renderer.

drawTable
([
["benchmark", "median/iter"], ["parse", "1.25µs"], ["render", "23.5µs"], ["noop", "980ns"], ],
(struct) sparkles.ui.components.table.layout.TableProps

Table rendering configuration. Defaults reproduce the pre-overhaul rendering byte-for-byte: rounded glyphs, column separators on, row separators off, outer border on, left/top alignment.

TableProps
(headerRows: 1,
columnAligns: [
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.left = 1
left
,
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.decimal = 4
decimal
])),
), // // 15. Per-cell halign/valign — overrides beat the column default //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "Per-cell align: a centered colspan banner over left/right columns", content:
string sparkles.ui.components.table.render.drawTable(sparkles.ui.components.table.grid.Cell[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null))

Render a dense Cell[][] (cells may carry colSpan/rowSpan) as a boxed table. Covered slots are omitted from the following cells (rows may be ragged); the placement cursor recovers their positions. Malformed tables (overlap, over-long rowspans) still render deterministically — use validateTable to detect them. See Cell.

drawTable
([
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("Quarterly totals", colSpan: 2, halign:
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.center = 2
center
)],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("north"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("1200", halign:
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
)],
[
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("south"),
(struct) sparkles.ui.components.table.grid.Cell

A table cell for the dense authoring form ``Cell[][]. colSpan/rowSpan (default

  1. make it cover a rectangle of grid slots; the slots it covers are omitted from the following cells of this and later rows (the placement cursor skips them). A plain string[][] is sugar for extent-1 cells.

Cell
("98", halign:
(enum) sparkles.base.text.width.Align

Horizontal alignment of text within a fixed-width field. inherit means "defer to a caller-supplied default" (e.g. a table column's default alignment) and is treated as left if it reaches alignField unresolved. decimal aligns a column of numbers on their last . — inherently columnar (a lone field has no shared dot position), so alignField treats it as right; the columnar pad is applied by the consumer (see drawTable's per-column handling).

Align
.
(enum value) sparkles.base.text.width.Align.right = 3
right
)],
]), ), // // 16. Streaming views — lazy line/chunk emission (eager layout) //
(struct) sparkles.ui.components.demo.Section

A section in a demo with a header and content.

Section
(
header: "drawTableLines: a forward range of lines (LiveRegion-ready), byte-identical joined", content:
string table.streamingNote()

Demonstrates the streaming views: drawTableLines yields the same bytes as drawTable line by line (no trailing newlines — ready for a LiveRegion frame), and drawTableChunks!false reveals the table cell by cell.

streamingNote
,
), ], ); } /// Demonstrates the streaming views: `drawTableLines` yields the same bytes as /// `drawTable` line by line (no trailing newlines — ready for a `LiveRegion` /// frame), and `drawTableChunks!false` reveals the table cell by cell. private
(alias) object.string = string
string
string table.streamingNote()

Demonstrates the streaming views: drawTableLines yields the same bytes as drawTable line by line (no trailing newlines — ready for a LiveRegion frame), and drawTableChunks!false reveals the table cell by cell.

streamingNote
()
{ import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.iteration

This is a submodule of std.algorithm. It contains generic iteration algorithms.

Function Name Description
cache Eagerly evaluates and caches another range's front.
lazyCache Lazily evaluates and caches another range's front, unlike cache.
cacheBidirectional As above, but also provides back and popBack.
chunkBy chunkBy!((a,b) => a[1] == b[1])([[1, 1], [1, 2], [2, 2], [2, 1]]) returns a range containing 3 subranges: the first with just [1, 1]; the second with the elements [1, 2] and [2, 2]; and the third with just [2, 1].
cumulativeFold cumulativeFold!((a, b) => a + b)([1, 2, 3, 4]) returns a lazily-evaluated range containing the successive reduced values 1, 3, 6, 10.
each each!writeln([1, 2, 3]) eagerly prints the numbers 1, 2 and 3 on their own lines.
filter filter!(a => a > 0)([1, -1, 2, 0, -3]) iterates over elements 1 and 2.
filterBidirectional Similar to filter, but also provides back and popBack at a small increase in cost.
fold fold!((a, b) => a + b)([1, 2, 3, 4]) returns 10.
group group([5, 2, 2, 3, 3]) returns a range containing the tuples tuple(5, 1), tuple(2, 2), and tuple(3, 2).
joiner joiner(["hello", "world!"], "; ") returns a range that iterates over the characters "hello; world!". No new string is created - the existing inputs are iterated.
map map!(a => a * 2)([1, 2, 3]) lazily returns a range with the numbers 2, 4, 6.
mean Colloquially known as the average, mean([1, 2, 3]) returns 2.
permutations Lazily computes all permutations using Heap's algorithm.
reduce reduce!((a, b) => a + b)([1, 2, 3, 4]) returns 10. This is the old implementation of fold.
splitWhen Lazily splits a range by comparing adjacent elements.
splitter Lazily splits a range by a separator, element predicate or whitespace.
substitute [1, 2].substitute(1, 0.1) returns [0.1, 2].
sum Same as fold, but specialized for accurate summation.
uniq Iterates over the unique elements in a range, which is assumed sorted.

Source

std/algorithm/iteration.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
iteration
:
(alias template) joiner = std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator sep)

Lazily joins a range of ranges with a separator. The separator itself is a range. If a separator is not provided, then the ranges are joined directly without anything in between them (often called flatten in other languages).

Params: r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of input ranges to be joined. sep = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) of element(s) to serve as separators in the joined range.

Returns: A range of elements in the joined range. This will be a bidirectional range if both outer and inner ranges of RoR are at least bidirectional ranges. Else if both outer and inner ranges of RoR are forward ranges, the returned range will be likewise. Otherwise it will be only an input range. The $(REF_ALTTEXT range bidirectionality, isBidirectionalRange, std,range,primitives) is propagated if no separator is specified.

See_also: $(REF chain, std,range), which chains a sequence of ranges with compatible elements into a single range.

Note: When both outer and inner ranges of RoR are bidirectional and the joiner is iterated from the back to the front, the separator will still be consumed from front to back, even if it is a bidirectional range too.

joiner
,
(alias template) map = std.algorithm.iteration.map(fun...) if (fun.length >= 1)

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Params: fun = one or more transformation functions

See_Also: $(HTTP en.wikipedia.org/wiki/Map_(higher-order_function), Map (higher-order function))

map
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) text = std.conv.text(T...)(T args) if (T.length > 0)

Convenience functions for converting one or more arguments of any type into _text (the three character widths).

text
,
(alias template) to = std.conv.to(T)

The to template converts a value from one type _to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 from double _to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string _to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -))

For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger))

to
;
import
(package) std
std
.
(module) std.range

This module defines the notion of a range. Ranges generalize the concept of arrays, lists, or anything that involves sequential access. This abstraction enables the same set of algorithms (see std.algorithm) to be used with a vast variety of different concrete types. For example, a linear search algorithm such as find works not just for arrays, but for linked-lists, input files, incoming network data, etc.

Guides

There are many articles available that can bolster understanding ranges:

Submodules

This module has two submodules:

The std.range.primitives submodule provides basic range functionality. It defines several templates for testing whether a given object is a range, what kind of range it is, and provides some common range operations.

The std.range.interfaces submodule provides object-based interfaces for working with ranges via runtime polymorphism.

The remainder of this module provides a rich set of range creation and composition templates that let you construct new ranges out of existing ranges:

| chain | Concatenates several ranges into a single range. | | choose | Chooses one of two ranges at runtime based on a boolean condition. | | chooseAmong | Chooses one of several ranges at runtime based on an index. | | chunks | Creates a range that returns fixed-size chunks of the original range. | | cycle | Creates an infinite range that repeats the given forward range indefinitely. Good for implementing circular buffers. | | drop | Creates the range that results from discarding the first n elements from the given range. | | dropBack | Creates the range that results from discarding the last n elements from the given range. | | dropExactly | Creates the range that results from discarding exactly n of the first elements from the given range. | | dropBackExactly | Creates the range that results from discarding exactly n of the last elements from the given range. | | dropOne | Creates the range that results from discarding the first element from the given range. | | dropBackOne | Creates the range that results from discarding the last element from the given range. | | enumerate | Iterates a range with an attached index variable. | | evenChunks | Creates a range that returns a number of chunks of approximately equal length from the original range. | | frontTransversal | Creates a range that iterates over the first elements of the given ranges. | | generate | Creates a range by successive calls to a given function. This allows to create ranges as a single delegate. | | indexed | Creates a range that offers a view of a given range as though its elements were reordered according to a given range of indices. | | iota | Creates a range consisting of numbers between a starting point and ending point, spaced apart by a given interval. | | lockstep | Iterates n ranges in lockstep, for use in a foreach loop. Similar to zip, except that lockstep is designed especially for foreach loops. | | nullSink | An output range that discards the data it receives. | | only | Creates a range that iterates over the given arguments. | | padLeft | Pads a range to a specified length by adding a given element to the front of the range. Is lazy if the range has a known length. | | padRight | Lazily pads a range to a specified length by adding a given element to the back of the range. | | radial | Given a random-access range and a starting point, creates a range that alternately returns the next left and next right element to the starting point. | | recurrence | Creates a forward range whose values are defined by a mathematical recurrence relation. | | refRange | Pass a range by reference. Both the original range and the RefRange will always have the exact same elements. Any operation done on one will affect the other. | | repeat | Creates a range that consists of a single element repeated n times, or an infinite range repeating that element indefinitely. | | retro | Iterates a bidirectional range backwards. | | roundRobin | Given n ranges, creates a new range that return the n first elements of each range, in turn, then the second element of each range, and so on, in a round-robin fashion. | | sequence | Similar to recurrence, except that a random-access range is created. | | slide | Creates a range that returns a fixed-size sliding window over the original range. Unlike chunks, it advances a configurable number of items at a time, not one chunk at a time. | | stride | Iterates a range with stride n. | | tail | Return a range advanced to within n elements of the end of the given range. | | take | Creates a sub-range consisting of only up to the first n elements of the given range. | | takeExactly | Like take, but assumes the given range actually has n elements, and therefore also defines the length property. | | takeNone | Creates a random-access range consisting of zero elements of the given range. | | takeOne | Creates a random-access range consisting of exactly the first element of the given range. | | tee | Creates a range that wraps a given range, forwarding along its elements while also calling a provided function with each element. | | transposed | Transposes a range of ranges. | | transversal | Creates a range that iterates over the n'th elements of the given random-access ranges. | | zip | Given n ranges, creates a range that successively returns a tuple of all the first elements, a tuple of all the second elements, etc. |

Sortedness

Ranges whose elements are sorted afford better efficiency with certain operations. For this, the assumeSorted function can be used to construct a SortedRange from a pre-sorted range. The sort function also conveniently returns a SortedRange. SortedRange objects provide some additional range operations that take advantage of the fact that the range is sorted.

Source

std/range/package.d

@licenseBoost License 1.0.@authorsAndrei Alexandrescu, David Simcha, Jonathan M Davis, and Jack Stouffer. Credit for some of the ideas in building this module goes to Leonardo Maffi.
range
:
(alias template) enumerate = std.range.enumerate(Enumerator = size_t, Range)(Range range, Enumerator start = 0) if (isIntegral!Enumerator && isInputRange!Range)

Iterate over range with an attached index variable.

Each element is a $(REF Tuple, std,typecons) containing the index and the element, in that order, where the index member is named index and the element member is named value.

The index starts at start and is incremented by one on every iteration.

Overflow: If range has length, then it is an error to pass a value for start so that start + range.length is bigger than Enumerator.max, thus it is ensured that overflow cannot happen.

    If `range` does not have length, and `popFront` is called when
    `front.index == Enumerator.max`, the index will overflow and
    continue from `Enumerator.min`.

Params: range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to attach indexes to start = the number to start the index counter from

Returns: At minimum, an input range. All other range primitives are given in the resulting range if range has them. The exceptions are the bidirectional primitives, which are propagated only if range has length.

Example: Useful for using foreach with an index loop variable:

    import std.stdio : stdin, stdout;
    import std.range : enumerate;

    foreach (lineNum, line; stdin.byLine().enumerate(1))
        stdout.writefln("line #%s: %s", lineNum, line);

----

enumerate
;
import
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.table

The span-capable table: pure model resolution in sparkles.ui.components.table.grid, the content-agnostic layout core (configuration, width/height solving, junction glyphs, line ordering) in sparkles.ui.components.table.layout, and the string view in sparkles.ui.components.table.render, re-exported here under the historical module name. Nothing else lives in this file — the test runner does not discover unittests in package.d modules.

The widget view (sparkles.ui.components.table.widgets) is deliberately not re-exported: it imports the whole toolkit — canvas, chrome, state, widget, wrap — where the three modules above reach no further than sparkles:base. Re-exporting it would put that closure on every consumer of drawTable, including the wasm playground, which compiles a hand-listed set of source directories and fails outright when the closure widens. Import it by its own module path where the widget view is actually wanted.

table
:
(alias template) drawTableChunks = sparkles.ui.components.table.render.drawTableChunks(bool lineBuffered = true)(string[][] cells, TableProps props = TableProps.init)

The chunk view of drawTable (the sibling of drawBoxChunks): chunks carry their own newlines and join("") reproduces drawTable byte-for-byte.

lineBuffered: true yields one chunk per rendered body text line (line + '\n'); lineBuffered: false yields one chunk per contentful cell field (the aligned content pad run), so pacing the output reveals the table cell by cell in reading order. Frame pieces — borders, junction rules (including a spliced title/footer), separators, blank filler fields — never form a standalone chunk: they accumulate as a pending prefix merged onto the next content chunk, and the trailing frame (closing border, bottom rule) is appended to the final content chunk. A table with no content at all degrades to a single chunk carrying the whole frame.

drawTableChunks
,
(alias) drawTableLines = sparkles.ui.components.table.render.TableLineRange sparkles.ui.components.table.render.drawTableLines(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null)) @system

The lazy line view of drawTable: eager layout, lazy emission. Table layout is two-pass (column widths scan all content), so unlike the fixed-width drawBox case the input can never be consumed lazily; what is lazy is emission — each rule / body text line is built on demand from the resolved layout.

A forward range of string lines without trailing newlines (ready for LiveRegion.update), with .length. Parity: drawTableLines(c, p).map!(l => l ~ '\n').join == drawTable(c, p) byte-for-byte (drawTable terminates every line, including the last), i.e. drawTableLines(c, p).array == drawTable(c, p).splitLines. An empty grid is an empty range (drawTable's historical "").

drawTableLines
;
auto
(local variable) string[][] cells
cells
= [["a", "b"], ["1", "2"]];
(alias) object.string = string
string
(local variable) string out_
out_
;
foreach (
(local variable) ulong i
i
,
(local variable) string line
line
;
sparkles.ui.components.table.render.TableLineRange sparkles.ui.components.table.render.drawTableLines(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null)) @system

The lazy line view of drawTable: eager layout, lazy emission. Table layout is two-pass (column widths scan all content), so unlike the fixed-width drawBox case the input can never be consumed lazily; what is lazy is emission — each rule / body text line is built on demand from the resolved layout.

A forward range of string lines without trailing newlines (ready for LiveRegion.update), with .length. Parity: drawTableLines`(c, p).map!(l => l ~ '\n').join == drawTable(c, p)` byte-for-byte (drawTable terminates every line, including the last), i.e. drawTableLines(c, p).array == drawTable(c, p).splitLines. An empty grid is an empty range (drawTable's historical "").

drawTableLines
(
(local variable) string[][] cells
cells
).
std.range.enumerate!(ulong, TableLineRange).Result std.range.enumerate!(ulong, sparkles.ui.components.table.render.TableLineRange)(sparkles.ui.components.table.render.TableLineRange range, ulong start = 0LU) pure nothrow @nogc @safe

Iterate over range with an attached index variable.

Each element is a Tuple containing the index and the element, in that order, where the index member is named index and the element member is named value.

The index starts at start and is incremented by one on every iteration.

Overflow

If range has length, then it is an error to pass a value for start so that ``start + range.length is bigger than Enumerator.max, thus it is ensured that overflow cannot happen.

If range does not have length, and popFront is called when front.index == Enumerator.max, the index will overflow and continue from Enumerator.min.

Example

Useful for using foreach with an index loop variable:

    import std.stdio : stdin, stdout;
    import std.range : enumerate;

    foreach (lineNum, line; stdin.byLine().enumerate(1))
        stdout.writefln("line #%s: %s", lineNum, line);

Examples

Can start enumeration from a negative position:

import std.array : assocArray;
import std.range : enumerate;

bool[int] aa = true.repeat(3).enumerate(-1).assocArray();
assert(aa[-1]);
assert(aa[0]);
assert(aa[1]);
@paramrange the input range to attach indexes to@paramstart the number to start the index counter from@returnsAt minimum, an input range. All other range primitives are given in the resulting range if range has them. The exceptions are the bidirectional primitives, which are propagated only if range has length.
enumerate
)
(local variable) string out_
out_
~=
string std.conv.text!(string, ulong, string, string, string)(string __param_0, ulong __param_1, string __param_2, string __param_3, string __param_4) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
("line ",
(local variable) ulong i
i
, ": ",
(local variable) string line
line
, "\n");
const
(local variable) const(string) chunks
chunks
=
sparkles.ui.components.table.render.TableChunkRange!false sparkles.ui.components.table.render.drawTableChunks!false(string[][] cells, sparkles.ui.components.table.layout.TableProps props = TableProps(TableGlyphs('\u256d', '\u256e', '\u2570', '\u256f', '\u2500', '\u2502', '\u252c', '\u2534', '\u251c', '\u2524', '\u253c', '\u250c', '\u2510', '\u2514', '\u2518', '\u257c', '\u257e', EmphasisGlyphs('\u2501', '\u2502', '\u252f', '\u2537', '\u251d', '\u2525', '\u253f', '\u250d', '\u2511', '\u2515', '\u2519'), EmphasisGlyphs('\u2500', '\u2503', '\u2530', '\u2538', '\u2520', '\u2528', '\u2542', '\u250e', '\u2512', '\u2516', '\u251a'), EmphasisGlyphs('\u2501', '\u2503', '\u2533', '\u253b', '\u2523', '\u252b', '\u254b', '\u250f', '\u2513', '\u2517', '\u251b')), true, true, false, 0LU, 0LU, 0LU, null, null, null, null, Align.left, null, VAlign.top, null)) @system

The chunk view of drawTable (the sibling of drawBoxChunks): chunks carry their own newlines and join("") reproduces drawTable byte-for-byte.

lineBuffered: true yields one chunk per rendered body text line (line + '\n'); lineBuffered: false yields one chunk per contentful cell field (the aligned content pad run), so pacing the output reveals the table cell by cell in reading order. Frame pieces — borders, junction rules (including a spliced title/footer), separators, blank filler fields — never form a standalone chunk: they accumulate as a pending prefix merged onto the next content chunk, and the trailing frame (closing border, bottom rule) is appended to the final content chunk. A table with no content at all degrades to a single chunk carrying the whole frame.

drawTableChunks
!false(
(local variable) string[][] cells
cells
).
std.algorithm.iteration.MapResult!(to, TableChunkRange!false) std.algorithm.iteration.map!(to).map!(sparkles.ui.components.table.render.TableChunkRange!false)(sparkles.ui.components.table.render.TableChunkRange!false r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(
(template) std.conv.to!string

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
).
std.algorithm.iteration.joiner!(MapResult!(to, TableChunkRange!false), string).Result std.algorithm.iteration.joiner!(std.algorithm.iteration.MapResult!(to, TableChunkRange!false), string)(std.algorithm.iteration.MapResult!(to, TableChunkRange!false) r, string sep) @system

Lazily joins a range of ranges with a separator. The separator itself is a range. If a separator is not provided, then the ranges are joined directly without anything in between them (often called flatten in other languages).

Note

When both outer and inner ranges of RoR are bidirectional and the joiner is iterated from the back to the front, the separator will still be consumed from front to back, even if it is a bidirectional range too.

Examples

import std.algorithm.comparison : equal;
import std.conv : text;

assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
    .joiner("...")
    .equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));
@paramr An input range of input ranges to be joined.@paramsep A forward range of element(s) to serve as separators in the joined range.@returnsA range of elements in the joined range. This will be a bidirectional range if both outer and inner ranges of RoR are at least bidirectional ranges. Else if both outer and inner ranges of RoR are forward ranges, the returned range will be likewise. Otherwise it will be only an input range. The range bidirectionality is propagated if no separator is specified.@seechain, which chains a sequence of ranges with compatible elements into a single range.
joiner
(" ⏵ ").
string std.conv.to!string.to!(std.algorithm.iteration.joiner!(MapResult!(to, TableChunkRange!false), string).Result)(std.algorithm.iteration.joiner!(MapResult!(to, TableChunkRange!false), string).Result __param_0) @system

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
;
(local variable) string out_
out_
~= "\ncell chunks: " ~
(local variable) const(string) chunks
chunks
;
return
(local variable) string out_
out_
;
}