smallmatrix + gathered environments#246
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for the smallmatrix and gathered LaTeX environments in iosMath. It adds parsing and layout logic for smallmatrix (compact inline matrix with script-style cells) and handles gathered as a single-column centered environment, along with comprehensive unit tests to verify their layout and serialization. The feedback suggests using NSUInteger instead of int for loop variables in MTMathAtomFactory.m to prevent signedness comparison warnings when iterating over collection counts.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| for (int i = 0; i < table.cells.count; i++) { | ||
| NSArray<MTMathList*>* row = table.cells[i]; | ||
| for (int j = 0; j < row.count; j++) { | ||
| [row[j] insertAtom:style atIndex:0]; | ||
| } | ||
| } |
There was a problem hiding this comment.
To avoid signedness comparison warnings (e.g., -Wsign-compare) when comparing signed int loop counters with NSUInteger properties like table.cells.count and row.count, it is recommended to use NSUInteger for the loop variables i and j.
for (NSUInteger i = 0; i < table.cells.count; i++) {
NSArray<MTMathList*>* row = table.cells[i];
for (NSUInteger j = 0; j < row.count; j++) {
[row[j] insertAtom:style atIndex:0];
}
}
kostub
left a comment
There was a problem hiding this comment.
Code Review — PR 2 (smallmatrix + gathered)
Reviewed the diff against base feature/subordinate-envs-pr1 (items 3-6). Built and ran the affected suites locally: all 6 new tests pass, and the full MTMathListBuilderTest (151) / MTMathListTest (10) / MTTypesetterTest (114) suites are green with no golden-value shifts. TEST SUCCEEDED.
Assessment: Ready to merge. No critical or important issues found.
The implementation matches the LLD (§3.3 factory/serialization) and the PR 2 plan (items 3-6) exactly:
smallmatrixfactory branch (MTMathAtomFactory.m) — center default (unset alignments),interColumnSpacing = kSmallMatrixInterColumnSpacing (5),interRowAdditionalSpacing = 0, injectsMTMathStyle(kMTLineStyleScript)per cell, no delimiters. ThekSmallMatrixInterColumnSpacing = 5constant with its amsmath/KaTeX-sourced comment is exactly the "honest 5mu, renderer scales it" design from the LLD;testSmallMatrixColumnGapcross-validates that PR 1's cell-style scaling produces5 * muUnit * scriptScaleDown.gathered— single-condition widen of thedisplaylines/gatherbranch; correctly reuses the existingnumColumns == 1loud error (verified by the newMTParseErrorInvalidNumColumnsrow +testGathered). Environment name is preserved (branch doesn't reassigntable.environment), so it round-trips as\begin{gathered}.- Serialization —
serializedCellAtRow:column:style-strip widened tosmallmatrix; round-trip asserted intestSmallMatrix.
Strengths
- Purely additive; no existing branch behavior changed.
matrix/cases/aligned/gather/eqnarraygolden tests all unchanged. - Honest-value + renderer-scaling design avoids a pre-scaled magic constant in the model, and the layout tests are characterization tests that lock the PR1+PR2 interaction rather than re-asserting an arbitrary number.
- Error path (
gatheredstray&) covered.
Minor / non-blocking observations
- Shared
MTMathStyleatom instance across all cells (MTMathAtomFactory.m, smallmatrix branch): a singlestyleobject isinsertAtom:'d into every cell. This is identical to the existingmatrix(line ~398) andcases(line ~485) branches, so it is a consistent, already-tested pattern — not a regression. Flagging only for awareness: if any future code mutates a cell's leading style atom in place, the aliasing would bite all cells. No action needed for this PR. testSmallMatrixcell indexing usestable.cells[j][i]inside thei=column /j=row loops — correct (row-major), but slightly confusing to read since the outer loop variableiis the column. Cosmetic only; the test passes and asserts the right thing.- Empty-environment safety:
\begin{smallmatrix}\end{smallmatrix}— the cell loop simply doesn't execute and a bare empty table is returned, handled by the existing-makeTable:empty early-out (LLD §6). Not explicitly tested here, but covered by existing empty-table paths; acceptable.
Nothing requires changes before merge.
d6b62ce to
8a82ff6
Compare
Goal
Add the two subordinate amsmath environments that need no parser-argument changes — purely additive
MTMathAtomFactorybranches plus serialization and layout coverage.smallmatrixis a script-size centered matrix with no delimiters whose honest amsmath gap (5 mu\thickspace) renders correctly thanks to PR 1's cell-style scaling;gatheredis layout-identical to the existinggather.Stack
This PR is based on
feature/subordinate-envs-pr1and will auto-retarget tomasteronce PR 1 merges.Design docs
docs/plans/2026-06-30-smallmatrix-gathered-alignedat.md(PR 2 section)docs/lld/2026-06-30-smallmatrix-gathered-alignedat.mdCommits
[item 3] Add smallmatrix environment (script-style centered matrix)— new factory branch +kSmallMatrixInterColumnSpacing = 5; widened serialization style-strip. TesttestSmallMatrix.[item 4] Add smallmatrix layout tests (gap fidelity + compactness)—testSmallMatrixColumnGap,testSmallMatrixCompactVsMatrix.[item 5] Add gathered environment (folds into gather branch)— widened thedisplaylines/gathercondition. TesttestGathered+ stray-&error row.[item 6] Add gathered/gather layout parity test—testGatheredMatchesGather.🤖 Generated with Claude Code