php-dextrin

Formatter
in package

FinalYes

Multi-line, indented `.dxn` rendering -- the `pretty: true` option on `Dextrin::encode()`, built on top of {@see Printer}. Every empty collection and every scalar falls through to the single-line printer unchanged (there's nothing multi-line about `[]` or `42`).

The layout (Jan, 2026-10-20): the top-level collection always breaks, one entry per line, however short it is. A nested collection is written on one line, its entries single-space separated, when that line -- its indent and its key included -- fits the width ($width, 80); otherwise it breaks too, and what it holds is laid out again by the same rule. Columns are counted in code points.

Comments cannot be preserved here, for the same reason no formatter built on this library's decode-then-reprint approach could: the lexer discards # comments as trivia before a value ever exists to carry them forward.

Same optional $registry as Printer, threaded through so a registered application class instance prints under its schema's name -- see Printer's own doc.

Table of Contents

Constants

DEFAULT_INDENT  : mixed = 2
DEFAULT_WIDTH  : mixed = 80

Methods

pretty()  : string
__construct()  : mixed
allowedPairs()  : array<int, array{0: mixed, 1: mixed}>
`$pairs`, having checked every key is one DXN.md §1.6 allows.
bracketed()  : string
bracketedEntries()  : string
bracketedItemsAndEntries()  : string
extraPairs()  : array<int, array{0: mixed, 1: mixed}>
A struct's extra fields as entries: a name like a field name, any other map key as itself.
indentStr()  : string
joined()  : string
The rendered entries between `$open` and `$close`: single-space separated on one line, or one per line, indented.
keywordPairs()  : array<int, DXNKeyword, 1: mixed}>
Struct field names and plain-object property names are always genuinely keyword-shaped (`DXN.md` §1.2's `map_entry` grammar applies to `%Name{...}`'s body too) -- never ambiguous with a string-typed key the way a bare `map`'s own key can be, so they get wrapped as `DXNKeyword` unconditionally, up front, rather than leaving `renderEntry()` to guess from a bare string alone.
layout()  : string
mapToDxnPairs()  : array<int, DXNKeyword|int|string, 1: mixed}>
A bare PHP array's own key already tells `MapBuilder::toDxnMapKey()` apart a `DXNKeyword` key from a `string` key with the same text (see that class's own doc) -- this converts every pair to that unambiguous form before `renderEntry()` ever sees it, so `renderEntry()` itself never has to guess.
render()  : string
A nested value on one line when that fits the room its line leaves it, and laid out over lines otherwise. The top level (depth 0) and a value inside a one-line one go straight to `layout()`.
renderEntry()  : string
Same colon-shorthand-vs-arrow-form rule as {@see Printer}'s own `printEntry()`/`printKeywordEntry()`: only a genuine `DXNKeyword` key gets the shorthand-or-keyword-arrow treatment.
renderPlainObject()  : string
A genuine application class instance -- every built-in DXN shape is already handled by `render()`'s own dispatch above.

Constants

DEFAULT_INDENT

private mixed DEFAULT_INDENT = 2

DEFAULT_WIDTH

private mixed DEFAULT_WIDTH = 80

Methods

pretty()

public static pretty(mixed $value[, int $indentSize = self::DEFAULT_INDENT ][, Registry|null $registry = null ][, int $width = self::DEFAULT_WIDTH ]) : string
Parameters
$value : mixed
$indentSize : int = self::DEFAULT_INDENT
$registry : Registry|null = null
$width : int = self::DEFAULT_WIDTH
Return values
string

allowedPairs()

`$pairs`, having checked every key is one DXN.md §1.6 allows.

private static allowedPairs(array<int, array{0: mixed, 1: mixed}> $pairs) : array<int, array{0: mixed, 1: mixed}>
Parameters
$pairs : array<int, array{0: mixed, 1: mixed}>
Return values
array<int, array{0: mixed, 1: mixed}>

bracketed()

private static bracketed(string $open, array<int, mixed> $items, string $close, int $depth, Layout $l) : string
Parameters
$open : string
$items : array<int, mixed>
$close : string
$depth : int
$l : Layout
Return values
string

bracketedEntries()

private static bracketedEntries(string $open, array<int, array{0: mixed, 1: mixed}> $pairs, string $close, int $depth, Layout $l) : string
Parameters
$open : string
$pairs : array<int, array{0: mixed, 1: mixed}>
$close : string
$depth : int
$l : Layout
Return values
string

