mathml_store_util.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Utility functions for mathml and mathjax rule store. 7 */ 8 9goog.provide('cvox.MathmlStoreUtil'); 10 11goog.require('cvox.MathUtil'); 12goog.require('cvox.TraverseMath'); 13 14 15/** 16 * Retrieves MathML sub element with same id as MathJax node. 17 * @param {!Node} inner A node internal to a MathJax node. 18 * @return {Node} The internal MathML node corresponding to the MathJax node. 19 */ 20cvox.MathmlStoreUtil.matchMathjaxToMathml = function(inner) { 21 var mml = cvox.TraverseMath.getInstance().activeMathmlHost; 22 return mml.querySelector('#' + inner.id); 23}; 24 25 26/** 27 * Retrieve an extender symbol for a given node. 28 * @param {!Node} jax The MathJax node. 29 * @return {Array.<Node>} The resulting node list. 30 */ 31cvox.MathmlStoreUtil.retrieveMathjaxExtender = function(jax) { 32 var ext = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); 33 if (ext) { 34 return [ext]; 35 } 36 return []; 37}; 38 39 40/** 41 * Retrieve an extender symbol for a given node. 42 * @param {!Node} jax The MathJax node. 43 * @return {Array.<Node>} The resulting node list. 44 */ 45cvox.MathmlStoreUtil.retrieveMathjaxLeaf = function(jax) { 46 var leaf = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); 47 if (leaf) { 48 return [leaf]; 49 } 50 return []; 51}; 52 53 54/** 55 * For a given MathJax node it returns the equivalent MathML node, 56 * if it is of the right tag. 57 * @param {!Node} jax The Mathjax node. 58 * @param {!string} tag The required tag. 59 * @return {Array.<Node>} The resulting node list. 60 */ 61cvox.MathmlStoreUtil.checkMathjaxTag = function(jax, tag) { 62 var node = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax); 63 if (node && node.tagName.toUpperCase() == tag) { 64 return [node]; 65 } 66 return []; 67}; 68 69 70/** 71 * Returns MathML node if MathJax is munder. 72 * @param {!Node} jax The Mathjax node. 73 * @return {Array.<Node>} The resulting node list. 74 */ 75cvox.MathmlStoreUtil.checkMathjaxMunder = function(jax) { 76 return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MUNDER'); 77}; 78 79 80/** 81 * Returns MathML node if MathJax is mover. 82 * @param {!Node} jax The Mathjax node. 83 * @return {Array.<Node>} The resulting node list. 84 */ 85cvox.MathmlStoreUtil.checkMathjaxMover = function(jax) { 86 return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MOVER'); 87}; 88 89 90/** 91 * Returns MathML node if MathJax is msub. 92 * @param {!Node} jax The Mathjax node. 93 * @return {Array.<Node>} The resulting node list. 94 */ 95cvox.MathmlStoreUtil.checkMathjaxMsub = function(jax) { 96 return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUB'); 97}; 98 99 100/** 101 * Returns MathML node if MathJax is msup. 102 * @param {!Node} jax The Mathjax node. 103 * @return {Array.<Node>} The resulting node list. 104 */ 105cvox.MathmlStoreUtil.checkMathjaxMsup = function(jax) { 106 return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUP'); 107}; 108 109 110/** 111 * Constructs a closure that returns separators for an MathML mfenced 112 * expression. 113 * Separators in MathML are represented by a list and used up one by one 114 * until the final element is used as the default. 115 * Example: a b c d e and separators [+,-,*] 116 * would result in a + b - c * d * e. 117 * @param {string} separators String representing a list of mfenced separators. 118 * @return {function(): string|null} A closure that returns the next separator 119 * for an mfenced expression starting with the first node in nodes. 120 */ 121cvox.MathmlStoreUtil.nextSeparatorFunction = function(separators) { 122 if (separators) { 123 // Mathjax does not expand empty separators. 124 if (separators.match(/^\s+$/)) { 125 return null; 126 } else { 127 var sepList = separators.replace(/\s/g, '') 128 .split('') 129 .filter(function(x) {return x;}); 130 } 131 } else { 132 // When no separator is given MathML uses comma as default. 133 var sepList = [',']; 134 } 135 136 return function() { 137 if (sepList.length > 1) { 138 return sepList.shift(); 139 } 140 return sepList[0]; 141 }; 142}; 143 144 145/** 146 * Computes the correct separators for each node. 147 * @param {Array.<Node>} nodes A node array. 148 * @param {string} context A context string. 149 * @return {function(): string} A closure that returns the next separator for an 150 * mfenced expression starting with the first node in nodes. 151 */ 152cvox.MathmlStoreUtil.mfencedSeparators = function(nodes, context) { 153 var nextSeparator = cvox.MathmlStoreUtil.nextSeparatorFunction(context); 154 return function() { 155 return nextSeparator ? nextSeparator() : ''; 156 }; 157}; 158 159 160/** 161 * Iterates over the list of content nodes of the parent of the given nodes. 162 * @param {Array.<Node>} nodes A node array. 163 * @param {string} context A context string. 164 * @return {function(): string} A closure that returns the content of the next 165 * content node. Returns only context string if list is exhausted. 166 */ 167cvox.MathmlStoreUtil.contentIterator = function(nodes, context) { 168 if (nodes.length > 0) { 169 var contentNodes = cvox.XpathUtil.evalXPath('../../content/*', nodes[0]); 170 } else { 171 var contentNodes = []; 172 } 173 return function() { 174 var content = contentNodes.shift(); 175 return context + (content ? content.textContent : ''); 176 }; 177}; 178