Skip to content

Commit 1c009c7

Browse files
OmikhleiaDidier Willis
authored andcommitted
fix(math): Fractions must have padding to avoid visual confusion
MathML Core 3.3.2: "To avoid visual confusion between the fraction bar and another adjacent items (e.g. minus sign or another fraction's bar)"
1 parent 3a0ef46 commit 1c009c7

File tree

1 file changed

+39
-39
lines changed

1 file changed

+39
-39
lines changed

packages/math/base-elements.lua

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,68 +1108,68 @@ function elements.fraction:styleChildren ()
11081108
end
11091109

11101110
function elements.fraction:shape ()
1111+
-- MathML Core 3.3.2: "To avoid visual confusion between the fraction bar
1112+
-- and another adjacent items (e.g. minus sign or another fraction's bar),"
1113+
-- By convention, here we use 1px = 1/96in = 0.75pt.
1114+
-- Note that PlainTeX would likely use \nulldelimiterspace (default 1.2pt)
1115+
-- but it would depend on the surrounding context, and might be far too
1116+
-- much in some cases, so we stick to MathML's suggested padding.
1117+
self.padding = SILE.types.length(0.75)
1118+
11111119
-- Determine relative abscissas and width
11121120
local widest, other
11131121
if self.denominator.width > self.numerator.width then
11141122
widest, other = self.denominator, self.numerator
11151123
else
11161124
widest, other = self.numerator, self.denominator
11171125
end
1118-
widest.relX = SILE.types.length(0)
1119-
other.relX = (widest.width - other.width) / 2
1120-
self.width = widest.width
1126+
widest.relX = self.padding
1127+
other.relX = self.padding + (widest.width - other.width) / 2
1128+
self.width = widest.width + 2 * self.padding
11211129
-- Determine relative ordinates and height
11221130
local constants = self:getMathMetrics().constants
11231131
local scaleDown = self:getScaleDown()
11241132
self.axisHeight = constants.axisHeight * scaleDown
11251133
self.ruleThickness = constants.fractionRuleThickness * scaleDown
1134+
1135+
local numeratorGapMin, denominatorGapMin, numeratorShiftUp, denominatorShiftDown
11261136
if isDisplayMode(self.mode) then
1127-
self.numerator.relY = -self.axisHeight
1128-
- self.ruleThickness / 2
1129-
- SILE.types.length(
1130-
math.max(
1131-
(constants.fractionNumDisplayStyleGapMin * scaleDown + self.numerator.depth):tonumber(),
1132-
constants.fractionNumeratorDisplayStyleShiftUp * scaleDown - self.axisHeight - self.ruleThickness / 2
1133-
)
1134-
)
1137+
numeratorGapMin = constants.fractionNumDisplayStyleGapMin * scaleDown
1138+
denominatorGapMin = constants.fractionDenomDisplayStyleGapMin * scaleDown
1139+
numeratorShiftUp = constants.fractionNumeratorDisplayStyleShiftUp * scaleDown
1140+
denominatorShiftDown = constants.fractionDenominatorDisplayStyleShiftDown * scaleDown
11351141
else
1136-
self.numerator.relY = -self.axisHeight
1137-
- self.ruleThickness / 2
1138-
- SILE.types.length(
1139-
math.max(
1140-
(constants.fractionNumeratorGapMin * scaleDown + self.numerator.depth):tonumber(),
1141-
constants.fractionNumeratorShiftUp * scaleDown - self.axisHeight - self.ruleThickness / 2
1142-
)
1142+
numeratorGapMin = constants.fractionNumeratorGapMin * scaleDown
1143+
denominatorGapMin = constants.fractionDenominatorGapMin * scaleDown
1144+
numeratorShiftUp = constants.fractionNumeratorShiftUp * scaleDown
1145+
denominatorShiftDown = constants.fractionDenominatorShiftDown * scaleDown
1146+
end
1147+
1148+
self.numerator.relY = -self.axisHeight
1149+
- self.ruleThickness / 2
1150+
- SILE.types.length(
1151+
math.max(
1152+
(numeratorGapMin + self.numerator.depth):tonumber(),
1153+
numeratorShiftUp - self.axisHeight - self.ruleThickness / 2
11431154
)
1144-
end
1145-
if isDisplayMode(self.mode) then
1146-
self.denominator.relY = -self.axisHeight
1147-
+ self.ruleThickness / 2
1148-
+ SILE.types.length(
1149-
math.max(
1150-
(constants.fractionDenomDisplayStyleGapMin * scaleDown + self.denominator.height):tonumber(),
1151-
constants.fractionDenominatorDisplayStyleShiftDown * scaleDown + self.axisHeight - self.ruleThickness / 2
1152-
)
1153-
)
1154-
else
1155-
self.denominator.relY = -self.axisHeight
1156-
+ self.ruleThickness / 2
1157-
+ SILE.types.length(
1158-
math.max(
1159-
(constants.fractionDenominatorGapMin * scaleDown + self.denominator.height):tonumber(),
1160-
constants.fractionDenominatorShiftDown * scaleDown + self.axisHeight - self.ruleThickness / 2
1161-
)
1155+
)
1156+
self.denominator.relY = -self.axisHeight
1157+
+ self.ruleThickness / 2
1158+
+ SILE.types.length(
1159+
math.max(
1160+
(denominatorGapMin + self.denominator.height):tonumber(),
1161+
denominatorShiftDown + self.axisHeight - self.ruleThickness / 2
11621162
)
1163-
end
1163+
)
11641164
self.height = self.numerator.height - self.numerator.relY
11651165
self.depth = self.denominator.relY + self.denominator.depth
11661166
end
11671167

11681168
function elements.fraction:output (x, y, line)
11691169
SILE.outputter:drawRule(
1170-
scaleWidth(x, line),
1170+
scaleWidth(x + self.padding, line),
11711171
y.length - self.axisHeight - self.ruleThickness / 2,
1172-
scaleWidth(self.width, line),
1172+
scaleWidth(self.width - 2 * self.padding, line),
11731173
self.ruleThickness
11741174
)
11751175
end

0 commit comments

Comments
 (0)