Home | History | Annotate | Download | only in speech_rules
      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 
      9 goog.provide('cvox.MathmlStoreUtil');
     10 
     11 goog.require('cvox.MathUtil');
     12 goog.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  */
     20 cvox.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  */
     31 cvox.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  */
     45 cvox.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  */
     61 cvox.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  */
     75 cvox.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  */
     85 cvox.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  */
     95 cvox.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  */
    105 cvox.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  */
    121 cvox.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  */
    152 cvox.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  */
    167 cvox.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