Skip to content

Large operators, multiple fonts - #1

Merged
kostub merged 20 commits into
masterfrom
largeops
May 24, 2016
Merged

kostub merged 20 commits into
masterfrom
largeops

Conversation

@kostub

@kostub kostub commented May 24, 2016

Copy link
Copy Markdown
Owner

No description provided.

@kostub
kostub merged commit 9d600ab into master May 24, 2016
@kostub
kostub deleted the largeops branch May 24, 2016 08:12
shuyu referenced this pull request in SnapaskProduct/iosMath May 8, 2018
Added Chinese font support
shuyu referenced this pull request in SnapaskProduct/iosMath May 8, 2018
delyethan pushed a commit to delyethan/iosMath that referenced this pull request Aug 2, 2020
kostub added a commit that referenced this pull request Jul 11, 2026
Review #1: add NSAssert(hLines.count <= numRows+1) in
makeRuleDisplaysForTable:. No out-of-bounds is reachable (the
b >= numRows branch draws extra boundaries at frameBot without
touching rows), but a model with more boundaries than numRows+1
draws redundant overlapping bottom rules — a silently-malformed
model. Fail loud on the invariant.

Review #2: add testArrayRuleGeometryIsDeterministic pinning a
vertical rule's absolute x (padding + thickness/2) and each
\hline's y (content edge +/- padding). Count/ordering tests
missed a constant offset applied to every rule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kostub added a commit that referenced this pull request Jul 26, 2026
Second review round on #265. The main change is which guards throw and which
assert. The rule this project uses is who can violate the invariant, not whether
the check survives NS_BLOCK_ASSERTIONS: NSAssert is for programmer bugs caught in
testing, exceptions for errors the person writing the LaTeX can cause and that
must still signal in Release.

Re-scored against that rule, two guards added in 0736def were escalated too far:

- InvalidTemplate (a #N nested in a sub-list) and InvalidMacroArgumentIndex (an
  arity mismatch) are both reachable only from templates authored inside this
  library, so both become NSAssert. Where the assert-only path would otherwise
  lose content in Release, the fallback is made visibly wrong rather than lossy:
  an out-of-range placeholder is carried into the output and renders as a literal
  "#2" instead of dropping the argument.
- The depth guard stays a throw. \pmod{\pmod{...}} nests straight from user LaTeX.

Restores the phase-2 macro guard that 0736def dropped when expansion switched to
isKindOfClass: dispatch. The two changes were orthogonal -- -type is a settable
public property, so a plain MTMathAtom relabelled kMTMathAtomMacro still walks
through expansion and reaches the typesetter, which drops it silently.

Also from the round:
- Boundary coverage at exactly 32 and 33 nesting levels, not just 8 and 64.
- Re-finalize idempotency on a list that contained a macro.
- MTContainsMacroParameter caches its selectors; it ran NSSelectorFromString 13
  times per visited object.
- Bare "MTUnicode.h" / "MTMacroParameterAtom.h" imports, matching the
  MTFont+Internal.h idiom now that lib/internal is on the search path everywhere.
- Header notes: -finalized on a lone macro atom does not expand, and templates
  must keep #N at the top level (so \frac{#1}{#2} is not expressible).
- Stale reference to finalizedAssumingNoMacros, removed in 0736def.

The hasMacro fast path stays out, per review direction; the ~6% on -finalized is
not worth a second scan.

swift test 488/488, iOS 447/447, macOS builds, release build warning-clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ts3f5UtUywaqimvE4U1rkw
kostub added a commit that referenced this pull request Jul 27, 2026
Overrules LLD §4.1, which rejected code-built expansions because "\newcommand
would need this template engine built from scratch anyway." That premise does not
survive the implementation: substitution only reaches the top level of a template,
so \newcommand{\abs}[1]{\left|#1\right|} — the example §8.2 cites as the payoff —
is rejected by MTMacroAtom's own nested-placeholder assert. MTMathList.h said so
outright ("a future user-facing \newcommand would need substitution to descend
into sub-lists first"). The engine was paying for a reuse it cannot deliver, and
\newcommand appears nowhere in the PRD.

MTMacroDefinition now holds a prefix and a suffix LaTeX string; \pmod{n} expands
to prefix + arguments + suffix:

  pmod  \mkern8mu(\mathrm{mod}\mkern6mu  …  )
  mod   \mkern12mu\mathrm{mod}\mkern6mu  …  (none)
  pod   \mkern8mu(                       …  )

Both halves are ordinary LaTeX parsed by the ordinary builder, so this deletes
template mode, #N parsing, +buildTemplate:, MTMacroParameterAtom (60 lines), the
recursive MTContainsMacroParameter walker (51 lines), and both template-invariant
asserts — the placeholder cannot be misplaced when there is no placeholder.

MTMacroAtom keeps command + arguments, which is the requirement that justified it
existing: \pmod{n} still serializes back as \pmod{n}, and ^/_ still attach to one
atom via the builder's shared tail.

Cost: an expansion that interleaves fixed text between several arguments is no
longer expressible. None of the three built-ins needs that, and \newcommand would
need the descending substitution above regardless.

No user-facing LaTeX behavior changes — parsing, expansion, spacing, serialization
and round-trip tests are unchanged and still pass. 527 tests, 0 failures; release
build clean. LLD §4 annotated with the supersession.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ts3f5UtUywaqimvE4U1rkw
kostub added a commit that referenced this pull request Aug 21, 2026
-readRawArgument's surrogate-pair branch is unreachable. Its only caller
skips spaces first, and -skipSpaces consumes everything outside 0x21-0x7E,
so a high surrogate never survives to be read as a braceless argument.

The comment on -rawArgumentWithError: survived the rename unchanged and
described none of what the method does: -readRawArgument returns a string
rather than a list, does not return empty at EOF, and \sqrt does not route
through it.

The \pmod{\frac} comment claimed the expansion degrades like a bare
trailing \frac. It does not — \frac takes its numerator from the template
text after #1, which is the closing paren, so the paren is swallowed and
the denominator is empty. Pinned with the finalized serialization in place
of the XCTAssertNoThrow that could not see it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CR3o91FfsodPmwJD1s8499
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.

1 participant