/** * The split grammar of a comic page (`:::page{split="30 [30 | 20 | *] / *"}`, * #555): how the page's frame is cut into panels. * * ``` * list := item (SEP item)* SEP is '/' (rows, stacked top to bottom) * or '|' (columns, from the start side) * item := size [ '[' list ']' ] a bracketed list splits that cell on the * other axis * size := number ['%'] ['~' number ['%']] | '*' | '' * ``` * * A size is the cell's extent along its list's axis, in percent of the * parent cell; the split lines sit at the running sums. `*` takes an equal * share of what is left; an empty size is a `*`. `30~40` slants the cell's * far edge: 30 % at the start of the cross axis (the top, for columns; the * start side, for rows), 40 % at its other end. The last cell of a list * runs to 100 % whatever its size says. * * Everything here is pure: the parser keeps the source offsets of every * size so the Sandbox can rewrite one number in place, and the editing * functions (`moveComicSplitLine`, `splitComicCell`, `mergeComicCells`) * take a `split` value and return the new one. */ /** The axis a list splits its cell along: `'rows'` stacks tiers top to * bottom, `'columns'` sets cells side by side from the start side. */ export type ComicSplitAxis = 'rows' | 'columns'; /** A size as written. */ export interface ComicSplitSize { /** `*`, or an empty size (`implicit`). */ star: boolean; /** The size was left empty (`[*|*] / *`): a `*` that serialises as * nothing. */ implicit?: boolean; /** Percent at the start end. Unset for a star. */ start?: number; /** Percent at the far end, when the size is slanted (`30~40`). */ end?: number; /** Written with a `%` sign. */ percent?: boolean; /** Offsets of the size in the source (empty at the item's start for an * implicit size). */ sourceStart: number; sourceEnd: number; } /** One cell of a list, with the list that splits it further. */ export interface ComicSplitItem { size: ComicSplitSize; children?: ComicSplitList; sourceStart: number; sourceEnd: number; } /** A list of cells sharing one axis. A one-item list has none. */ export interface ComicSplitList { axis?: ComicSplitAxis; items: ComicSplitItem[]; sourceStart: number; sourceEnd: number; } /** A size token with where it sits in the tree: `path` is the list's path * (the indices of the items walked down from the top list), `index` the * item's in that list. */ export interface ComicSplitToken { path: number[]; index: number; size: ComicSplitSize; } /** Something the grammar could not read as written. */ export interface ComicSplitIssue { kind: 'syntax' | 'overflow'; message: string; sourceStart: number; sourceEnd: number; /** `overflow`: the sum of the list's sizes (percent). */ total?: number; } export interface ComicSplitParse { tree: ComicSplitList; tokens: ComicSplitToken[]; issues: ComicSplitIssue[]; } /** The smallest share a cell keeps (percent) when the sizes of its list * overflow, and the least a drag leaves a cell. */ export declare const COMIC_MIN_CELL_PERCENT = 5; /** Parse a `split` value. Never throws: what cannot be read is reported in * `issues` and the rest is kept (an empty or unreadable value is one * cell, a splash page). */ export declare function parseComicSplit(src: string): ComicSplitParse; /** The axis a list's children split on: its own, or for a one-item list * the cross axis of its parent (rows at the top). */ export declare function crossAxis(axis: ComicSplitAxis): ComicSplitAxis; /** * The line positions of a list (cumulative percent of its cell) at each end * of the cross axis: `lines[b]` is the line between items `b` and `b + 1`. * Stars share what the fixed sizes leave; sizes past 100 are scaled down so * every star keeps {@link COMIC_MIN_CELL_PERCENT}; the last item runs to * 100. Lines never run backwards. */ export declare function comicSplitLines(list: ComicSplitList): { start: number[]; end: number[]; }; /** The list at `path` (item indices walked down from the top list). */ export declare function comicSplitListAt(tree: ComicSplitList, path: readonly number[]): ComicSplitList | undefined; /** Leaf cells in reading order (tree order), each with its item path. */ export declare function comicSplitLeaves(tree: ComicSplitList): number[][]; /** Write a tree back as a `split` value: ` / ` between rows, ` | ` between * columns, numbers with at most one decimal. */ export declare function serializeComicSplit(tree: ComicSplitList): string; /** * Move the split line between children `boundary` and `boundary + 1` of the * list at `path` to `newPercentAtStart` (cumulative percent of the parent * cell). With `newPercentAtEnd` the far end goes there (a slant); without * it the line keeps its slant, both ends moving by the same amount. The * line is clamped so every cell keeps {@link COMIC_MIN_CELL_PERCENT}. Only * the sizes that change are rewritten, in place; `*` stays where the * result allows. Returns `src` unchanged when the path names no line. */ export declare function moveComicSplitLine(src: string, path: readonly number[], boundary: number, newPercentAtStart: number, newPercentAtEnd?: number): string; /** * Split the cell at `cellPath` (item indices walked down from the top list) * in two along `axis` (`'rows'`: one above the other). A cell whose list * runs along `axis` gets a sibling after it, the two sharing its size; any * other cell is split by a bracketed list (`30` → `30 [* | *]`). Returns the * new `split` value, re-serialised (`serializeComicSplit`). */ export declare function splitComicCell(src: string, cellPath: readonly number[], axis: ComicSplitAxis): string; /** * Merge children `boundary` and `boundary + 1` of the list at `path` into one * cell spanning both (the split line between them goes). The merged cell * keeps the first one's own split, if any. A bracketed list left with one * cell loses its brackets. Returns the new `split` value, re-serialised. */ export declare function mergeComicCells(src: string, path: readonly number[], boundary: number): string; //# sourceMappingURL=split.d.ts.map