Expand description
Project declarations: the closed vocabulary a project uses to name constructs the parser cannot see.
A \bea/\eea delimiter pair defined in a sibling .sty, an environment
that behaves like align but has no built-in counterpart, a verbatim
environment built by machinery no definition scan can follow — these are
facts about the document that its text does not carry, and the inferred
environment-alias scan (crate::semantic::define) cannot reach them
(issue #109). This module is the type those facts arrive in.
It is the one sanctioned input to the parse that is not the text
(AGENTS.md decision #12). What keeps that admissible is the safety
property that a declaration names a spelling, never a pairing: every
shape gate still runs, so a declared \bea whose \eea is unreachable
demotes to a plain command exactly as an inferred one does. Config widens
what is recognized and can never force a tree the text does not support,
which is what makes a wrong declaration a no-op rather than a corruption.
Three shape rules, recorded here because they are what keep the vocabulary from growing into a query language:
- Keyed by category, then name. One dedicated map per syntactic
category (
Declarations::environmentstoday; commands and, if the shortverb case is ever taken, characters later), and never a scalar knob inside a name map — a category-wide switch would collide with a construct of that name, so it belongs in a sibling section. likenever crosses categories. It means “copy the curated built-in entry of the same kind”, and a genuinely cross-category relation gets its own key instead (EnvironmentDecl::begin/EnvironmentDecl::end, the command spellings that stand in for an environment’s delimiters).- Deserialization validates nothing. Every rule is checked in one later
pass,
Declarations::resolve, so that a failure can be reported against the key the user wrote (environments.myenv.like) rather than swallowed by a deserializer that only knows it was handed a string.
The type lives in this crate, not in the CLI, because the parse is what
consumes it and because three front ends must be able to produce the same
value: badness.toml, the dprint plugin’s own config (sandboxed, no
filesystem), and eventually a % badness-env comment directive. Serde is a
hard dependency here (the signature database is JSON), so — unlike
badness-formatter’s FormatStyle — the derives need no feature gate and
the CLI can deserialize straight into these types instead of maintaining a
mirror that could drift. The wire spellings are therefore public API,
pinned by the tests at the bottom of this file.
Structs§
- Command
Name - A control-word name as written in a declaration, stored without the
leading backslash — the spelling every signature and
ParseCtxmap is keyed by. - Declaration
Error - A rule
Declarations::resolverejected, with the dotted key of the entry that broke it (environments.myenv.like) so the CLI can point at the line the user wrote. - Declarations
- Every declaration a project makes, as authored — unresolved and unvalidated.
- Environment
Decl - One
[environments.<name>]entry: what the environment named by the key behaves like, and which command spellings stand in for its delimiters. - Resolved
Declarations - A project’s declarations, checked and projected into signature data by
Declarations::resolve.
Enums§
- Declaration
Error Kind - Why a declaration was rejected. Each variant is a rule from
AGENTS.mddecision #12 or its architecture section.
Type Aliases§
- Environment
Decls - The name-keyed
[environments]map. A type alias so the CLI’sConfigcan name the field’s type without restating the key type.