Skip to content

Commit 567ac54

Browse files
Omikhleiaalerque
authored andcommitted
feat(math): Support MathML bevelled fractions
1 parent 626fe7a commit 567ac54

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

packages/math/base-elements.lua

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,7 @@ function elements.sqrt:output (x, y, line)
15231523
local symbol = {
15241524
_r(self.radicalRuleThickness),
15251525
"w", -- line width
1526-
2,
1526+
1,
15271527
"j", -- round line joins
15281528
_r(sw + s0),
15291529
_r(self.extraAscender),
@@ -1598,6 +1598,63 @@ end
15981598

15991599
function elements.padded.output (_, _, _, _) end
16001600

1601+
-- Bevelled fractions are not part of MathML Core, and MathML4 does not
1602+
-- exactly specify how to compute the layout.
1603+
elements.bevelledFraction = pl.class(elements.fraction) -- Inherit from fraction
1604+
elements.fraction._type = "BevelledFraction"
1605+
1606+
function elements.bevelledFraction:shape ()
1607+
local constants = self:getMathMetrics().constants
1608+
local scaleDown = self:getScaleDown()
1609+
local hSkew = constants.skewedFractionHorizontalGap * scaleDown
1610+
-- OpenType has properties which are not totally explicit.
1611+
-- The definition of skewedFractionVerticalGap (and its value in fonts
1612+
-- such as Libertinus Math) seems to imply that it is measured from the
1613+
-- bottom of the numerator to the top of the denominator.
1614+
-- This does not seem to be a nice general layout.
1615+
-- So we will use superscriptShiftUp(Cramped) for the numerator:
1616+
local vSkewUp = isCrampedMode(self.mode) and constants.superscriptShiftUpCramped * scaleDown
1617+
or constants.superscriptShiftUp * scaleDown
1618+
-- And all good books say that the denominator should not be shifted down:
1619+
local vSkewDown = 0
1620+
1621+
self.ruleThickness = self.attributes.linethickness
1622+
and SU.cast("measurement", self.attributes.linethickness):tonumber()
1623+
or constants.fractionRuleThickness * scaleDown
1624+
self.numerator.relX = SILE.types.length(0)
1625+
self.numerator.relY = SILE.types.length(-vSkewUp)
1626+
self.denominator.relX = self.numerator.width + hSkew
1627+
self.denominator.relY = SILE.types.length(vSkewDown)
1628+
self.width = self.numerator.width + self.denominator.width + hSkew
1629+
self.height = maxLength(self.numerator.height + vSkewUp, self.denominator.height - vSkewDown)
1630+
self.depth = maxLength(self.numerator.depth - vSkewUp, self.denominator.depth + vSkewDown)
1631+
self.barWidth = SILE.types.length(hSkew)
1632+
self.barX = self.numerator.relX + self.numerator.width
1633+
end
1634+
1635+
function elements.bevelledFraction:output (x, y, line)
1636+
local h = self.height:tonumber()
1637+
local d = self.depth:tonumber()
1638+
local barwidth = scaleWidth(self.barWidth, line):tonumber()
1639+
local xscaled = scaleWidth(x + self.barX, line)
1640+
local rd = self.ruleThickness / 2
1641+
local symbol = {
1642+
_r(self.ruleThickness),
1643+
"w", -- line width
1644+
1,
1645+
"J", -- round line caps
1646+
_r(0),
1647+
_r(d + h - rd),
1648+
"m",
1649+
_r(barwidth),
1650+
_r(rd),
1651+
"l",
1652+
"S",
1653+
}
1654+
local svg = table.concat(symbol, " ")
1655+
SILE.outputter:drawSVG(svg, xscaled, y, barwidth, h, 1)
1656+
end
1657+
16011658
elements.mathMode = mathMode
16021659
elements.atomType = atomType
16031660
elements.symbolDefaults = symbolDefaults

packages/math/typesetter.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ function ConvertMathML (_, content)
147147
if #children ~= 2 then
148148
SU.error("Wrong number of children in mfrac: " .. #children)
149149
end
150-
return b.fraction(content.options, children[1], children[2])
150+
return SU.boolean(content.options.bevelled, false)
151+
and b.bevelledFraction(content.options, children[1], children[2])
152+
or b.fraction(content.options, children[1], children[2])
151153
elseif content.command == "msqrt" then
152154
local children = convertChildren(content)
153155
-- "The <msqrt> element generates an anonymous <mrow> box called the msqrt base

0 commit comments

Comments
 (0)