bracketedItemsAndEntries()

private static bracketedItemsAndEntries(DXNStruct $value, int $depth, Layout $l) : string
Parameters
$value : DXNStruct
$depth : int
$l : Layout
Return values
string

extraPairs()

A struct's extra fields as entries: a name like a field name, any other map key as itself.

private static extraPairs(DXNStruct $value) : array<int, array{0: mixed, 1: mixed}>
Parameters
$value : DXNStruct
Return values
array<int, array{0: mixed, 1: mixed}>

indentStr()

private static indentStr(int $depth, Layout $l) : string
Parameters
$depth : int
$l : Layout
Return values
string

joined()

The rendered entries between `$open` and `$close`: single-space separated on one line, or one per line, indented.

private static joined(string $open, array<int, string> $rendered, string $close, int $depth, Layout $l) : string
Parameters
$open : string
$rendered : array<int, string>
$close : string
$depth : int
$l : Layout
Return values
string

keywordPairs()

Struct field names and plain-object property names are always genuinely keyword-shaped (`DXN.md` §1.2's `map_entry` grammar applies to `%Name{...}`'s body too) -- never ambiguous with a string-typed key the way a bare `map`'s own key can be, so they get wrapped as `DXNKeyword` unconditionally, up front, rather than leaving `renderEntry()` to guess from a bare string alone.

private static keywordPairs(array<int, array{0: string, 1: mixed}> $pairs) : array<int, DXNKeyword, 1: mixed}>
Parameters
$pairs : array<int, array{0: string, 1: mixed}>
Return values
array<int, DXNKeyword, 1: mixed}>

layout()

private static layout(mixed $value, int $depth, Layout $l) : string
Parameters
$value : mixed
$depth : int
$l : Layout
Return values
string

mapToDxnPairs()

A bare PHP array's own key already tells `MapBuilder::toDxnMapKey()` apart a `DXNKeyword` key from a `string` key with the same text (see that class's own doc) -- this converts every pair to that unambiguous form before `renderEntry()` ever sees it, so `renderEntry()` itself never has to guess.

private static mapToDxnPairs(array<int|string, mixed> $map) : array<int, DXNKeyword|int|string, 1: mixed}>
Parameters
$map : array<int|string, mixed>
Return values
array<int, DXNKeyword|int|string, 1: mixed}>

render()

A nested value on one line when that fits the room its line leaves it, and laid out over lines otherwise. The top level (depth 0) and a value inside a one-line one go straight to `layout()`.

private static render(mixed $value, int $depth, Layout $l) : string
Parameters
$value : mixed
$depth : int
$l : Layout
Return values
string

renderEntry()

Same colon-shorthand-vs-arrow-form rule as {@see Printer}'s own `printEntry()`/`printKeywordEntry()`: only a genuine `DXNKeyword` key gets the shorthand-or-keyword-arrow treatment.

private static renderEntry(mixed $key, mixed $value, int $depth, Layout $l) : string

Every other key (ordered-map's own preserved key type, or a bare map's already-disambiguated MapBuilder::toDxnMapKey() result) renders through the generic value printer on the arrow's left side -- correctly quoting a genuinely string-typed key instead of guessing it was a keyword.

Parameters
$key : mixed
$value : mixed
$depth : int
$l : Layout
Return values
string

renderPlainObject()

A genuine application class instance -- every built-in DXN shape is already handled by `render()`'s own dispatch above.

private static renderPlainObject(object $value, int $depth, Layout $l) : string

Same three-way registry precedence as Printer::printPlainObjectAsStruct()'s own doc, in one pass (no repeated registry lookups, unlike calling that precedence twice from two different helpers would need):

  1. A struct schema registered for this class renders as that named struct, multi-line if it has any fields.
  2. Otherwise, a registered tag encoder means this isn't struct-shaped at all -- defers entirely to Printer::print()'s own single-line @tag value handling, the same precedent already set for DXNCustomTag (never rendered multi-line by this class either).
  3. Otherwise, the PHP-specific "any object is data" convenience: multi-line if it has any public properties, single-line (Printer::print()) if it has none.
Parameters
$value : object
$depth : int
$l : Layout
Return values
string
On this page

Search results