Skip to content

Commit 46e5954

Browse files
OmikhleiaDidier Willis
authored andcommitted
feat(math): Support MathML mphantom and TeX-like phantom, hphantom, vphantom
1 parent 3a0ef46 commit 46e5954

3 files changed

Lines changed: 47 additions & 0 deletions

File tree

packages/math/base-elements.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,43 @@ end
533533

534534
function elements.stackbox.output (_, _, _, _) end
535535

536+
elements.phantom = pl.class(elements.stackbox) -- inherit from stackbox
537+
elements.phantom._type = "Phantom"
538+
539+
function elements.phantom:_init (children, special)
540+
-- MathML core 3.3.7:
541+
-- "Its layout algorithm is the same as the mrow element".
542+
-- Also not the MathML states that <mphantom> is sort of legacy, "implemented
543+
-- for compatibility with full MathML. Authors whose only target is MathML
544+
-- Core are encouraged to use CSS for styling."
545+
-- The thing is that we don't have CSS in SILE, so supporting <mphantom> is
546+
-- a must.
547+
elements.stackbox._init(self, "H", children)
548+
self.special = special
549+
end
550+
551+
function elements.phantom:shape ()
552+
elements.stackbox.shape(self)
553+
-- From https://latexref.xyz:
554+
-- "The \vphantom variant produces an invisible box with the same vertical size
555+
-- as subformula, the same height and depth, but having zero width.
556+
-- And \hphantom makes a box with the same width as subformula but
557+
-- with zero height and depth."
558+
if self.special == "v" then
559+
self.width = SILE.types.length()
560+
elseif self.special == "h" then
561+
self.height = SILE.types.length()
562+
self.depth = SILE.types.length()
563+
end
564+
end
565+
566+
function elements.phantom:output (_, _, _)
567+
-- Note the trick here: when the tree is rendered, the node's output
568+
-- function is invoked, then all its children's output functions.
569+
-- So we just cancel the list of children here, before it's rendered.
570+
self.children = {}
571+
end
572+
536573
elements.subscript = pl.class(elements.mbox)
537574
elements.subscript._type = "Subscript"
538575

packages/math/texlike.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ compileToMathML(
499499
% Modulus operator forms
500500
\def{bmod}{\mo{mod}}
501501
\def{pmod}{\quad(\mo{mod} #1)}
502+
503+
% Phantom commands from TeX/LaTeX
504+
\def{phantom}{\mphantom{#1}}
505+
\def{hphantom}{\mphantom[special=h]{#1}}
506+
\def{vphantom}{\mphantom[special=v]{#1}}
502507
]==],
503508
})
504509
)

packages/math/typesetter.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ function ConvertMathML (_, content)
4141
return b.stackbox("V", convertChildren(content))
4242
elseif content.command == "mrow" then
4343
return b.stackbox("H", convertChildren(content))
44+
elseif content.command == "mphantom" then
45+
-- MathML's standard mphantom corresponds to TeX's \phantom only.
46+
-- Let's support a special attribute "h" or "v" for TeX-like \hphantom or \vphantom.
47+
local special = content.options.special
48+
return b.phantom(convertChildren(content), special)
4449
elseif content.command == "mi" then
4550
local script = content.options.mathvariant and b.mathVariantToScriptType(content.options.mathvariant)
4651
local text = content[1]

0 commit comments

Comments
 (0)