Expand description
A total, lossless lexer for LaTeX surface syntax.
Every byte of the input ends up in exactly one token, so concatenating all token texts reproduces the input verbatim — the losslessness invariant. The lexer is mostly context-free, with a small set of statically recognizable modes:
\verb/\verb*inline verbatim: the delimited argument is consumed as a singleSyntaxKind::VERBtoken (otherwise the delimiters glue into ordinaryWORDruns and become un-splittable downstream).- verbatim-like environments (
verbatim,lstlisting,minted, …): the body between\begin{name}and\end{name}is oneSyntaxKind::VERBATIM_BODYtoken, so%,$,\inside are never (mis)lexed as comments / math. For argument-taking ones the\beginarguments are tokenized first (the built-in signature DB says where the raw body starts); see [lex_verbatim_environment]. \makeatletter/\makeatother: toggles@into a letter so that\foo@barlexes as one control word.\ExplSyntaxOn/\ExplSyntaxOff(also opened by\ProvidesExplPackage/\ProvidesExplClass/\ProvidesExplFile): toggles_and:into letters so expl3 names (\seq_new:N,\__module_internal:nn) lex as one control word. Composes with\makeatletterfor the@@module-prefix convention (\g_@@_frame_title_tl).\left/\rightdelimiters: the single delimiter that follows is isolated as its own token, so a word-character delimiter ((,),|,/,.,<,>) does not glue into the following word run and become un-splittable downstream (the same problem\verbhas). Control-symbol / control-word / bracket delimiters already lex as single tokens.
None of these resolve macro meaning; they are surface lexing concerns (in TeX, catcodes genuinely change in these regions).
Structs§
- LexConfig
- The lexer’s per-parse mode.
flavorfixes the initial catcode regime (a.sty/.clsstarts under an implicit\makeatletter), whiledtxis an orthogonal axis: when set, the lexer runs the bounded line-oriented docstrip mode for a.dtxfile — line-leading%margins becomeDOC_MARGINtrivia, line-leading%<…>guards becomeGUARDtrivia, andmacrocodebodies lex as ordinary code (AGENTS.mddecision #1). The two axes are independent because a.dtx’s catcode regime varies by layer (its documentation isDocument-flavored, itsmacrocodePackage-flavored), sodtxcannot be folded into aLatexFlavorvariant. - Parse
Ctx - Per-parse context carrying the facts the parser can only learn by first
scanning the file’s own definitions (
crate::semantic::define) — the sanctioned second pass described inparser::core. Empty for the first pass; populated for the second when the document defines any. Both the lexer and the grammar read it, so the two can never disagree about what a name is. - Token
- A single lexed token: its kind plus the exact source slice it covers.
Enums§
- Expl
Toggle - An expl3 catcode-mode toggle recognized purely by its control-word spelling.
Shared by the lexer (which flips its
expl_syntaxflag) and the formatter’s region pre-pass (thebadness-formattercrate recomputes in-region byte spans), so the two read the same fixed toggle set and can never drift. - Latex
Flavor - The LaTeX file flavor, fixing the lexer’s initial catcode regime. A
document (
.tex) starts in the ordinary regime; a package or class (.sty/.cls) is loaded under an implicit\makeatletter, so@is a letter from the first byte. A trailing explicit\makeatotherstill applies.
Functions§
- expl_
toggle - Classify a control word’s text as an expl3 catcode-mode toggle, if any. Only
meaningful on
SyntaxKind::CONTROL_WORDtext: a\ExplSyntaxOninside a\verb/comment lexes as aVERB/COMMENTtoken and so never reaches here. - is_
control_ word_ name - Could
name(without its leading\) lex as a single control word in some catcode regime? - is_
word_ char - Ordinary text: anything that is not whitespace, a line break, or one of the characters the lexer treats specially.
- lex
- Lex
inputinto a flat, lossless token stream, consulting only the built-in signature DB for verbatim commands/environments. The entry used by the first parse pass;lex_withadds user-defined verbatim commands. Uses theDocumentflavor (ordinary starting catcodes). - lex_
with - Lex
inputlikelex, additionally treating the user-defined verbatim commands inctxas verbatim (their final argument captured as oneVERBtoken). Used by the second parse pass once definition scanning has discovered catcode-othering commands.configfixes the initial catcode regime (aPackageflavor starts with@already a letter) and whether to run the.dtxdocstrip mode.