diff --git a/packages/math/base-elements.lua b/packages/math/base-elements.lua index a2401ae01..1ad91c2a2 100644 --- a/packages/math/base-elements.lua +++ b/packages/math/base-elements.lua @@ -423,8 +423,8 @@ function elements.stackbox:shape () end -- Handle stretchy operators for _, elt in ipairs(self.children) do - if elt.is_a(elements.text) and elt.kind == "operator" and elt.stretchy then - elt:stretchyReshape(self.depth, self.height) + if elt.is_a(elements.text) and elt.kind == "operator" and SU.boolean(elt.stretchy, false) then + elt:_vertStretchyReshape(self.depth, self.height) end end -- Set self.width @@ -468,7 +468,7 @@ function elements.stackbox.output (_, _, _, _) end elements.phantom = pl.class(elements.stackbox) -- inherit from stackbox elements.phantom._type = "Phantom" -function elements.phantom:_init (children, special) +function elements.phantom:_init (children) -- MathML core 3.3.7: -- "Its layout algorithm is the same as the mrow element". -- Also not the MathML states that is sort of legacy, "implemented @@ -477,22 +477,6 @@ function elements.phantom:_init (children, special) -- The thing is that we don't have CSS in SILE, so supporting is -- a must. elements.stackbox._init(self, "H", children) - self.special = special -end - -function elements.phantom:shape () - elements.stackbox.shape(self) - -- From https://latexref.xyz: - -- "The \vphantom variant produces an invisible box with the same vertical size - -- as subformula, the same height and depth, but having zero width. - -- And \hphantom makes a box with the same width as subformula but - -- with zero height and depth." - if self.special == "v" then - self.width = SILE.types.length() - elseif self.special == "h" then - self.height = SILE.types.length() - self.depth = SILE.types.length() - end end function elements.phantom:output (_, _, _) @@ -567,10 +551,12 @@ function elements.subscript:shape () self.width = SILE.types.length(0) end local itCorr = self:calculateItalicsCorrection() * scaleDown + local isBaseSymbol = not self.base or self.base:is_a(elements.terminal) + local isBaseLargeOp = SU.boolean(self.base and self.base.largeop, false) local subShift local supShift if self.sub then - if self.isUnderOver or self.base.largeop then + if self.isUnderOver or isBaseLargeOp then -- Ad hoc correction on integral limits, following LuaTeX's -- `\mathnolimitsmode=0` (see LuaTeX Reference Manual). subShift = -itCorr @@ -578,17 +564,20 @@ function elements.subscript:shape () subShift = 0 end self.sub.relX = self.width + subShift - self.sub.relY = SILE.types.length(math.max( - constants.subscriptShiftDown * scaleDown, - --self.base.depth + constants.subscriptBaselineDropMin * scaleDown, - (self.sub.height - constants.subscriptTopMax * scaleDown):tonumber() - )) - if self:is_a(elements.underOver) or self:is_a(elements.stackbox) or self.base.largeop then + self.sub.relY = SILE.types.length( + math.max( + constants.subscriptShiftDown * scaleDown, + isBaseSymbol and 0 -- TeX (σ19) is more finicky than MathML Core + or (self.base.depth + constants.subscriptBaselineDropMin * scaleDown):tonumber(), + (self.sub.height - constants.subscriptTopMax * scaleDown):tonumber() + ) + ) + if self:is_a(elements.underOver) or self:is_a(elements.stackbox) or isBaseLargeOp then self.sub.relY = maxLength(self.sub.relY, self.base.depth + constants.subscriptBaselineDropMin * scaleDown) end end if self.sup then - if self.isUnderOver or self.base.largeop then + if self.isUnderOver or isBaseLargeOp then -- Ad hoc correction on integral limits, following LuaTeX's -- `\mathnolimitsmode=0` (see LuaTeX Reference Manual). supShift = 0 @@ -596,13 +585,16 @@ function elements.subscript:shape () supShift = itCorr end self.sup.relX = self.width + supShift - self.sup.relY = SILE.types.length(math.max( - isCrampedMode(self.mode) and constants.superscriptShiftUpCramped * scaleDown - or constants.superscriptShiftUp * scaleDown, -- or cramped - --self.base.height - constants.superscriptBaselineDropMax * scaleDown, - (self.sup.depth + constants.superscriptBottomMin * scaleDown):tonumber() - )) * -1 - if self:is_a(elements.underOver) or self:is_a(elements.stackbox) or self.base.largeop then + self.sup.relY = SILE.types.length( + math.max( + isCrampedMode(self.mode) and constants.superscriptShiftUpCramped * scaleDown + or constants.superscriptShiftUp * scaleDown, + isBaseSymbol and 0 -- TeX (σ18) is more finicky than MathML Core + or (self.base.height - constants.superscriptBaselineDropMax * scaleDown):tonumber(), + (self.sup.depth + constants.superscriptBottomMin * scaleDown):tonumber() + ) + ) * -1 + if self:is_a(elements.underOver) or self:is_a(elements.stackbox) or isBaseLargeOp then self.sup.relY = maxLength( (0 - self.sup.relY), self.base.height - constants.superscriptBaselineDropMax * scaleDown @@ -649,12 +641,22 @@ function elements.underOver:__tostring () return self._type .. "(" .. tostring(self.base) .. ", " .. tostring(self.sub) .. ", " .. tostring(self.sup) .. ")" end +local function isNotEmpty (element) + -- The MathML test suite uses with an empty as sub/sup. + -- I don't know why they didn't use a or instead... + -- But the expectation is to behave as if the empty element was not there, + -- so that height and depth are not affected by the axis height. + -- See notably: + -- MathML3 "complex1" torture test: Maxwell's Equations (vectors in fractions) + return element and (element:is_a(elements.terminal) or #element.children > 0) +end + function elements.underOver:_init (base, sub, sup) elements.mbox._init(self) self.atom = base.atom self.base = base - self.sub = sub - self.sup = sup + self.sub = isNotEmpty(sub) and sub or nil + self.sup = isNotEmpty(sup) and sup or nil if self.sup then table.insert(self.children, self.sup) end @@ -678,8 +680,55 @@ function elements.underOver:styleChildren () end end +function elements.underOver:_stretchyReshapeToBase (part) + -- FIXME: Big leap of faith here. + -- MathML Core only mentions stretching along the inline axis in 3.4.2.2, + -- i.e. under the section on , , . + -- So we are "somewhat" good here, but... the algorithm is totally unclear + -- to me and seems to imply a lot of recursion and reshaping. + -- The implementation below is NOT general and only works for the cases + -- I checked: + -- Mozilla MathML tests: braces in f19, f22 + -- Personal tests: vectors in d19, d22, d23 + -- Joe Javawaski's tests: braces in 8a, 8b + -- MathML3 "complex1" torture test: Maxwell's Equations (vectors in fractions) + if #part.children == 0 then + local elt = part + if elt.is_a(elements.text) and elt.kind == "operator" and SU.boolean(elt.stretchy, false) then + elt:_horizStretchyReshape(self.base.width) + end + elseif part:is_a(elements.underOver) then + -- Big assumption here: only considering one level of stacked under/over. + local hasStreched = false + for _, elt in ipairs(part.children) do + if elt.is_a(elements.text) and elt.kind == "operator" and SU.boolean(elt.stretchy, false) then + local stretched = elt:_horizStretchyReshape(self.base.width) + if stretched then + hasStreched = true + end + end + end + if hasStreched then + -- We need to re-calculate the shape so positions are re-calculated on each + -- of its own parts. + -- (Added after seeing that Mozilla test f19 was not rendering correctly.) + part:shape() + end + end +end + function elements.underOver:shape () - if not (self.mode == mathMode.display or self.mode == mathMode.displayCramped) then + local isBaseLargeOp = SU.boolean(self.base and self.base.largeop, false) + if not (self.mode == mathMode.display or self.mode == mathMode.displayCramped) and isBaseLargeOp then + -- FIXME + -- Added the "largeop" condition, but it's kind of a workaround: + -- It should rather be the "moveablelimits" propery in MathML, but we do not have that yet. + -- When the base is a moveable limit, the under/over scripts are not placed under/over the base, + -- but ather to the right of it, when display mode is not used. + -- Notable effects: + -- Mozilla MathML test 19 (on "k times" > overbrace > base) + -- Maxwell's Equations in MathML3 Test Suite "complex1" (on the vectors in fractions) + -- For now, go with the "largeop" property, but this is not correct. self.isUnderOver = true elements.subscript.shape(self) return @@ -691,6 +740,7 @@ function elements.underOver:shape () self.base.relY = SILE.types.length(0) end if self.sub then + self:_stretchyReshapeToBase(self.sub) self.sub.relY = self.base.depth + SILE.types.length( math.max( @@ -700,6 +750,7 @@ function elements.underOver:shape () ) end if self.sup then + self:_stretchyReshapeToBase(self.sup) self.sup.relY = 0 - self.base.height - SILE.types.length( @@ -868,8 +919,8 @@ function elements.text:__tostring () .. tostring(self.kind) .. ", script=" .. tostring(self.script) - .. (self.stretchy and ", stretchy" or "") - .. (self.largeop and ", largeop" or "") + .. (SU.boolean(self.stretchy, false) and ", stretchy" or "") + .. (SU.boolean(self.largeop, false) and ", largeop" or "") .. ', text="' .. (self.originalText or self.text) .. '")' @@ -904,7 +955,7 @@ function elements.text:shape () local mathMetrics = self:getMathMetrics() local glyphs = SILE.shaper:shapeToken(self.text, self.font) -- Use bigger variants for big operators in display style - if isDisplayMode(self.mode) and self.largeop then + if isDisplayMode(self.mode) and SU.boolean(self.largeop, false) then -- We copy the glyph list to avoid modifying the shaper's cache. Yes. glyphs = pl.tablex.deepcopy(glyphs) local constructions = mathMetrics.mathVariants.vertGlyphConstructions[glyphs[1].gid] @@ -973,38 +1024,56 @@ function elements.text:shape () end end -function elements.text:stretchyReshape (depth, height) - -- Required depth+height of stretched glyph, in font units +function elements.text.findClosestVariant (_, variants, requiredAdvance, currentAdvance) + local closest + local closestI + local m = requiredAdvance - currentAdvance + for i, variant in ipairs(variants) do + local diff = math.abs(variant.advanceMeasurement - requiredAdvance) + SU.debug("math", "stretch: diff =", diff) + if diff < m then + closest = variant + closestI = i + m = diff + end + end + return closest, closestI +end + +function elements.text:_reshapeGlyph (glyph, closestVariant, sz) + local face = SILE.font.cache(self.font, SILE.shaper.getFace) + local dimen = hb.get_glyph_dimensions(face, sz, closestVariant.variantGlyph) + glyph.gid = closestVariant.variantGlyph + glyph.width, glyph.height, glyph.depth, glyph.glyphAdvance = + dimen.width, dimen.height, dimen.depth, dimen.glyphAdvance + return dimen +end + +function elements.text:_stretchyReshape (target, direction) + -- direction is the required direction of stretching: true for vertical, false for horizontal + -- target is the required dimension of the stretched glyph, in font units local mathMetrics = self:getMathMetrics() local upem = mathMetrics.unitsPerEm local sz = self.font.size - local requiredAdvance = (depth + height):tonumber() * upem / sz + local requiredAdvance = target:tonumber() * upem / sz SU.debug("math", "stretch: rA =", requiredAdvance) -- Choose variant of the closest size. The criterion we use is to have -- an advance measurement as close as possible as the required one. - -- The advance measurement is simply the depth+height of the glyph. + -- The advance measurement is simply the dimension of the glyph. -- Therefore, the selected glyph may be smaller or bigger than - -- required. TODO: implement assembly of stretchable glyphs form - -- their parts for cases when the biggest variant is not big enough. + -- required. + -- TODO: implement assembly of stretchable glyphs from their parts for cases + -- when the biggest variant is not big enough. -- We copy the glyph list to avoid modifying the shaper's cache. Yes. local glyphs = pl.tablex.deepcopy(self.value.items) - local constructions = self:getMathMetrics().mathVariants.vertGlyphConstructions[glyphs[1].gid] + local glyphConstructions = direction and mathMetrics.mathVariants.vertGlyphConstructions + or mathMetrics.mathVariants.horizGlyphConstructions + local constructions = glyphConstructions[glyphs[1].gid] if constructions then local variants = constructions.mathGlyphVariantRecord SU.debug("math", "stretch: variants =", variants) - local closest - local closestI - local m = requiredAdvance - (self.depth + self.height):tonumber() * upem / sz - SU.debug("math", "stretch: m =", m) - for i, v in ipairs(variants) do - local diff = math.abs(v.advanceMeasurement - requiredAdvance) - SU.debug("math", "stretch: diff =", diff) - if diff < m then - closest = v - closestI = i - m = diff - end - end + local currentAdvance = (direction and (self.depth + self.height):tonumber() or self.width:tonumber()) * upem / sz + local closest, closestI = self:findClosestVariant(variants, requiredAdvance, currentAdvance) SU.debug("math", "stretch: closestI =", closestI) if closest then -- Now we have to re-shape the glyph chain. We will assume there @@ -1012,21 +1081,38 @@ function elements.text:stretchyReshape (depth, height) -- TODO: this code is probably wrong when the vertical -- variants have a different width than the original, because -- the shaping phase is already done. Need to do better. - glyphs[1].gid = closest.variantGlyph - local face = SILE.font.cache(self.font, SILE.shaper.getFace) - local dimen = hb.get_glyph_dimensions(face, self.font.size, closest.variantGlyph) - glyphs[1].width = dimen.width - glyphs[1].height = dimen.height - glyphs[1].depth = dimen.depth - glyphs[1].glyphAdvance = dimen.glyphAdvance - self.width = SILE.types.length(dimen.glyphAdvance) - self.depth = SILE.types.length(dimen.depth) - self.height = SILE.types.length(dimen.height) + local dimen = self:_reshapeGlyph(glyphs[1], closest, sz) + self.width, self.depth, self.height = + SILE.types.length(dimen.glyphAdvance), SILE.types.length(dimen.depth), SILE.types.length(dimen.height) SILE.shaper:preAddNodes(glyphs, self.value) self.value.items = glyphs self.value.glyphString = { glyphs[1].gid } + return true end end + return false +end + +function elements.text:_vertStretchyReshape (depth, height) + local hasStretched = self:_stretchyReshape(depth + height, true) + if hasStretched then + -- HACK: see output routine + self.vertExpectedSz = height + depth + self.vertScalingRatio = (depth + height):tonumber() / (self.height:tonumber() + self.depth:tonumber()) + self.height = height + self.depth = depth + end + return hasStretched +end + +function elements.text:_horizStretchyReshape (width) + local hasStretched = self:_stretchyReshape(width, false) + if hasStretched then + -- HACK: see output routine + self.horizScalingRatio = width:tonumber() / self.width:tonumber() + self.width = width + end + return hasStretched end function elements.text:output (x, y, line) @@ -1034,7 +1120,7 @@ function elements.text:output (x, y, line) return end local compensatedY - if isDisplayMode(self.mode) and self.atom == atomType.bigOperator and self.value.items[1].fontDepth then + if isDisplayMode(self.mode) and SU.boolean(self.largeop, false) and self.value.items[1].fontDepth then compensatedY = SILE.types.length(y.length + self.value.items[1].depth - self.value.items[1].fontDepth) else compensatedY = y @@ -1044,7 +1130,21 @@ function elements.text:output (x, y, line) -- There should be no stretch or shrink on the width of a text -- element. local width = self.width.length - SILE.outputter:drawHbox(self.value, width) + -- HACK: For stretchy operators, MathML Core and OpenType define how to build large glyphs + -- from an assembly of smaller ones. It's fairly complex and idealistic... + -- Anyhow, we do not have that yet, so we just stretch the glyph artificially. + -- There are cases where this will not look very good. + -- Call that a compromise, so that long vectors or large matrices look "decent" without assembly. + if SILE.outputter.scaleFn and (self.horizScalingRatio or self.vertScalingRatio) then + local xratio = self.horizScalingRatio or 1 + local yratio = self.vertScalingRatio or 1 + SU.debug("math", "fake glyph stretch: xratio =", xratio, "yratio =", yratio) + SILE.outputter:scaleFn(x, y, xratio, yratio, function () + SILE.outputter:drawHbox(self.value, width) + end) + else + SILE.outputter:drawHbox(self.value, width) + end end elements.fraction = pl.class(elements.mbox) @@ -1054,10 +1154,11 @@ function elements.fraction:__tostring () return self._type .. "(" .. tostring(self.numerator) .. ", " .. tostring(self.denominator) .. ")" end -function elements.fraction:_init (numerator, denominator) +function elements.fraction:_init (attributes, numerator, denominator) elements.mbox._init(self) self.numerator = numerator self.denominator = denominator + self.attributes = attributes table.insert(self.children, numerator) table.insert(self.children, denominator) end @@ -1069,12 +1170,12 @@ end function elements.fraction:shape () -- 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)," - -- By convention, here we use 1px = 1/96in = 0.75pt. + -- and another adjacent items (e.g. minus sign or another fraction's bar), + -- a default 1-pixel space is added around the element." -- Note that PlainTeX would likely use \nulldelimiterspace (default 1.2pt) -- but it would depend on the surrounding context, and might be far too -- much in some cases, so we stick to MathML's suggested padding. - self.padding = SILE.types.length(0.75) + self.padding = SILE.types.length("1px"):absolute() -- Determine relative abscissas and width local widest, other @@ -1090,7 +1191,16 @@ function elements.fraction:shape () local constants = self:getMathMetrics().constants local scaleDown = self:getScaleDown() self.axisHeight = constants.axisHeight * scaleDown - self.ruleThickness = constants.fractionRuleThickness * scaleDown + self.ruleThickness = self.attributes.linethickness + and SU.cast("measurement", self.attributes.linethickness):tonumber() + or constants.fractionRuleThickness * scaleDown + + -- MathML Core 3.3.2.2 ("Fraction with zero line thickness") uses + -- stack(DisplayStyle)GapMin, stackTop(DisplayStyle)ShiftUp and stackBottom(DisplayStyle)ShiftDown. + -- TODO not implemented + -- The most common use cases for zero line thickness are: + -- - Binomial coefficients + -- - Stacked subscript/superscript on big operators such as sums. local numeratorGapMin, denominatorGapMin, numeratorShiftUp, denominatorShiftDown if isDisplayMode(self.mode) then @@ -1126,12 +1236,14 @@ function elements.fraction:shape () end function elements.fraction:output (x, y, line) - SILE.outputter:drawRule( - scaleWidth(x + self.padding, line), - y.length - self.axisHeight - self.ruleThickness / 2, - scaleWidth(self.width - 2 * self.padding, line), - self.ruleThickness - ) + if self.ruleThickness > 0 then + SILE.outputter:drawRule( + scaleWidth(x + self.padding, line), + y.length - self.axisHeight - self.ruleThickness / 2, + scaleWidth(self.width - 2 * self.padding, line), + self.ruleThickness + ) + end end local function newSubscript (spec) @@ -1180,9 +1292,9 @@ function elements.table:_init (children, options) return #row.children end, self.children))) SU.debug("math", "self.ncols =", self.ncols) - self.rowspacing = self.options.rowspacing and SILE.types.length(self.options.rowspacing) or SILE.types.length("7pt") - self.columnspacing = self.options.columnspacing and SILE.types.length(self.options.columnspacing) - or SILE.types.length("6pt") + local spacing = SILE.settings:get("math.font.size") * 0.6 -- arbitrary ratio of the current math font size + self.rowspacing = self.options.rowspacing and SILE.types.length(self.options.rowspacing) or spacing + self.columnspacing = self.options.columnspacing and SILE.types.length(self.options.columnspacing) or spacing -- Pad rows that do not have enough cells by adding cells to the -- right. for i, row in ipairs(self.children) do @@ -1442,6 +1554,50 @@ function elements.sqrt:output (x, y, line) ) end +elements.padded = pl.class(elements.mbox) +elements.padded._type = "Padded" + +function elements.padded:__tostring () + return self._type .. "(" .. tostring(self.impadded) .. ")" +end + +function elements.padded:_init (attributes, impadded) + elements.mbox._init(self) + self.impadded = impadded + self.attributes = attributes or {} + table.insert(self.children, impadded) +end + +function elements.padded:styleChildren () + self.impadded.mode = self.mode +end + +function elements.padded:shape () + -- TODO MathML allows percentages font-relative units (em, ex) for padding + -- But our units work with font.size, not math.font.size (possibly adjusted by scaleDown) + -- so the expectations might not be met. + local width = self.attributes.width and SU.cast("measurement", self.attributes.width) + local height = self.attributes.height and SU.cast("measurement", self.attributes.height) + local depth = self.attributes.depth and SU.cast("measurement", self.attributes.depth) + local lspace = self.attributes.lspace and SU.cast("measurement", self.attributes.lspace) + local voffset = self.attributes.voffset and SU.cast("measurement", self.attributes.voffset) + -- Clamping for width, height, depth, lspace + width = width and (width:tonumber() > 0 and width or SILE.types.measurement()) + height = height and (height:tonumber() > 0 and height or SILE.types.measurement()) + depth = depth and (depth:tonumber() > 0 and depth or SILE.types.measurement()) + lspace = lspace and (lspace:tonumber() > 0 and lspace or SILE.types.measurement()) + -- No clamping for voffset + voffset = voffset or SILE.types.measurement(0) + -- Compute the dimensions + self.width = width and SILE.types.length(width) or self.impadded.width + self.height = height and SILE.types.length(height) or self.impadded.height + self.depth = depth and SILE.types.length(depth) or self.impadded.depth + self.impadded.relX = lspace and SILE.types.length(lspace) or SILE.types.length() + self.impadded.relY = voffset and SILE.types.length(voffset):negate() or SILE.types.length() +end + +function elements.padded.output (_, _, _, _) end + elements.mathMode = mathMode elements.atomType = atomType elements.symbolDefaults = symbolDefaults diff --git a/packages/math/texlike.lua b/packages/math/texlike.lua index 618884b97..7b7430b12 100644 --- a/packages/math/texlike.lua +++ b/packages/math/texlike.lua @@ -260,23 +260,40 @@ local compileToStr = function (argEnv, mathlist) end end -local function isBigOperator (tree) +local function isOperatorKind (tree, typeOfAtom, typeOfSymbol) + if not tree then + return false -- safeguard + end if tree.command ~= "mo" then return false end -- Case \mo[atom=big]{ops} -- E.g. \mo[atom=big]{lim} - if tree.options and tree.options.atom == "big" then + if tree.options and tree.options.atom == typeOfAtom then return true end - -- Case \mo{ops} where ops is registered as big operator (unicode-symbols) + -- Case \mo{ops} where ops is registered with the resquested type -- E.g. \mo{∑) or \sum - if tree[1] and symbolDefaults[tree[1]] and symbolDefaults[tree[1]].atom == atomType.bigOperator then + if tree[1] and symbolDefaults[tree[1]] and symbolDefaults[tree[1]].atom == typeOfSymbol then return true end return false end +local function isBigOperator (tree) + return isOperatorKind(tree, "big", atomType.bigOperator) +end +local function isCloseOperator (tree) + return isOperatorKind(tree, "close", atomType.closeSymbol) +end +local function isOpeningOperator (tree) + return isOperatorKind(tree, "open", atomType.openingSymbol) +end + +local function isAccentSymbol (symbol) + return symbolDefaults[symbol] and symbolDefaults[symbol].atom == atomType.accentSymbol +end + local function compileToMathML_aux (_, arg_env, tree) if type(tree) == "string" then return tree @@ -323,12 +340,56 @@ local function compileToMathML_aux (_, arg_env, tree) -- Turn mathlist into `mrow` except if it has exactly one `mtr` or `mtd` -- child. -- Note that `def`s have already been compiled away at this point. - if #tree == 1 and (tree[1].command == "mtr" or tree[1].command == "mtd") then - return tree[1] + if #tree == 1 then + if tree[1].command == "mtr" or tree[1].command == "mtd" then + return tree[1] + else + tree.command = "mrow" + end else + -- Re-wrap content from opening to closing operator in an implicit mrow, + -- so stretchy operators apply to the correct span of content. + local children = {} + local stack = {} + for _, child in ipairs(tree) do + if isOpeningOperator(child) then + table.insert(stack, children) + local mrow = { + command = "mrow", + options = {}, + child, + } + table.insert(children, mrow) + children = mrow + elseif isCloseOperator(child) then + table.insert(children, child) + if #stack > 0 then + children = table.remove(stack) + end + elseif + (child.command == "msubsup" or child.command == "msub" or child.command == "msup") + and isCloseOperator(child[1]) -- child[1] is the base + then + if #stack > 0 then + -- Special case for closing operator with sub/superscript: + -- (....)^i must be interpreted as {(....)}^i, not as (...{)}^i + -- Push the closing operator into the mrow + table.insert(children, child[1]) + -- Move the mrow into the msubsup, replacing the closing operator + child[1] = children + -- And insert the msubsup into the parent + children = table.remove(stack) + children[#children] = child + else + table.insert(children, child) + end + else + table.insert(children, child) + end + end + tree = #stack > 0 and stack[1] or children tree.command = "mrow" end - tree.command = "mrow" elseif tree.id == "atom" then local codepoints = {} for _, cp in luautf8.codes(tree[1]) do @@ -424,7 +485,36 @@ local function compileToMathML_aux (_, arg_env, tree) return res elseif tree.id == "command" and symbols[tree.command] then local atom = { id = "atom", [1] = symbols[tree.command] } - tree = compileToMathML_aux(nil, arg_env, atom) + if isAccentSymbol(symbols[tree.command]) and #tree > 0 then + -- LaTeX-style accents \vec{v} = v + local accent = { + id = "command", + command = "mover", + options = { + accent = "true", + }, + } + accent[1] = compileToMathML_aux(nil, arg_env, tree[1]) + accent[2] = compileToMathML_aux(nil, arg_env, atom) + tree = accent + elseif #tree > 0 then + -- Play cool with LaTeX-style commands that don't take arguments: + -- Edge case for non-accent symbols so we don't loose bracketed groups + -- that might have been seen as command arguments. + -- Ex. \langle{x}\rangle (without space after \langle) + local sym = compileToMathML_aux(nil, arg_env, atom) + -- Compile all children in-place + for i, child in ipairs(tree) do + tree[i] = compileToMathML_aux(nil, arg_env, child) + end + -- Insert symbol at the beginning, + -- And add a wrapper mrow to be unwrapped in the parent. + table.insert(tree, 1, sym) + tree.command = "mrow" + tree.id = "wrapper" + else + tree = compileToMathML_aux(nil, arg_env, atom) + end elseif tree.id == "argument" then if arg_env[tree.index] then return arg_env[tree.index] @@ -566,8 +656,9 @@ compileToMathML( % Phantom commands from TeX/LaTeX \def{phantom}{\mphantom{#1}} - \def{hphantom}{\mphantom[special=h]{#1}} - \def{vphantom}{\mphantom[special=v]{#1}} + \def{hphantom}{\mpadded[height=0, depth=0]{\mphantom{#1}}} + \def{vphantom}{\mpadded[width=0]{\mphantom{#1}}} + %\mphantom[special=v]{#1}}} ]==], }) ) diff --git a/packages/math/typesetter.lua b/packages/math/typesetter.lua index 78d435fde..bbc82f856 100644 --- a/packages/math/typesetter.lua +++ b/packages/math/typesetter.lua @@ -34,13 +34,24 @@ local function convertChildren (tree) return mboxes end +local function convertFirstChild (tree) + -- We need to loop until the first non-nil box is found, because + -- we may have blank lines in the tree. + for _, n in ipairs(tree) do + local box = ConvertMathML(nil, n) + if box then + return box + end + end +end + -- convert MathML into mbox function ConvertMathML (_, content) if content == nil or content.command == nil then return nil end if content.command == "math" or content.command == "mathml" then -- toplevel - return b.stackbox("V", convertChildren(content)) + return b.stackbox("H", convertChildren(content)) elseif content.command == "mrow" then return b.stackbox("H", convertChildren(content)) elseif content.command == "mphantom" then @@ -61,11 +72,16 @@ function ConvertMathML (_, content) or scriptType.upright local text = content[1] local attributes = {} + -- Attributes from the (default) oerator table if syms.symbolDefaults[text] then for attribute, value in pairs(syms.symbolDefaults[text]) do attributes[attribute] = value end end + -- Overwrite with attributes from the element + for attribute, value in pairs(content.options) do + attributes[attribute] = value + end if content.options.atom then if not atomTypeShort[content.options.atom] then SU.error("Unknown atom type " .. content.options.atom) @@ -131,7 +147,7 @@ function ConvertMathML (_, content) if #children ~= 2 then SU.error("Wrong number of children in mfrac: " .. #children) end - return b.fraction(children[1], children[2]) + return b.fraction(content.options, children[1], children[2]) elseif content.command == "msqrt" then local children = convertChildren(content) -- "The element generates an anonymous box called the msqrt base @@ -159,6 +175,17 @@ function ConvertMathML (_, content) -- There's also some explanations about CSS, italic correction etc. which we ignore too. text = text:gsub("[\n\r]", " ") return b.text("string", {}, scriptType.upright, text:gsub("%s+", " ")) + elseif content.command == "maction" then + -- MathML Core 3.6: display as mrow, ignoring all but the first child + return b.stackbox("H", { convertFirstChild(content) }) + elseif content.command == "mstyle" then + -- It's an mrow, but with some style attributes that we ignore. + SU.warn("MathML mstyle is not fully supported yet") + return b.stackbox("H", convertChildren(content)) + elseif content.command == "mpadded" then + -- MathML Core 3.3.6.1: The element generates an anonymous box + -- called the "impadded inner box" + return b.padded(content.options, b.stackbox("H", convertChildren(content))) else SU.error("Unknown math command " .. content.command) end diff --git a/tests/bug-1495-inline-math-layout.expected b/tests/bug-1495-inline-math-layout.expected index f5969e666..b4c8ae2bd 100644 --- a/tests/bug-1495-inline-math-layout.expected +++ b/tests/bug-1495-inline-math-layout.expected @@ -65,13 +65,11 @@ T 30 w=6.4800 (nil) Mx 217.4262 T 68 80 84 w=13.2200 (nil) Mx 230.6462 -Mx 2.8200 -T 9 a=3.5600 (nil) +T 9 w=3.5600 (nil) Mx 234.2062 T 3421 w=5.9100 (nil) Mx 240.1162 -Mx 2.8200 -T 10 a=3.5600 (nil) +T 10 w=3.5600 (nil) Mx 247.3974 T 30 w=6.4800 (nil) Mx 257.5986 @@ -88,53 +86,49 @@ My 52.6701 T 87 68 72 w=12.6514 (tae) Mx 27.5333 T 17 w=2.2900 (.) -Mx 32.4913 +Mx 32.7068 T 48 68 72 70 72 81 68 86 w=40.2295 (Maecenas) -Mx 75.3888 +Mx 75.8198 T 89 72 81 72 81 68 87 76 86 w=39.8096 (venenatis) -Mx 117.8663 +Mx 118.5129 T 88 79 87 85 76 70 72 86 w=30.9717 (ultrices) -Mx 148.8380 +Mx 149.4846 T 17 w=2.2900 (.) -Mx 153.7961 +Mx 154.6581 T 51 75 68 86 72 79 79 88 86 w=38.3984 (Phasellus) -Mx 194.8625 +Mx 195.9401 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2750 w=3.8100 (nil) -Mx 198.6725 +Mx 199.7501 My 49.5701 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2753 w=1.8320 (nil) -Mx 200.5045 +Mx 201.5821 T 3413 w=3.5152 (nil) -Mx 207.2916 +Mx 208.9129 My 52.6701 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) -Mx 216.6135 +Mx 218.7785 T 68 80 84 w=13.2200 (nil) -Mx 229.8335 -Mx 3.0000 -T 3798 a=4.2100 (nil) -Mx 234.0435 +Mx 231.9985 +T 9 w=3.5600 (nil) +Mx 235.5585 T 3413 w=4.5600 (nil) -Mx 238.6035 -Mx 2.9900 -T 3799 a=4.2100 (nil) -Mx 245.0614 +Mx 240.1185 +T 10 w=3.5600 (nil) +Mx 246.1439 T 12 w=6.4800 (nil) -Mx 253.7892 +Mx 255.0892 T 2753 w=2.2900 (nil) -Mx 257.7459 +Mx 259.0459 T 84 74 79 w=12.0300 (nil) -Mx 269.7759 -Mx 3.0000 -T 3798 a=4.2100 (nil) -Mx 273.9859 +Mx 271.0759 +T 9 w=3.5600 (nil) +Mx 274.6359 T 3413 w=4.5600 (nil) -Mx 278.5459 -Mx 2.9900 -T 3799 a=4.2100 (nil) +Mx 279.1959 +T 10 w=3.5600 (nil) Mx 14.8819 My 64.6701 Set font Gentium Plus;10;400;;normal;;;LTR diff --git a/tests/feat-math-display-numbered.expected b/tests/feat-math-display-numbered.expected index 76c5e4fee..265f6825e 100644 --- a/tests/feat-math-display-numbered.expected +++ b/tests/feat-math-display-numbered.expected @@ -167,7 +167,7 @@ T 38 88 86 87 82 80 w=34.1279 (Custom) Mx 51.4559 T 70 82 88 81 87 72 85 w=35.4600 (counter) Mx 96.0755 -My 293.6298 +My 293.1298 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 2.9400 T 4118 a=4.0500 (nil) @@ -185,14 +185,14 @@ T 30 w=6.4800 (nil) Mx 127.3283 T 2722 w=6.2100 (nil) Mx 100.1255 -My 301.1048 +My 300.1048 T 2765 w=4.9200 (nil) Mx 104.6855 -My 303.2048 +My 302.2048 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 114.8483 -My 301.1048 +My 300.1048 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 127.3283 @@ -202,7 +202,7 @@ T 151 w=5.1000 (nil) Mx 140.6728 T 2765 w=4.9200 (nil) Mx 145.2328 -My 303.2048 +My 302.2048 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 148.9656 @@ -210,7 +210,7 @@ T 2088 w=5.1840 (nil) Mx 154.1496 T 18 w=3.7200 (nil) Mx 158.2996 -My 301.1048 +My 300.1048 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 162.1662 @@ -222,7 +222,7 @@ T 2618 w=6.4800 (nil) Mx 184.8918 T 18 w=4.6500 (nil) Mx 270.7354 -My 293.6298 +My 293.1298 Set font Gentium Plus;11;400;;normal;;;LTR T 11 w=3.4858 (() Mx 274.2212 @@ -230,12 +230,12 @@ T 68 w=5.0488 (a) Mx 279.2701 T 12 w=3.4858 ()) Mx 14.8819 -My 322.6002 +My 321.6002 T 39 76 85 72 70 87 w=27.5322 (Direct) Mx 44.8592 T 81 88 80 69 72 85 76 81 74 w=50.1714 (numbering) Mx 122.8959 -My 345.7905 +My 344.7905 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 18 w=4.6500 (nil) Mx 130.3237 @@ -245,13 +245,13 @@ T 2088 w=6.4800 (nil) Mx 146.0615 T 2750 w=3.8100 (nil) Mx 149.8715 -My 342.0405 +My 341.0405 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2753 w=1.8320 (nil) Mx 151.7035 T 3421 w=4.5776 (nil) Mx 264.7251 -My 345.7905 +My 344.7905 Set font Gentium Plus;11;400;;normal;;;LTR T 11 w=3.4858 (() Mx 268.2110 diff --git a/tests/math-bigops.expected b/tests/math-bigops.expected index effbcc6cd..56b4890e1 100644 --- a/tests/math-bigops.expected +++ b/tests/math-bigops.expected @@ -816,7 +816,7 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 160.0108 T 29 w=2.2900 (:) Mx 229.1344 -My 381.4105 +My 384.4305 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 9.7200 T 4231 a=10.7600 (nil) @@ -846,7 +846,7 @@ My 390.5105 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 284.6860 -My 381.4105 +My 384.4305 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 12.1800 T 3983 a=13.7400 (nil) @@ -863,6 +863,7 @@ T 69 55 w=11.5800 (nil) Mx 321.1850 T 30 w=6.4800 (nil) Mx 330.4428 +My 384.4305 Mx 5.3800 T 3981 a=6.9400 (nil) Mx 334.8828 @@ -911,7 +912,7 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 209.5572 T 29 w=2.2900 (:) Mx 174.9317 -My 447.5261 +My 452.9621 Set font Libertinus Math;18;400;Regular;normal;;;LTR Mx 17.4960 T 4231 a=19.3680 (nil) @@ -941,7 +942,7 @@ My 463.9061 Set font Libertinus Math;14.4;400;Regular;normal;;;LTR T 17 w=6.6960 (nil) Mx 273.7246 -My 447.5261 +My 452.9621 Set font Libertinus Math;18;400;Regular;normal;;;LTR Mx 21.9240 T 3983 a=24.7320 (nil) @@ -958,6 +959,7 @@ T 69 55 w=20.8440 (nil) Mx 339.4228 T 30 w=11.6640 (nil) Mx 356.0868 +My 452.9621 Mx 9.6840 T 3981 a=12.4920 (nil) Mx 364.0788 @@ -1056,13 +1058,11 @@ My 483.7961 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2751 w=5.8900 (nil) Mx 245.6942 -Mx 2.8200 -T 9 a=3.5600 (nil) +T 9 w=3.5600 (nil) Mx 249.2542 T 2764 w=3.0300 (nil) Mx 252.2842 -Mx 2.8200 -T 10 a=3.5600 (nil) +T 10 w=3.5600 (nil) Mx 255.8442 T 69 w=5.0600 (nil) Mx 260.9042 @@ -1082,7 +1082,7 @@ T 55 72 59 w=16.2793 (TeX) Mx 141.8605 T 29 w=2.2900 (:) Mx 229.1344 -My 526.1599 +My 529.1799 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 9.7200 T 4231 a=10.7600 (nil) @@ -1112,7 +1112,7 @@ My 535.2599 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 284.6860 -My 526.1599 +My 529.1799 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 12.1800 T 3983 a=13.7400 (nil) @@ -1129,6 +1129,7 @@ T 69 55 w=11.5800 (nil) Mx 321.1850 T 30 w=6.4800 (nil) Mx 330.4428 +My 529.1799 Mx 5.3800 T 3981 a=6.9400 (nil) Mx 334.8828 @@ -1143,13 +1144,11 @@ My 526.1599 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2751 w=5.8900 (nil) Mx 347.9012 -Mx 2.8200 -T 9 a=3.5600 (nil) +T 9 w=3.5600 (nil) Mx 351.4612 T 2764 w=3.0300 (nil) Mx 354.4912 -Mx 2.8200 -T 10 a=3.5600 (nil) +T 10 w=3.5600 (nil) Mx 358.0512 T 69 w=5.0600 (nil) Mx 363.1112 diff --git a/tests/math-macros.expected b/tests/math-macros.expected index 74a374dac..857e88b8d 100644 --- a/tests/math-macros.expected +++ b/tests/math-macros.expected @@ -1,33 +1,31 @@ Set paper size 595.275597 841.8897729 Begin page -Mx 241.7172 -My 51.6845 +Mx 243.0172 +My 52.1045 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 84 74 79 w=12.0300 (nil) -Mx 253.7472 +Mx 255.0472 My 47.9345 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 9 w=2.8480 (nil) -Mx 256.5952 +Mx 257.8952 T 19 w=3.7200 (nil) -Mx 260.3152 +Mx 261.6152 T 2758 w=3.7328 (nil) -Mx 264.0480 +Mx 265.3480 T 12 w=5.1840 (nil) -Mx 269.2320 +Mx 270.5320 T 18 w=3.7200 (nil) -Mx 272.9520 +Mx 274.2520 T 10 w=2.8480 (nil) -Mx 276.2300 -My 51.6845 +Mx 277.5300 +My 52.1045 Set font Libertinus Math;10;400;Regular;normal;;;LTR -Mx 3.0000 -T 3798 a=4.2100 (nil) -Mx 280.4400 +T 9 w=3.5600 (nil) +Mx 281.0900 T 2768 w=5.4100 (nil) -Mx 285.8500 -Mx 2.9900 -T 3799 a=4.2100 (nil) +Mx 286.5000 +T 10 w=3.5600 (nil) Mx 292.8378 T 30 w=6.4800 (nil) Mx 302.0956 @@ -37,74 +35,72 @@ T 2088 18 w=11.1300 (nil) Mx 316.7856 T 10 w=3.5600 (nil) Mx 320.3456 -My 47.9345 +My 47.1045 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 326.5084 -My 51.6845 +My 52.1045 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 68 80 84 w=13.2200 (nil) Mx 339.7284 -Mx 3.0000 -T 3798 a=4.2100 (nil) -Mx 343.9384 +T 9 w=3.5600 (nil) +Mx 343.2884 T 2768 w=5.4100 (nil) -Mx 349.3484 -Mx 2.9900 -T 3799 a=4.2100 (nil) -Draw line 275.3007 84.0086 11.3900 0.6500 +Mx 348.6984 +T 10 w=3.5600 (nil) +Draw line 275.3007 84.4286 11.3900 0.6500 Mx 275.3007 -My 79.6886 +My 80.1086 T 69 w=5.0600 (nil) Mx 280.3607 T 2812 w=6.3300 (nil) Mx 276.9507 -My 93.9336 +My 94.3536 T 69 w=5.0600 (nil) Mx 282.0107 T 2764 w=3.0300 (nil) Mx 290.2185 -My 86.9336 +My 87.3536 T 30 w=6.4800 (nil) Mx 299.4762 -My 86.8386 +My 87.2586 Mx 10.6300 T 3985 a=12.4300 (nil) Mx 304.7752 -My 97.5426 +My 97.9626 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2753 w=1.8320 (nil) Mx 313.5729 -My 86.9336 +My 87.3536 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2776 w=6.0300 (nil) Mx 318.4629 -My 89.0336 +My 89.4536 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2753 w=1.8320 (nil) Mx 262.2436 -My 124.0866 +My 124.5066 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 2.8200 T 9 a=3.5600 (nil) Mx 265.8036 T 3424 w=5.6700 (nil) Mx 270.4736 -My 126.1866 +My 126.6066 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 274.6236 -My 124.0866 +My 124.5066 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 278.4903 T 3424 w=5.6700 (nil) Mx 283.1603 -My 126.1866 +My 126.6066 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 18 w=3.7200 (nil) Mx 287.3103 -My 124.0866 +My 124.5066 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 291.1770 @@ -114,11 +110,11 @@ T 13 w=2.2000 (nil) Mx 302.5336 T 3424 w=5.6700 (nil) Mx 307.2036 -My 126.1866 +My 126.6066 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 311.3664 -My 124.0866 +My 124.5066 Set font Libertinus Math;10;400;Regular;normal;;;LTR Mx 2.8200 T 10 a=3.5600 (nil) diff --git a/tests/math-tables-mathml.expected b/tests/math-tables-mathml.expected index a9b842829..55063c30b 100644 --- a/tests/math-tables-mathml.expected +++ b/tests/math-tables-mathml.expected @@ -1,7 +1,7 @@ Set paper size 595.275597 841.8897729 Begin page Mx 49.7638 -My 61.0395 +My 60.0395 Set font Gentium Plus;10;400;;normal;;;LTR T 49 88 80 69 72 85 w=33.4766 (Number) Mx 85.9226 @@ -25,21 +25,21 @@ T 19 w=4.6500 (nil) Mx 200.8698 T 24 w=4.6500 (nil) Mx 179.5698 -My 61.4745 +My 60.4745 T 17 w=4.6500 (nil) Mx 190.2198 T 22 w=4.6500 (nil) Mx 200.8698 T 20 w=4.6500 (nil) Mx 179.5698 -My 74.6845 +My 72.6845 T 25 w=4.6500 (nil) Mx 190.2198 T 19 w=4.6500 (nil) Mx 200.8698 T 18 w=4.6500 (nil) Mx 49.7638 -My 83.3528 +My 81.3528 Set font Gentium Plus;10;400;;normal;;;LTR T 49 88 80 69 72 85 w=33.4766 (Number) Mx 85.9243 @@ -55,7 +55,7 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 187.3713 T 29 w=2.2900 (:) Mx 284.6628 -My 102.0163 +My 100.0163 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 18 w=4.6500 (nil) Mx 295.3128 @@ -63,21 +63,21 @@ T 19 w=4.6500 (nil) Mx 305.9628 T 24 w=4.6500 (nil) Mx 284.6628 -My 115.2563 +My 112.2563 T 17 w=4.6500 (nil) Mx 295.3128 T 22 w=4.6500 (nil) Mx 305.9628 T 20 w=4.6500 (nil) Mx 284.6628 -My 128.4663 +My 124.4663 T 25 w=4.6500 (nil) Mx 295.3128 T 19 w=4.6500 (nil) Mx 305.9628 T 18 w=4.6500 (nil) Mx 49.7638 -My 160.8513 +My 155.8513 Set font Gentium Plus;10;400;;normal;;;LTR T 41 82 85 80 88 79 68 86 w=38.2617 (Formulas) Mx 88.0255 @@ -91,47 +91,47 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 148.9251 T 29 w=2.2900 (:) Mx 153.9043 -My 144.7283 +My 140.7283 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2765 w=4.9200 (nil) Mx 158.4643 -My 146.8283 +My 142.8283 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 168.6143 -My 144.7283 +My 140.7283 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 181.0943 T 18 w=4.6500 (nil) Mx 153.9043 -My 159.9883 +My 154.9883 T 2765 w=4.9200 (nil) Mx 158.4643 -My 162.0883 +My 157.0883 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 18 w=3.7200 (nil) Mx 168.6143 -My 159.9883 +My 154.9883 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 181.0943 T 18 w=4.6500 (nil) Mx 153.8915 -My 175.6743 +My 169.6743 T 2765 w=4.9200 (nil) Mx 158.4515 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 168.6143 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 181.0943 T 2765 w=4.9200 (nil) Mx 185.6543 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 189.3871 @@ -139,13 +139,13 @@ T 2088 w=5.1840 (nil) Mx 194.5711 T 18 w=3.7200 (nil) Mx 200.9774 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 12 w=6.4800 (nil) Mx 209.7137 T 2765 w=4.9200 (nil) Mx 214.2737 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 218.0065 @@ -153,7 +153,7 @@ T 2088 w=5.1840 (nil) Mx 223.1905 T 19 w=3.7200 (nil) Mx 227.3405 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 231.2072 @@ -165,7 +165,7 @@ T 2618 w=6.4800 (nil) Mx 254.1031 T 19 w=4.6500 (nil) Mx 49.7638 -My 186.4227 +My 180.4227 Set font Gentium Plus;10;400;;normal;;;LTR T 41 82 85 80 88 79 68 86 w=38.2617 (Formulas) Mx 88.0255 @@ -179,47 +179,47 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 161.7145 T 29 w=2.2900 (:) Mx 245.3391 -My 205.0261 +My 199.0261 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2765 w=4.9200 (nil) Mx 249.8991 -My 207.1261 +My 201.1261 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 260.0491 -My 205.0261 +My 199.0261 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 18 w=4.6500 (nil) Mx 245.3391 -My 220.2861 +My 213.2861 T 2765 w=4.9200 (nil) Mx 249.8991 -My 222.3861 +My 215.3861 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 18 w=3.7200 (nil) Mx 260.0491 -My 220.2861 +My 213.2861 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 18 w=4.6500 (nil) Mx 245.3263 -My 235.9721 +My 227.9721 T 2765 w=4.9200 (nil) Mx 249.8863 -My 238.0721 +My 230.0721 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 260.0491 -My 235.9721 +My 227.9721 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 2765 w=4.9200 (nil) Mx 277.0891 -My 238.0721 +My 230.0721 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 280.8219 @@ -227,13 +227,13 @@ T 2088 w=5.1840 (nil) Mx 286.0059 T 18 w=3.7200 (nil) Mx 292.3781 -My 235.9721 +My 227.9721 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 12 w=6.4800 (nil) Mx 301.0803 T 2765 w=4.9200 (nil) Mx 305.6403 -My 238.0721 +My 230.0721 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 309.3731 @@ -241,7 +241,7 @@ T 2088 w=5.1840 (nil) Mx 314.5571 T 19 w=3.7200 (nil) Mx 318.7071 -My 235.9721 +My 227.9721 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 322.5738 diff --git a/tests/math-tables-tex.expected b/tests/math-tables-tex.expected index 9217f7766..0c7122c6d 100644 --- a/tests/math-tables-tex.expected +++ b/tests/math-tables-tex.expected @@ -1,7 +1,7 @@ Set paper size 595.275597 841.8897729 Begin page Mx 49.7638 -My 61.0395 +My 60.0395 Set font Gentium Plus;10;400;;normal;;;LTR T 49 88 80 69 72 85 w=33.4766 (Number) Mx 85.9246 @@ -25,21 +25,21 @@ T 19 w=4.6500 (nil) Mx 182.7235 T 24 w=4.6500 (nil) Mx 161.4235 -My 61.4745 +My 60.4745 T 17 w=4.6500 (nil) Mx 172.0735 T 22 w=4.6500 (nil) Mx 182.7235 T 20 w=4.6500 (nil) Mx 161.4235 -My 74.6845 +My 72.6845 T 25 w=4.6500 (nil) Mx 172.0735 T 19 w=4.6500 (nil) Mx 182.7235 T 18 w=4.6500 (nil) Mx 49.7638 -My 83.3528 +My 81.3528 Set font Gentium Plus;10;400;;normal;;;LTR T 49 88 80 69 72 85 w=33.4766 (Number) Mx 85.9263 @@ -55,7 +55,7 @@ T 55 72 59 w=16.2793 (TeX) Mx 169.2230 T 29 w=2.2900 (:) Mx 284.6628 -My 102.0163 +My 100.0163 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 18 w=4.6500 (nil) Mx 295.3128 @@ -63,21 +63,21 @@ T 19 w=4.6500 (nil) Mx 305.9628 T 24 w=4.6500 (nil) Mx 284.6628 -My 115.2563 +My 112.2563 T 17 w=4.6500 (nil) Mx 295.3128 T 22 w=4.6500 (nil) Mx 305.9628 T 20 w=4.6500 (nil) Mx 284.6628 -My 128.4663 +My 124.4663 T 25 w=4.6500 (nil) Mx 295.3128 T 19 w=4.6500 (nil) Mx 305.9628 T 18 w=4.6500 (nil) Mx 49.7638 -My 160.8513 +My 155.8513 Set font Gentium Plus;10;400;;normal;;;LTR T 41 82 85 80 88 79 68 86 w=38.2617 (Formulas) Mx 88.0255 @@ -91,47 +91,47 @@ T 55 72 59 w=16.2793 (TeX) Mx 130.7748 T 29 w=2.2900 (:) Mx 135.7560 -My 144.7283 +My 140.7283 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2765 w=4.9200 (nil) Mx 140.3160 -My 146.8283 +My 142.8283 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 150.4660 -My 144.7283 +My 140.7283 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 162.9460 T 18 w=4.6500 (nil) Mx 135.7560 -My 159.9883 +My 154.9883 T 2765 w=4.9200 (nil) Mx 140.3160 -My 162.0883 +My 157.0883 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 18 w=3.7200 (nil) Mx 150.4660 -My 159.9883 +My 154.9883 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 162.9460 T 18 w=4.6500 (nil) Mx 135.7432 -My 175.6743 +My 169.6743 T 2765 w=4.9200 (nil) Mx 140.3032 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 150.4660 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 162.9460 T 2765 w=4.9200 (nil) Mx 167.5060 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 171.2388 @@ -139,13 +139,13 @@ T 2088 w=5.1840 (nil) Mx 176.4228 T 18 w=3.7200 (nil) Mx 182.8311 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 12 w=6.4800 (nil) Mx 191.5694 T 2765 w=4.9200 (nil) Mx 196.1294 -My 177.7743 +My 171.7743 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 199.8622 @@ -153,7 +153,7 @@ T 2088 w=5.1840 (nil) Mx 205.0462 T 19 w=3.7200 (nil) Mx 209.1962 -My 175.6743 +My 169.6743 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 213.0629 @@ -165,7 +165,7 @@ T 2618 w=6.4800 (nil) Mx 235.9689 T 19 w=4.6500 (nil) Mx 49.7638 -My 186.4227 +My 180.4227 Set font Gentium Plus;10;400;;normal;;;LTR T 41 82 85 80 88 79 68 86 w=38.2617 (Formulas) Mx 88.0255 @@ -179,47 +179,47 @@ T 55 72 59 w=16.2793 (TeX) Mx 130.7985 T 29 w=2.2900 (:) Mx 245.3391 -My 204.0740 +My 198.0740 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2765 w=4.9200 (nil) Mx 249.8991 -My 206.1740 +My 200.1740 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 17 w=3.7200 (nil) Mx 260.0491 -My 204.0740 +My 198.0740 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 18 w=4.6500 (nil) Mx 245.3391 -My 219.3340 +My 212.3340 T 2765 w=4.9200 (nil) Mx 249.8991 -My 221.4340 +My 214.4340 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 18 w=3.7200 (nil) Mx 260.0491 -My 219.3340 +My 212.3340 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 18 w=4.6500 (nil) Mx 245.3263 -My 235.0200 +My 227.0200 T 2765 w=4.9200 (nil) Mx 249.8863 -My 237.1200 +My 229.1200 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 260.0491 -My 235.0200 +My 227.0200 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 30 w=6.4800 (nil) Mx 272.5291 T 2765 w=4.9200 (nil) Mx 277.0891 -My 237.1200 +My 229.1200 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 280.8219 @@ -227,13 +227,13 @@ T 2088 w=5.1840 (nil) Mx 286.0059 T 18 w=3.7200 (nil) Mx 292.3781 -My 235.0200 +My 227.0200 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 12 w=6.4800 (nil) Mx 301.0803 T 2765 w=4.9200 (nil) Mx 305.6403 -My 237.1200 +My 229.1200 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 309.3731 @@ -241,7 +241,7 @@ T 2088 w=5.1840 (nil) Mx 314.5571 T 19 w=3.7200 (nil) Mx 318.7071 -My 235.0200 +My 227.0200 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 322.5738 diff --git a/tests/math-variants.expected b/tests/math-variants.expected index 36c4000ae..fdf17775c 100644 --- a/tests/math-variants.expected +++ b/tests/math-variants.expected @@ -1,157 +1,157 @@ Set paper size 595.275597 841.8897729 Begin page Mx 49.7638 -My 50.0745 +My 51.9745 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) -Mx 74.0469 +Mx 74.0466 T 89 68 85 76 68 81 87 86 w=33.6035 (variants) -Mx 107.6504 +Mx 107.6501 T 15 w=2.2900 (,) -Mx 112.6122 +Mx 112.6116 T 87 72 91 87 w=16.5332 (text) -Mx 129.1454 +Mx 129.1448 T 15 w=2.2900 (,) -Mx 134.1072 +Mx 134.1063 T 48 68 87 75 48 47 w=34.4336 (MathML) -Mx 168.5408 +Mx 168.5399 T 29 w=2.2900 (:) -Mx 173.5026 +Mx 173.5014 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2070 w=5.9800 (nil) -Mx 179.4826 +Mx 179.4814 T 2758 w=4.7100 (nil) -Mx 187.0439 +Mx 187.0421 T 2078 w=6.3700 (nil) -Mx 196.2653 +Mx 196.2627 T 1880 w=8.2400 (nil) -Mx 204.5053 +Mx 204.5027 T 13 w=2.2000 (nil) -Mx 208.3720 -Mx 2.8200 -T 9 a=3.5600 (nil) -Mx 211.9320 +Mx 208.3694 +Mx 3.0000 +T 3798 a=4.2100 (nil) +Mx 212.5794 T 70 w=4.4700 (nil) -Mx 216.4020 -My 46.9745 +Mx 217.0494 +My 48.8745 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) -Mx 220.5648 -My 50.0745 +Mx 221.2122 +My 51.9745 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) -Mx 224.4315 +Mx 225.0789 T 3000 2990 2995 w=14.3900 (nil) -Mx 238.8215 -Mx 2.8200 -T 9 a=3.5600 (nil) -Mx 242.3815 +Mx 239.4689 +Mx 3.0000 +T 3798 a=4.2100 (nil) +Mx 243.6789 T 2758 w=4.7100 (nil) -Mx 247.0915 -Mx 2.8200 -T 10 a=3.5600 (nil) -Mx 250.6515 -Mx 2.8200 -T 10 a=3.5600 (nil) -Mx 257.0628 +Mx 248.3889 +Mx 2.9900 +T 3799 a=4.2100 (nil) +Mx 252.5989 +Mx 2.9900 +T 3799 a=4.2100 (nil) +Mx 259.6595 T 2078 w=6.3700 (nil) -Mx 266.2842 +Mx 268.8802 Mx 2.8200 T 9 a=3.5600 (nil) -Mx 269.8442 +Mx 272.4402 T 1887 w=6.1800 (nil) -Mx 278.2759 +Mx 280.8716 T 2601 w=5.2700 (nil) -Mx 285.7976 +Mx 288.3930 T 1884 w=7.0200 (nil) -Mx 292.8176 +Mx 295.4130 Mx 2.8200 T 10 a=3.5600 (nil) -Mx 296.3776 +Mx 298.9730 My 46.9745 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 19 w=3.7200 (nil) Mx 49.7638 -My 67.5285 +My 72.8485 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) -Mx 74.0300 +Mx 74.0295 T 89 68 85 76 68 81 87 86 w=33.6035 (variants) -Mx 107.6335 +Mx 107.6330 T 15 w=2.2900 (,) -Mx 112.5784 +Mx 112.5774 T 87 72 91 87 w=16.5332 (text) -Mx 131.7665 +Mx 131.7649 T 11 w=3.1689 (() -Mx 134.9354 +Mx 134.9339 T 79 68 85 74 72 w=20.7568 (large) -Mx 158.3471 +Mx 158.3451 T 73 82 81 87 w=17.0996 (font) -Mx 175.4467 +Mx 175.4447 T 12 w=3.1689 ()) -Mx 178.6157 +Mx 178.6136 T 15 w=2.2900 (,) -Mx 183.5606 +Mx 183.5580 T 48 68 87 75 48 47 w=34.4336 (MathML) -Mx 217.9942 +Mx 217.9916 T 29 w=2.2900 (:) -Mx 225.5940 +Mx 225.5904 Set font Libertinus Math;18;400;Regular;normal;;;LTR T 2070 w=10.7640 (nil) -Mx 236.3580 +Mx 236.3544 T 2758 w=8.4780 (nil) -Mx 249.8918 +Mx 249.8859 T 2078 w=11.4660 (nil) -Mx 266.4136 +Mx 266.4053 T 1880 w=14.8320 (nil) -Mx 281.2456 +Mx 281.2373 T 13 w=3.9600 (nil) -Mx 288.2056 -Mx 5.0760 -T 9 a=6.4080 (nil) -Mx 294.6136 +Mx 288.1973 +Mx 5.4000 +T 3798 a=7.5780 (nil) +Mx 295.7753 T 70 w=8.0460 (nil) -Mx 302.6596 -My 61.9485 +Mx 303.8213 +My 67.2685 Set font Libertinus Math;14.4;400;Regular;normal;;;LTR T 2758 w=6.7190 (nil) -Mx 310.1526 -My 67.5285 +Mx 311.3144 +My 72.8485 Set font Libertinus Math;18;400;Regular;normal;;;LTR T 13 w=3.9600 (nil) -Mx 317.1126 +Mx 318.2744 T 3000 2990 2995 w=25.9020 (nil) -Mx 343.0146 -Mx 5.0760 -T 9 a=6.4080 (nil) -Mx 349.4226 +Mx 344.1764 +Mx 5.4000 +T 3798 a=7.5780 (nil) +Mx 351.7544 T 2758 w=8.4780 (nil) -Mx 357.9006 -Mx 5.0760 -T 10 a=6.4080 (nil) -Mx 364.3086 -Mx 5.0760 -T 10 a=6.4080 (nil) -Mx 375.7725 +Mx 360.2324 +Mx 5.3820 +T 3799 a=7.5780 (nil) +Mx 367.8104 +Mx 5.3820 +T 3799 a=7.5780 (nil) +Mx 380.4419 T 2078 w=11.4660 (nil) -Mx 392.2943 +Mx 396.9614 Mx 5.0760 T 9 a=6.4080 (nil) -Mx 398.7023 +Mx 403.3694 T 1887 w=11.1240 (nil) -Mx 413.8486 +Mx 418.5148 T 2601 w=9.4860 (nil) -Mx 427.3569 +Mx 432.0222 T 1884 w=12.6360 (nil) -Mx 439.9929 +Mx 444.6582 Mx 5.0760 T 10 a=6.4080 (nil) -Mx 446.4009 -My 61.9485 +Mx 451.0662 +My 63.8485 Set font Libertinus Math;14.4;400;Regular;normal;;;LTR T 19 w=6.6960 (nil) Mx 49.7638 -My 79.8588 +My 85.1788 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) Mx 74.0597 @@ -167,7 +167,7 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 181.3479 T 29 w=2.2900 (:) Mx 233.0020 -My 101.0123 +My 107.5823 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2070 w=5.9800 (nil) Mx 238.9820 @@ -184,11 +184,11 @@ T 3798 a=4.2100 (nil) Mx 271.9342 T 70 w=4.4700 (nil) Mx 276.4042 -My 97.2623 +My 103.8323 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 280.5670 -My 101.0123 +My 107.5823 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 284.4336 @@ -219,11 +219,11 @@ Mx 354.5636 Mx 2.8200 T 10 a=3.5600 (nil) Mx 358.1236 -My 97.2623 +My 102.5823 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 19 w=3.7200 (nil) Mx 49.7638 -My 122.0943 +My 128.6643 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) Mx 74.0543 @@ -247,7 +247,7 @@ T 48 68 87 75 48 47 w=34.4336 (MathML) Mx 230.8842 T 29 w=2.2900 (:) Mx 181.2933 -My 150.1518 +My 158.9718 Set font Libertinus Math;18;400;Regular;normal;;;LTR T 2070 w=10.7640 (nil) Mx 192.0573 @@ -264,11 +264,11 @@ T 3798 a=7.5780 (nil) Mx 251.3713 T 70 w=8.0460 (nil) Mx 259.4173 -My 143.4018 +My 152.2218 Set font Libertinus Math;14.4;400;Regular;normal;;;LTR T 2758 w=6.7190 (nil) Mx 266.9103 -My 150.1518 +My 158.9718 Set font Libertinus Math;18;400;Regular;normal;;;LTR T 13 w=3.9600 (nil) Mx 273.8703 @@ -299,11 +299,11 @@ Mx 400.1043 Mx 5.0760 T 10 a=6.4080 (nil) Mx 406.5123 -My 143.4018 +My 149.9718 Set font Libertinus Math;14.4;400;Regular;normal;;;LTR T 19 w=6.6960 (nil) Mx 49.7638 -My 171.9758 +My 182.6958 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) Mx 74.0491 @@ -330,31 +330,27 @@ T 1880 w=8.2400 (nil) Mx 186.3714 T 13 w=2.2000 (nil) Mx 190.2381 -Mx 2.8200 -T 9 a=3.5600 (nil) +T 9 w=3.5600 (nil) Mx 193.7981 T 70 w=4.4700 (nil) Mx 198.2681 -My 168.8758 +My 179.5958 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) Mx 202.4309 -My 171.9758 +My 182.6958 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) Mx 206.2976 T 84 74 79 w=12.0300 (nil) Mx 218.3276 -Mx 2.8200 -T 9 a=3.5600 (nil) +T 9 w=3.5600 (nil) Mx 221.8876 T 2758 w=4.7100 (nil) Mx 226.5976 -Mx 2.8200 -T 10 a=3.5600 (nil) +T 10 w=3.5600 (nil) Mx 230.1576 -Mx 2.8200 -T 10 a=3.5600 (nil) +T 10 w=3.5600 (nil) Mx 236.5746 T 2078 w=6.3700 (nil) Mx 245.8017 @@ -370,11 +366,11 @@ Mx 272.3396 Mx 2.8200 T 10 a=3.5600 (nil) Mx 275.8996 -My 168.8758 +My 177.6958 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 19 w=3.7200 (nil) Mx 49.7638 -My 183.9758 +My 194.6958 Set font Gentium Plus;10;400;;normal;;;LTR T 48 68 87 75 w=21.6113 (Math) Mx 74.0617 @@ -389,60 +385,56 @@ Mx 146.9203 T 55 72 59 w=16.2793 (TeX) Mx 163.1996 T 29 w=2.2900 (:) -Mx 234.1820 -My 205.1292 +Mx 235.4820 +My 217.0992 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 2070 w=5.9800 (nil) -Mx 240.1620 +Mx 241.4620 T 2758 w=4.7100 (nil) -Mx 247.6497 +Mx 248.9497 T 2078 w=6.3700 (nil) -Mx 256.7975 +Mx 258.0975 T 1880 w=8.2400 (nil) -Mx 265.0375 +Mx 266.3375 T 13 w=2.2000 (nil) -Mx 268.9042 -Mx 3.0000 -T 3798 a=4.2100 (nil) -Mx 273.1142 +Mx 270.2042 +T 9 w=3.5600 (nil) +Mx 273.7642 T 70 w=4.4700 (nil) -Mx 277.5842 -My 201.3792 +Mx 278.2342 +My 213.3492 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 2758 w=3.7328 (nil) -Mx 281.7470 -My 205.1292 +Mx 282.3970 +My 217.0992 Set font Libertinus Math;10;400;Regular;normal;;;LTR T 13 w=2.2000 (nil) -Mx 285.6136 +Mx 286.2636 T 84 74 79 w=12.0300 (nil) -Mx 297.6436 -Mx 3.0000 -T 3798 a=4.2100 (nil) +Mx 298.2936 +T 9 w=3.5600 (nil) Mx 301.8536 T 2758 w=4.7100 (nil) Mx 306.5636 -Mx 2.9900 -T 3799 a=4.2100 (nil) -Mx 310.7736 -Mx 2.9900 -T 3799 a=4.2100 (nil) -Mx 317.7614 +T 10 w=3.5600 (nil) +Mx 310.1236 +T 10 w=3.5600 (nil) +Mx 316.4614 T 2078 w=6.3700 (nil) -Mx 326.9092 +Mx 325.6092 Mx 2.8200 T 9 a=3.5600 (nil) -Mx 330.4692 +Mx 329.1692 T 1887 w=6.1800 (nil) -Mx 338.8714 +Mx 337.5714 T 2601 w=5.2700 (nil) -Mx 346.3636 +Mx 345.0636 T 1884 w=7.0200 (nil) -Mx 353.3836 +Mx 352.0836 Mx 2.8200 T 10 a=3.5600 (nil) -Mx 356.9436 -My 201.3792 +Mx 355.6436 +My 212.0992 Set font Libertinus Math;8;400;Regular;normal;;;LTR T 19 w=3.7200 (nil) Mx 295.2916 diff --git a/types/unit.lua b/types/unit.lua index 8991360ae..169de78a9 100644 --- a/types/unit.lua +++ b/types/unit.lua @@ -76,6 +76,13 @@ unittypes["pc"] = { definition = "0.166666667in", } +-- Pixel, by convention 1px = 1/96in = 0.75pt +-- (CSS Values and Units Module Level 3, §5.2) +-- Used in MathML, etc. +unittypes["px"] = { + definition = "0.75pt", +} + local checkPaperDefined = function () if not SILE.documentState or not SILE.documentState.orgPaperSize then SU.error("A measurement tried to measure the paper size before the paper was defined", true)