| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview Utility functions for mathml and mathjax rule store. |
| */ |
| |
| goog.provide('cvox.MathmlStoreUtil'); |
| |
| goog.require('cvox.MathUtil'); |
| goog.require('cvox.TraverseMath'); |
| |
| |
| /** |
| * Retrieves MathML sub element with same id as MathJax node. |
| * @param {!Node} inner A node internal to a MathJax node. |
| * @return {Node} The internal MathML node corresponding to the MathJax node. |
| */ |
| cvox.MathmlStoreUtil.matchMathjaxToMathml = function(inner) { |
| var mml = cvox.TraverseMath.getInstance().activeMathmlHost; |
| return mml.querySelector('#' + inner.id); |
| }; |
| |
| |
| /** |
| * Retrieve an extender symbol for a given node. |
| * @param {!Node} jax The MathJax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.retrieveMathjaxExtender = function(jax) { |
| var ext = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); |
| if (ext) { |
| return [ext]; |
| } |
| return []; |
| }; |
| |
| |
| /** |
| * Retrieve an extender symbol for a given node. |
| * @param {!Node} jax The MathJax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.retrieveMathjaxLeaf = function(jax) { |
| var leaf = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); |
| if (leaf) { |
| return [leaf]; |
| } |
| return []; |
| }; |
| |
| |
| /** |
| * For a given MathJax node it returns the equivalent MathML node, |
| * if it is of the right tag. |
| * @param {!Node} jax The Mathjax node. |
| * @param {!string} tag The required tag. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.checkMathjaxTag = function(jax, tag) { |
| var node = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); |
| if (node && node.tagName.toUpperCase() == tag) { |
| return [node]; |
| } |
| return []; |
| }; |
| |
| |
| /** |
| * Returns MathML node if MathJax is munder. |
| * @param {!Node} jax The Mathjax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.checkMathjaxMunder = function(jax) { |
| return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MUNDER'); |
| }; |
| |
| |
| /** |
| * Returns MathML node if MathJax is mover. |
| * @param {!Node} jax The Mathjax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.checkMathjaxMover = function(jax) { |
| return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MOVER'); |
| }; |
| |
| |
| /** |
| * Returns MathML node if MathJax is msub. |
| * @param {!Node} jax The Mathjax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.checkMathjaxMsub = function(jax) { |
| return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUB'); |
| }; |
| |
| |
| /** |
| * Returns MathML node if MathJax is msup. |
| * @param {!Node} jax The Mathjax node. |
| * @return {Array.<Node>} The resulting node list. |
| */ |
| cvox.MathmlStoreUtil.checkMathjaxMsup = function(jax) { |
| return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUP'); |
| }; |
| |
| |
| /** |
| * Constructs a closure that returns separators for an MathML mfenced |
| * expression. |
| * Separators in MathML are represented by a list and used up one by one |
| * until the final element is used as the default. |
| * Example: a b c d e and separators [+,-,*] |
| * would result in a + b - c * d * e. |
| * @param {string} separators String representing a list of mfenced separators. |
| * @return {function(): string|null} A closure that returns the next separator |
| * for an mfenced expression starting with the first node in nodes. |
| */ |
| cvox.MathmlStoreUtil.nextSeparatorFunction = function(separators) { |
| if (separators) { |
| // Mathjax does not expand empty separators. |
| if (separators.match(/^\s+$/)) { |
| return null; |
| } else { |
| var sepList = separators.replace(/\s/g, '') |
| .split('') |
| .filter(function(x) {return x;}); |
| } |
| } else { |
| // When no separator is given MathML uses comma as default. |
| var sepList = [',']; |
| } |
| |
| return function() { |
| if (sepList.length > 1) { |
| return sepList.shift(); |
| } |
| return sepList[0]; |
| }; |
| }; |
| |
| |
| /** |
| * Computes the correct separators for each node. |
| * @param {Array.<Node>} nodes A node array. |
| * @param {string} context A context string. |
| * @return {function(): string} A closure that returns the next separator for an |
| * mfenced expression starting with the first node in nodes. |
| */ |
| cvox.MathmlStoreUtil.mfencedSeparators = function(nodes, context) { |
| var nextSeparator = cvox.MathmlStoreUtil.nextSeparatorFunction(context); |
| return function() { |
| return nextSeparator ? nextSeparator() : ''; |
| }; |
| }; |
| |
| |
| /** |
| * Iterates over the list of content nodes of the parent of the given nodes. |
| * @param {Array.<Node>} nodes A node array. |
| * @param {string} context A context string. |
| * @return {function(): string} A closure that returns the content of the next |
| * content node. Returns only context string if list is exhausted. |
| */ |
| cvox.MathmlStoreUtil.contentIterator = function(nodes, context) { |
| if (nodes.length > 0) { |
| var contentNodes = cvox.XpathUtil.evalXPath('../../content/*', nodes[0]); |
| } else { |
| var contentNodes = []; |
| } |
| return function() { |
| var content = contentNodes.shift(); |
| return context + (content ? content.textContent : ''); |
| }; |
| }; |