Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove/Deprecate mfrac@bevelled #29

Open
fred-wang opened this issue Feb 22, 2019 · 32 comments
Open

Remove/Deprecate mfrac@bevelled #29

fred-wang opened this issue Feb 22, 2019 · 32 comments
Labels
compatibility Issues affecting backward compatibility MathML 4 Issues affecting the MathML 4 specification need specification update Issues requiring specification changes need tests Issues related to writing WPT tests

Comments

@fred-wang
Copy link

Just opening for discussion. I wonder if this is really used in practice.

@fred-wang fred-wang added the MathML 4 Issues affecting the MathML 4 specification label Feb 22, 2019
@davidcarlisle
Copy link
Collaborator

The equivalent layout in tex is provided by several popular packages, nicefrac, xfrac for example. Not used so much in scientific documents but quite a lot for fractions in other fields. Arguably of course in a web context one should use characters such as ¾ rather than constructed fractions for many of these uses, but still mapping between TeX and MathML is easier with this in, I think.

@fred-wang
Copy link
Author

Thanks for the info.

@dani31415
Copy link

I understand that it is difficult to implement. But since we have the icon in MathType, I assume some people are using it.

@fred-wang
Copy link
Author

I understand that it is difficult to implement.

It's not really about the difficulty to implement but about
(1) implementing in a way that is compatible with web engines's layout approach.
(2) not adding extra code/complexity or duplicate features to web engines if it has limited usage. Again we need #55


cc @rwlbuis, @emilio :

Currently it's only implemented in Gecko. Regarding (1), the issue is that the width of the slash might strongly depend on the vertical metrics of numerator/denomiator preventing to get accurate intrinsic widths. See https://dxr.mozilla.org/mozilla-central/source/layout/mathml/nsMathMLmfracFrame.cpp where intrinsic width and actual width calculation differ:

 // Set the width of the slash
 if (aWidthOnly) {
   mLineRect.width = mLineThickness + slashMaxWidthConstant;
 } else {
   mLineRect.width =
       mLineThickness +
       std::min(slashMaxWidthConstant,
                (mBoundingMetrics.ascent + mBoundingMetrics.descent) /
                    slashRatio);
 }

We have a similar issues for vertical stretchy operators, but at least the width generally does not depend too strongly on the height so it's acceptable to take the max widths for preferred width calculation... except of course for U+2044 FRACTION SLASH !!

The equivalent layout in tex is provided by several popular packages, nicefrac, xfrac for example. Not used so much in scientific documents but quite a lot for fractions in other fields. Arguably of course in a web context one should use characters such as ¾ rather than constructed fractions for many of these uses, but still mapping between TeX and MathML is easier with this in, I think.

In general one can probably implement the slash fraction layout <mpadded>NUMERATOR</mpadded><mo>&#x2215;</mo><mpadded>DENOMINATOR</mpadded></mrow> with some mpadded attributes to adjust the position of numerator and denominator. This suggests that (1) duplicates existing features (2) could be implemented via polyfills ; hence should not be in core.

@fred-wang fred-wang added the compatibility Issues affecting backward compatibility label Mar 20, 2019
@NSoiffer
Copy link
Contributor

According to the stats we have so far, the DLMF and arXiv converters don't support it and NAG doesn't use it. However, I've seen it many times in textbooks. I think we should defer a decision until we get stats from Pearson. That represents a group where I think it is used, but the stats may say something different.

@fred-wang fred-wang added the need resolution Issues needing resolution at MathML Refresh CG meeting label May 16, 2019
@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Jun 12, 2019

I think bevelled is only really used for small fractions in mostly non technical works and is essentially the same usage as U+2044 (fraction slash)

123⁄456

Seems to be supported by most browsers (well chrome and firefox at least) and I'd be happy if core only supported this for the case of mfrac with two token elements and

<mfrac type="bevelled"><mn>123</mn><mn>456</mN></mfrac>

was treated as

<mn>123⁄456</mn>

In which case it might be cleaner if core didn't support mfrac bevelled at all, and that mapping was left to convertors from full.

@fred-wang fred-wang added need specification update Issues requiring specification changes need tests Issues related to writing WPT tests labels Sep 17, 2019
fred-wang added a commit to web-platform-tests/wpt that referenced this issue Oct 1, 2019
fred-wang added a commit to web-platform-tests/wpt that referenced this issue Oct 1, 2019
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Oct 14, 2019
…ght remove from Core / unship…, a=testonly

