754 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			754 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import katex from '../katex.mjs';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * renderA11yString returns a readable string.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * In some cases the string will have the proper semantic math
							 | 
						||
| 
								 | 
							
								 * meaning,:
							 | 
						||
| 
								 | 
							
								 *   renderA11yString("\\frac{1}{2}"")
							 | 
						||
| 
								 | 
							
								 *   -> "start fraction, 1, divided by, 2, end fraction"
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * However, other cases do not:
							 | 
						||
| 
								 | 
							
								 *   renderA11yString("f(x) = x^2")
							 | 
						||
| 
								 | 
							
								 *   -> "f, left parenthesis, x, right parenthesis, equals, x, squared"
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The commas in the string aim to increase ease of understanding
							 | 
						||
| 
								 | 
							
								 * when read by a screenreader.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const stringMap = {
							 | 
						||
| 
								 | 
							
								  "(": "left parenthesis",
							 | 
						||
| 
								 | 
							
								  ")": "right parenthesis",
							 | 
						||
| 
								 | 
							
								  "[": "open bracket",
							 | 
						||
| 
								 | 
							
								  "]": "close bracket",
							 | 
						||
| 
								 | 
							
								  "\\{": "left brace",
							 | 
						||
| 
								 | 
							
								  "\\}": "right brace",
							 | 
						||
| 
								 | 
							
								  "\\lvert": "open vertical bar",
							 | 
						||
| 
								 | 
							
								  "\\rvert": "close vertical bar",
							 | 
						||
| 
								 | 
							
								  "|": "vertical bar",
							 | 
						||
| 
								 | 
							
								  "\\uparrow": "up arrow",
							 | 
						||
| 
								 | 
							
								  "\\Uparrow": "up arrow",
							 | 
						||
| 
								 | 
							
								  "\\downarrow": "down arrow",
							 | 
						||
| 
								 | 
							
								  "\\Downarrow": "down arrow",
							 | 
						||
| 
								 | 
							
								  "\\updownarrow": "up down arrow",
							 | 
						||
| 
								 | 
							
								  "\\leftarrow": "left arrow",
							 | 
						||
| 
								 | 
							
								  "\\Leftarrow": "left arrow",
							 | 
						||
| 
								 | 
							
								  "\\rightarrow": "right arrow",
							 | 
						||
| 
								 | 
							
								  "\\Rightarrow": "right arrow",
							 | 
						||
| 
								 | 
							
								  "\\langle": "open angle",
							 | 
						||
| 
								 | 
							
								  "\\rangle": "close angle",
							 | 
						||
| 
								 | 
							
								  "\\lfloor": "open floor",
							 | 
						||
| 
								 | 
							
								  "\\rfloor": "close floor",
							 | 
						||
| 
								 | 
							
								  "\\int": "integral",
							 | 
						||
| 
								 | 
							
								  "\\intop": "integral",
							 | 
						||
| 
								 | 
							
								  "\\lim": "limit",
							 | 
						||
| 
								 | 
							
								  "\\ln": "natural log",
							 | 
						||
| 
								 | 
							
								  "\\log": "log",
							 | 
						||
| 
								 | 
							
								  "\\sin": "sine",
							 | 
						||
| 
								 | 
							
								  "\\cos": "cosine",
							 | 
						||
| 
								 | 
							
								  "\\tan": "tangent",
							 | 
						||
| 
								 | 
							
								  "\\cot": "cotangent",
							 | 
						||
| 
								 | 
							
								  "\\sum": "sum",
							 | 
						||
| 
								 | 
							
								  "/": "slash",
							 | 
						||
| 
								 | 
							
								  ",": "comma",
							 | 
						||
| 
								 | 
							
								  ".": "point",
							 | 
						||
| 
								 | 
							
								  "-": "negative",
							 | 
						||
| 
								 | 
							
								  "+": "plus",
							 | 
						||
| 
								 | 
							
								  "~": "tilde",
							 | 
						||
| 
								 | 
							
								  ":": "colon",
							 | 
						||
| 
								 | 
							
								  "?": "question mark",
							 | 
						||
| 
								 | 
							
								  "'": "apostrophe",
							 | 
						||
| 
								 | 
							
								  "\\%": "percent",
							 | 
						||
| 
								 | 
							
								  " ": "space",
							 | 
						||
| 
								 | 
							
								  "\\ ": "space",
							 | 
						||
| 
								 | 
							
								  "\\$": "dollar sign",
							 | 
						||
| 
								 | 
							
								  "\\angle": "angle",
							 | 
						||
| 
								 | 
							
								  "\\degree": "degree",
							 | 
						||
| 
								 | 
							
								  "\\circ": "circle",
							 | 
						||
| 
								 | 
							
								  "\\vec": "vector",
							 | 
						||
| 
								 | 
							
								  "\\triangle": "triangle",
							 | 
						||
| 
								 | 
							
								  "\\pi": "pi",
							 | 
						||
| 
								 | 
							
								  "\\prime": "prime",
							 | 
						||
| 
								 | 
							
								  "\\infty": "infinity",
							 | 
						||
| 
								 | 
							
								  "\\alpha": "alpha",
							 | 
						||
| 
								 | 
							
								  "\\beta": "beta",
							 | 
						||
| 
								 | 
							
								  "\\gamma": "gamma",
							 | 
						||
| 
								 | 
							
								  "\\omega": "omega",
							 | 
						||
| 
								 | 
							
								  "\\theta": "theta",
							 | 
						||
| 
								 | 
							
								  "\\sigma": "sigma",
							 | 
						||
| 
								 | 
							
								  "\\lambda": "lambda",
							 | 
						||
| 
								 | 
							
								  "\\tau": "tau",
							 | 
						||
| 
								 | 
							
								  "\\Delta": "delta",
							 | 
						||
| 
								 | 
							
								  "\\delta": "delta",
							 | 
						||
| 
								 | 
							
								  "\\mu": "mu",
							 | 
						||
| 
								 | 
							
								  "\\rho": "rho",
							 | 
						||
| 
								 | 
							
								  "\\nabla": "del",
							 | 
						||
| 
								 | 
							
								  "\\ell": "ell",
							 | 
						||
| 
								 | 
							
								  "\\ldots": "dots",
							 | 
						||
| 
								 | 
							
								  // TODO: add entries for all accents
							 | 
						||
| 
								 | 
							
								  "\\hat": "hat",
							 | 
						||
| 
								 | 
							
								  "\\acute": "acute"
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const powerMap = {
							 | 
						||
| 
								 | 
							
								  "prime": "prime",
							 | 
						||
| 
								 | 
							
								  "degree": "degrees",
							 | 
						||
| 
								 | 
							
								  "circle": "degrees",
							 | 
						||
| 
								 | 
							
								  "2": "squared",
							 | 
						||
| 
								 | 
							
								  "3": "cubed"
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const openMap = {
							 | 
						||
| 
								 | 
							
								  "|": "open vertical bar",
							 | 
						||
| 
								 | 
							
								  ".": ""
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const closeMap = {
							 | 
						||
| 
								 | 
							
								  "|": "close vertical bar",
							 | 
						||
| 
								 | 
							
								  ".": ""
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const binMap = {
							 | 
						||
| 
								 | 
							
								  "+": "plus",
							 | 
						||
| 
								 | 
							
								  "-": "minus",
							 | 
						||
| 
								 | 
							
								  "\\pm": "plus minus",
							 | 
						||
| 
								 | 
							
								  "\\cdot": "dot",
							 | 
						||
| 
								 | 
							
								  "*": "times",
							 | 
						||
| 
								 | 
							
								  "/": "divided by",
							 | 
						||
| 
								 | 
							
								  "\\times": "times",
							 | 
						||
| 
								 | 
							
								  "\\div": "divided by",
							 | 
						||
| 
								 | 
							
								  "\\circ": "circle",
							 | 
						||
| 
								 | 
							
								  "\\bullet": "bullet"
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const relMap = {
							 | 
						||
| 
								 | 
							
								  "=": "equals",
							 | 
						||
| 
								 | 
							
								  "\\approx": "approximately equals",
							 | 
						||
| 
								 | 
							
								  "≠": "does not equal",
							 | 
						||
| 
								 | 
							
								  "\\geq": "is greater than or equal to",
							 | 
						||
| 
								 | 
							
								  "\\ge": "is greater than or equal to",
							 | 
						||
| 
								 | 
							
								  "\\leq": "is less than or equal to",
							 | 
						||
| 
								 | 
							
								  "\\le": "is less than or equal to",
							 | 
						||
| 
								 | 
							
								  ">": "is greater than",
							 | 
						||
| 
								 | 
							
								  "<": "is less than",
							 | 
						||
| 
								 | 
							
								  "\\leftarrow": "left arrow",
							 | 
						||
| 
								 | 
							
								  "\\Leftarrow": "left arrow",
							 | 
						||
| 
								 | 
							
								  "\\rightarrow": "right arrow",
							 | 
						||
| 
								 | 
							
								  "\\Rightarrow": "right arrow",
							 | 
						||
| 
								 | 
							
								  ":": "colon"
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								const accentUnderMap = {
							 | 
						||
| 
								 | 
							
								  "\\underleftarrow": "left arrow",
							 | 
						||
| 
								 | 
							
								  "\\underrightarrow": "right arrow",
							 | 
						||
| 
								 | 
							
								  "\\underleftrightarrow": "left-right arrow",
							 | 
						||
| 
								 | 
							
								  "\\undergroup": "group",
							 | 
						||
| 
								 | 
							
								  "\\underlinesegment": "line segment",
							 | 
						||
| 
								 | 
							
								  "\\utilde": "tilde"
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const buildString = (str, type, a11yStrings) => {
							 | 
						||
| 
								 | 
							
								  if (!str) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let ret;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (type === "open") {
							 | 
						||
| 
								 | 
							
								    ret = str in openMap ? openMap[str] : stringMap[str] || str;
							 | 
						||
| 
								 | 
							
								  } else if (type === "close") {
							 | 
						||
| 
								 | 
							
								    ret = str in closeMap ? closeMap[str] : stringMap[str] || str;
							 | 
						||
| 
								 | 
							
								  } else if (type === "bin") {
							 | 
						||
| 
								 | 
							
								    ret = binMap[str] || str;
							 | 
						||
| 
								 | 
							
								  } else if (type === "rel") {
							 | 
						||
| 
								 | 
							
								    ret = relMap[str] || str;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    ret = stringMap[str] || str;
							 | 
						||
| 
								 | 
							
								  } // If the text to add is a number and there is already a string
							 | 
						||
| 
								 | 
							
								  // in the list and the last string is a number then we should
							 | 
						||
| 
								 | 
							
								  // combine them into a single number
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (/^\d+$/.test(ret) && a11yStrings.length > 0 && // TODO(kevinb): check that the last item in a11yStrings is a string
							 | 
						||
| 
								 | 
							
								  // I think we might be able to drop the nested arrays, which would make
							 | 
						||
| 
								 | 
							
								  // this easier to type - $FlowFixMe
							 | 
						||
| 
								 | 
							
								  /^\d+$/.test(a11yStrings[a11yStrings.length - 1])) {
							 | 
						||
| 
								 | 
							
								    a11yStrings[a11yStrings.length - 1] += ret;
							 | 
						||
| 
								 | 
							
								  } else if (ret) {
							 | 
						||
| 
								 | 
							
								    a11yStrings.push(ret);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const buildRegion = (a11yStrings, callback) => {
							 | 
						||
| 
								 | 
							
								  const regionStrings = [];
							 | 
						||
| 
								 | 
							
								  a11yStrings.push(regionStrings);
							 | 
						||
| 
								 | 
							
								  callback(regionStrings);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const handleObject = (tree, a11yStrings, atomType) => {
							 | 
						||
| 
								 | 
							
								  // Everything else is assumed to be an object...
							 | 
						||
| 
								 | 
							
								  switch (tree.type) {
							 | 
						||
| 
								 | 
							
								    case "accent":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, a11yStrings => {
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.base, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("with");
							 | 
						||
| 
								 | 
							
								          buildString(tree.label, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("on top");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "accentUnder":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, a11yStrings => {
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.base, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("with");
							 | 
						||
| 
								 | 
							
								          buildString(accentUnderMap[tree.label], "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("underneath");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "accent-token":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // Used internally by accent symbols.
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "atom":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        const text = tree.text;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        switch (tree.family) {
							 | 
						||
| 
								 | 
							
								          case "bin":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(text, "bin", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          case "close":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(text, "close", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          // TODO(kevinb): figure out what should be done for inner
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          case "inner":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(tree.text, "inner", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          case "open":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(text, "open", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          case "punct":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(text, "punct", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          case "rel":
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              buildString(text, "rel", a11yStrings);
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          default:
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              tree.family;
							 | 
						||
| 
								 | 
							
								              throw new Error(`"${tree.family}" is not a valid atom type`);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "color":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        const color = tree.color.replace(/katex-/, "");
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, regionStrings => {
							 | 
						||
| 
								 | 
							
								          regionStrings.push("start color " + color);
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								          regionStrings.push("end color " + color);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "color-token":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // Used by \color, \colorbox, and \fcolorbox but not directly rendered.
							 | 
						||
| 
								 | 
							
								        // It's a leaf node and has no children so just break.
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "delimsizing":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        if (tree.delim && tree.delim !== ".") {
							 | 
						||
| 
								 | 
							
								          buildString(tree.delim, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "genfrac":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, regionStrings => {
							 | 
						||
| 
								 | 
							
								          // genfrac can have unbalanced delimiters
							 | 
						||
| 
								 | 
							
								          const leftDelim = tree.leftDelim,
							 | 
						||
| 
								 | 
							
								                rightDelim = tree.rightDelim; // NOTE: Not sure if this is a safe assumption
							 | 
						||
| 
								 | 
							
								          // hasBarLine true -> fraction, false -> binomial
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (tree.hasBarLine) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start fraction");
							 | 
						||
| 
								 | 
							
								            leftDelim && buildString(leftDelim, "open", regionStrings);
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.numer, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("divided by");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.denom, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            rightDelim && buildString(rightDelim, "close", regionStrings);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end fraction");
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start binomial");
							 | 
						||
| 
								 | 
							
								            leftDelim && buildString(leftDelim, "open", regionStrings);
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.numer, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("over");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.denom, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            rightDelim && buildString(rightDelim, "close", regionStrings);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end binomial");
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "kern":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // No op: we don't attempt to present kerning information
							 | 
						||
| 
								 | 
							
								        // to the screen reader.
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "leftright":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, regionStrings => {
							 | 
						||
| 
								 | 
							
								          buildString(tree.left, "open", regionStrings);
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								          buildString(tree.right, "close", regionStrings);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "leftright-right":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // TODO: double check that this is a no-op
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "lap":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "mathord":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildString(tree.text, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "op":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        const body = tree.body,
							 | 
						||
| 
								 | 
							
								              name = tree.name;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (body) {
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        } else if (name) {
							 | 
						||
| 
								 | 
							
								          buildString(name, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "op-token":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // Used internally by operator symbols.
							 | 
						||
| 
								 | 
							
								        buildString(tree.text, atomType, a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "ordgroup":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "overline":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, function (a11yStrings) {
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("start overline");
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("end overline");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "phantom":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        a11yStrings.push("empty space");
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "raisebox":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "rule":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        a11yStrings.push("rectangle");
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "sizing":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "spacing":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        a11yStrings.push("space");
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "styling":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // We ignore the styling and just pass through the contents
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "sqrt":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, regionStrings => {
							 | 
						||
| 
								 | 
							
								          const body = tree.body,
							 | 
						||
| 
								 | 
							
								                index = tree.index;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (index) {
							 | 
						||
| 
								 | 
							
								            const indexString = flatten(buildA11yStrings(index, [], atomType)).join(",");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (indexString === "3") {
							 | 
						||
| 
								 | 
							
								              regionStrings.push("cube root of");
							 | 
						||
| 
								 | 
							
								              buildA11yStrings(body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								              regionStrings.push("end cube root");
							 | 
						||
| 
								 | 
							
								              return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            regionStrings.push("root");
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start index");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(index, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end index");
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          regionStrings.push("square root of");
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								          regionStrings.push("end square root");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "supsub":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        const base = tree.base,
							 | 
						||
| 
								 | 
							
								              sub = tree.sub,
							 | 
						||
| 
								 | 
							
								              sup = tree.sup;
							 | 
						||
| 
								 | 
							
								        let isLog = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (base) {
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(base, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								          isLog = base.type === "op" && base.name === "\\log";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (sub) {
							 | 
						||
| 
								 | 
							
								          const regionName = isLog ? "base" : "subscript";
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push(`start ${regionName}`);
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(sub, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push(`end ${regionName}`);
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (sup) {
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            const supString = flatten(buildA11yStrings(sup, [], atomType)).join(",");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (supString in powerMap) {
							 | 
						||
| 
								 | 
							
								              regionStrings.push(powerMap[supString]);
							 | 
						||
| 
								 | 
							
								              return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start superscript");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(sup, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end superscript");
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "text":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // TODO: handle other fonts
							 | 
						||
| 
								 | 
							
								        if (tree.font === "\\textbf") {
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start bold text");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end bold text");
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								          regionStrings.push("start text");
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								          regionStrings.push("end text");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "textord":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildString(tree.text, atomType, a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "smash":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "enclose":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // TODO: create a map for these.
							 | 
						||
| 
								 | 
							
								        // TODO: differentiate between a body with a single atom, e.g.
							 | 
						||
| 
								 | 
							
								        // "cancel a" instead of "start cancel, a, end cancel"
							 | 
						||
| 
								 | 
							
								        if (/cancel/.test(tree.label)) {
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start cancel");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end cancel");
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        } else if (/box/.test(tree.label)) {
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start box");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end box");
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        } else if (/sout/.test(tree.label)) {
							 | 
						||
| 
								 | 
							
								          buildRegion(a11yStrings, function (regionStrings) {
							 | 
						||
| 
								 | 
							
								            regionStrings.push("start strikeout");
							 | 
						||
| 
								 | 
							
								            buildA11yStrings(tree.body, regionStrings, atomType);
							 | 
						||
| 
								 | 
							
								            regionStrings.push("end strikeout");
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw new Error(`KaTeX-a11y: enclose node with ${tree.label} not supported yet`);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "vphantom":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: vphantom not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "hphantom":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: hphantom not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "operatorname":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "array":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: array not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "raw":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: raw not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "size":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // Although there are nodes of type "size" in the parse tree, they have
							 | 
						||
| 
								 | 
							
								        // no semantic meaning and should be ignored.
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "url":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: url not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "tag":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: tag not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "verb":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildString(`start verbatim`, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        buildString(tree.body, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        buildString(`end verbatim`, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "environment":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: environment not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "horizBrace":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildString(`start ${tree.label.slice(1)}`, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.base, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        buildString(`end ${tree.label.slice(1)}`, "normal", a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "infix":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // All infix nodes are replace with other nodes.
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "includegraphics":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: includegraphics not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "font":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // TODO: callout the start/end of specific fonts
							 | 
						||
| 
								 | 
							
								        // TODO: map \BBb{N} to "the naturals" or something like that
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "href":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: href not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "cr":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // This is used by environments.
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: cr not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "underline":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildRegion(a11yStrings, function (a11yStrings) {
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("start underline");
							 | 
						||
| 
								 | 
							
								          buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								          a11yStrings.push("end underline");
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "xArrow":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        throw new Error("KaTeX-a11y: xArrow not implemented yet");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "mclass":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // \neq and \ne are macros so we let "htmlmathml" render the mathmal
							 | 
						||
| 
								 | 
							
								        // side of things and extract the text from that.
							 | 
						||
| 
								 | 
							
								        const atomType = tree.mclass.slice(1); // $FlowFixMe: drop the leading "m" from the values in mclass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "mathchoice":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // TODO: track which which style we're using, e.g. dispaly, text, etc.
							 | 
						||
| 
								 | 
							
								        // default to text style if even that may not be the correct style
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.text, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "htmlmathml":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.mathml, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "middle":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildString(tree.delim, atomType, a11yStrings);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "internal":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // internal nodes are never included in the parse tree
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case "html":
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        buildA11yStrings(tree.body, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								      tree.type;
							 | 
						||
| 
								 | 
							
								      throw new Error("KaTeX a11y un-recognized type: " + tree.type);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const buildA11yStrings = function buildA11yStrings(tree, a11yStrings, atomType) {
							 | 
						||
| 
								 | 
							
								  if (a11yStrings === void 0) {
							 | 
						||
| 
								 | 
							
								    a11yStrings = [];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (tree instanceof Array) {
							 | 
						||
| 
								 | 
							
								    for (let i = 0; i < tree.length; i++) {
							 | 
						||
| 
								 | 
							
								      buildA11yStrings(tree[i], a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    handleObject(tree, a11yStrings, atomType);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return a11yStrings;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const flatten = function flatten(array) {
							 | 
						||
| 
								 | 
							
								  let result = [];
							 | 
						||
| 
								 | 
							
								  array.forEach(function (item) {
							 | 
						||
| 
								 | 
							
								    if (item instanceof Array) {
							 | 
						||
| 
								 | 
							
								      result = result.concat(flatten(item));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      result.push(item);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  return result;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const renderA11yString = function renderA11yString(text, settings) {
							 | 
						||
| 
								 | 
							
								  const tree = katex.__parse(text, settings);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const a11yStrings = buildA11yStrings(tree, [], "normal");
							 | 
						||
| 
								 | 
							
								  return flatten(a11yStrings).join(", ");
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default renderA11yString;
							 |