API / Minn\Content / TagBalancer

TagBalancer final class

Minn\Content\TagBalancer · public/minn/src/Minn/Content/TagBalancer.php · 82 lines

Closes what markup leaves open and drops what it closes without opening, as the reference's force_balance_tags does, from its observed rules (contracts/runtime.md "The content filters"): tag names are lowercased; a void element is written self-closed (bare as <br />, with attributes as <img src="x"/>, one already self-closed as given); reopening the innermost open element closes it first unless it is one of the ten that may contain themselves; a closer shuts every element opened inside its own; a closer with nothing to close goes; what is still open at the end closes in reverse. Script and style text is left as it is, and a "<" not followed by a name is text.

Constants and properties

privateVOID = array ( 0 => 'area', 1 => 'base', 2 => 'basefont', 3 => 'br', 4 => 'col', 5 => 'command', 6 => 'embed', 7 => 'frame', 8 => 'hr', 9 => 'img', 10 => 'input', 11 => 'isindex', 12 => 'link', 13 => 'meta', 14 => 'param', 15 => 'source', 16 => 'track', 17 => 'wbr', )
privateNESTABLE = array ( 0 => 'article', 1 => 'aside', 2 => 'blockquote', 3 => 'details', 4 => 'div', 5 => 'figure', 6 => 'object', 7 => 'q', 8 => 'section', 9 => 'span', )
privateRAW = array ( 0 => 'script', 1 => 'style', )
privateTAG = '/<(\\/?)([a-zA-Z][\\w:-]*)(\\s[^>]*|\\/)?>/'

Public

staticbalance(string $text): string#

The markup with every element closed in order and every stray closer gone.

Internals 3

Private and protected methods: how the class does its work. Not a contract; they change whenever the code is tidied.

privateclose(array $stack, string $name): string#

A closer: every element opened inside the named one closes with it; with nothing to close it is dropped. @param list<string> $stack

$stacklist<string>
privatevoidAttributes(string $attributes): string#

A void element's attributes, written self-closed.

privaterawText(string $text, int $offset, string $name): array#

Script or style text up to the element's own closer, which stays for the main loop. @return array{0: string, 1: int}

@return array{0: string, 1: int}