mathjax / MathJax

Beautiful and accessible math in all browsers
http://www.mathjax.org/
Apache License 2.0
10.16k stars 1.16k forks source link

alttext value default aria-label value when present #2849

Open jmegginson opened 2 years ago

jmegginson commented 2 years ago

MathJax v3.2.0 does not render the alttext attribute value provided to the MathML object as the default (accessible) aria-label.

I have observed that MathJax v2.7.9 worked in this manner and was a good feature at the time.

There are situations when the alttext attribute value can provide clear language to students than MathML markup alone could provide. For example terms like “in equilibrium with…the coefficient...molar concentration of…” applied via the alttext attribute would be more meaningful than "right facing arrow over left facing arrow" when left to automated MathSpeak generation alone.

<math displaystyle="true" xmlns="http://www.w3.org/1998/Math/MathML" alttext="K sub c, equals the fraction with numerator, the molar concentration of uppercase C raised to the lowercase c, times, the molar concentration of uppercase D raised to the lowercase d, and denominator, the molar concentration of uppercase A raised to the lowercase a, times, the molar concentration of uppercase B raised to the lowercase b, where the coefficient, lowercase a before uppercase A, plus, the coefficient lowercase b before uppercase B is in equilibrium with the coefficient, lowercase c before uppercase C, plus, the coefficient lowercase d before uppercase D">...</math>

I propose that when alttext is present within the mathml element MathJax utilizes this as the default aria-label. When the alttext attribute is not present, then users would rely on the default automated MathSpeak generated aria-label.

If a situation occurs where the alttext is not sufficient, users could be given a (new) menu option like "MathML alttext" to choose from along with MathSpeak, ClearSpeak and other options that are currently offered through accessibility menu options.

shawnharvell commented 2 years ago

I second this request because it seems obvious to me that content authors should have a way to define their preferred alt text.

mgbales commented 2 years ago

Third; it's a necessary tool to work around known issues with MathML and provide author-provided semantic meaning when there is none to be had in MathML itself.

dpvc commented 2 years ago

There are some reasons not to do this, and I've asked Volker Sorge, author of the speech-rule-engine that underlies MathJax's speech-text generation, to comment on the pros and cons of this approach.

In the meantime, you can accomplish this using the following configuration:

MathJax = {
  options: {
    renderActions: {
      alttext: [150,
        (doc) => {for (const math of doc.math) MathJax.config.addAlttext(doc, math)}, 
        (doc, math) => MathJax.config.addAlttext(doc, math)
      ]
    }
  },
  addAlttext(doc, math) {
    const alttext = math.root.attributes.get('alttext');
    if (alttext) doc.adaptor.setAttribute(math.typesetRoot, 'aria-label', alttext);
  }
};

One could make an extension that does a more formal job of doing this, and it could even hook into the context menu to add the option you suggest. While there are some technicalities to this, it is actually a good first project for someone who wants to make a contribution to MathJax. If anyone wants to give it a try, I can point you in the right direction.

jmegginson commented 2 years ago

Hi Davide. Thanks.

We've implemented this and see general success albeit some various screen reader discrepancies when setting the aria-label via the math.typesetRoot. Setting the aria-label to this location (math.typesetRoot) is indeed the most consistent location and may serve our purpose (regardless if MathJax Accessibility features are enabled or not). Thank you.

In lieu of math.typesetRoot is there a property to place the aria-label to the element (that becomes a child of in the DOM)?

I've tried math.root but with no success.

For Example:

addAlttext(doc, math) { const alttext = math.root.attributes.get('alttext'); if (alttext) doc.adaptor.setAttribute(math.root, 'aria-label', alttext); }

dpvc commented 2 years ago

The math.typesetRoot is the element that becomes the child of the DOM. It is not yet in the DOM when addAlttext() is called, but later in the render actions, it will be inserted into the DOM.

The math.root is the internal MathML representation (as javascript objects, not DOM elements), and so it is not appropriate to use setAttribute() on it (and it will probably crash if you do).

NSoiffer commented 2 years ago

If you use alttext, the reading experience will be very different when navigating the expression. That could cause a lot of confusion.

FYI: The MathML WG is working on a MathML 4, and one of the main additions is an intent attribute on any element so that authors can expression what they want spoken for any notation. The value is a simple function syntax (which can also just be a string). This will allow consistent speech when browsing and navigating. With intent, one can mark up an mrow that had "[...]" as intent="molecular-concetration($arg1)" where the contents had the attribute arg="arg1". That element can in turn have an intent attr or some child can have that. There are a couple of prototypes we've done and hopefully fuller implementations are on the horizon. For details, see the MathML draft spec. Of course, none of this helps you in the near term, but you may want to consider this for the future.

mgbales commented 2 years ago

@NSoiffer, agree that the reading experience could be potentially confusing. However, we have to support several different genres of notation, and while immediate context does help, our users are in timed situations. The quicker we can deliver appropriate information, the better. We will be documenting our use cases as best we can.

Thank you for pointing out the intent section of the draft MathML 4.0 spec. I'll be reading it with interest. (Also - big props to your shoulder cat.)