Skip to content

feat(parser): Recognize commands nested in \text{...} - #64

Open
gjtorikian wants to merge 4 commits into
carloskiki:mainfrom
gjtorikian:fix/issue-29-text-mode-parsing
Open

feat(parser): Recognize commands nested in \text{...}#64
gjtorikian wants to merge 4 commits into
carloskiki:mainfrom
gjtorikian:fix/issue-29-text-mode-parsing

Conversation

@gjtorikian

@gjtorikian gjtorikian commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

\text{...} now re-parses its body in a dedicated text-mode path instead of treating it as a single opaque string, so nested control sequences (\LaTeX, \textbf, \emph, escaped specials, accents, etc.) typeset correctly and $...$ switches back into math via the new Grouping::InlineMath.

This PR also introduces Grouping::Text / Grouping::InlineMath and a text_mode flag on ParserState and Instruction::SubGroup so the existing iterator loop can drive both modes from the same stack without duplicating script-handling logic.

Text-mode font commands are routed through the existing StateChange::Font(...) machinery; the MathML renderer now emits mathvariant="..." on <mtext> so \textbf / \textit / \emph are visibly distinct.

until_unescaped_dollar is a lexer helper that respects brace nesting and % comments, so $...$ inside \text is scanned safely and reports a parser error on a missing closing $.

Closes #29

Previously `\text{...}` took its argument as a single opaque
string, so `\text{Hello \LaTeX}` rendered the control sequence
as literal source rather than typesetting it, and `\textbf`,
`\emph`, `$...$`, and the escaped specials inside text were
all silently dropped or mangled.

This implements the design accepted on issue carloskiki#29: \text bodies
re-enter the parser through a text-mode path (driven by a new
`text_mode` flag on ParserState and Instruction::SubGroup) and
emit a Grouping::Text wrapper; embedded `$...$` switches back
via Grouping::InlineMath. Font commands route through the
existing StateChange::Font machinery so the renderer can pick
up mathvariant on <mtext>.

Closes carloskiki#29
@codecov

codecov Bot commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.23789% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.3%. Comparing base (d385cae) to head (c195d00).

Files with missing lines Patch % Lines
src/parser/primitives.rs 97.5% 4 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
src/event.rs 74.2% <100.0%> (+0.1%) ⬆️
src/mathml.rs 81.2% <100.0%> (+0.2%) ⬆️
src/parser.rs 99.6% <100.0%> (+<0.1%) ⬆️
src/parser/lex.rs 94.0% <100.0%> (+0.6%) ⬆️
src/parser/state.rs 100.0% <100.0%> (ø)
src/parser/primitives.rs 85.0% <97.5%> (+1.2%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The text-mode test helper allocated a Storage with Box::leak so
the parser's borrowed events could outlive the helper. That made
LeakSanitizer and Miri reject every test in this file. Switch to
a caller-owned Storage and add cases for the spacing commands,
symbol commands, comment handling, single-token arguments, and
the inline-math lexer's escape paths so codecov patch coverage
clears the project threshold.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Commands nested in \text are not recognized.

1 participant