// 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 Semantic attributes of Math symbols and expressions. * * This file contains the basic functionality to lookup and assign semantic * attributes for mathematical expressions. Since there is no such thing as a * well-defined semantics for all of mathematics we compute a default semantics * that closely models mathematical expressions found in K-12 mathematics as * well as in general undergraduate curriculum (i.e., calculus, linear algebra, * etc). * * Currently semantic attributes of symbols consist of the following two parts: * * type -- An unmutable property of an expression, regardless of its position in * the math expression. For example, the letter 'f' will always have the * type identifier, regardless of its use in context, e.g. as function * symbol or variable. * * role -- A mutable description of the role an expression plays in the context * of the overall mathematical expression. For instance, the symbol '|' * is of type punctuation, but depending on context it has the role of a * neutral fence or of a single vertical bar. * * In addition for some symbols we record the font as a further attribute. * * When a semantically interpreted expression is transformed into a XML * representation, types become tag names, while role, font, etc. are added as * attributes. * * This file is part of the content script as we do not want to call out to the * background page every time we need to look up the semantic of a symbol. * * TODO (sorge) Move semantic tree translation into the background page * alongside MathJax. * */ goog.provide('cvox.SemanticAttr'); goog.require('cvox.SemanticUtil'); /** * Contains the basic mappings of characters/symbols and functions to semantic * attributes. * * Observe that all characters are given as hex code number in order to ease the * comparison with those in the JSON files that define speech rules per * character. * @constructor */ cvox.SemanticAttr = function() { // Punctuation Characters. /** * @type {Array} */ this.generalPunctuations = [ '!', '"', '#', '%', '&', '\'', '*', ',', ':', ';', '?', '@', '\\', '¡', '§', '¶', '·', '¿', '‗', '†', '‡', '•', '‣', '․', '‥', '‧', '‰', '‱', '‸', '※', '‼', '‽', '‾', '⁁', '⁂', '⁃', '⁇', '⁈', '⁉', '⁋', '⁌', '⁍', '⁎', '⁏', '⁐', '⁑', '⁓', '⁕', '⁖', '⁘', '⁙', '⁚', '⁛', '⁜', '⁝', '⁞', '︐', '︓', '︔', '︕', '︖', '︰', '﹅', '﹆', '﹉', '﹊', '﹋', '﹌', '﹐', '﹔', '﹕', '﹖', '﹗', '﹟', '﹠', '﹡', '﹨', '﹪', '﹫', '!', '"', '#', '%', '&', ''', '*', ',', '/', ':', ';', '?', '@', '\' ]; /** * @type {string} * @private */ this.invisibleComma_ = cvox.SemanticUtil.numberToUnicode(0x2063); this.generalPunctuations.push(this.invisibleComma_); /** * @type {Array} */ this.ellipses = [ '…', '⋮', '⋯', '⋰', '⋱', '︙' ]; /** * @type {Array} */ this.fullStops = [ '.', '﹒', '.' ]; /** * @type {Array} */ this.dashes = [ '‒', '–', '—', '―', '〜', '︱', '︲', '﹘' ]; /** * @type {Array} */ this.primes = [ '′', '″', '‴', '‵', '‶', '‷', '⁗' ]; // Fences. // Fences are treated slightly differently from other symbols as we want to // record pairs of opening/closing and top/bottom fences. /** * Mapping opening to closing fences. * @type {Object} */ this.openClosePairs = { // Unicode categories Ps and Pe. // Observe that left quotation 301D could also be matched to 301F, // but is currently matched to 301E. '(': ')', '[': ']', '{': '}', '⁅': '⁆', '〈': '〉', '❨': '❩', '❪': '❫', '❬': '❭', '❮': '❯', '❰': '❱', '❲': '❳', '❴': '❵', '⟅': '⟆', '⟦': '⟧', '⟨': '⟩', '⟪': '⟫', '⟬': '⟭', '⟮': '⟯', '⦃': '⦄', '⦅': '⦆', '⦇': '⦈', '⦉': '⦊', '⦋': '⦌', '⦍': '⦎', '⦏': '⦐', '⦑': '⦒', '⦓': '⦔', '⦕': '⦖', '⦗': '⦘', '⧘': '⧙', '⧚': '⧛', '⧼': '⧽', '⸢': '⸣', '⸤': '⸥', '⸦': '⸧', '⸨': '⸩', '〈': '〉', '《': '》', '「': '」', '『': '』', '【': '】', '〔': '〕', '〖': '〗', '〘': '〙', '〚': '〛', '〝': '〞', '﴾': '﴿', '︗': '︘', '﹙': '﹚', '﹛': '﹜', '﹝': '﹞', '(': ')', '[': ']', '{': '}', '⦅': '⦆', '「': '」', // Unicode categories Sm and So. '⌈': '⌉', '⌊': '⌋', '⌌': '⌍', '⌎': '⌏', '⌜': '⌝', '⌞': '⌟', // Extender fences. // Parenthesis. '⎛': '⎞', '⎜': '⎟', '⎝': '⎠', // Square bracket. '⎡': '⎤', '⎢': '⎥', '⎣': '⎦', // Curly bracket. '⎧': '⎫', '⎨': '⎬', '⎩': '⎭', '⎰': '⎱', '⎸': '⎹' }; /** * Mapping top to bottom fences. * @type {Object} */ this.topBottomPairs = { '⎴': '⎵', '⏜': '⏝', '⏞': '⏟', '⏠': '⏡', '︵': '︶', '︷': '︸', '︹': '︺', '︻': '︼', '︽': '︾', '︿': '﹀', '﹁': '﹂', '﹃': '﹄', '﹇': '﹈' }; /** * @type {Array} */ this.leftFences = cvox.SemanticUtil.objectsToKeys(this.openClosePairs); /** * @type {Array} */ this.rightFences = cvox.SemanticUtil.objectsToValues(this.openClosePairs); this.rightFences.push('〟'); /** * @type {Array} */ this.topFences = cvox.SemanticUtil.objectsToKeys(this.topBottomPairs); /** * @type {Array} */ this.bottomFences = cvox.SemanticUtil.objectsToValues(this.topBottomPairs); /** * @type {Array} */ this.neutralFences = [ '|', '¦', '‖', '❘', '⦀', '⫴', '¦', '|' ]; /** Array of all fences. * @type {Array} */ this.fences = this.neutralFences.concat( this.leftFences, this.rightFences, this.topFences, this.bottomFences); // Identifiers. // Latin Alphabets. /** * @type {Array} */ this.capitalLatin = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]; /** * @type {Array} */ this.smallLatin = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', // dotless i and j. 'ı', 'ȷ' ]; /** * @type {Array} */ this.capitalLatinFullWidth = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]; /** * @type {Array} */ this.smallLatinFullWidth = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ]; /** * @type {Array} */ this.capitalLatinBold = [ '𝐀', '𝐁', '𝐂', '𝐃', '𝐄', '𝐅', '𝐆', '𝐇', '𝐈', '𝐉', '𝐊', '𝐋', '𝐌', '𝐍', '𝐎', '𝐏', '𝐐', '𝐑', '𝐒', '𝐓', '𝐔', '𝐕', '𝐖', '𝐗', '𝐘', '𝐙' ]; /** * @type {Array} */ this.smallLatinBold = [ '𝐚', '𝐛', '𝐜', '𝐝', '𝐞', '𝐟', '𝐠', '𝐡', '𝐢', '𝐣', '𝐤', '𝐥', '𝐦', '𝐧', '𝐨', '𝐩', '𝐪', '𝐫', '𝐬', '𝐭', '𝐮', '𝐯', '𝐰', '𝐱', '𝐲', '𝐳' ]; /** * @type {Array} */ this.capitalLatinItalic = [ '𝐴', '𝐵', '𝐶', '𝐷', '𝐸', '𝐹', '𝐺', '𝐻', '𝐼', '𝐽', '𝐾', '𝐿', '𝑀', '𝑁', '𝑂', '𝑃', '𝑄', '𝑅', '𝑆', '𝑇', '𝑈', '𝑉', '𝑊', '𝑋', '𝑌', '𝑍' ]; /** * @type {Array} */ this.smallLatinItalic = [ '𝑎', '𝑏', '𝑐', '𝑑', '𝑒', '𝑓', '𝑔', 'ℎ', '𝑖', '𝑗', '𝑘', '𝑙', '𝑚', '𝑛', '𝑜', '𝑝', '𝑞', '𝑟', '𝑠', '𝑡', '𝑢', '𝑣', '𝑤', '𝑥', '𝑦', '𝑧', // dotless i and j. '𝚤', '𝚥' ]; /** * @type {Array} */ this.capitalLatinScript = [ '𝒜', 'ℬ', '𝒞', '𝒟', 'ℰ', 'ℱ', '𝒢', 'ℋ', 'ℐ', '𝒥', '𝒦', 'ℒ', 'ℳ', '𝒩', '𝒪', '𝒫', '𝒬', 'ℛ', '𝒮', '𝒯', '𝒰', '𝒱', '𝒲', '𝒳', '𝒴', '𝒵', // Powerset Cap P. '℘' ]; /** * @type {Array} */ this.smallLatinScript = [ '𝒶', '𝒷', '𝒸', '𝒹', 'ℯ', '𝒻', 'ℊ', '𝒽', '𝒾', '𝒿', '𝓀', '𝓁', '𝓂', '𝓃', 'ℴ', '𝓅', '𝓆', '𝓇', '𝓈', '𝓉', '𝓊', '𝓋', '𝓌', '𝓍', '𝓎', '𝓏', // script small l 'ℓ' ]; /** * @type {Array} */ this.capitalLatinBoldScript = [ '𝓐', '𝓑', '𝓒', '𝓓', '𝓔', '𝓕', '𝓖', '𝓗', '𝓘', '𝓙', '𝓚', '𝓛', '𝓜', '𝓝', '𝓞', '𝓟', '𝓠', '𝓡', '𝓢', '𝓣', '𝓤', '𝓥', '𝓦', '𝓧', '𝓨', '𝓩' ]; /** * @type {Array} */ this.smallLatinBoldScript = [ '𝓪', '𝓫', '𝓬', '𝓭', '𝓮', '𝓯', '𝓰', '𝓱', '𝓲', '𝓳', '𝓴', '𝓵', '𝓶', '𝓷', '𝓸', '𝓹', '𝓺', '𝓻', '𝓼', '𝓽', '𝓾', '𝓿', '𝔀', '𝔁', '𝔂', '𝔃' ]; /** * @type {Array} */ this.capitalLatinFraktur = [ '𝔄', '𝔅', 'ℭ', '𝔇', '𝔈', '𝔉', '𝔊', 'ℌ', 'ℑ', '𝔍', '𝔎', '𝔏', '𝔐', '𝔑', '𝔒', '𝔓', '𝔔', 'ℜ', '𝔖', '𝔗', '𝔘', '𝔙', '𝔚', '𝔛', '𝔜', 'ℨ' ]; /** * @type {Array} */ this.smallLatinFraktur = [ '𝔞', '𝔟', '𝔠', '𝔡', '𝔢', '𝔣', '𝔤', '𝔥', '𝔦', '𝔧', '𝔨', '𝔩', '𝔪', '𝔫', '𝔬', '𝔭', '𝔮', '𝔯', '𝔰', '𝔱', '𝔲', '𝔳', '𝔴', '𝔵', '𝔶', '𝔷' ]; /** * @type {Array} */ this.capitalLatinDoubleStruck = [ '𝔸', '𝔹', 'ℂ', '𝔻', '𝔼', '𝔽', '𝔾', 'ℍ', '𝕀', '𝕁', '𝕂', '𝕃', '𝕄', 'ℕ', '𝕆', 'ℙ', 'ℚ', 'ℝ', '𝕊', '𝕋', '𝕌', '𝕍', '𝕎', '𝕏', '𝕐', 'ℤ' ]; /** * @type {Array} */ this.smallLatinDoubleStruck = [ '𝕒', '𝕓', '𝕔', '𝕕', '𝕖', '𝕗', '𝕘', '𝕙', '𝕚', '𝕛', '𝕜', '𝕝', '𝕞', '𝕟', '𝕠', '𝕡', '𝕢', '𝕣', '𝕤', '𝕥', '𝕦', '𝕧', '𝕨', '𝕩', '𝕪', '𝕫' ]; /** * @type {Array} */ this.capitalLatinBoldFraktur = [ '𝕬', '𝕭', '𝕮', '𝕯', '𝕰', '𝕱', '𝕲', '𝕳', '𝕴', '𝕵', '𝕶', '𝕷', '𝕸', '𝕹', '𝕺', '𝕻', '𝕼', '𝕽', '𝕾', '𝕿', '𝖀', '𝖁', '𝖂', '𝖃', '𝖄', '𝖅' ]; /** * @type {Array} */ this.smallLatinBoldFraktur = [ '𝖆', '𝖇', '𝖈', '𝖉', '𝖊', '𝖋', '𝖌', '𝖍', '𝖎', '𝖏', '𝖐', '𝖑', '𝖒', '𝖓', '𝖔', '𝖕', '𝖖', '𝖗', '𝖘', '𝖙', '𝖚', '𝖛', '𝖜', '𝖝', '𝖞', '𝖟' ]; /** * @type {Array} */ this.capitalLatinSansSerif = [ '𝖠', '𝖡', '𝖢', '𝖣', '𝖤', '𝖥', '𝖦', '𝖧', '𝖨', '𝖩', '𝖪', '𝖫', '𝖬', '𝖭', '𝖮', '𝖯', '𝖰', '𝖱', '𝖲', '𝖳', '𝖴', '𝖵', '𝖶', '𝖷', '𝖸', '𝖹' ]; /** * @type {Array} */ this.smallLatinSansSerif = [ '𝖺', '𝖻', '𝖼', '𝖽', '𝖾', '𝖿', '𝗀', '𝗁', '𝗂', '𝗃', '𝗄', '𝗅', '𝗆', '𝗇', '𝗈', '𝗉', '𝗊', '𝗋', '𝗌', '𝗍', '𝗎', '𝗏', '𝗐', '𝗑', '𝗒', '𝗓' ]; /** * @type {Array} */ this.capitalLatinSansSerifBold = [ '𝗔', '𝗕', '𝗖', '𝗗', '𝗘', '𝗙', '𝗚', '𝗛', '𝗜', '𝗝', '𝗞', '𝗟', '𝗠', '𝗡', '𝗢', '𝗣', '𝗤', '𝗥', '𝗦', '𝗧', '𝗨', '𝗩', '𝗪', '𝗫', '𝗬', '𝗭' ]; /** * @type {Array} */ this.smallLatinSansSerifBold = [ '𝗮', '𝗯', '𝗰', '𝗱', '𝗲', '𝗳', '𝗴', '𝗵', '𝗶', '𝗷', '𝗸', '𝗹', '𝗺', '𝗻', '𝗼', '𝗽', '𝗾', '𝗿', '𝘀', '𝘁', '𝘂', '𝘃', '𝘄', '𝘅', '𝘆', '𝘇' ]; /** * @type {Array} */ this.capitalLatinSansSerifItalic = [ '𝘈', '𝘉', '𝘊', '𝘋', '𝘌', '𝘍', '𝘎', '𝘏', '𝘐', '𝘑', '𝘒', '𝘓', '𝘔', '𝘕', '𝘖', '𝘗', '𝘘', '𝘙', '𝘚', '𝘛', '𝘜', '𝘝', '𝘞', '𝘟', '𝘠', '𝘡' ]; /** * @type {Array} */ this.smallLatinSansSerifItalic = [ '𝘢', '𝘣', '𝘤', '𝘥', '𝘦', '𝘧', '𝘨', '𝘩', '𝘪', '𝘫', '𝘬', '𝘭', '𝘮', '𝘯', '𝘰', '𝘱', '𝘲', '𝘳', '𝘴', '𝘵', '𝘶', '𝘷', '𝘸', '𝘹', '𝘺', '𝘻' ]; /** * @type {Array} */ this.capitalLatinMonospace = [ '𝙰', '𝙱', '𝙲', '𝙳', '𝙴', '𝙵', '𝙶', '𝙷', '𝙸', '𝙹', '𝙺', '𝙻', '𝙼', '𝙽', '𝙾', '𝙿', '𝚀', '𝚁', '𝚂', '𝚃', '𝚄', '𝚅', '𝚆', '𝚇', '𝚈', '𝚉' ]; /** * @type {Array} */ this.smallLatinMonospace = [ '𝚊', '𝚋', '𝚌', '𝚍', '𝚎', '𝚏', '𝚐', '𝚑', '𝚒', '𝚓', '𝚔', '𝚕', '𝚖', '𝚗', '𝚘', '𝚙', '𝚚', '𝚛', '𝚜', '𝚝', '𝚞', '𝚟', '𝚠', '𝚡', '𝚢', '𝚣' ]; /** * @type {Array} */ this.latinDoubleStruckItalic = [ 'ⅅ', 'ⅆ', 'ⅇ', 'ⅈ', 'ⅉ' ]; // Greek Alphabets /** * @type {Array} */ this.capitalGreek = [ 'Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', 'Π', 'Ρ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω' ]; /** * @type {Array} */ this.smallGreek = [ 'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'ς', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω' ]; /** * @type {Array} */ this.capitalGreekBold = [ '𝚨', '𝚩', '𝚪', '𝚫', '𝚬', '𝚭', '𝚮', '𝚯', '𝚰', '𝚱', '𝚲', '𝚳', '𝚴', '𝚵', '𝚶', '𝚷', '𝚸', '𝚺', '𝚻', '𝚼', '𝚽', '𝚾', '𝚿', '𝛀' ]; /** * @type {Array} */ this.smallGreekBold = [ '𝛂', '𝛃', '𝛄', '𝛅', '𝛆', '𝛇', '𝛈', '𝛉', '𝛊', '𝛋', '𝛌', '𝛍', '𝛎', '𝛏', '𝛐', '𝛑', '𝛒', '𝛓', '𝛔', '𝛕', '𝛖', '𝛗', '𝛘', '𝛙', '𝛚' ]; /** * @type {Array} */ this.capitalGreekItalic = [ '𝛢', '𝛣', '𝛤', '𝛥', '𝛦', '𝛧', '𝛨', '𝛩', '𝛪', '𝛫', '𝛬', '𝛭', '𝛮', '𝛯', '𝛰', '𝛱', '𝛲', '𝛴', '𝛵', '𝛶', '𝛷', '𝛸', '𝛹', '𝛺' ]; /** * @type {Array} */ this.smallGreekItalic = [ '𝛼', '𝛽', '𝛾', '𝛿', '𝜀', '𝜁', '𝜂', '𝜃', '𝜄', '𝜅', '𝜆', '𝜇', '𝜈', '𝜉', '𝜊', '𝜋', '𝜌', '𝜍', '𝜎', '𝜏', '𝜐', '𝜑', '𝜒', '𝜓', '𝜔' ]; /** * @type {Array} */ this.capitalGreekSansSerifBold = [ '𝝖', '𝝗', '𝝘', '𝝙', '𝝚', '𝝛', '𝝜', '𝝝', '𝝞', '𝝟', '𝝠', '𝝡', '𝝢', '𝝣', '𝝤', '𝝥', '𝝦', '𝝨', '𝝩', '𝝪', '𝝫', '𝝬', '𝝭', '𝝮' ]; /** * @type {Array} */ this.smallGreekSansSerifBold = [ '𝝰', '𝝱', '𝝲', '𝝳', '𝝴', '𝝵', '𝝶', '𝝷', '𝝸', '𝝹', '𝝺', '𝝻', '𝝼', '𝝽', '𝝾', '𝝿', '𝞀', '𝞁', '𝞂', '𝞃', '𝞄', '𝞅', '𝞆', '𝞇', '𝞈' ]; /** * @type {Array} */ this.greekDoubleStruck = [ 'ℼ', 'ℽ', 'ℾ', 'ℿ' ]; // Other alphabets. /** * @type {Array} */ this.hebrewLetters = [ 'ℵ', 'ℶ', 'ℷ', 'ℸ' ]; //Operator symbols /** * @type {Array} */ this.additions = [ '+', '±', '∓', '∔', '∧', '∨', '∩', '∪', '⊌', '⊓', '⊔', '⊝', '⊞', '⊤', '⊥', '⊺', '⊻', '⊼', '⋄', '⋎', '⋏', '⋒', '⋓', '△', '▷', '▽', '◁', '⩞', '⊕' ]; /** * @type {Array} */ /** * Invisible operator for plus. * @type {string} * @private */ this.invisiblePlus_ = cvox.SemanticUtil.numberToUnicode(0x2064); this.additions.push(this.invisiblePlus_); /** * @type {Array} */ this.multiplications = [ '†', '‡', '∐', '∗', '∘', '∙', '≀', '⊚', '⊛', '⊠', '⊡', '⋅', '⋆', '⋇', '⋉', '⋊', '⋋', '⋌', '○' ]; /** * Invisible operator for multiplication. * @type {string} * @private */ this.invisibleTimes_ = cvox.SemanticUtil.numberToUnicode(0x2062); this.multiplications.push(this.invisibleTimes_); /** * @type {Array} */ this.subtractions = [ '-', '⁒', '⁻', '₋', '−', '∖', '∸', '≂', '⊖', '⊟', '➖', '⨩', '⨪', '⨫', '⨬', '⨺', '⩁', '⩬', '﹣', '-', '‐', '‑' ]; /** * @type {Array} */ this.divisions = [ '/', '÷', '⁄', '∕', '⊘', '⟌', '⦼', '⨸' ]; /** * Invisible operator for function application. * @type {string} * @private */ this.functionApplication_ = cvox.SemanticUtil.numberToUnicode(0x2061); //Relation symbols /** * @type {Array} */ this.equalities = [ '=', '~', '⁼', '₌', '∼', '∽', '≃', '≅', '≈', '≊', '≋', '≌', '≍', '≎', '≑', '≒', '≓', '≔', '≕', '≖', '≗', '≘', '≙', '≚', '≛', '≜', '≝', '≞', '≟', '≡', '≣', '⧤', '⩦', '⩮', '⩯', '⩰', '⩱', '⩲', '⩳', '⩴', '⩵', '⩶', '⩷', '⩸', '⋕', '⩭', '⩪', '⩫', '⩬', '﹦', '=' ]; /** * @type {Array} */ this.inequalities = [ '<', '>', '≁', '≂', '≄', '≆', '≇', '≉', '≏', '≐', '≠', '≢', '≤', '≥', '≦', '≧', '≨', '≩', '≪', '≫', '≬', '≭', '≮', '≯', '≰', '≱', '≲', '≳', '≴', '≵', '≶', '≷', '≸', '≹', '≺', '≻', '≼', '≽', '≾', '≿', '⊀', '⊁', '⋖', '⋗', '⋘', '⋙', '⋚', '⋛', '⋜', '⋝', '⋞', '⋟', '⋠', '⋡', '⋢', '⋣', '⋤', '⋥', '⋦', '⋧', '⋨', '⋩', '⩹', '⩺', '⩻', '⩼', '⩽', '⩾', '⩿', '⪀', '⪁', '⪂', '⪃', '⪄', '⪅', '⪆', '⪇', '⪈', '⪉', '⪊', '⪋', '⪌', '⪍', '⪎', '⪏', '⪐', '⪑', '⪒', '⪓', '⪔', '⪕', '⪖', '⪗', '⪘', '⪙', '⪚', '⪛', '⪜', '⪝', '⪞', '⪟', '⪠', '⪡', '⪢', '⪣', '⪤', '⪥', '⪦', '⪧', '⪨', '⪩', '⪪', '⪫', '⪬', '⪭', '⪮', '⪯', '⪰', '⪱', '⪲', '⪳', '⪴', '⪵', '⪶', '⪷', '⪸', '⪹', '⪺', '⪻', '⪼', '⫷', '⫸', '⫹', '⫺', '⧀', '⧁', '﹤', '﹥', '<', '>' ]; /** * @type {Array} */ this.relations = [ // TODO (sorge): Add all the other relations. ]; /** * @type {Array} */ this.arrows = [ '←', '↑', '→', '↓', '↔', '↕', '↖', '↗', '↘', '↙', '↚', '↛', '↜', '↝', '↞', '↟', '↠', '↡', '↢', '↣', '↤', '↥', '↦', '↧', '↨', '↩', '↪', '↫', '↬', '↭', '↮', '↯', '↰', '↱', '↲', '↳', '↴', '↵', '↶', '↷', '↸', '↹', '↺', '↻', '⇄', '⇅', '⇆', '⇇', '⇈', '⇉', '⇊', '⇍', '⇎', '⇏', '⇐', '⇑', '⇒', '⇓', '⇔', '⇕', '⇖', '⇗', '⇘', '⇙', '⇚', '⇛', '⇜', '⇝', '⇞', '⇟', '⇠', '⇡', '⇢', '⇣', '⇤', '⇥', '⇦', '⇧', '⇨', '⇩', '⇪', '⇫', '⇬', '⇭', '⇮', '⇯', '⇰', '⇱', '⇲', '⇳', '⇴', '⇵', '⇶', '⇷', '⇸', '⇹', '⇺', '⇻', '⇼', '⇽', '⇾', '⇿', '⌁', '⌃', '⌄', '⌤', '⎋', '➔', '➘', '➙', '➚', '➛', '➜', '➝', '➞', '➟', '➠', '➡', '➢', '➣', '➤', '➥', '➦', '➧', '➨', '➩', '➪', '➫', '➬', '➭', '➮', '➯', '➱', '➲', '➳', '➴', '➵', '➶', '➷', '➸', '➹', '➺', '➻', '➼', '➽', '➾', '⟰', '⟱', '⟲', '⟳', '⟴', '⟵', '⟶', '⟷', '⟸', '⟹', '⟺', '⟻', '⟼', '⟽', '⟾', '⟿', '⤀', '⤁', '⤂', '⤃', '⤄', '⤅', '⤆', '⤇', '⤈', '⤉', '⤊', '⤋', '⤌', '⤍', '⤎', '⤏', '⤐', '⤑', '⤒', '⤓', '⤔', '⤕', '⤖', '⤗', '⤘', '⤙', '⤚', '⤛', '⤜', '⤝', '⤞', '⤟', '⤠', '⤡', '⤢', '⤣', '⤤', '⤥', '⤦', '⤧', '⤨', '⤩', '⤪', '⤭', '⤮', '⤯', '⤰', '⤱', '⤲', '⤳', '⤴', '⤵', '⤶', '⤷', '⤸', '⤹', '⤺', '⤻', '⤼', '⤽', '⤾', '⤿', '⥀', '⥁', '⥂', '⥃', '⥄', '⥅', '⥆', '⥇', '⥈', '⥉', '⥰', '⥱', '⥲', '⥳', '⥴', '⥵', '⥶', '⥷', '⥸', '⥹', '⥺', '⥻', '⦳', '⦴', '⦽', '⧪', '⧬', '⧭', '⨗', '⬀', '⬁', '⬂', '⬃', '⬄', '⬅', '⬆', '⬇', '⬈', '⬉', '⬊', '⬋', '⬌', '⬍', '⬎', '⬏', '⬐', '⬑', '⬰', '⬱', '⬲', '⬳', '⬴', '⬵', '⬶', '⬷', '⬸', '⬹', '⬺', '⬻', '⬼', '⬽', '⬾', '⬿', '⭀', '⭁', '⭂', '⭃', '⭄', '⭅', '⭆', '⭇', '⭈', '⭉', '⭊', '⭋', '⭌', '←', '↑', '→', '↓', // Harpoons '↼', '↽', '↾', '↿', '⇀', '⇁', '⇂', '⇃', '⇋', '⇌', '⥊', '⥋', '⥌', '⥍', '⥎', '⥏', '⥐', '⥑', '⥒', '⥓', '⥔', '⥕', '⥖', '⥗', '⥘', '⥙', '⥚', '⥛', '⥜', '⥝', '⥞', '⥟', '⥠', '⥡', '⥢', '⥣', '⥤', '⥥', '⥦', '⥧', '⥨', '⥩', '⥪', '⥫', '⥬', '⥭', '⥮', '⥯', '⥼', '⥽', '⥾', '⥿' ]; //Big operation symbols /** * @type {Array} */ this.sumOps = [ '⅀', // double struck '∏', '∐', '∑', '⋀', '⋁', '⋂', '⋃', '⨀', '⨁', '⨂', '⨃', '⨄', '⨅', '⨆', '⨇', '⨈', '⨉', '⨊', '⨋', '⫼', '⫿' ]; /** * @type {Array} */ this.intOps = [ '∫', '∬', '∭', '∮', '∯', '∰', '∱', '∲', '∳', '⨌', '⨍', '⨎', '⨏', '⨐', '⨑', '⨒', '⨓', '⨔', '⨕', '⨖', '⨗', '⨘', '⨙', '⨚', '⨛', '⨜' ]; /** * @type {Array} */ this.prefixOps = // TODO (sorge) Insert nabla, differential operators etc. [ '∀', '∃' ]; /** * @type {Array} */ this.operatorBits = // TODO (sorge) What to do if single glyphs of big ops occur on their own. [ '⌠', '⌡', '⎶', '⎪', '⎮', '⎯', '⎲', '⎳', '⎷' ]; // Accents. // TODO (sorge) Add accented characters. // Numbers. // Digits. /** * @type {Array} */ this.digitsNormal = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; /** * @type {Array} */ this.digitsFullWidth = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; /** * @type {Array} */ this.digitsBold = [ '𝟎', '𝟏', '𝟐', '𝟑', '𝟒', '𝟓', '𝟔', '𝟕', '𝟖', '𝟗' ]; /** * @type {Array} */ this.digitsDoubleStruck = [ '𝟘', '𝟙', '𝟚', '𝟛', '𝟜', '𝟝', '𝟞', '𝟟', '𝟠', '𝟡' ]; /** * @type {Array} */ this.digitsSansSerif = [ '𝟢', '𝟣', '𝟤', '𝟥', '𝟦', '𝟧', '𝟨', '𝟩', '𝟪', '𝟫' ]; /** * @type {Array} */ this.digitsSansSerifBold = [ '𝟬', '𝟭', '𝟮', '𝟯', '𝟰', '𝟱', '𝟲', '𝟳', '𝟴', '𝟵' ]; /** * @type {Array} */ this.digitsMonospace = [ '𝟶', '𝟷', '𝟸', '𝟹', '𝟺', '𝟻', '𝟼', '𝟽', '𝟾', '𝟿' ]; /** * @type {Array} */ this.digitsSuperscript = [ '²', '³', '¹', '⁰', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹' ]; /** * @type {Array} */ this.digitsSubscript = [ '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉' ]; /** * @type {Array} */ this.fractions = [ '¼', '½', '¾', '⅐', '⅑', '⅒', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '↉' ]; /** * @type {Array} */ this.enclosedNumbers = // Encircled numbers. [ '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', '⓪', '⓫', '⓬', '⓭', '⓮', '⓯', '⓰', '⓱', '⓲', '⓳', '⓴', '⓵', '⓶', '⓷', '⓸', '⓹', '⓺', '⓻', '⓼', '⓽', '⓾', '⓿', '❶', '❷', '❸', '❹', '❺', '❻', '❼', '❽', '❾', '❿', '➀', '➁', '➂', '➃', '➄', '➅', '➆', '➇', '➈', '➉', '➊', '➋', '➌', '➍', '➎', '➏', '➐', '➑', '➒', '➓', '㉈', '㉉', '㉊', '㉋', '㉌', '㉍', '㉎', '㉏', '㉑', '㉒', '㉓', '㉔', '㉕', '㉖', '㉗', '㉘', '㉙', '㉚', '㉛', '㉜', '㉝', '㉞', '㉟', '㊱', '㊲', '㊳', '㊴', '㊵', '㊶', '㊷', '㊸', '㊹', '㊺', '㊻', '㊼', '㊽', '㊾', '㊿']; /** * @type {Array} */ this.fencedNumbers = // Numbers in Parenthesis. [ '⑴', '⑵', '⑶', '⑷', '⑸', '⑹', '⑺', '⑻', '⑼', '⑽', '⑾', '⑿', '⒀', '⒁', '⒂', '⒃', '⒄', '⒅', '⒆', '⒇' ]; /** * @type {Array} */ this.punctuatedNumbers = // Numbers with other punctuation. ['⒈', '⒉', '⒊', '⒋', '⒌', '⒍', '⒎', '⒏', '⒐', '⒑', '⒒', '⒓', '⒔', '⒕', '⒖', '⒗', '⒘', '⒙', '⒚', '⒛', // full stop. '🄀', '🄁', '🄂', '🄃', '🄄', '🄅', '🄆', '🄇', '🄈', '🄉', '🄊' // comma. ]; /** Array of all single digits. * @type {Array} */ this.digits = this.digitsNormal.concat( this.digitsFullWidth, this.digitsBold, this.digitsDoubleStruck, this.digitsSansSerif, this.digitsSansSerifBold, this.digitsMonospace); /** Array of all non-digit number symbols. * @type {Array} */ this.numbers = this.fractions.concat( this.digitsSuperscript, this.digitsSubscript, this.enclosedNumbers, this.fencedNumbers, this.punctuatedNumbers); /** Array of all number symbols. * @type {Array} */ this.allNumbers = this.digits.concat(this.numbers); // Functions. /** * @type {Array} */ this.trigonometricFunctions = [ 'cos', 'cot', 'csc', 'sec', 'sin', 'tan', 'arccos', 'arccot', 'arccsc', 'arcsec', 'arcsin', 'arctan' ]; /** * @type {Array} */ this.hyperbolicFunctions = [ 'cosh', 'coth', 'csch', 'sech', 'sinh', 'tanh', 'arcosh', 'arcoth', 'arcsch', 'arsech', 'arsinh', 'artanh', 'arccosh', 'arccoth', 'arccsch', 'arcsech', 'arcsinh', 'arctanh' ]; /** * @type {Array} */ this.algebraicFunctions = [ 'deg', 'det', 'dim', 'hom', 'ker', 'Tr', 'tr' ]; /** * @type {Array} */ this.elementaryFunctions = [ 'log', 'ln', 'lg', 'exp', 'expt', 'gcd', 'gcd', 'arg', 'im', 're', 'Pr' ]; /** All predefined prefix functions. * @type {Array} */ this.prefixFunctions = this.trigonometricFunctions.concat( this.hyperbolicFunctions, this.algebraicFunctions, this.elementaryFunctions ); /** Limit functions are handled separately as they can have lower (and upper) * limiting expressions. * @type {Array} */ this.limitFunctions = [ 'inf', 'lim', 'liminf', 'limsup', 'max', 'min', 'sup', 'injlim', 'projlim' ]; /** * @type {Array} */ this.infixFunctions = [ 'mod', 'rem' ]; /** * Default assignments of semantic attributes. * @type {Array<{set: Array, * role: cvox.SemanticAttr.Role, * type: cvox.SemanticAttr.Type, * font: cvox.SemanticAttr.Font}>} The semantic meaning of the symbol. * @private */ this.symbolSetToSemantic_ = [ // Punctuation {set: this.generalPunctuations, type: cvox.SemanticAttr.Type.PUNCTUATION, role: cvox.SemanticAttr.Role.UNKNOWN }, {set: this.ellipses, type: cvox.SemanticAttr.Type.PUNCTUATION, role: cvox.SemanticAttr.Role.ELLIPSIS }, {set: this.fullStops, type: cvox.SemanticAttr.Type.PUNCTUATION, role: cvox.SemanticAttr.Role.FULLSTOP }, {set: this.dashes, type: cvox.SemanticAttr.Type.PUNCTUATION, role: cvox.SemanticAttr.Role.DASH }, {set: this.primes, type: cvox.SemanticAttr.Type.PUNCTUATION, role: cvox.SemanticAttr.Role.PRIME }, // Fences {set: this.leftFences, type: cvox.SemanticAttr.Type.FENCE, role: cvox.SemanticAttr.Role.OPEN }, {set: this.rightFences, type: cvox.SemanticAttr.Type.FENCE, role: cvox.SemanticAttr.Role.CLOSE }, {set: this.topFences, type: cvox.SemanticAttr.Type.FENCE, role: cvox.SemanticAttr.Role.TOP }, {set: this.bottomFences, type: cvox.SemanticAttr.Type.FENCE, role: cvox.SemanticAttr.Role.BOTTOM }, {set: this.neutralFences, type: cvox.SemanticAttr.Type.FENCE, role: cvox.SemanticAttr.Role.NEUTRAL }, // Single characters. // Latin alphabets. {set: this.smallLatin, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.capitalLatin, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.smallLatinFullWidth, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.capitalLatinFullWidth, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.smallLatinBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLD }, {set: this.capitalLatinBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLD }, {set: this.smallLatinItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.ITALIC }, {set: this.capitalLatinItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.ITALIC }, {set: this.smallLatinScript, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SCRIPT }, {set: this.capitalLatinScript, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SCRIPT }, {set: this.smallLatinBoldScript, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLDSCRIPT }, {set: this.capitalLatinBoldScript, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLDSCRIPT }, {set: this.smallLatinFraktur, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.FRAKTUR }, {set: this.capitalLatinFraktur, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.FRAKTUR }, {set: this.smallLatinDoubleStruck, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.DOUBLESTRUCK }, {set: this.capitalLatinDoubleStruck, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.DOUBLESTRUCK }, {set: this.smallLatinBoldFraktur, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLDFRAKTUR }, {set: this.capitalLatinBoldFraktur, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.BOLDFRAKTUR }, {set: this.smallLatinSansSerif, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIF }, {set: this.capitalLatinSansSerif, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIF }, {set: this.smallLatinSansSerifBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIFBOLD }, {set: this.capitalLatinSansSerifBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIFBOLD }, {set: this.smallLatinSansSerifItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIFITALIC }, {set: this.capitalLatinSansSerifItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.SANSSERIFITALIC }, {set: this.smallLatinMonospace, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.MONOSPACE }, {set: this.capitalLatinMonospace, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.MONOSPACE }, {set: this.latinDoubleStruckItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.LATINLETTER, font: cvox.SemanticAttr.Font.DOUBLESTRUCKITALIC }, // Greek alphabets. {set: this.smallGreek, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.capitalGreek, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.smallGreekBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.BOLD }, {set: this.capitalGreekBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.BOLD }, {set: this.smallGreekItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.ITALIC }, {set: this.capitalGreekItalic, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.ITALIC }, {set: this.smallGreekSansSerifBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.SANSSERIFBOLD }, {set: this.capitalGreekSansSerifBold, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.SANSSERIFBOLD }, {set: this.greekDoubleStruck, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.GREEKLETTER, font: cvox.SemanticAttr.Font.DOUBLESTRUCK }, // Other alphabets. {set: this.hebrewLetters, type: cvox.SemanticAttr.Type.IDENTIFIER, role: cvox.SemanticAttr.Role.OTHERLETTER, font: cvox.SemanticAttr.Font.NORMAL }, // Numbers. {set: this.digitsNormal, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.digitsFullWidth, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.NORMAL }, {set: this.digitsBold, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.BOLD }, {set: this.digitsDoubleStruck, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.DOUBLESTRUCK }, {set: this.digitsSansSerif, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.SANSSERIF }, {set: this.digitsSansSerifBold, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.SANSSERIFBOLD }, {set: this.digitsMonospace, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER, font: cvox.SemanticAttr.Font.MONOSPACE }, {set: this.numbers, type: cvox.SemanticAttr.Type.NUMBER, role: cvox.SemanticAttr.Role.INTEGER }, // Operators. {set: this.additions, type: cvox.SemanticAttr.Type.OPERATOR, role: cvox.SemanticAttr.Role.ADDITION }, {set: this.multiplications, type: cvox.SemanticAttr.Type.OPERATOR, role: cvox.SemanticAttr.Role.MULTIPLICATION }, {set: this.subtractions, type: cvox.SemanticAttr.Type.OPERATOR, role: cvox.SemanticAttr.Role.SUBTRACTION }, {set: this.divisions, type: cvox.SemanticAttr.Type.OPERATOR, role: cvox.SemanticAttr.Role.DIVISION }, {set: this.prefixOps, type: cvox.SemanticAttr.Type.PREFIXOP, role: cvox.SemanticAttr.Role.PREFIXFUNC }, // Relations {set: this.equalities, type: cvox.SemanticAttr.Type.RELATION, role: cvox.SemanticAttr.Role.EQUALITY }, {set: this.inequalities, type: cvox.SemanticAttr.Type.RELATION, role: cvox.SemanticAttr.Role.INEQUALITY }, {set: this.relations, type: cvox.SemanticAttr.Type.RELATION, role: cvox.SemanticAttr.Role.UNKNOWN }, {set: this.arrows, type: cvox.SemanticAttr.Type.RELATION, role: cvox.SemanticAttr.Role.ARROW }, // Large operators {set: this.sumOps, type: cvox.SemanticAttr.Type.LARGEOP, role: cvox.SemanticAttr.Role.SUM}, {set: this.intOps, type: cvox.SemanticAttr.Type.LARGEOP, role: cvox.SemanticAttr.Role.INTEGRAL}, // Functions {set: this.limitFunctions, type: cvox.SemanticAttr.Type.FUNCTION, role: cvox.SemanticAttr.Role.LIMFUNC}, {set: this.prefixFunctions, type: cvox.SemanticAttr.Type.FUNCTION, role: cvox.SemanticAttr.Role.PREFIXFUNC}, {set: this.infixFunctions, type: cvox.SemanticAttr.Type.OPERATOR, role: cvox.SemanticAttr.Role.MULTIPLICATION } // TODO (sorge) Add some of the remaining elements. ]; }; goog.addSingletonGetter(cvox.SemanticAttr); /** * Union type of semantic attributes. * @typedef {cvox.SemanticAttr.Type|cvox.SemanticAttr.Role} */ cvox.SemanticAttr.Attr; /** * Mapping for types of elements. * @enum {string} */ cvox.SemanticAttr.Type = { // Leafs. // Punctuation like comma, dot, ellipses. PUNCTUATION: 'punctuation', // Fence symbol. FENCE: 'fence', // One or several digits, plus some punctuation. NUMBER: 'number', // Single or multiple letters. IDENTIFIER: 'identifier', // Regular text in a math expression. TEXT: 'text', // e.g. +, *. OPERATOR: 'operator', // Relation symbol, e.g. equals. RELATION: 'relation', // e.g. Sum, product, integral. LARGEOP: 'largeop', // Some named function. FUNCTION: 'function', // Branches. // Compound Symbols. ACCENT: 'accent', FENCED: 'fenced', FRACTION: 'fraction', PUNCTUATED: 'punctuated', // Relations. // Relation sequence of a single relation. RELSEQ: 'relseq', // Relation sequence containing at least two different relations. MULTIREL: 'multirel', // Operations. INFIXOP: 'infixop', PREFIXOP: 'prefixop', POSTFIXOP: 'postfixop', // Function and Bigop Application. APPL: 'appl', INTEGRAL: 'integral', BIGOP: 'bigop', SQRT: 'sqrt', ROOT: 'root', // These are bigops or functions with limits. LIMUPPER: 'limupper', LIMLOWER: 'limlower', LIMBOTH: 'limboth', SUBSCRIPT: 'subscript', SUPERSCRIPT: 'superscript', UNDERSCORE: 'underscore', OVERSCORE: 'overscore', // Tables and their elements. TABLE: 'table', MULTILINE: 'multiline', MATRIX: 'matrix', VECTOR: 'vector', CASES: 'cases', ROW: 'row', // Lines are effectively single cell rows. LINE: 'line', CELL: 'cell', // General. UNKNOWN: 'unknown', EMPTY: 'empty' }; /** * Mapping for roles of nodes. * Roles are more specific than types. * @enum {string} */ cvox.SemanticAttr.Role = { // Punctuation. ELLIPSIS: 'ellipsis', FULLSTOP: 'fullstop', DASH: 'dash', PRIME: 'prime', // Superscript. VBAR: 'vbar', // A vertical bar. OPENFENCE: 'openfence', CLOSEFENCE: 'closefence', APPLICATION: 'application', // Function Application. // Fences. OPEN: 'open', CLOSE: 'close', TOP: 'top', BOTTOM: 'bottom', NEUTRAL: 'neutral', // Letters. LATINLETTER: 'latinletter', GREEKLETTER: 'greekletter', OTHERLETTER: 'otherletter', // Numbers. INTEGER: 'integer', FLOAT: 'float', OTHERNUMBER: 'othernumber', // Accents. MULTIACCENT: 'multiaccent', OVERACCENT: 'overaccent', UNDERACCENT: 'underaccent', // Fenced. LEFTRIGHT: 'leftright', ABOVEBELOW: 'abovebelow', // Punctuated elements. SEQUENCE: 'sequence', ENDPUNCT: 'endpunct', STARTPUNCT: 'startpunct', // Operators. NEGATIVE: 'negative', NEGATION: 'negation', MULTIOP: 'multiop', // Functions. LIMFUNC: 'limit function', INFIXFUNC: 'infix function', PREFIXFUNC: 'prefix function', POSTFIXFUNC: 'postfix function', // Large operators. SUM: 'sum', INTEGRAL: 'integral', // Binary operations. ADDITION: 'addition', MULTIPLICATION: 'multiplication', DIVISION: 'division', SUBTRACTION: 'subtraction', IMPLICIT: 'implicit', // Relations. EQUALITY: 'equality', INEQUALITY: 'inequality', ELEMENT: 'element', BINREL: 'binrel', ARROW: 'arrow', // Roles of rows, lines, cells. // They mirror the different types for tables. MULTILINE: 'multiline', MATRIX: 'matrix', VECTOR: 'vector', CASES: 'cases', TABLE: 'table', // General UNKNOWN: 'unknown' }; /** * Mapping for font annotations. (Taken from MathML2 section 3.2.2, with the * exception of double-struck-italic.) * @enum {string} */ cvox.SemanticAttr.Font = { BOLD: 'bold', BOLDFRAKTUR: 'bold-fraktur', BOLDITALIC: 'bold-italic', BOLDSCRIPT: 'bold-script', DOUBLESTRUCK: 'double-struck', DOUBLESTRUCKITALIC: 'double-struck-italic', FRAKTUR: 'fraktur', ITALIC: 'italic', MONOSPACE: 'monospace', NORMAL: 'normal', SCRIPT: 'script', SANSSERIF: 'sans-serif', SANSSERIFITALIC: 'sans-serif-italic', SANSSERIFBOLD: 'sans-serif-bold', SANSSERIFBOLDITALIC: 'sans-serif-bold-italic', UNKNOWN: 'unknown' }; /** * Lookup the semantic type of a symbol. * @param {string} symbol The symbol to which we want to determine the type. * @return {cvox.SemanticAttr.Type} The semantic type of the symbol. */ cvox.SemanticAttr.prototype.lookupType = function(symbol) { return cvox.SemanticAttr.Type.UNKNOWN; }; /** * Lookup the semantic role of a symbol. * @param {string} symbol The symbol to which we want to determine the role. * @return {cvox.SemanticAttr.Role} The semantic role of the symbol. */ cvox.SemanticAttr.prototype.lookupRole = function(symbol) { return cvox.SemanticAttr.Role.UNKNOWN; }; /** * Lookup the semantic meaning of a symbol in terms of type and role. * @param {string} symbol The symbol to which we want to determine the meaning. * @return {{role: cvox.SemanticAttr.Role, * type: cvox.SemanticAttr.Type}} The semantic meaning of the symbol. */ cvox.SemanticAttr.lookupMeaning = function(symbol) { return cvox.SemanticAttr.getInstance().lookupMeaning_(symbol); }; /** * String representation of the invisible times unicode character. * @return {string} The invisible times character. */ cvox.SemanticAttr.invisibleTimes = function() { return cvox.SemanticAttr.getInstance().invisibleTimes_; }; /** * String representation of the invisible comma unicode character. * @return {string} The invisible comma character. */ cvox.SemanticAttr.invisibleComma = function() { return cvox.SemanticAttr.getInstance().invisibleComma_; }; /** * String representation of the function application character. * @return {string} The invisible function application character. */ cvox.SemanticAttr.functionApplication = function() { return cvox.SemanticAttr.getInstance().functionApplication_; }; /** * Decide when two fences match. Currently we match any right to left * or bottom to top fence and neutral to neutral. * @param {cvox.SemanticAttr.Role} open Opening fence. * @param {cvox.SemanticAttr.Role} close Closing fence. * @return {boolean} True if the fences are matching. */ cvox.SemanticAttr.isMatchingFenceRole = function(open, close) { return (open == cvox.SemanticAttr.Role.OPEN && close == cvox.SemanticAttr.Role.CLOSE) || (open == cvox.SemanticAttr.Role.NEUTRAL && close == cvox.SemanticAttr.Role.NEUTRAL) || (open == cvox.SemanticAttr.Role.TOP && close == cvox.SemanticAttr.Role.BOTTOM); }; /** * Decide when opening and closing fences match. For neutral fences they have to * be the same. * @param {string} open Opening fence. * @param {string} close Closing fence. * @return {boolean} True if the fences are matching. */ cvox.SemanticAttr.isMatchingFence = function(open, close) { return cvox.SemanticAttr.getInstance().isMatchingFence_(open, close); }; /** * Determines if a fence is an opening fence. * @param {cvox.SemanticAttr.Role} fence Opening fence. * @return {boolean} True if the fence is open or neutral. */ cvox.SemanticAttr.isOpeningFence = function(fence) { return (fence == cvox.SemanticAttr.Role.OPEN || fence == cvox.SemanticAttr.Role.NEUTRAL); }; /** * Determines if a fence is a closing fence. * @param {cvox.SemanticAttr.Role} fence Closing fence. * @return {boolean} True if the fence is close or neutral. */ cvox.SemanticAttr.isClosingFence = function(fence) { return (fence == cvox.SemanticAttr.Role.CLOSE || fence == cvox.SemanticAttr.Role.NEUTRAL); }; // TODO (sorge) Make this depended on position in the alphabets. /** * Check if a character is a small 'd' in some font. * @param {!string} chr The character string. * @return {boolean} True if the character is indeed a single small d. */ cvox.SemanticAttr.isCharacterD = function(chr) { var Ds = ['d', 'ⅆ', 'd', '𝐝', '𝑑', '𝒹', '𝓭', '𝔡', '𝕕', '𝖉', '𝖽', '𝗱', '𝘥', '𝚍']; return Ds.indexOf(chr) != -1; }; /** * Decide when opening and closing fences match. For neutral fences they have to * be the same. * @param {!string} open Opening fence. * @param {!string} close Closing fence. * @return {boolean} True if the fences are matching. * @private */ cvox.SemanticAttr.prototype.isMatchingFence_ = function(open, close) { if (this.neutralFences.indexOf(open) != -1) { return open == close; } return this.openClosePairs[open] == close || this.topBottomPairs[open] == close; }; /** * Lookup the semantic meaning of a symbol in terms of type and role. * @param {!string} symbol The symbol to which we want to determine the meaning. * @return {{role: cvox.SemanticAttr.Role, * type: cvox.SemanticAttr.Type, * font: cvox.SemanticAttr.Font}} The semantic meaning of the symbol. * @private */ cvox.SemanticAttr.prototype.lookupMeaning_ = function(symbol) { for (var i = 0, set; set = this.symbolSetToSemantic_[i]; i++) { if (set.set.indexOf(symbol) != -1) { return {role: set.role || cvox.SemanticAttr.Role.UNKNOWN, type: set.type || cvox.SemanticAttr.Type.UNKNOWN, font: set.font || cvox.SemanticAttr.Font.UNKNOWN }; } } return {role: cvox.SemanticAttr.Role.UNKNOWN, type: cvox.SemanticAttr.Type.UNKNOWN, font: cvox.SemanticAttr.Font.UNKNOWN }; };