/** * The angle-bracket element form a target may activate: what one element is, * how deep a nest may go, and whether it may be broken across lines. Core owns * the shape and the layout; the target owns the vocabulary of tag names, which * never reaches this module. * * D115 §三 / D114 R1f: the markup half of `formatter.ts`. It is spelled * `markup` and not after any target's name, because Core must not embed a * target-owned word (`check:boundaries`). */ import type { CompilerExtension } from "../extension.ts"; /** * D39 §54 — the canonical shape of embedded angle-bracket markup. * * The formatter reflows one thing and only one thing: an element that both * opens and closes on a single physical line. Such an element is written on one * line while it fits inside the print width, and takes the block shape — open * tag, one child per line indented one level, closing tag at the element's own * indentation — as soon as it does not. Attributes follow the same rule one * level down: they stay on the open tag until the open tag alone overflows, * and then take one line each. * * Two rules keep this a layout change and never a rendering change: * * - Whitespace between children is program text. Markup drops a line break * with its surrounding indentation but keeps a written space, so an element * whose children carry meaningful spaces is never broken, and text is never * re-wrapped or re-spaced. * - Markup the author already spread across lines keeps its line structure, * exactly like every other construct in the language: the formatter * canonicalizes spelling, not the author's line breaks. */ export declare const MAX_MARKUP_DEPTH = 48; export type MarkupEmbedding = NonNullable["angleBracketEmbedding"] | null; export interface MarkupLayout { readonly indentWidth: number; /** The canonical indentation column of the line the markup starts on. */ readonly column: number; /** False inside a string interpolation, where a line break would change the string. */ readonly breakable: boolean; readonly embedding: MarkupEmbedding; } /** * The layout of markup that cannot take a line of its own — inside a string * interpolation, or inside a `{...}` hole. It still carries the embedding, so * markup nested further in is recognized as markup rather than re-spaced as * comparison operators. */ export declare function heldLayoutFor(embedding: MarkupEmbedding): MarkupLayout; export declare function markupLayout(indentWidth: number, column: number, embedding: MarkupEmbedding): MarkupLayout; export declare function heldMarkupLayout(layout: MarkupLayout): MarkupLayout; export interface MarkupAttribute { /** The attribute name, or "" for a `{...spread}` attribute. */ readonly name: string; /** The written value including its quotes or braces, or null for a bare attribute. */ readonly value: string | null; } export type MarkupChild = { readonly kind: "element"; readonly element: MarkupElement; } | { readonly kind: "expression"; readonly text: string; } | { readonly kind: "text"; readonly text: string; }; export interface MarkupElement { readonly tag: string; readonly attributes: readonly MarkupAttribute[]; readonly children: readonly MarkupChild[]; readonly selfClosing: boolean; } /** * Reads one balanced element starting at `<`. It returns null the moment the * element is not complete and unambiguous within `source` — an unclosed * element, a mismatched closing tag, an HTML comment, an unterminated string or * expression — and the caller then leaves the text exactly as written. */ export declare function scanMarkupElement(source: string, start: number, embedding: MarkupEmbedding, layout: MarkupLayout, depth?: number): { readonly element: MarkupElement; readonly end: number; } | null; /** * An element breaks between children only when it has no text child at all — * when it is a container of elements and holes rather than a piece of written * content. * * That is one line drawn for two reasons at once. It is the safe line: markup * renders a written space between children but not a line break with its * indentation, so any text child (even a bare "/" separator) could change what * the page shows if the boundaries around it moved. It is also the readable * line: a sentence belongs on its line, not spread one word and one hole at a * time. */ export declare function isBreakableMarkup(element: MarkupElement): boolean; //# sourceMappingURL=markup.d.ts.map