Home | History | Annotate | Download | only in common
      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 Semantic attributes of Math symbols and expressions.
      7  *
      8  * This file contains the basic functionality to lookup and assign semantic
      9  * attributes for mathematical expressions. Since there is no such thing as a
     10  * well-defined semantics for all of mathematics we compute a default semantics
     11  * that closely models mathematical expressions found in K-12 mathematics as
     12  * well as in general undergraduate curriculum (i.e., calculus, linear algebra,
     13  * etc).
     14  *
     15  * Currently semantic attributes of symbols consist of the following two parts:
     16  *
     17  * type -- An unmutable property of an expression, regardless of its position in
     18  *         the math expression. For example, the letter 'f' will always have the
     19  *         type identifier, regardless of its use in context, e.g. as function
     20  *         symbol or variable.
     21  *
     22  * role -- A mutable description of the role an expression plays in the context
     23  *         of the overall mathematical expression. For instance, the symbol '|'
     24  *         is of type punctuation, but depending on context it has the role of a
     25  *         neutral fence or of a single vertical bar.
     26  *
     27  * In addition for some symbols we record the font as a further attribute.
     28  *
     29  * When a semantically interpreted expression is transformed into a XML
     30  * representation, types become tag names, while role, font, etc. are added as
     31  * attributes.
     32  *
     33  * This file is part of the content script as we do not want to call out to the
     34  * background page every time we need to look up the semantic of a symbol.
     35  *
     36  * TODO (sorge) Move semantic tree translation into the background page
     37  *    alongside MathJax.
     38  *
     39  */
     40 
     41 goog.provide('cvox.SemanticAttr');
     42 
     43 goog.require('cvox.SemanticUtil');
     44 
     45 
     46 /**
     47  * Contains the basic mappings of characters/symbols and functions to semantic
     48  * attributes.
     49  *
     50  * Observe that all characters are given as hex code number in order to ease the
     51  * comparison with those in the JSON files that define speech rules per
     52  * character.
     53  * @constructor
     54  */
     55 cvox.SemanticAttr = function() {
     56   // Punctuation Characters.
     57   /**
     58    * @type {Array.<string>}
     59    */
     60   this.generalPunctuations =
     61       [
     62         '!', '"', '#', '%', '&', '\'', '*', ',', ':', ';', '?', '@', '\\',
     63         '', '', '', '', '', '', '', '', '', '', '', '', '',
     64         '', '', '', '', '', '', '', '', '', '', '', '', '',
     65         '', '', '', '', '', '', '', '', '', '', '', '', '',
     66         '', '', '', '', '', '', '', '', '', '', '', '',
     67         '', '', '', '', '', '', '', '', '', '', '', '', '',
     68         '', '', '', '', '', '', '', '', '', '', '', '',
     69         '', '', '', ''
     70       ];
     71   /**
     72    * @type {string}
     73    * @private
     74    */
     75   this.invisibleComma_ = cvox.SemanticUtil.numberToUnicode(0x2063);
     76   this.generalPunctuations.push(this.invisibleComma_);
     77   /**
     78    * @type {Array.<string>}
     79    */
     80   this.ellipses =
     81       [
     82         '', '', '', '', '', ''
     83       ];
     84   /**
     85    * @type {Array.<string>}
     86    */
     87   this.fullStops =
     88       [
     89         '.', '', ''
     90       ];
     91   /**
     92    * @type {Array.<string>}
     93    */
     94   this.dashes =
     95       [
     96         '', '', '', '', '', '', '', ''
     97       ];
     98   /**
     99    * @type {Array.<string>}
    100    */
    101   this.primes =
    102       [
    103         '', '', '', '', '', '', ''
    104       ];
    105 
    106   // Fences.
    107   // Fences are treated slightly differently from other symbols as we want to
    108   // record pairs of opening/closing and top/bottom fences.
    109   /**
    110    * Mapping opening to closing fences.
    111    * @type {Object.<string, string>}
    112    */
    113   this.openClosePairs =
    114       {
    115         // Unicode categories Ps and Pe.
    116         // Observe that left quotation 301D could also be matched to 301F,
    117         // but is currently matched to 301E.
    118         '(': ')', '[': ']', '{': '}', '': '', '': '', '': '',
    119         '': '', '': '', '': '', '': '', '': '', '': '',
    120         '': '', '': '', '': '', '': '', '': '', '': '',
    121         '': '', '': '', '': '', '': '', '': '', '': '',
    122         '': '', '': '', '': '', '': '', '': '', '': '',
    123         '': '', '': '', '': '', '': '', '': '', '': '',
    124         '': '', '': '', '': '', '': '', '': '',
    125         '': '', '': '', '': '', '': '', '': '',
    126         '': '', '': '', '': '', '': '', '': '', '': '',
    127         '': '', '': '', '': '', '': '',
    128         // Unicode categories Sm and So.
    129         '': '', '': '', '': '', '': '', '': '', '': '',
    130         // Extender fences.
    131         // Parenthesis.
    132         '': '', '': '', '': '',
    133         // Square bracket.
    134         '': '', '': '', '': '',
    135         // Curly bracket.
    136         '': '', '': '', '': '', '': '', '': ''
    137       };
    138   /**
    139    * Mapping top to bottom fences.
    140    * @type {Object.<string, string>}
    141    */
    142   this.topBottomPairs =
    143       {
    144         '': '', '': '', '': '', '': '', '': '', '': '',
    145         '': '', '': '', '': '', '': '', '': '',
    146         '': '', '': ''
    147       };
    148   /**
    149    * @type {Array.<string>}
    150    */
    151   this.leftFences = cvox.SemanticUtil.objectsToKeys(this.openClosePairs);
    152   /**
    153    * @type {Array.<string>}
    154    */
    155   this.rightFences = cvox.SemanticUtil.objectsToValues(this.openClosePairs);
    156   this.rightFences.push('');
    157   /**
    158    * @type {Array.<string>}
    159    */
    160   this.topFences = cvox.SemanticUtil.objectsToKeys(this.topBottomPairs);
    161   /**
    162    * @type {Array.<string>}
    163    */
    164   this.bottomFences = cvox.SemanticUtil.objectsToValues(this.topBottomPairs);
    165   /**
    166    * @type {Array.<string>}
    167    */
    168   this.neutralFences =
    169       [
    170         '|', '', '', '', '', '', '', ''
    171       ];
    172   /** Array of all fences.
    173    * @type {Array.<string>}
    174    */
    175   this.fences = this.neutralFences.concat(
    176       this.leftFences, this.rightFences, this.topFences, this.bottomFences);
    177 
    178   // Identifiers.
    179   // Latin Alphabets.
    180   /**
    181    * @type {Array.<string>}
    182    */
    183   this.capitalLatin =
    184       [
    185         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    186         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    187       ];
    188   /**
    189    * @type {Array.<string>}
    190    */
    191   this.smallLatin =
    192       [
    193         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    194         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    195         // dotless i and j.
    196         '', ''
    197       ];
    198   /**
    199    * @type {Array.<string>}
    200    */
    201   this.capitalLatinFullWidth =
    202       [
    203         '', '', '', '', '', '', '', '', '', '', '', '', '',
    204        '', '', '', '', '', '', '', '', '', '', '', '', ''
    205       ];
    206   /**
    207    * @type {Array.<string>}
    208    */
    209   this.smallLatinFullWidth =
    210       [
    211         '', '', '', '', '', '', '', '', '', '', '', '', '',
    212         '', '', '', '', '', '', '', '', '', '', '', '', ''
    213       ];
    214   /**
    215    * @type {Array.<string>}
    216    */
    217   this.capitalLatinBold =
    218       [
    219         '', '', '', '', '', '', '', '', '', '', '', '', '',
    220        '', '', '', '', '', '', '', '', '', '', '', '', ''
    221         ];
    222   /**
    223    * @type {Array.<string>}
    224    */
    225   this.smallLatinBold =
    226       [
    227         '', '', '', '', '', '', '', '', '', '', '', '', '',
    228        '', '', '', '', '', '', '', '', '', '', '', '', ''
    229         ];
    230   /**
    231    * @type {Array.<string>}
    232    */
    233   this.capitalLatinItalic =
    234       [
    235         '', '', '', '', '', '', '', '', '', '', '', '', '',
    236        '', '', '', '', '', '', '', '', '', '', '', '', ''
    237         ];
    238   /**
    239    * @type {Array.<string>}
    240    */
    241   this.smallLatinItalic =
    242       [
    243         '', '', '', '', '', '', '', '', '', '', '', '', '',
    244        '', '', '', '', '', '', '', '', '', '', '', '', '',
    245        // dotless i and j.
    246        '', ''
    247         ];
    248   /**
    249    * @type {Array.<string>}
    250    */
    251   this.capitalLatinScript =
    252       [
    253         '', '', '', '', '', '', '', '', '', '', '', '', '',
    254        '', '', '', '', '', '', '', '', '', '', '', '', '',
    255        // Powerset Cap P.
    256        ''
    257         ];
    258   /**
    259    * @type {Array.<string>}
    260    */
    261   this.smallLatinScript =
    262       [
    263         '', '', '', '', '', '', '', '', '', '', '', '', '',
    264        '', '', '', '', '', '', '', '', '', '', '', '', '',
    265        // script small l
    266        ''
    267         ];
    268   /**
    269    * @type {Array.<string>}
    270    */
    271   this.capitalLatinBoldScript =
    272       [
    273         '', '', '', '', '', '', '', '', '', '', '', '', '',
    274        '', '', '', '', '', '', '', '', '', '', '', '', ''
    275         ];
    276   /**
    277    * @type {Array.<string>}
    278    */
    279   this.smallLatinBoldScript =
    280       [
    281         '', '', '', '', '', '', '', '', '', '', '', '', '',
    282        '', '', '', '', '', '', '', '', '', '', '', '', ''
    283         ];
    284   /**
    285    * @type {Array.<string>}
    286    */
    287   this.capitalLatinFraktur =
    288       [
    289         '', '', '', '', '', '', '', '', '', '', '', '', '',
    290        '', '', '', '', '', '', '', '', '', '', '', '', ''
    291         ];
    292   /**
    293    * @type {Array.<string>}
    294    */
    295   this.smallLatinFraktur =
    296       [
    297         '', '', '', '', '', '', '', '', '', '', '', '', '',
    298        '', '', '', '', '', '', '', '', '', '', '', '', ''
    299         ];
    300   /**
    301    * @type {Array.<string>}
    302    */
    303   this.capitalLatinDoubleStruck =
    304       [
    305         '', '', '', '', '', '', '', '', '', '', '', '', '',
    306        '', '', '', '', '', '', '', '', '', '', '', '', ''
    307         ];
    308   /**
    309    * @type {Array.<string>}
    310    */
    311   this.smallLatinDoubleStruck =
    312       [
    313         '', '', '', '', '', '', '', '', '', '', '', '', '',
    314        '', '', '', '', '', '', '', '', '', '', '', '', ''
    315         ];
    316   /**
    317    * @type {Array.<string>}
    318    */
    319   this.capitalLatinBoldFraktur =
    320       [
    321         '', '', '', '', '', '', '', '', '', '', '', '', '',
    322        '', '', '', '', '', '', '', '', '', '', '', '', ''
    323         ];
    324   /**
    325    * @type {Array.<string>}
    326    */
    327   this.smallLatinBoldFraktur =
    328       [
    329         '', '', '', '', '', '', '', '', '', '', '', '', '',
    330        '', '', '', '', '', '', '', '', '', '', '', '', ''
    331         ];
    332   /**
    333    * @type {Array.<string>}
    334    */
    335   this.capitalLatinSansSerif =
    336       [
    337         '', '', '', '', '', '', '', '', '', '', '', '', '',
    338        '', '', '', '', '', '', '', '', '', '', '', '', ''
    339         ];
    340   /**
    341    * @type {Array.<string>}
    342    */
    343   this.smallLatinSansSerif =
    344       [
    345         '', '', '', '', '', '', '', '', '', '', '', '', '',
    346        '', '', '', '', '', '', '', '', '', '', '', '', ''
    347         ];
    348   /**
    349    * @type {Array.<string>}
    350    */
    351   this.capitalLatinSansSerifBold =
    352       [
    353         '', '', '', '', '', '', '', '', '', '', '', '', '',
    354        '', '', '', '', '', '', '', '', '', '', '', '', ''
    355         ];
    356   /**
    357    * @type {Array.<string>}
    358    */
    359   this.smallLatinSansSerifBold =
    360       [
    361         '', '', '', '', '', '', '', '', '', '', '', '', '',
    362        '', '', '', '', '', '', '', '', '', '', '', '', ''
    363         ];
    364   /**
    365    * @type {Array.<string>}
    366    */
    367   this.capitalLatinSansSerifItalic =
    368       [
    369         '', '', '', '', '', '', '', '', '', '', '', '', '',
    370        '', '', '', '', '', '', '', '', '', '', '', '', ''
    371         ];
    372   /**
    373    * @type {Array.<string>}
    374    */
    375   this.smallLatinSansSerifItalic =
    376       [
    377         '', '', '', '', '', '', '', '', '', '', '', '', '',
    378        '', '', '', '', '', '', '', '', '', '', '', '', ''
    379         ];
    380   /**
    381    * @type {Array.<string>}
    382    */
    383   this.capitalLatinMonospace =
    384       [
    385         '', '', '', '', '', '', '', '', '', '', '', '', '',
    386        '', '', '', '', '', '', '', '', '', '', '', '', ''
    387         ];
    388   /**
    389    * @type {Array.<string>}
    390    */
    391   this.smallLatinMonospace =
    392       [
    393         '', '', '', '', '', '', '', '', '', '', '', '', '',
    394        '', '', '', '', '', '', '', '', '', '', '', '', ''
    395         ];
    396   /**
    397    * @type {Array.<string>}
    398    */
    399   this.latinDoubleStruckItalic =
    400       [
    401         '', '', '', '', ''
    402         ];
    403 
    404   // Greek Alphabets
    405   /**
    406    * @type {Array.<string>}
    407    */
    408   this.capitalGreek =
    409       [
    410         '', '', '', '', '', '', '', '', '', '', '', '', '',
    411        '', '', '', '', '', '', '', '', '', '', ''
    412         ];
    413   /**
    414    * @type {Array.<string>}
    415    */
    416   this.smallGreek =
    417       [
    418         '', '', '', '', '', '', '', '', '', '', '', '', '',
    419        '', '', '', '', '', '', '', '', '', '', '', ''
    420         ];
    421   /**
    422    * @type {Array.<string>}
    423    */
    424   this.capitalGreekBold =
    425       [
    426         '', '', '', '', '', '', '', '', '', '', '', '', '',
    427        '', '', '', '', '', '', '', '', '', '', ''
    428         ];
    429   /**
    430    * @type {Array.<string>}
    431    */
    432   this.smallGreekBold =
    433       [
    434         '', '', '', '', '', '', '', '', '', '', '', '', '',
    435        '', '', '', '', '', '', '', '', '', '', '', ''
    436         ];
    437   /**
    438    * @type {Array.<string>}
    439    */
    440   this.capitalGreekItalic =
    441       [
    442         '', '', '', '', '', '', '', '', '', '', '', '', '',
    443        '', '', '', '', '', '', '', '', '', '', ''
    444         ];
    445   /**
    446    * @type {Array.<string>}
    447    */
    448   this.smallGreekItalic =
    449       [
    450         '', '', '', '', '', '', '', '', '', '', '', '', '',
    451        '', '', '', '', '', '', '', '', '', '', '', ''
    452         ];
    453   /**
    454    * @type {Array.<string>}
    455    */
    456   this.capitalGreekSansSerifBold =
    457       [
    458         '', '', '', '', '', '', '', '', '', '', '', '', '',
    459        '', '', '', '', '', '', '', '', '', '', ''
    460         ];
    461   /**
    462    * @type {Array.<string>}
    463    */
    464   this.smallGreekSansSerifBold =
    465       [
    466         '', '', '', '', '', '', '', '', '', '', '', '', '',
    467        '', '', '', '', '', '', '', '', '', '', '', ''
    468         ];
    469   /**
    470    * @type {Array.<string>}
    471    */
    472   this.greekDoubleStruck =
    473       [
    474         '', '', '', ''
    475         ];
    476 
    477   // Other alphabets.
    478   /**
    479    * @type {Array.<string>}
    480    */
    481   this.hebrewLetters =
    482       [
    483         '', '', '', ''
    484         ];
    485 
    486   //Operator symbols
    487   /**
    488    * @type {Array.<string>}
    489    */
    490   this.additions =
    491       [
    492         '+', '', '', '', '', '', '', '', '', '', '', '', '',
    493         '', '', '', '', '', '', '', '', '', '', '', '', '',
    494         '', '', ''
    495         ];
    496       /**
    497        * @type {Array.<string>}
    498            */
    499   /**
    500    * Invisible operator for plus.
    501    * @type {string}
    502    * @private
    503    */
    504   this.invisiblePlus_ = cvox.SemanticUtil.numberToUnicode(0x2064);
    505   this.additions.push(this.invisiblePlus_);
    506   /**
    507    * @type {Array.<string>}
    508    */
    509   this.multiplications =
    510       [
    511         '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    512         '', '', '', '', ''
    513         ];
    514   /**
    515    * Invisible operator for multiplication.
    516    * @type {string}
    517    * @private
    518    */
    519   this.invisibleTimes_ = cvox.SemanticUtil.numberToUnicode(0x2062);
    520   this.multiplications.push(this.invisibleTimes_);
    521   /**
    522    * @type {Array.<string>}
    523    */
    524   this.subtractions =
    525       [
    526         '-', '', '', '', '', '', '', '', '', '', '', '', '',
    527        '', '', '', '', '', '', '', '', ''
    528         ];
    529   /**
    530    * @type {Array.<string>}
    531    */
    532   this.divisions =
    533       [
    534         '/', '', '', '', '', '', '', ''
    535         ];
    536   /**
    537    * Invisible operator for function application.
    538    * @type {string}
    539    * @private
    540    */
    541   this.functionApplication_ = cvox.SemanticUtil.numberToUnicode(0x2061);
    542 
    543   //Relation symbols
    544   /**
    545    * @type {Array.<string>}
    546    */
    547   this.equalities =
    548       [
    549         '=', '~', '', '', '', '', '', '', '', '', '', '', '',
    550        '', '', '', '', '', '', '', '', '', '', '', '', '',
    551        '', '', '', '', '', '', '', '', '', '', '', '', '',
    552        '', '', '', '', '', '', '', '', '', '', '', ''
    553         ];
    554   /**
    555    * @type {Array.<string>}
    556    */
    557   this.inequalities =
    558       [
    559         '<', '>', '', '', '', '', '', '', '', '', '', '', '',
    560         '', '', '', '', '', '', '', '', '', '', '', '', '',
    561         '', '', '', '', '', '', '', '', '', '', '', '', '',
    562         '', '', '', '', '', '', '', '', '', '', '', '', '',
    563         '', '', '', '', '', '', '', '', '', '', '', '', '',
    564         '', '', '', '', '', '', '', '', '', '', '', '', '',
    565         '', '', '', '', '', '', '', '', '', '', '', '', '',
    566         '', '', '', '', '', '', '', '', '', '', '', '', '',
    567         '', '', '', '', '', '', '', '', '', '', '', '', '',
    568         '', '', '', '', '', '', '', '', '', '', '', '', '',
    569         '', '', '', '', '', '', '', '', '', ''
    570       ];
    571   /**
    572    * @type {Array.<string>}
    573    */
    574   this.relations =
    575       [
    576             // TODO (sorge): Add all the other relations.
    577       ];
    578   /**
    579    * @type {Array.<string>}
    580    */
    581   this.arrows =
    582       [
    583         '', '', '', '', '', '', '', '', '', '', '', '', '',
    584         '', '', '', '', '', '', '', '', '', '', '', '', '',
    585         '', '', '', '', '', '', '', '', '', '', '', '', '',
    586         '', '', '', '', '', '', '', '', '', '', '', '', '',
    587         '', '', '', '', '', '', '', '', '', '', '', '', '',
    588         '', '', '', '', '', '', '', '', '', '', '', '', '',
    589         '', '', '', '', '', '', '', '', '', '', '', '', '',
    590         '', '', '', '', '', '', '', '', '', '', '', '', '',
    591         '', '', '', '', '', '', '', '', '', '', '', '', '',
    592         '', '', '', '', '', '', '', '', '', '', '', '', '',
    593         '', '', '', '', '', '', '', '', '', '', '', '', '',
    594         '', '', '', '', '', '', '', '', '', '', '', '', '',
    595         '', '', '', '', '', '', '', '', '', '', '', '', '',
    596         '', '', '', '', '', '', '', '', '', '', '', '', '',
    597         '', '', '', '', '', '', '', '', '', '', '', '', '',
    598         '', '', '', '', '', '', '', '', '', '', '', '', '',
    599         '', '', '', '', '', '', '', '', '', '', '', '', '',
    600         '', '', '', '', '', '', '', '', '', '', '', '', '',
    601         '', '', '', '', '', '', '', '', '', '', '', '', '',
    602         '', '', '', '', '', '', '', '', '', '', '', '', '',
    603         '', '', '', '', '', '', '', '', '', '', '', '', '',
    604         '', '', '', '', '', '', '', '', '', '', '', '', '',
    605         '', '', '', '', '', '', '', '', '', '', '', '', '',
    606         '', '', '', '', '',
    607         // Harpoons
    608         '', '', '', '', '', '', '', '', '', '', '', '', '',
    609         '', '', '', '', '', '', '', '', '', '', '', '', '',
    610         '', '', '', '', '', '', '', '', '', '', '', '', '',
    611         '', '', '', '', '', '', '', '', '', '', '', '', ''
    612       ];
    613 
    614   //Big operation symbols
    615   /**
    616    * @type {Array.<string>}
    617    */
    618   this.sumOps =
    619       [
    620         '', // double struck
    621         '', '', '', '', '', '', '', '', '', '', '', '', '',
    622         '', '', '', '', '', '', '', ''
    623         ];
    624   /**
    625    * @type {Array.<string>}
    626    */
    627   this.intOps =
    628       [
    629         '', '', '', '', '', '', '', '', '', '', '', '', '',
    630         '', '', '', '', '', '', '', '', '', '', '', '', ''
    631       ];
    632   /**
    633    * @type {Array.<string>}
    634    */
    635   this.prefixOps =
    636       // TODO (sorge) Insert nabla, differential operators etc.
    637       [
    638         '', ''
    639       ];
    640   /**
    641    * @type {Array.<string>}
    642    */
    643   this.operatorBits =
    644       // TODO (sorge) What to do if single glyphs of big ops occur on their own.
    645       [
    646         '', '', '', '', '', '', '', '', ''
    647       ];
    648 
    649   // Accents.
    650   // TODO (sorge) Add accented characters.
    651 
    652   // Numbers.
    653   // Digits.
    654   /**
    655    * @type {Array.<string>}
    656    */
    657   this.digitsNormal =
    658       [
    659         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
    660         ];
    661   /**
    662    * @type {Array.<string>}
    663    */
    664   this.digitsFullWidth =
    665       [
    666         '', '', '', '', '', '', '', '', '', ''
    667       ];
    668   /**
    669    * @type {Array.<string>}
    670    */
    671   this.digitsBold =
    672       [
    673         '', '', '', '', '', '', '', '', '', ''
    674         ];
    675   /**
    676    * @type {Array.<string>}
    677    */
    678   this.digitsDoubleStruck =
    679       [
    680         '', '', '', '', '', '', '', '', '', ''
    681         ];
    682   /**
    683    * @type {Array.<string>}
    684    */
    685   this.digitsSansSerif =
    686       [
    687         '', '', '', '', '', '', '', '', '', ''
    688         ];
    689   /**
    690    * @type {Array.<string>}
    691    */
    692   this.digitsSansSerifBold =
    693       [
    694         '', '', '', '', '', '', '', '', '', ''
    695         ];
    696   /**
    697    * @type {Array.<string>}
    698    */
    699   this.digitsMonospace =
    700       [
    701         '', '', '', '', '', '', '', '', '', ''
    702         ];
    703   /**
    704    * @type {Array.<string>}
    705    */
    706   this.digitsSuperscript =
    707       [
    708         '', '', '', '', '', '', '', '', '', ''
    709         ];
    710   /**
    711    * @type {Array.<string>}
    712    */
    713   this.digitsSubscript =
    714       [
    715         '', '', '', '', '', '', '', '', '', ''
    716         ];
    717   /**
    718    * @type {Array.<string>}
    719    */
    720   this.fractions =
    721       [
    722         '', '', '', '', '', '', '', '', '', '', '', '', '',
    723         '', '', '', '', '', '', ''
    724       ];
    725   /**
    726    * @type {Array.<string>}
    727    */
    728   this.enclosedNumbers =
    729       // Encircled numbers.
    730       [
    731         '', '', '', '', '', '', '', '', '', '', '', '', '',
    732         '', '', '', '', '', '', '', '', '', '', '', '', '',
    733         '', '', '', '', '', '', '', '', '', '', '', '', '',
    734         '', '', '', '', '', '', '', '', '', '', '', '', '',
    735         '', '', '', '', '', '', '', '', '', '', '', '', '',
    736         '', '', '', '', '', '', '', '', '', '', '', '',
    737         '', '', '', '', '', '', '', '', '', '', '',
    738         '', '', '', '', '', '', '', '', '', '', '',
    739         '', '', '', '', '', '', '', '', '', '', ''];
    740   /**
    741    * @type {Array.<string>}
    742    */
    743   this.fencedNumbers =
    744       // Numbers in Parenthesis.
    745       [
    746         '', '', '', '', '', '', '', '', '', '', '', '', '',
    747         '', '', '', '', '', '', ''
    748       ];
    749   /**
    750    * @type {Array.<string>}
    751    */
    752   this.punctuatedNumbers =
    753       // Numbers with other punctuation.
    754       ['', '', '', '', '', '', '', '', '', '', '', '', '',
    755        '', '', '', '', '', '', '', // full stop.
    756        '', '', '', '', '', '', '', '', '', '', '' // comma.
    757       ];
    758   /** Array of all single digits.
    759    * @type {Array.<string>}
    760    */
    761   this.digits = this.digitsNormal.concat(
    762       this.digitsFullWidth, this.digitsBold, this.digitsDoubleStruck,
    763       this.digitsSansSerif, this.digitsSansSerifBold, this.digitsMonospace);
    764   /** Array of all non-digit number symbols.
    765    * @type {Array.<string>}
    766    */
    767   this.numbers = this.fractions.concat(
    768       this.digitsSuperscript, this.digitsSubscript,
    769       this.enclosedNumbers, this.fencedNumbers, this.punctuatedNumbers);
    770   /** Array of all number symbols.
    771    * @type {Array.<string>}
    772    */
    773   this.allNumbers = this.digits.concat(this.numbers);
    774 
    775   // Functions.
    776   /**
    777    * @type {Array.<string>}
    778    */
    779   this.trigonometricFunctions =
    780       [
    781         'cos', 'cot', 'csc', 'sec', 'sin', 'tan', 'arccos', 'arccot',
    782         'arccsc', 'arcsec', 'arcsin', 'arctan'
    783       ];
    784   /**
    785    * @type {Array.<string>}
    786    */
    787   this.hyperbolicFunctions =
    788       [
    789         'cosh', 'coth', 'csch', 'sech', 'sinh', 'tanh',
    790         'arcosh', 'arcoth', 'arcsch', 'arsech', 'arsinh', 'artanh',
    791         'arccosh', 'arccoth', 'arccsch', 'arcsech', 'arcsinh', 'arctanh'
    792       ];
    793   /**
    794    * @type {Array.<string>}
    795    */
    796   this.algebraicFunctions =
    797       [
    798         'deg', 'det', 'dim', 'hom', 'ker', 'Tr', 'tr'
    799       ];
    800   /**
    801    * @type {Array.<string>}
    802    */
    803   this.elementaryFunctions =
    804       [
    805         'log', 'ln', 'lg', 'exp', 'expt', 'gcd', 'gcd', 'arg', 'im', 're', 'Pr'
    806       ];
    807   /** All predefined prefix functions.
    808    * @type {Array.<string>}
    809    */
    810   this.prefixFunctions = this.trigonometricFunctions.concat(
    811       this.hyperbolicFunctions,
    812       this.algebraicFunctions,
    813       this.elementaryFunctions
    814       );
    815   /** Limit functions are handled separately as they can have lower (and upper)
    816    * limiting expressions.
    817    * @type {Array.<string>}
    818    */
    819   this.limitFunctions =
    820       [
    821         'inf', 'lim', 'liminf', 'limsup', 'max', 'min', 'sup', 'injlim',
    822         'projlim'
    823       ];
    824   /**
    825    * @type {Array.<string>}
    826    */
    827   this.infixFunctions =
    828       [
    829         'mod', 'rem'
    830       ];
    831   /**
    832    * Default assignments of semantic attributes.
    833    * @type  {Array.<{set: Array.<string>,
    834    *         role: cvox.SemanticAttr.Role,
    835    *         type: cvox.SemanticAttr.Type,
    836    *         font: cvox.SemanticAttr.Font}>} The semantic meaning of the symbol.
    837    * @private
    838    */
    839   this.symbolSetToSemantic_ = [
    840     // Punctuation
    841     {set: this.generalPunctuations,
    842      type: cvox.SemanticAttr.Type.PUNCTUATION,
    843      role: cvox.SemanticAttr.Role.UNKNOWN
    844     },
    845     {set: this.ellipses,
    846      type: cvox.SemanticAttr.Type.PUNCTUATION,
    847      role: cvox.SemanticAttr.Role.ELLIPSIS
    848     },
    849     {set: this.fullStops,
    850      type: cvox.SemanticAttr.Type.PUNCTUATION,
    851      role: cvox.SemanticAttr.Role.FULLSTOP
    852     },
    853     {set: this.dashes,
    854      type: cvox.SemanticAttr.Type.PUNCTUATION,
    855      role: cvox.SemanticAttr.Role.DASH
    856     },
    857     {set: this.primes,
    858      type: cvox.SemanticAttr.Type.PUNCTUATION,
    859      role: cvox.SemanticAttr.Role.PRIME
    860     },
    861     // Fences
    862     {set: this.leftFences,
    863      type: cvox.SemanticAttr.Type.FENCE,
    864      role: cvox.SemanticAttr.Role.OPEN
    865     },
    866     {set: this.rightFences,
    867      type: cvox.SemanticAttr.Type.FENCE,
    868      role: cvox.SemanticAttr.Role.CLOSE
    869     },
    870     {set: this.topFences,
    871      type: cvox.SemanticAttr.Type.FENCE,
    872      role: cvox.SemanticAttr.Role.TOP
    873     },
    874     {set: this.bottomFences,
    875      type: cvox.SemanticAttr.Type.FENCE,
    876      role: cvox.SemanticAttr.Role.BOTTOM
    877     },
    878     {set: this.neutralFences,
    879      type: cvox.SemanticAttr.Type.FENCE,
    880      role: cvox.SemanticAttr.Role.NEUTRAL
    881     },
    882     // Single characters.
    883     // Latin alphabets.
    884     {set: this.smallLatin,
    885      type: cvox.SemanticAttr.Type.IDENTIFIER,
    886      role: cvox.SemanticAttr.Role.LATINLETTER,
    887      font: cvox.SemanticAttr.Font.NORMAL
    888     },
    889     {set: this.capitalLatin,
    890      type: cvox.SemanticAttr.Type.IDENTIFIER,
    891      role: cvox.SemanticAttr.Role.LATINLETTER,
    892      font: cvox.SemanticAttr.Font.NORMAL
    893     },
    894     {set: this.smallLatinFullWidth,
    895      type: cvox.SemanticAttr.Type.IDENTIFIER,
    896      role: cvox.SemanticAttr.Role.LATINLETTER,
    897      font: cvox.SemanticAttr.Font.NORMAL
    898     },
    899     {set: this.capitalLatinFullWidth,
    900      type: cvox.SemanticAttr.Type.IDENTIFIER,
    901      role: cvox.SemanticAttr.Role.LATINLETTER,
    902      font: cvox.SemanticAttr.Font.NORMAL
    903     },
    904     {set: this.smallLatinBold,
    905      type: cvox.SemanticAttr.Type.IDENTIFIER,
    906      role: cvox.SemanticAttr.Role.LATINLETTER,
    907      font: cvox.SemanticAttr.Font.BOLD
    908     },
    909     {set: this.capitalLatinBold,
    910      type: cvox.SemanticAttr.Type.IDENTIFIER,
    911      role: cvox.SemanticAttr.Role.LATINLETTER,
    912      font: cvox.SemanticAttr.Font.BOLD
    913     },
    914     {set: this.smallLatinItalic,
    915      type: cvox.SemanticAttr.Type.IDENTIFIER,
    916      role: cvox.SemanticAttr.Role.LATINLETTER,
    917      font: cvox.SemanticAttr.Font.ITALIC
    918     },
    919     {set: this.capitalLatinItalic,
    920      type: cvox.SemanticAttr.Type.IDENTIFIER,
    921      role: cvox.SemanticAttr.Role.LATINLETTER,
    922      font: cvox.SemanticAttr.Font.ITALIC
    923     },
    924     {set: this.smallLatinScript,
    925      type: cvox.SemanticAttr.Type.IDENTIFIER,
    926      role: cvox.SemanticAttr.Role.LATINLETTER,
    927      font: cvox.SemanticAttr.Font.SCRIPT
    928     },
    929     {set: this.capitalLatinScript,
    930      type: cvox.SemanticAttr.Type.IDENTIFIER,
    931      role: cvox.SemanticAttr.Role.LATINLETTER,
    932      font: cvox.SemanticAttr.Font.SCRIPT
    933     },
    934     {set: this.smallLatinBoldScript,
    935      type: cvox.SemanticAttr.Type.IDENTIFIER,
    936      role: cvox.SemanticAttr.Role.LATINLETTER,
    937      font: cvox.SemanticAttr.Font.BOLDSCRIPT
    938     },
    939     {set: this.capitalLatinBoldScript,
    940      type: cvox.SemanticAttr.Type.IDENTIFIER,
    941      role: cvox.SemanticAttr.Role.LATINLETTER,
    942      font: cvox.SemanticAttr.Font.BOLDSCRIPT
    943     },
    944     {set: this.smallLatinFraktur,
    945      type: cvox.SemanticAttr.Type.IDENTIFIER,
    946      role: cvox.SemanticAttr.Role.LATINLETTER,
    947      font: cvox.SemanticAttr.Font.FRAKTUR
    948     },
    949     {set: this.capitalLatinFraktur,
    950      type: cvox.SemanticAttr.Type.IDENTIFIER,
    951      role: cvox.SemanticAttr.Role.LATINLETTER,
    952      font: cvox.SemanticAttr.Font.FRAKTUR
    953     },
    954     {set: this.smallLatinDoubleStruck,
    955      type: cvox.SemanticAttr.Type.IDENTIFIER,
    956      role: cvox.SemanticAttr.Role.LATINLETTER,
    957      font: cvox.SemanticAttr.Font.DOUBLESTRUCK
    958     },
    959     {set: this.capitalLatinDoubleStruck,
    960      type: cvox.SemanticAttr.Type.IDENTIFIER,
    961      role: cvox.SemanticAttr.Role.LATINLETTER,
    962      font: cvox.SemanticAttr.Font.DOUBLESTRUCK
    963     },
    964     {set: this.smallLatinBoldFraktur,
    965      type: cvox.SemanticAttr.Type.IDENTIFIER,
    966      role: cvox.SemanticAttr.Role.LATINLETTER,
    967      font: cvox.SemanticAttr.Font.BOLDFRAKTUR
    968     },
    969     {set: this.capitalLatinBoldFraktur,
    970      type: cvox.SemanticAttr.Type.IDENTIFIER,
    971      role: cvox.SemanticAttr.Role.LATINLETTER,
    972      font: cvox.SemanticAttr.Font.BOLDFRAKTUR
    973     },
    974     {set: this.smallLatinSansSerif,
    975      type: cvox.SemanticAttr.Type.IDENTIFIER,
    976      role: cvox.SemanticAttr.Role.LATINLETTER,
    977      font: cvox.SemanticAttr.Font.SANSSERIF
    978     },
    979     {set: this.capitalLatinSansSerif,
    980      type: cvox.SemanticAttr.Type.IDENTIFIER,
    981      role: cvox.SemanticAttr.Role.LATINLETTER,
    982      font: cvox.SemanticAttr.Font.SANSSERIF
    983     },
    984     {set: this.smallLatinSansSerifBold,
    985      type: cvox.SemanticAttr.Type.IDENTIFIER,
    986      role: cvox.SemanticAttr.Role.LATINLETTER,
    987      font: cvox.SemanticAttr.Font.SANSSERIFBOLD
    988     },
    989     {set: this.capitalLatinSansSerifBold,
    990      type: cvox.SemanticAttr.Type.IDENTIFIER,
    991      role: cvox.SemanticAttr.Role.LATINLETTER,
    992      font: cvox.SemanticAttr.Font.SANSSERIFBOLD
    993     },
    994     {set: this.smallLatinSansSerifItalic,
    995      type: cvox.SemanticAttr.Type.IDENTIFIER,
    996      role: cvox.SemanticAttr.Role.LATINLETTER,
    997      font: cvox.SemanticAttr.Font.SANSSERIFITALIC
    998     },
    999     {set: this.capitalLatinSansSerifItalic,
   1000      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1001      role: cvox.SemanticAttr.Role.LATINLETTER,
   1002      font: cvox.SemanticAttr.Font.SANSSERIFITALIC
   1003     },
   1004     {set: this.smallLatinMonospace,
   1005      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1006      role: cvox.SemanticAttr.Role.LATINLETTER,
   1007      font: cvox.SemanticAttr.Font.MONOSPACE
   1008     },
   1009     {set: this.capitalLatinMonospace,
   1010      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1011      role: cvox.SemanticAttr.Role.LATINLETTER,
   1012      font: cvox.SemanticAttr.Font.MONOSPACE
   1013     },
   1014     {set: this.latinDoubleStruckItalic,
   1015      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1016      role: cvox.SemanticAttr.Role.LATINLETTER,
   1017      font: cvox.SemanticAttr.Font.DOUBLESTRUCKITALIC
   1018     },
   1019     // Greek alphabets.
   1020     {set: this.smallGreek,
   1021      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1022      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1023      font: cvox.SemanticAttr.Font.NORMAL
   1024     },
   1025     {set: this.capitalGreek,
   1026      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1027      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1028      font: cvox.SemanticAttr.Font.NORMAL
   1029     },
   1030     {set: this.smallGreekBold,
   1031      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1032      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1033      font: cvox.SemanticAttr.Font.BOLD
   1034     },
   1035     {set: this.capitalGreekBold,
   1036      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1037      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1038      font: cvox.SemanticAttr.Font.BOLD
   1039     },
   1040     {set: this.smallGreekItalic,
   1041      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1042      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1043      font: cvox.SemanticAttr.Font.ITALIC
   1044     },
   1045     {set: this.capitalGreekItalic,
   1046      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1047      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1048      font: cvox.SemanticAttr.Font.ITALIC
   1049     },
   1050     {set: this.smallGreekSansSerifBold,
   1051      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1052      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1053      font: cvox.SemanticAttr.Font.SANSSERIFBOLD
   1054     },
   1055     {set: this.capitalGreekSansSerifBold,
   1056      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1057      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1058      font: cvox.SemanticAttr.Font.SANSSERIFBOLD
   1059     },
   1060     {set: this.greekDoubleStruck,
   1061      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1062      role: cvox.SemanticAttr.Role.GREEKLETTER,
   1063      font: cvox.SemanticAttr.Font.DOUBLESTRUCK
   1064     },
   1065     // Other alphabets.
   1066     {set: this.hebrewLetters,
   1067      type: cvox.SemanticAttr.Type.IDENTIFIER,
   1068      role: cvox.SemanticAttr.Role.OTHERLETTER,
   1069      font: cvox.SemanticAttr.Font.NORMAL
   1070     },
   1071     // Numbers.
   1072     {set: this.digitsNormal,
   1073      type: cvox.SemanticAttr.Type.NUMBER,
   1074      role: cvox.SemanticAttr.Role.INTEGER,
   1075      font: cvox.SemanticAttr.Font.NORMAL
   1076     },
   1077     {set: this.digitsFullWidth,
   1078      type: cvox.SemanticAttr.Type.NUMBER,
   1079      role: cvox.SemanticAttr.Role.INTEGER,
   1080      font: cvox.SemanticAttr.Font.NORMAL
   1081     },
   1082     {set: this.digitsBold,
   1083      type: cvox.SemanticAttr.Type.NUMBER,
   1084      role: cvox.SemanticAttr.Role.INTEGER,
   1085      font: cvox.SemanticAttr.Font.BOLD
   1086     },
   1087     {set: this.digitsDoubleStruck,
   1088      type: cvox.SemanticAttr.Type.NUMBER,
   1089      role: cvox.SemanticAttr.Role.INTEGER,
   1090      font: cvox.SemanticAttr.Font.DOUBLESTRUCK
   1091     },
   1092     {set: this.digitsSansSerif,
   1093      type: cvox.SemanticAttr.Type.NUMBER,
   1094      role: cvox.SemanticAttr.Role.INTEGER,
   1095      font: cvox.SemanticAttr.Font.SANSSERIF
   1096     },
   1097     {set: this.digitsSansSerifBold,
   1098      type: cvox.SemanticAttr.Type.NUMBER,
   1099      role: cvox.SemanticAttr.Role.INTEGER,
   1100      font: cvox.SemanticAttr.Font.SANSSERIFBOLD
   1101     },
   1102     {set: this.digitsMonospace,
   1103      type: cvox.SemanticAttr.Type.NUMBER,
   1104      role: cvox.SemanticAttr.Role.INTEGER,
   1105      font: cvox.SemanticAttr.Font.MONOSPACE
   1106     },
   1107    {set: this.numbers,
   1108      type: cvox.SemanticAttr.Type.NUMBER,
   1109      role: cvox.SemanticAttr.Role.INTEGER
   1110     },
   1111     // Operators.
   1112     {set: this.additions,
   1113      type: cvox.SemanticAttr.Type.OPERATOR,
   1114      role: cvox.SemanticAttr.Role.ADDITION
   1115     },
   1116     {set: this.multiplications,
   1117      type: cvox.SemanticAttr.Type.OPERATOR,
   1118      role: cvox.SemanticAttr.Role.MULTIPLICATION
   1119     },
   1120     {set: this.subtractions,
   1121      type: cvox.SemanticAttr.Type.OPERATOR,
   1122      role: cvox.SemanticAttr.Role.SUBTRACTION
   1123     },
   1124     {set: this.divisions,
   1125      type: cvox.SemanticAttr.Type.OPERATOR,
   1126      role: cvox.SemanticAttr.Role.DIVISION
   1127     },
   1128     {set: this.prefixOps,
   1129      type: cvox.SemanticAttr.Type.PREFIXOP,
   1130      role: cvox.SemanticAttr.Role.PREFIXFUNC
   1131     },
   1132     // Relations
   1133     {set: this.equalities,
   1134      type: cvox.SemanticAttr.Type.RELATION,
   1135      role: cvox.SemanticAttr.Role.EQUALITY
   1136     },
   1137     {set: this.inequalities,
   1138      type: cvox.SemanticAttr.Type.RELATION,
   1139      role: cvox.SemanticAttr.Role.INEQUALITY
   1140     },
   1141     {set: this.relations,
   1142      type: cvox.SemanticAttr.Type.RELATION,
   1143      role: cvox.SemanticAttr.Role.UNKNOWN
   1144     },
   1145     {set: this.arrows,
   1146      type: cvox.SemanticAttr.Type.RELATION,
   1147      role: cvox.SemanticAttr.Role.ARROW
   1148     },
   1149     // Large operators
   1150     {set: this.sumOps,
   1151      type: cvox.SemanticAttr.Type.LARGEOP,
   1152      role: cvox.SemanticAttr.Role.SUM},
   1153     {set: this.intOps,
   1154      type: cvox.SemanticAttr.Type.LARGEOP,
   1155      role: cvox.SemanticAttr.Role.INTEGRAL},
   1156     // Functions
   1157     {set: this.limitFunctions,
   1158      type: cvox.SemanticAttr.Type.FUNCTION,
   1159      role: cvox.SemanticAttr.Role.LIMFUNC},
   1160     {set: this.prefixFunctions,
   1161      type: cvox.SemanticAttr.Type.FUNCTION,
   1162      role: cvox.SemanticAttr.Role.PREFIXFUNC},
   1163     {set: this.infixFunctions,
   1164      type: cvox.SemanticAttr.Type.OPERATOR,
   1165      role: cvox.SemanticAttr.Role.MULTIPLICATION
   1166     }
   1167     // TODO (sorge) Add some of the remaining elements.
   1168   ];
   1169 };
   1170 goog.addSingletonGetter(cvox.SemanticAttr);
   1171 
   1172 
   1173 /**
   1174  * Union type of semantic attributes.
   1175  * @typedef {cvox.SemanticAttr.Type|cvox.SemanticAttr.Role}
   1176  */
   1177 cvox.SemanticAttr.Attr;
   1178 
   1179 
   1180 /**
   1181  * Mapping for types of elements.
   1182  * @enum {string}
   1183  */
   1184 cvox.SemanticAttr.Type = {
   1185   // Leafs.
   1186   // Punctuation like comma, dot, ellipses.
   1187   PUNCTUATION: 'punctuation',
   1188   // Fence symbol.
   1189   FENCE: 'fence',
   1190   // One or several digits, plus some punctuation.
   1191   NUMBER: 'number',
   1192   // Single or multiple letters.
   1193   IDENTIFIER: 'identifier',
   1194   // Regular text in a math expression.
   1195   TEXT: 'text',
   1196   // e.g. +, *.
   1197   OPERATOR: 'operator',
   1198   // Relation symbol, e.g. equals.
   1199   RELATION: 'relation',
   1200   // e.g. Sum, product, integral.
   1201   LARGEOP: 'largeop',
   1202   // Some named function.
   1203   FUNCTION: 'function',
   1204 
   1205   // Branches.
   1206   // Compound Symbols.
   1207   ACCENT: 'accent',
   1208   FENCED: 'fenced',
   1209   FRACTION: 'fraction',
   1210   PUNCTUATED: 'punctuated',
   1211 
   1212   // Relations.
   1213   // Relation sequence of a single relation.
   1214   RELSEQ: 'relseq',
   1215   // Relation sequence containing at least two different relations.
   1216   MULTIREL: 'multirel',
   1217   // Operations.
   1218   INFIXOP: 'infixop',
   1219   PREFIXOP: 'prefixop',
   1220   POSTFIXOP: 'postfixop',
   1221 
   1222   // Function and Bigop Application.
   1223   APPL: 'appl',
   1224   INTEGRAL: 'integral',
   1225   BIGOP: 'bigop',
   1226 
   1227   SQRT: 'sqrt',
   1228   ROOT: 'root',
   1229   // These are bigops or functions with limits.
   1230   LIMUPPER: 'limupper',
   1231   LIMLOWER: 'limlower',
   1232   LIMBOTH: 'limboth',
   1233   SUBSCRIPT: 'subscript',
   1234   SUPERSCRIPT: 'superscript',
   1235   UNDERSCORE: 'underscore',
   1236   OVERSCORE: 'overscore',
   1237 
   1238   // Tables and their elements.
   1239   TABLE: 'table',
   1240   MULTILINE: 'multiline',
   1241   MATRIX: 'matrix',
   1242   VECTOR: 'vector',
   1243   CASES: 'cases',
   1244   ROW: 'row',
   1245   // Lines are effectively single cell rows.
   1246   LINE: 'line',
   1247   CELL: 'cell',
   1248 
   1249   // General.
   1250   UNKNOWN: 'unknown',
   1251   EMPTY: 'empty'
   1252 };
   1253 
   1254 
   1255 /**
   1256  * Mapping for roles of nodes.
   1257  * Roles are more specific than types.
   1258  * @enum {string}
   1259  */
   1260 cvox.SemanticAttr.Role = {
   1261   // Punctuation.
   1262   ELLIPSIS: 'ellipsis',
   1263   FULLSTOP: 'fullstop',
   1264   DASH: 'dash',
   1265   PRIME: 'prime',   // Superscript.
   1266   VBAR: 'vbar',  // A vertical bar.
   1267   OPENFENCE: 'openfence',
   1268   CLOSEFENCE: 'closefence',
   1269   APPLICATION: 'application', // Function Application.
   1270 
   1271   // Fences.
   1272   OPEN: 'open',
   1273   CLOSE: 'close',
   1274   TOP: 'top',
   1275   BOTTOM: 'bottom',
   1276   NEUTRAL: 'neutral',
   1277 
   1278   // Letters.
   1279   LATINLETTER: 'latinletter',
   1280   GREEKLETTER: 'greekletter',
   1281   OTHERLETTER: 'otherletter',
   1282 
   1283   // Numbers.
   1284   INTEGER: 'integer',
   1285   FLOAT: 'float',
   1286   OTHERNUMBER: 'othernumber',
   1287 
   1288   // Accents.
   1289   MULTIACCENT: 'multiaccent',
   1290   OVERACCENT: 'overaccent',
   1291   UNDERACCENT: 'underaccent',
   1292 
   1293   // Fenced.
   1294   LEFTRIGHT: 'leftright',
   1295   ABOVEBELOW: 'abovebelow',
   1296 
   1297   // Punctuated elements.
   1298   SEQUENCE: 'sequence',
   1299   ENDPUNCT: 'endpunct',
   1300   STARTPUNCT: 'startpunct',
   1301 
   1302   // Operators.
   1303   NEGATIVE: 'negative',
   1304   NEGATION: 'negation',
   1305   MULTIOP: 'multiop',
   1306 
   1307   // Functions.
   1308   LIMFUNC: 'limit function',
   1309   INFIXFUNC: 'infix function',
   1310   PREFIXFUNC: 'prefix function',
   1311   POSTFIXFUNC: 'postfix function',
   1312 
   1313   // Large operators.
   1314   SUM: 'sum',
   1315   INTEGRAL: 'integral',
   1316 
   1317   // Binary operations.
   1318   ADDITION: 'addition',
   1319   MULTIPLICATION: 'multiplication',
   1320   DIVISION: 'division',
   1321   SUBTRACTION: 'subtraction',
   1322   IMPLICIT: 'implicit',
   1323 
   1324   // Relations.
   1325   EQUALITY: 'equality',
   1326   INEQUALITY: 'inequality',
   1327   ELEMENT: 'element',
   1328   BINREL: 'binrel',
   1329   ARROW: 'arrow',
   1330 
   1331   // Roles of rows, lines, cells.
   1332   // They mirror the different types for tables.
   1333   MULTILINE: 'multiline',
   1334   MATRIX: 'matrix',
   1335   VECTOR: 'vector',
   1336   CASES: 'cases',
   1337   TABLE: 'table',
   1338 
   1339   // General
   1340   UNKNOWN: 'unknown'
   1341 };
   1342 
   1343 
   1344 /**
   1345  * Mapping for font annotations. (Taken from MathML2 section 3.2.2, with the
   1346  * exception of double-struck-italic.)
   1347  * @enum {string}
   1348  */
   1349 cvox.SemanticAttr.Font = {
   1350   BOLD: 'bold',
   1351   BOLDFRAKTUR: 'bold-fraktur',
   1352   BOLDITALIC: 'bold-italic',
   1353   BOLDSCRIPT: 'bold-script',
   1354   DOUBLESTRUCK: 'double-struck',
   1355   DOUBLESTRUCKITALIC: 'double-struck-italic',
   1356   FRAKTUR: 'fraktur',
   1357   ITALIC: 'italic',
   1358   MONOSPACE: 'monospace',
   1359   NORMAL: 'normal',
   1360   SCRIPT: 'script',
   1361   SANSSERIF: 'sans-serif',
   1362   SANSSERIFITALIC: 'sans-serif-italic',
   1363   SANSSERIFBOLD: 'sans-serif-bold',
   1364   SANSSERIFBOLDITALIC: 'sans-serif-bold-italic',
   1365   UNKNOWN: 'unknown'
   1366 };
   1367 
   1368 
   1369 /**
   1370  * Lookup the semantic type of a symbol.
   1371  * @param {string} symbol The symbol to which we want to determine the type.
   1372  * @return {cvox.SemanticAttr.Type} The semantic type of the symbol.
   1373  */
   1374 cvox.SemanticAttr.prototype.lookupType = function(symbol) {
   1375   return cvox.SemanticAttr.Type.UNKNOWN;
   1376 };
   1377 
   1378 
   1379 /**
   1380  * Lookup the semantic role of a symbol.
   1381  * @param {string} symbol The symbol to which we want to determine the role.
   1382  * @return {cvox.SemanticAttr.Role} The semantic role of the symbol.
   1383  */
   1384 cvox.SemanticAttr.prototype.lookupRole = function(symbol) {
   1385   return cvox.SemanticAttr.Role.UNKNOWN;
   1386 };
   1387 
   1388 
   1389 /**
   1390  * Lookup the semantic meaning of a symbol in terms of type and role.
   1391  * @param {string} symbol The symbol to which we want to determine the meaning.
   1392  * @return {{role: cvox.SemanticAttr.Role,
   1393  *           type: cvox.SemanticAttr.Type}} The semantic meaning of the symbol.
   1394  */
   1395 cvox.SemanticAttr.lookupMeaning = function(symbol) {
   1396   return cvox.SemanticAttr.getInstance().lookupMeaning_(symbol);
   1397 };
   1398 
   1399 
   1400 /**
   1401  * String representation of the invisible times unicode character.
   1402  * @return {string} The invisible times character.
   1403  */
   1404 cvox.SemanticAttr.invisibleTimes = function() {
   1405   return cvox.SemanticAttr.getInstance().invisibleTimes_;
   1406 };
   1407 
   1408 
   1409 /**
   1410  * String representation of the invisible comma unicode character.
   1411  * @return {string} The invisible comma character.
   1412  */
   1413 cvox.SemanticAttr.invisibleComma = function() {
   1414   return cvox.SemanticAttr.getInstance().invisibleComma_;
   1415 };
   1416 
   1417 
   1418 /**
   1419  * String representation of the function application character.
   1420  * @return {string} The invisible function application character.
   1421  */
   1422 cvox.SemanticAttr.functionApplication = function() {
   1423   return cvox.SemanticAttr.getInstance().functionApplication_;
   1424 };
   1425 
   1426 
   1427 /**
   1428  * Decide when two fences match. Currently we match any right to left
   1429  * or bottom to top fence and neutral to neutral.
   1430  * @param {cvox.SemanticAttr.Role} open Opening fence.
   1431  * @param {cvox.SemanticAttr.Role} close Closing fence.
   1432  * @return {boolean} True if the fences are matching.
   1433  */
   1434 cvox.SemanticAttr.isMatchingFenceRole = function(open, close) {
   1435   return (open == cvox.SemanticAttr.Role.OPEN &&
   1436       close == cvox.SemanticAttr.Role.CLOSE) ||
   1437           (open == cvox.SemanticAttr.Role.NEUTRAL &&
   1438               close == cvox.SemanticAttr.Role.NEUTRAL) ||
   1439                   (open == cvox.SemanticAttr.Role.TOP &&
   1440                       close == cvox.SemanticAttr.Role.BOTTOM);
   1441 };
   1442 
   1443 
   1444 /**
   1445  * Decide when opening and closing fences match. For neutral fences they have to
   1446  * be the same.
   1447  * @param {string} open Opening fence.
   1448  * @param {string} close Closing fence.
   1449  * @return {boolean} True if the fences are matching.
   1450  */
   1451 cvox.SemanticAttr.isMatchingFence = function(open, close) {
   1452   return cvox.SemanticAttr.getInstance().isMatchingFence_(open, close);
   1453 };
   1454 
   1455 
   1456 /**
   1457  * Determines if a fence is an opening fence.
   1458  * @param {cvox.SemanticAttr.Role} fence Opening fence.
   1459  * @return {boolean} True if the fence is open or neutral.
   1460  */
   1461 cvox.SemanticAttr.isOpeningFence = function(fence) {
   1462   return (fence == cvox.SemanticAttr.Role.OPEN ||
   1463           fence == cvox.SemanticAttr.Role.NEUTRAL);
   1464 };
   1465 
   1466 
   1467 /**
   1468  * Determines if a fence is a closing fence.
   1469  * @param {cvox.SemanticAttr.Role} fence Closing fence.
   1470  * @return {boolean} True if the fence is close or neutral.
   1471  */
   1472 cvox.SemanticAttr.isClosingFence = function(fence) {
   1473   return (fence == cvox.SemanticAttr.Role.CLOSE ||
   1474           fence == cvox.SemanticAttr.Role.NEUTRAL);
   1475 };
   1476 
   1477 
   1478 // TODO (sorge) Make this depended on position in the alphabets.
   1479 /**
   1480  * Check if a character is a small 'd' in some font.
   1481  * @param {!string} chr The character string.
   1482  * @return {boolean} True if the character is indeed a single small d.
   1483  */
   1484 cvox.SemanticAttr.isCharacterD = function(chr) {
   1485   var Ds = ['d', '', '', '', '', '', '', '',
   1486             '', '', '', '', '', ''];
   1487   return Ds.indexOf(chr) != -1;
   1488 };
   1489 
   1490 
   1491 /**
   1492  * Decide when opening and closing fences match. For neutral fences they have to
   1493  * be the same.
   1494  * @param {!string} open Opening fence.
   1495  * @param {!string} close Closing fence.
   1496  * @return {boolean} True if the fences are matching.
   1497  * @private
   1498  */
   1499 cvox.SemanticAttr.prototype.isMatchingFence_ = function(open, close) {
   1500   if (this.neutralFences.indexOf(open) != -1) {
   1501     return open == close;
   1502   }
   1503   return this.openClosePairs[open] == close ||
   1504       this.topBottomPairs[open] == close;
   1505 };
   1506 
   1507 
   1508 /**
   1509  * Lookup the semantic meaning of a symbol in terms of type and role.
   1510  * @param {!string} symbol The symbol to which we want to determine the meaning.
   1511  * @return {{role: cvox.SemanticAttr.Role,
   1512  *           type: cvox.SemanticAttr.Type,
   1513  *           font: cvox.SemanticAttr.Font}} The semantic meaning of the symbol.
   1514  * @private
   1515  */
   1516 cvox.SemanticAttr.prototype.lookupMeaning_ = function(symbol) {
   1517   for (var i = 0, set; set = this.symbolSetToSemantic_[i]; i++) {
   1518     if (set.set.indexOf(symbol) != -1) {
   1519       return {role: set.role || cvox.SemanticAttr.Role.UNKNOWN,
   1520               type: set.type || cvox.SemanticAttr.Type.UNKNOWN,
   1521               font: set.font || cvox.SemanticAttr.Font.UNKNOWN
   1522              };
   1523     }
   1524   }
   1525   return {role: cvox.SemanticAttr.Role.UNKNOWN,
   1526           type: cvox.SemanticAttr.Type.UNKNOWN,
   1527           font: cvox.SemanticAttr.Font.UNKNOWN
   1528          };
   1529 };
   1530