Fix inline mode rendering for large operators and fractions
This commit addresses three issues with math rendering:
1. Large operator limits positioning (continued from previous commit)
Modified makeLargeOp() and addLimitsToDisplay() to show limits above/below
in both display and text (inline) modes:
- Changed: op.limits && style == .display
- To: op.limits && (style == .display || style == .text)
This enables operators like \lim, \sum, and \prod to show subscripts/
superscripts above and below even in inline mode \(...\), not just in
display mode \[...\].
2. Fraction font size issue
Fixed fractions appearing too small in inline mode. Previously, fractions
used one style level smaller than their parent (standard LaTeX behavior):
- Display mode → fractions use text style (acceptable)
- Text mode →
Root cause:
Inline delimiters \(...\) insert \textstyle, forcing text mode. In text
mode, fractionStyle() returned style.inc(), making numerator/denominator
use script style (two levels smaller than display). This made fraction
numbers tiny compared to surrounding text in expressions like:
\(\frac{a}{b} = c\) - a, b were script-sized while c was text-sized
Solution:
Modified fractionStyle() to return the SAME style instead of incrementing:
func fractionStyle() -> MTLineStyle {
return style // Was: return style.inc()
}
This keeps fraction numerators/denominators at the same font size as
regular text, preventing them from becoming too small. Spacing and
positioning (numeratorShiftUp, etc.) still vary by parent style.
3. Non-regression fixes
Updated test expectations to match new fraction sizing behavior
This commit is contained in:
@@ -271,7 +271,11 @@ public struct MTMathListBuilder {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Optionally: Add style hint for inline mode
|
||||
// Note: For inline mode, we insert \textstyle to match LaTeX behavior.
|
||||
// However, fractionStyle() has been modified to keep fractions at the
|
||||
// same font size in both display and text modes (not one level smaller).
|
||||
// Large operators show limits above/below in text style due to the updated
|
||||
// condition in makeLargeOp() that checks both .display and .text styles.
|
||||
if mode == .inline && list != nil && !list!.atoms.isEmpty {
|
||||
// Prepend \textstyle to force inline rendering
|
||||
let styleAtom = MTMathStyle(style: .text)
|
||||
|
||||
@@ -1726,10 +1726,11 @@ class MTTypesetter {
|
||||
}
|
||||
|
||||
func fractionStyle() -> MTLineStyle {
|
||||
if style == .scriptOfScript {
|
||||
return .scriptOfScript
|
||||
}
|
||||
return style.inc()
|
||||
// Keep fractions at the same style level instead of incrementing.
|
||||
// This ensures that fraction numerators/denominators have the same
|
||||
// font size as regular text, preventing them from appearing too small
|
||||
// in inline mode or when nested.
|
||||
return style
|
||||
}
|
||||
|
||||
func makeFraction(_ frac:MTFraction?) -> MTDisplay? {
|
||||
@@ -2041,7 +2042,9 @@ class MTTypesetter {
|
||||
// MARK: - Large Operators
|
||||
|
||||
func makeLargeOp(_ op:MTLargeOperator!) -> MTDisplay? {
|
||||
let limits = op.limits && style == .display
|
||||
// Show limits above/below in both display and text (inline) modes
|
||||
// Only show limits to the side in script modes to keep them compact
|
||||
let limits = op.limits && (style == .display || style == .text)
|
||||
var delta = CGFloat(0)
|
||||
if op.nucleus.count == 1 {
|
||||
var glyph = self.findGlyphForCharacterAtIndex(op.nucleus.startIndex, inString:op.nucleus)
|
||||
@@ -2086,7 +2089,8 @@ class MTTypesetter {
|
||||
currentPosition.x += display!.width
|
||||
return display;
|
||||
}
|
||||
if op.limits && style == .display {
|
||||
// Show limits above/below in both display and text (inline) modes
|
||||
if op.limits && (style == .display || style == .text) {
|
||||
// make limits
|
||||
var superScript:MTMathListDisplay? = nil, subScript:MTMathListDisplay? = nil
|
||||
if op.superScript != nil {
|
||||
|
||||
Reference in New Issue
Block a user