Cascade.LocSourceSource locations: byte-offset ranges in the CSS Syntax-preprocessed input.
Reader.of_string strips a leading UTF-8 BOM, replaces NUL with U+FFFD, and maps CR, FF and CRLF to LF before the lexer records these offsets.
Every Token.t and Component.t carries one.
Metadata level collected during parsing, mirroring ocaml-json's type meta:
`None: no source positions or snippets attached; fastest.`Locs: source positions are kept on tokens / components / errors (already unconditional in Cascade since tokens always carry t). Equivalent to `None in Cascade -- present for API symmetry with ocaml-json.`Full: also attach source-context snippets to errors and warnings, so Context.t.snippet is populated for diagnostics.default_meta_level is `Full. Entry points default to this so that callers who don't pass ?meta get the rich diagnostics behaviour.
v ~start_pos ~end_pos is a location spanning [start_pos, end_pos) in the preprocessed source buffer.
dummy is a location of zero width at position 0. For test data and synthetic values that don't come from a real input.
snippet source loc extracts a snippet of source around loc: source must be the same preprocessed buffer the lexer indexed, such as Reader.source; a caller's original BOM/CRLF/NUL/FF-containing string is in a different coordinate space.
Context.snippet.text is the window (default: 40 bytes on each side of the location), Context.snippet.marker_pos counts the characters of Context.snippet.text before loc.start_pos, and Context.snippet.marker_len counts the characters the located range spans.
A column is one Unicode scalar value, which a combining mark and a wide glyph each make approximate on a terminal. window is a target rather than a cap: a boundary falling inside a UTF-8 sequence moves outward to the lead byte, so Context.snippet.text is never a truncated code point.