Fix rendering of embedded HTML to work with scaling and mathsize changes. (mathjax/MathJax#3116) #1012
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR consolidates the handling of HTML nodes in MathML with the handling of XML nodes in generate (that are used in
annotation-xml
nodes). This makes the output for HTML embedded in token nodes and the legacy handling of an initialannotation-xml
node in asemantics
node both work the same, and allows them to share common code. The main reason to revisit this code was to make it work better when the output is scaled, either by a scaling factor in the configuration, or by amathsize
attribute. Also, when the math is being processed outside of the DOM (as inMathJax.tex2svg()
orMathJax.mml2chtml()
and other similar calls, and the result is inserted into a container with a different font size.This PR should make nested HTML work in all combinations of container
font-size
,mathsize
attributes on the MathML (including those set by\large
,\small
, etc.), MathJax output scaling (as set by theScale all math
contextual menu item),font-size
attributes within the embedded HTML, and output renderer. It should also work in combination with thedata-mjx-hdw
attribute on the top-level HTML element that specifies the size of the HTML (in the em units of the HTML node itself, not the em units of the math font) in all the above combinations. That is a lot of potential interactions!These can be tested using
This makes several tables containing examples of HTML that have em-unit dimensions (first two columns) and px-unit dimensions (last two columns). The first table uses
\tiny
size, the middle is normal size, and the last is\Large
size. The em-dimensions should change with the size, while the px-dimensions should stay the same through all three. The tables also include black bars below that are em- and px-sized as comparisons within TeX for the HTML content. Note that the px-size stays the same in TeX as well as HTML. The em within TeX is based on the em-size of the TeX fonts (which are scaled to match the ex-height of the surrounding font), so doesn't match the em-size in the HTML exactly, but should give you a sense of expected size.You can use the contextual menu to set the math scaling factor to larger or smaller percentages, and should see the entire table scale including the px sized content.
In order to allow the HTML content to be processed, you need to add the
allowTexHTML
flag to thetex
block of the configuration. If you are using the v4 lab, you can enterin the command console and then clock one of the TeX package checkboxes to get that to be processed. Otherwise, you can use a stand-alone document with that value set.
The code changes are summarized below.
The changes in
semantic-enrich.ts
are to allow the HTML content to be serialized as XML (in order to get end tags to be included), so that SRE can parse the result as XML without producing error messages.In the past, there were basically two separate implementations of embedded HTML, on in the
HtmlNode.ts
files, and one forannotation-xml
nodes when they are used as the first child of asemantics
node (the legacy way of getting HTML into MathML that is not actually valid MathML, but worked in Firefox, so we retained it). In this PR, we refactor the code to use a commonXmlNode
as the basis for both (theHtmlNode
is is a subclass of that). The output jax have aCommonXmlNode
wrapper forXmlNodes
and create jax-specificChtmlXmlNode
andSvgXmlNode
classes that do the needed work for each output format, andChtmlHtmlNode
andSvgHtmlNode
classes that are basically shells around the XmlNode implementations. This makes the HTML embedded in token nodes work the same as the HTML inannotation-xml
nodes, as the same code is used for both.So the core
HtmlNode
object is based off the coreXmlNode
object, so the changes here reflect that.The
getInitialScale()
inchtml.ts
is removed, since that is the default incommon.ts
.The CHTML and SVG HtmlNode wrappers are now based on the XmlNode wrapper, so they now basically just inherit everything. The
ChtmlXmlNode
andSvgXmlNode
classes are defined in thesemantics.ts
files, and since they now share a common XmlNode wrapper as the base, they now call theCommonXmlNodeMixin
to create these jax-specific classes. That requires adding the interfaces for the instance and class objects. Most of the code is now in the common mixin, with just thetoCHTML()
ortoSVG()
andaddHDW()
functions handling the specifics that differ for CHTML and SVG output.The
measureXMLnode()
function has been moved fromcommon.ts
to the common XmlNode wrapper mixin.The common Wrapper object now has a new
getRScale()
function that gets the scale of the node relative to the top of the math tree (as opposed to therscale
property of theBBox
object, which is the scale relative just to its parent node). This is needed in order to properly measure the size of the HTML content as it will be scaled in the end.The code that used to be in the common HtmlNode wrapper has been moved to the new common XmlNode wrapper (the file was actually renamed and then edited). The
measureXmlNode()
code has been moved here, and modified to handle all the scaling issues, and theaddHDW()
function is meant to be implemented in the output jax themselves.Finally, the SVG output jax sets the
matchFontHeight
value, since it is being done automatically in the width and height of the final SVG element, as they are in units of ex, so match the surrounding text automatically.Resolves issue mathjax/MathJax#3116