/** * Flat-event lexer substrate — the engine beneath the hand-written per-language * lexers (`lexer_json.ts`, `lexer_ts.ts`, …). * * Tokens are emitted as variable-length records into one `Int32Array`: * * - leaf: `[type_id, start, end]` where `type_id > 0` * - open: `[-type_id, start]` — opens a container token * - close: `[0, end]` — closes the innermost open container * * Untyped text is implicit — it's the gap between events, recovered from * offsets. Adjacent same-type leaves are coalesced at emit time so runs like * `});` become one span. * * @module */ /** * Interned metadata for a token type. */ export interface TokenTypeInfo { id: number; name: string; aliases: Array; /** * Space-separated CSS classes, e.g. `'token_null token_keyword'`. */ classes: string; /** * Precomputed HTML open tag, e.g. `''`. */ open_tag: string; } /** * An id space of interned token types with precomputed CSS classes and HTML * open tags. Ids are only meaningful against the registry that interned them — * a lexed event stream resolves back through the registry stamped on its * `LexedSyntax`. */ export declare class TokenTypeRegistry { #private; /** * Interned infos indexed by id. Hot loops hoist and index this directly; * grow it only via `intern`. */ readonly infos: Array; /** * Interns a token type by name (+ optional aliases) and returns its id. * Repeated calls with the same name and aliases return the same id. The CSS * class list and HTML open tag are precomputed here so emitters never build * class strings at runtime. */ intern(name: string, alias?: string | Array): number; /** * Looks up the interned info for a token type id. */ info(id: number): TokenTypeInfo; } /** * The shared default registry — the single id space used by the built-in * lexers' module-load `token_type` constants and by any `SyntaxStyler` not * given its own registry. The type vocabulary is global by design, mirroring * the global `.token_*` CSS namespace; per-registry isolation exists for * fully-custom stylers and tests, whose lexers must intern into the same * registry they're rendered against. */ export declare const token_types_global: TokenTypeRegistry; /** * Interns a token type into `token_types_global` — the zero-config authoring * path used by the built-in lexers' module-load type constants. */ export declare const token_type: (name: string, alias?: string | Array) => number; /** * Builds a word→kind classification map from `[kind, words]` entries, where * `words` is space-separated — the shared shape of the lexers' keyword tables. */ export declare const words_map: (...entries: Array<[kind: number, words: string]>) => Map; /** * A lexer-based language registration. */ export interface SyntaxLang { /** * Primary language id, e.g. `'ts'`. */ id: string; /** * Alternate ids resolving to this language, e.g. `['typescript']`. */ aliases?: Array; /** * Lexes the `lexer`'s current `[pos, end)` window, emitting token events. * Must never throw and must always terminate with `lexer.pos === lexer.end`. */ lex: (lexer: Lexer) => void; } /** * The result of lexing: the source text plus its flat token event stream. */ export interface LexedSyntax { text: string; events: Int32Array; events_len: number; /** * The registry that interned the type ids in `events` — consumers resolve * ids through it, so a stream can never be rendered against the wrong * id space. */ types: TokenTypeRegistry; } /** * Shared lexing context passed to language lex functions. Holds the text * window, the event buffer, and the language registry for embedding. */ export declare class Lexer { #private; text: string; pos: number; end: number; /** * Language registry for `embed` — set by `lex_syntax`. */ langs: Map | null; events: Int32Array; events_len: number; constructor(capacity?: number); /** * Emits a leaf token. Empty spans are dropped; a leaf adjacent to a * preceding leaf of the same type extends it instead (span coalescing). */ leaf(type_id: number, start: number, end: number): void; /** * Opens a container token at `start`. Must be balanced by a later `close`. */ open(type_id: number, start: number): void; /** * Closes the innermost open container at `end`. */ close(end: number): void; /** * Lexes `[start, end)` with the language registered as `lang_id`, * restoring this lexer's window afterward. Returns `false` (leaving the * region as plain text) when the language isn't registered or embedding * is nested past `MAX_EMBED_DEPTH`. */ embed(lang_id: string, start: number, end: number): boolean; } /** * Lexes `text` with `lang`, returning the flat token event stream. * * @param langs - registry used to resolve embedded languages by id * @param types - token-type registry stamped on the result; must be the one * `lang` (and any embedded language) interned its type ids into */ export declare const lex_syntax: (text: string, lang: SyntaxLang, langs?: Map, types?: TokenTypeRegistry) => LexedSyntax; /** * Renders a lexed token event stream to HTML in one forward pass. * Gap text is copy-escaped; token spans use the precomputed open tags. */ export declare const render_syntax_html: (lexed: LexedSyntax) => string; /** * A flattened token span, in document order with containers before their * children. Used by fixtures, tests, and range building. */ export interface SyntaxEventToken { type: string; start: number; end: number; } /** * Flattens a lexed event stream to `SyntaxEventToken`s in document order * (containers precede their children). */ export declare const syntax_events_to_tokens: (lexed: LexedSyntax) => Array; /** * Validates a lexed event stream's structural invariants, returning a list of * human-readable issues (empty when valid): records well-formed, offsets * monotonic and in-bounds, containers balanced. */ export declare const validate_syntax_events: (lexed: LexedSyntax) => Array; export declare const is_space: (c: number) => boolean; /** * Case-insensitive ASCII match of `word` (must be lowercase) at * `text[from..]`, via `code | 0x20` folding — never allocates, unlike * `toLowerCase()` comparisons. */ export declare const matches_ci: (text: string, from: number, word: string) => boolean; export declare const is_digit: (c: number) => boolean; export declare const is_upper: (c: number) => boolean; export declare const is_ascii_alnum: (c: number) => boolean; /** * A `\w` word char — ASCII letters, digits, and `_`. */ export declare const is_ascii_word: (c: number) => boolean; export declare const is_hex_digit: (c: number) => boolean; export declare const is_ident_start: (c: number) => boolean; export declare const is_ident: (c: number) => boolean; /** * Scans an identifier starting at `from` (assumed to be an identifier start), * returning the exclusive end index. */ export declare const scan_ident: (text: string, from: number, end: number) => number; /** * Skips whitespace (including newlines) from `from`, returning the next * non-space index. */ export declare const skip_space: (text: string, from: number, end: number) => number; /** * Trims trailing whitespace from a `[from, to)` span, returning the new * exclusive end. */ export declare const trim_space_end: (text: string, from: number, to: number) => number; /** * Returns the index of the next `\n` at or after `i` (exclusive end of the * line's content, excluding a preceding `\r`), or `end` when there is none. * Uses native `indexOf` — the fast path for line-oriented scans. */ export declare const scan_to_line_end: (text: string, i: number, end: number) => number; /** * Skips a js-style quoted span from the quote at `from` (used inside balanced * scans), returning the index after the closing quote. Unterminated `'`/`"` * strings stop at the newline; templates (`` ` ``) span lines. */ export declare const skip_quoted: (text: string, from: number, end: number, quote: number) => number; /** * Returns the cached next occurrence of `ch` at or after `from`, re-probing * with `indexOf` only when the cached position has fallen behind. `Infinity` * when the text has no further occurrence — a monotonic probe that keeps * delimiter scans linear across a construct that is dense in `ch`. */ export declare const advance_probe: (text: string, cached: number, from: number, ch: string) => number; /** * Finds the matching `}` for the `{` at `i`, skipping js-style strings, * templates, and comments. Returns -1 when unbalanced within the window. */ export declare const scan_balanced_braces: (text: string, i: number, end: number) => number; //# sourceMappingURL=lexer.d.ts.map