parse: expand \def macros in the mouth, instead of dropping the formula - #10
Merged
Conversation
A \def written inside a formula — a paper's own inline shorthand reaching the
math layer, \def\R{\mathbb{R}}\R or \def\abs#1{\lvert#1\rvert}\abs{x} — was an
unknown command that dropped the whole equation. Macros defined in the preamble
are already substituted upstream by go-tex/engine; the ones that live inside the
formula were not handled, and \def is a top math-drop cause across the arXiv
corpus.
Add a TeX "mouth" pass (macro.go) that runs before the parser: it records each
\def and expands every use — arguments spliced into #1…#n of the body, the
result re-processed so nested and chained macros resolve — with a budget that
stops a self- or mutually-recursive macro from spinning. It handles undelimited
parameters (the inline form that occurs); a \def it cannot read (delimited
parameters, no body) or a use with too few arguments is left verbatim for the
parser to report, never guessed at. The pass is transparent to a def-free
stream.
Verified: parameterless and parameterised macros, chained and nested macros,
expansion inside \frac arguments, single-token vs {group} arguments, and every
rejecting path (bad name, delimited params, missing/unbalanced body, too few
args, self-recursion) all covered; full suite, race, go vet, gofmt clean at 100%.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
\defwritten inside a formula — a paper's own inline shorthand reaching the math layer (\def\R{\mathbb{R}}\R,\def\abs#1{\lvert#1\rvert}\abs{x}) — was an unknown command that dropped the whole equation. Macros defined in the preamble are already substituted upstream by go-tex/engine's math retry; the ones defined in the formula were not, and\defis a top math-drop cause across the arXiv corpus.How
A TeX "mouth" pass (
macro.go) runs before the parser (expandMacros, afterresolveConditionals): it records each\defand expands every use — arguments spliced into#1…#nof the body, the result re-processed so nested and chained macros resolve — with a budget so a self- or mutually-recursive macro (\def\x{\x}) can't spin. It supports undelimited parameters (the inline form that occurs); a\defit cannot read (delimited parameters, missing/unbalanced body) or a use with too few arguments is left verbatim for the parser to report, never guessed at. Transparent to a def-free stream.Verification
New
macro_test.go: parameterless/parameterised macros, chained (\a→\b→x+y) and nested macros, expansion inside\fracarguments, single-token vs{group}args, an undeclared-#nbody, and every rejecting path (bad name, delimited params, missing/unbalanced body, too few args, unbalanced arg, self-recursion halts). Full suite +-race+go vet+gofmtclean at 100% coverage.Continues the worst-first math-drop robustness pass (after
\char, #9). A follow-up bumps the engine'sgo-tex/mathdependency so the corpus recovers end-to-end.🤖 Generated with Claude Code