Skip to main content

Module expl3

Module expl3 

Source
Expand description

The expl3 call-site model: argspec arity for expl3 function names, and the statement segmentation built on it.

Two halves, both semantics layered on the syntax tree (like define’s definition scan): expl3_slots derives per-slot arity from the letters after the final : in \cs_new:Npn, \tl_if_empty:nTF, …, and segment_expl_statements applies it to an in-region element stream to produce the statement model the formatter’s expl3 layout consumes. Neither builds Ir or touches layout policy — a wrong answer here can only produce ugly formatting downstream, never a wrong tree or a lost byte.

Like xparse, the argspec is a spec mini-language that is parsed, never executed (AGENTS.md decision #1): each letter names the shape an argument takes at the call site, a bounded, purely lexical fact — squarely decision #2’s “the semantic layer assigns arity”. No signature database is involved: the name string alone carries the spec, so there is nothing to curate and nothing to drift. Only meaningful inside an expl3 region, where :/_ are catcode-11 and the whole name lexes as one CONTROL_WORD — callers of the segmentation guarantee the stream is in-region (out-of-region, colon names lex split and everything degrades to the fallback).

The letter-by-letter model (interface3’s argument specifiers):

  • N, VExpl3Slot::SingleToken: one token, typically a control sequence (V differs from N only in expansion, not call-site shape).
  • n, c, v, o, x, e, fExpl3Slot::Group: one braced {…} group (again, the letters differ only in how the material is processed, which we never model).
  • T, FExpl3Slot::Branch: a braced conditional branch. Sanctioned only as a trailing run — in a standard argspec T/F are always last, so a mid-spec T/F is treated as unknown.
  • pExpl3Slot::ParameterText: TeX parameter text (#1#2…), which has no fixed token count but a static end: TeX’s own rule that the parameter text runs to the first explicit {. The consumer scans by that shape.
  • w (arbitrary delimiters) and D (kernel primitive) have no lexically derivable call-site shape → the whole name is unrecognized (None), as is any unknown letter (including one added to expl3 after this list was written — new letters degrade to unrecognized, never to a wrong arity).

Structs§

Expl3Unit
The resolved shape of one expl3 call unit — what [consume_unit]’s slot scan learns, kept rather than discarded.
StatementMap
The statement-boundary map for one element stream: boundary_after(i) says a statement ends in the gap after element i. Boundaries sit on whole top-level siblings — a boundary never splits a CST node, so anything the greedy parser over-attached to a consumed sibling rides along in its statement.

Enums§

Expl3Slot
The call-site shape of one expl3 argument slot, derived from an argspec letter.

Functions§

conditional_branches
The number of trailing T/F branch arguments of an expl3 conditional, read from the command name’s argspec (the substring after the final :). \tl_if_empty:nTFSome(2), \bool_if:nT/:nFSome(1); None for any name without a :-argspec ending in T/F — a non-conditional expl3 function (\seq_new:N), or a LaTeX2e command with no colon (\@ifpackageloaded). In an expl3 argspec T/F denote only the true/false branch slots, so a trailing T/F run is exactly the branch count.
expl3_slots
The argument slots of an expl3 function name, read from its argspec suffix (the substring after the final :), or None when the name has no derivable call-site arity.
expl3_unit
Resolve the expl3 call unit headed by elements[head_idx], or None when the shape scan cannot (an unrecognized head, a slot facing the wrong shape, a docstrip guard mid-unit, or the stream ending mid-unit) — exactly the conditions under which segment_expl_statements degrades that statement to the fallback.
segment_expl_statements
Segment an in-region element stream into statements. See the module docs for the model; the caller guarantees the stream is inside an expl3 region (so :/_ were letters and names carry their argspec suffix).