Automatic update from web-platform-tests
Add tests for MathML features that we might remove from Core / unship from browsers (#19450)

w3c/mathml#27
w3c/mathml#29
w3c/mathml#2

--

wpt-commits: d9e0e15247ca5269b4e2c9060f38416c2068997b
wpt-pr: 19450
xeonchen pushed a commit to xeonchen/gecko that referenced this issue Oct 14, 2019
…ght remove from Core / unship…, a=testonly

Automatic update from web-platform-tests
Add tests for MathML features that we might remove from Core / unship from browsers (#19450)

w3c/mathml#27
w3c/mathml#29
w3c/mathml#2

--

wpt-commits: d9e0e15247ca5269b4e2c9060f38416c2068997b
wpt-pr: 19450
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Oct 16, 2019
…ght remove from Core / unship…, a=testonly

Automatic update from web-platform-tests
Add tests for MathML features that we might remove from Core / unship from browsers (#19450)

w3c/mathml#27
w3c/mathml#29
w3c/mathml#2

--

wpt-commits: d9e0e15247ca5269b4e2c9060f38416c2068997b
wpt-pr: 19450

UltraBlame original commit: f3f6dad0dad824e643e833dfd3bcc0ebdec1f28e
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Oct 16, 2019
…ght remove from Core / unship…, a=testonly

Automatic update from web-platform-tests
Add tests for MathML features that we might remove from Core / unship from browsers (#19450)

w3c/mathml#27
w3c/mathml#29
w3c/mathml#2

--

wpt-commits: d9e0e15247ca5269b4e2c9060f38416c2068997b
wpt-pr: 19450

UltraBlame original commit: f3f6dad0dad824e643e833dfd3bcc0ebdec1f28e
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Oct 16, 2019
…ght remove from Core / unship…, a=testonly

Automatic update from web-platform-tests
Add tests for MathML features that we might remove from Core / unship from browsers (#19450)

w3c/mathml#27
w3c/mathml#29
w3c/mathml#2

--

wpt-commits: d9e0e15247ca5269b4e2c9060f38416c2068997b
wpt-pr: 19450

UltraBlame original commit: f3f6dad0dad824e643e833dfd3bcc0ebdec1f28e
@fred-wang
Copy link
Author

I can't find any conclusion on this in the minutes, can we decide to remove it from Core?

@brucemiller
Copy link
Contributor

I checked LaTeXML's implementation of nicefrac.sty, which is quite old. I ended up implementing \nicefrac as an mrow with the "/" being an mo; possibly because firefox's bevelled mfrac wasn't so good, or unsupported, at the time(?). For fun, I made a quick branch to use bevelled for \nicefrac and the result looks quite reasonable on both Firefox and in MathJax. So, quite easy to restore to LaTeXML, if that's desired.

FWIW, it seems kind of a shame to lose bevelled. It's quite attractive when used appropriately (and very ugly otherwise). I'd think its best use is inline in text with & within simple expressions, rather than part of complex math.

@NSoiffer
Copy link
Contributor

NSoiffer commented Feb 8, 2020

Below are some renderings from MathJax. MathJax uses a CSS ::before rule with the char '/'. I imported the image into "paint" and turned on grid lines and then enlarged it to make counting pixels easier:

image

Depending on how you do the count for subpixel rendering/aliasing, the number of pixels for the larger fraction is either 4 or 3 and the number for the smaller one is either 3 or 2 -- a difference of one pixel in either case. I also zoomed the original page to 300% magnification and there was only a difference of 2 pixels.

Based on the this (and also on how no one would never use a bevelled slash for such a tall fraction), there is not a strong relation between the width and height, at least there isn't with the method that MathJax is using.

@fred-wang
Copy link
Author

@NSoiffer These screenshot only contain the trivial cases of small numerator/denominator and default linethickness. What happens with very tall content like <mfrac linethickness="..."><mspace width="10px" height="..." depth="..."></mspace><mspace width="10px" height="..." depth="..."></mspace></mfrac> with height+depth and linethickness taking arbitrary large values?

@NSoiffer
Copy link
Contributor

NSoiffer commented Feb 9, 2020

Bevelled fraction are only used when fractions are not tall. Indeed, no one would use a bevelled fraction for the first example I showed because it is too tall. It is similar to using a tall fraction for inline math -- it results in poor typesetting. Hence it doesn't make sense to use a really tall bevelled fraction as an example and then worry about whether it looks good -- it never will even if core didn't have problems with intrinsic width calculations.

Putting aside the issue of it doesn't make sense to use a bevelled fraction for a tall expression, the problem is no different than if "/" were inside of an mo. Or if you had a font that supported many sizes of a summation sign -- the summation char would grow significantly in width as it grew in height.

Finally, there is a simple solution to "/" growing wide in a very tall bevelled fraction -- limit how much it can grow just as the summation sign is currently limited by fonts to only a few sizes. In fact, MathJax does just that: at 100% zoom, the max width of a bevelled fraction's "/" is four pixels. MathJax also ignores linethickness. If a core implementation didn't ignore linethickness, the code would just add the thickness onto whatever intrinsic width calculation it made.

@fred-wang
Copy link
Author

I believe we have a problem of methodology here. The general rule is that modern web standards have a very detailed layout algorithm that is compatible with web engine & CSS layout, exhaustive automated conformance tests, support by browser implementers and focus on the most fundamental primitives. This is the approach we agreed to follow for MathML Core (or at least the one I keep repeating) and I hope will continue that way if we want to preserve our credibility ;-)

Now, my two cents in that particular case : the first one is currently lacking (as a reminder screenshots and sketches are acceptable for MathML 3, not for MathML Core) and a fortiori WPT tests don't exist. Bevelled fractions were only implemented in Mozilla and AFAIK there is not any plan to implement it in other browsers (MathJax is not particularly relevant for discussing native implementation although the lack of linethickness support and handling of edge cases suggest its implementation is incomplete or underspecified anyway). Finally, it seems the current usage is very limited and as you said it duplicates stretchy mo slash (+ extra mpadded-like shifts). So unless someone can (and has time to) address all these prerequisites, I still don't see any compelling argument to put this attribute in MathML Core.

@brucemiller
Copy link
Contributor

First off, Neil is exactly right: the only sensible use case for bevelled fractions is simple numerators and denominators; most typically single line, even simply numbers. They're popular for numeric fractions and units, like m/s.

Nevertheless, I tested out a few pathalogically tall cases. Firefox misinterprets the "slightly" raised/lowered in the spec (basically missing the whole point and making it almost as tall as a regular mfrac). MathJax ignores linethickness and doesn't stretch the "/" very far (probably a limitation in its stretch handling).
(no screen-shots, since they're apparently unwelcome)

As Fred says, a bevelled fraction is essentially

<mrow>
  <mpadded voffset="0.5em">n</mpadded>
  <mo stretchy='true'>/</mo>
  <mpadded voffset="-0.5em">d</mpadded>
</mrow>

While I'm not experienced programming either polyfills or browsers, I have a hard time seeing why this is such a problem. It doesn't need any more measurement or complication than what stretchy already does.

@fred-wang
Copy link
Author

(no screen-shots, since they're apparently unwelcome)

Not sure whether you are serious, but my previous comment was clearly related to the requirement "have a very detailed layout algorithm that is compatible with web engine & CSS layout". Screenshots can be used for examples or illustrations but are definitely not enough for the specification of the algorithm.

@brucemiller
Copy link
Contributor

brucemiller commented Feb 10, 2020 via email

@fred-wang
Copy link
Author

You are certainly right that bevelled is currently underspecified. (whether it's in core, or not). Perhaps the above equivalence could serve as a sufficiently precise specification?

For now I see several things to clarify. Off the top of my head:

  • Is the thickness taken into account? (intuitively, I would say yes as that would otherwise be weird for users, but that's not the case with a mo+mpadded equivalent and MathJax does not support it).
  • What is the vertical shift of numerator & denumerator? (with the equivalent mo+mpadded, their baselines are just aligned with the baseline, but IIUC Mozilla does shift them vertically).
  • What is the horizontal (negative) spacing between the bar and the numerator/denominator?
  • If we draw the slash with a graphical line (rather than an equivalent stretchy mo), what are the coordinates of the ends (and so slant), thickness and shape (e.g. stroke-linecap) of the bar? What is the width it's bounding box? What happens for very small and very large heights (i.e. does the slash have a minimal and maximal height and what are they?)

It seems to me that the fact that we can specify the construction with an equivalent mo+mapped is actually an argument for not having it in core. However, if we want more powerful things like what Mozilla implements (arbitrary height and thickness) a polyfill would probably be a bit more complicated than a DOM conversion.

@fred-wang
Copy link
Author

* What is the vertical shift of numerator & denumerator? (with the equivalent mo+mpadded, their baselines are just aligned with the baseline, but IIUC Mozilla does shift them vertically).
* What is the horizontal (negative) spacing between the bar and the numerator/denominator?

Actually with the proposal in #29 (comment) it's .5em voffset and no horizontal shifts.

@brucemiller
Copy link
Contributor

Good points. Yes, ideally linethickness should be supported (& this connects to your 4th point). I'm not too sure what the idea solution is. I'd hate to propose svg instead of mo :> and saying something vague like "draw a line like a big /" doesn't improve things that much, either.

As far as the positioning & shift, mpadded +/- 0.5em pretty much captures my sense of how it should look. Although it probably should be line-height instead of em; which is now in CSS, but not yet MathML lengths, right?

@fred-wang
Copy link
Author

fred-wang commented Feb 10, 2020

As far as the positioning & shift, mpadded +/- 0.5em pretty much captures my sense of how it should look. Although it probably should be line-height instead of em; which is now in CSS, but not yet MathML lengths, right?

The preferred inline size / layout algos can use any computed CSS properties (including font-size and line-height), MATH data (e.g. skewedFractionHorizontalGap and skewedFractionVerticalGap parameters) and results of preferred inline size / layout for num/denum.

@brucemiller
Copy link
Contributor

Good to know for spec purposes. But unsurprisingly when I replaced "em" by "lh" on my by-hand equivalence test, neither Firefox nor MathJax recognizes it.

@brucemiller
Copy link
Contributor

On your other point: I agree that usage statistics and polyfill-ability are among the useful criteria for removing from core. But I think we should also be careful not to create an impossible task for authors to figure out which polyfills are needed.

@NSoiffer
Copy link
Contributor

I don't think a fixed shift is right. MathPlayer has a fixed shift (relative to font size), but it is not what MathJax does.

Here's the MathJax code:

 const u = nbox.scale * (nbox.d - nbox.h) / 2 + a + delta; 
 const v = dbox.scale * (dbox.d - dbox.h) / 2 + a - delta;            

'u' is the numerator shift, 'v' the denominator shift, 'a' is the axis and 'delta' is based on whether it is inline or display. I think scale is something coming from scaling the fonts for the current context.

So basically MathJax centers the boxes on the axis and shifts them up/down a bit. For display, it is .4em and for inline it is .15em. It depends upon stretchy=true for the "/" char, hence it is relying on the font for that.

MathPlayer

  • shifts the numerator up by the default amount used for superscripts
  • shifts the denominator down by default subscript shift
  • draws a line (instead of using '/' char) that uses linethickness

@fred-wang: what does Gecko do?
@brucemiller: what does the TeX package you played with do?

If we are going to specify what should happen (which I think we should), we should look how the various systems draw a few examples so we can decide on what we like best, and also whether it makes sense to support linethickness for bevelled fractions.

I think the following are the "goals" for the bevelled notation syntax (and hence form an evaluation criteria):

  1. draw a fraction that minimizes the vertical space used
  2. shift the numerator and denominator enough so they are immediately recognizable as a numerator and denominator; therefore they don't require parens.

Bevelled fractions are mainly used for inline math, although I could see them being used inside of a complex (i.e., nested) fraction, a subscript, superscript, or limit. Any examples we come up with should reflect their use case.

@brucemiller
Copy link
Contributor

An interesting rabbit hole! I ended up fine-tuning my LaTeXML implementation to better match what nicefrac.sty does (xfrac appears to have similar layout, but improves font handing, solidus vs /, etc).

It turns out that nicefrac uses quite different adjustments than what the spec (or I) suggested. It moves the numerator up by a smallish amount: In text or display mode, it shifts it up essentially the height of M in display minus the height of M in script. I've used 0.3em as a reasonable approximation. It does not move the denominator down, at all. It also applies some negative kerning (-2mu,-1mu) on the left & right of the "/", but does not stretch it.

The net effect is that on the simple cases for which nicefrac was designed, something like \nicefrac{1}{2} lines up the base of the 2 with the outer baseline. Which seems as it should be. It also deals with pathological cases more sensibly.

To my tastes, the (tweaked) "inline" version looks better in Firefox & MathJax, so I'm sticking with that for LaTeXML. I can't see how the semantics are any worse.

So, I guess I'm now less obsessed with keeping bevelled in core. And I also am a little unsure how we should clarify the main spec, since there is this contradiction (whether or not to shift the denominator). At least if we take nicefrac as the goal.

@NSoiffer
Copy link
Contributor

There are now several proposals for rendering bevelled fractions. Seems like we should get rendering examples and see which we prefer (ideally, all using the same font size/family, but that may be hard).

I propose the following examples as these represent what I think is a likely range of bevelled fractions. If they do a poor job on something that shouldn't be represented as a bevelled fraction, I don't think it matters:

  1. 1/2
  2. x+y+z / 3
  3. u'/ \sqrt(u^2+1)
  4. g / cm^3
  5. x^2 + y^2 / x^2 - y^2

All of these are meant to be bevelled fractions where everything before the "/" is the numerator and everything after it is the denominator.

Note: a few of the larger ones come from a quick web search for examples.

It might be good to replace a couple of the examples with more math (or text) before/after the expression to see the fraction in context.

After we agree on few examples, I'll generate some renderings from MathPlayer, Firefox, and MathJax. I'll let some else do one or two TeX packages with OpenType fonts.

@brucemiller
Copy link
Contributor

Some initial observations: Your examples seem quite sensible for bevelled fractions. I checked these cases in both text and display using

  • LaTeX nicefrac.sty
  • Xelatex xfrac.sty (using URW Bookman light)
  • MathML bevelled mfrac in Firefox and Chrome+MathJax
    All cases look pretty reasonable except that Firefox & MathJax lower the denominator (as per the spec), whereas the TeX versions dont, leaving the denominator essentially aligned to the baseline. (The latter looks best, imho). Also, in display Firefox is a bit too generous with the shifts.

I then pushed the envelope a bit where bevelled normally wouldn't be used to check for reasonable (if not beautiful) as opposed to downright ugly. I used for numerator & denominator small fractions (like \frac{1}{2}) and 3 row matrices. Here nicefrac & MathJax are still reasonable. xfrac strangely shifts the numerator down. Firefox shifts both the numerator up and the denominator down way too much.

Hopefully those descriptions can help guide to testcases; I don't want to bombard with images till we settle a bit.

@brucemiller
Copy link
Contributor

brucemiller commented Feb 24, 2020

Sorry, running out of time to chop up 50+ images, but let's try the following. The samples are Neil's from above and two taller ones containing fractions and vectors; all are shown in inline and then in display. Each group is rendered using LaTeX's nicefrac (from pdf): mfrac with bevelled true in Firefox and Chrome with MathJax. Note that the images are getting shrunk to fit the table (you can click each image for fullsize)

nicefrac Firefox MathJax
nicefrac mfrac-firefox mfrac-mathjax

The following is using a proposed mrow equivalent (corrected
mrow-firefox
version)

@NSoiffer
Copy link
Contributor

NSoiffer commented Feb 24, 2020 via email

@bruce
Copy link

bruce commented Feb 24, 2020

@NSoiffer 👋 You probably meant to tag @brucemiller.

@brucemiller
Copy link
Contributor

Here's the pages (bev-mfrac.html is probably what you want)
bev.zip

@MurraySargent
Copy link

Here are images of Bruce's beveled fractions in OfficeMath (Word, PowerPoint, OneNote,...)
BevelledFractionsInOfficeMath

@NSoiffer NSoiffer added the need polyfill Issues requiring implementation changes label May 18, 2020
@NSoiffer
Copy link
Contributor

Based on what @brucemiller found, it seems we don't need to measure to do the layout, so a polyfill becomes much more reasonable. I have added the 'need polyfill' label.

@NSoiffer
Copy link
Contributor

NSoiffer commented Jun 3, 2020

I've written a polyfill for this: https://github.com/mathml-refresh/mathml-polyfills/tree/master/bevelled

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Issues affecting backward compatibility MathML 4 Issues affecting the MathML 4 specification need specification update Issues requiring specification changes need tests Issues related to writing WPT tests
Projects
None yet
Development

No branches or pull requests

7 participants