Skip to content

Commit

Permalink
fix(math): Suppress invisible operators in MathML
Browse files Browse the repository at this point in the history
  • Loading branch information
Omikhleia authored and Didier Willis committed Nov 23, 2024
1 parent f0ddaed commit 8bffb56
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/math/typesetter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,40 @@ function ConvertMathML (_, content)
if type(text) ~= "string" then
SU.error("mo command contains content which is not text")
end
local cp = text and luautf8.len(text) == 1 and luautf8.codepoint(text, 1)
if cp and cp >= 0x2061 and cp <= 0x2064 then
-- "Invisible operators"
-- - Several test cases in Joe Javawaski's Browser Test and the
-- - The MathML Test Suite use these too, with ad hoc spacing attributes.
-- MathML Core doesn't mention anything special about these.
-- MathML4 §8.3: "They are especially important new additions to the UCS
-- because they provide textual clues which can increase the quality of
-- print rendering (...)" (Note the absence of indication on how "print"
-- rendering is supposed to be improved.)
-- MathML4 §3.1.1: "they usually render invisibly (...) but may influence
-- visual spacing." (Note the ill-defined "usually" and "may" in this
-- specification.)
-- The best we can do is to suppress these operators, but handle any
-- explicitspacing (despite not handling rsup/rspace attributes on other
-- operators in our TeX-based spacing logic).
local number = lpeg.R("09")^0 * (lpeg.P(".")^-1 * lpeg.R("09")^1)^0 / tonumber
-- 0 something is 0 in whatever unit (ex. "0", "0mu", "0em" etc.)
local rspace, lspace = number:match(attributes.rspace), number:match(attributes.lspace)
if rspace == 0 and lspace == 0 then
return nil -- Just skip the invisible operator.
end
-- Skip it but honor the non-zero spacing.
if rspace == 0 then
return b.space(attributes.lspace, 0, 0)
end
if lspace == 0 then
return b.space(attributes.rspace, 0, 0)
end
-- I haven't found examples of invisible operators with both rspace and lspace set,
-- but it may happen, whatever spaces around something invisible mean.
-- We'll just stack the spaces in this case (as we can only return one box).
return b.stackbox("H", { b.space(attributes.lspace, 0, 0), b.space(attributes.rspace, 0, 0) })
end
return b.text("operator", attributes, script, text)
elseif content.command == "mn" then
local script = content.options.mathvariant and mathVariantToScriptType(content.options.mathvariant)
Expand Down

0 comments on commit 8bffb56

Please sign in to comment.