1
0

add initial marp implementation with sample content and build configuration

This commit is contained in:
2025-09-13 18:13:22 +02:00
parent dcacc9b409
commit e5f219507f
10319 changed files with 1402023 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
export declare enum Font {
BOLD = "bold",
BOLDFRAKTUR = "bold-fraktur",
BOLDITALIC = "bold-italic",
BOLDSCRIPT = "bold-script",
DOUBLESTRUCK = "double-struck",
DOUBLESTRUCKITALIC = "double-struck-italic",
FULLWIDTH = "fullwidth",
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"
}
export declare enum Embellish {
SUPER = "super",
SUB = "sub",
CIRCLED = "circled",
PARENTHESIZED = "parenthesized",
PERIOD = "period",
NEGATIVECIRCLED = "negative-circled",
DOUBLECIRCLED = "double-circled",
CIRCLEDSANSSERIF = "circled-sans-serif",
NEGATIVECIRCLEDSANSSERIF = "negative-circled-sans-serif",
COMMA = "comma",
SQUARED = "squared",
NEGATIVESQUARED = "negative-squared"
}
export declare enum Base {
LATINCAP = "latinCap",
LATINSMALL = "latinSmall",
GREEKCAP = "greekCap",
GREEKSMALL = "greekSmall",
DIGIT = "digit"
}
export declare function makeInterval([a, b]: [string, string], subst: {
[key: string]: string | boolean;
}): string[];
export declare function makeMultiInterval(ints: (string | [string, string])[]): string[];
export declare function makeCodeInterval(ints: (string | [string, string])[]): number[];
export declare interface ProtoAlphabet {
interval: [string, string];
base: Base;
subst: {
[key: string]: string | boolean;
};
category: string;
font: Font | Embellish;
capital?: boolean;
offset?: number;
}
export declare interface Alphabet extends ProtoAlphabet {
unicode: string[];
}
export declare const INTERVALS: Map<string, Alphabet>;
export declare function alphabetName(base: string, font: string): string;

View File

@@ -0,0 +1,699 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.INTERVALS = exports.Base = exports.Embellish = exports.Font = void 0;
exports.makeInterval = makeInterval;
exports.makeMultiInterval = makeMultiInterval;
exports.makeCodeInterval = makeCodeInterval;
exports.alphabetName = alphabetName;
var Font;
(function (Font) {
Font["BOLD"] = "bold";
Font["BOLDFRAKTUR"] = "bold-fraktur";
Font["BOLDITALIC"] = "bold-italic";
Font["BOLDSCRIPT"] = "bold-script";
Font["DOUBLESTRUCK"] = "double-struck";
Font["DOUBLESTRUCKITALIC"] = "double-struck-italic";
Font["FULLWIDTH"] = "fullwidth";
Font["FRAKTUR"] = "fraktur";
Font["ITALIC"] = "italic";
Font["MONOSPACE"] = "monospace";
Font["NORMAL"] = "normal";
Font["SCRIPT"] = "script";
Font["SANSSERIF"] = "sans-serif";
Font["SANSSERIFITALIC"] = "sans-serif-italic";
Font["SANSSERIFBOLD"] = "sans-serif-bold";
Font["SANSSERIFBOLDITALIC"] = "sans-serif-bold-italic";
})(Font || (exports.Font = Font = {}));
var Embellish;
(function (Embellish) {
Embellish["SUPER"] = "super";
Embellish["SUB"] = "sub";
Embellish["CIRCLED"] = "circled";
Embellish["PARENTHESIZED"] = "parenthesized";
Embellish["PERIOD"] = "period";
Embellish["NEGATIVECIRCLED"] = "negative-circled";
Embellish["DOUBLECIRCLED"] = "double-circled";
Embellish["CIRCLEDSANSSERIF"] = "circled-sans-serif";
Embellish["NEGATIVECIRCLEDSANSSERIF"] = "negative-circled-sans-serif";
Embellish["COMMA"] = "comma";
Embellish["SQUARED"] = "squared";
Embellish["NEGATIVESQUARED"] = "negative-squared";
})(Embellish || (exports.Embellish = Embellish = {}));
var Base;
(function (Base) {
Base["LATINCAP"] = "latinCap";
Base["LATINSMALL"] = "latinSmall";
Base["GREEKCAP"] = "greekCap";
Base["GREEKSMALL"] = "greekSmall";
Base["DIGIT"] = "digit";
})(Base || (exports.Base = Base = {}));
function num2str(num) {
const str = num.toString(16).toUpperCase();
return str.length > 3 ? str : ('000' + str).slice(-4);
}
function makeInterval([a, b], subst) {
const start = parseInt(a, 16);
const end = parseInt(b, 16);
const result = [];
for (let i = start; i <= end; i++) {
let key = num2str(i);
const sub = subst[key];
if (sub === false) {
continue;
}
key = subst[key] || key;
result.push(key);
}
return result;
}
function makeCharInterval(int, subst = {}) {
return makeInterval(int, subst).map((x) => String.fromCodePoint(parseInt(x, 16)));
}
function makeMultiInterval(ints) {
let result = [];
for (const int of ints) {
if (Array.isArray(int)) {
result = result.concat(makeCharInterval(int));
continue;
}
result.push(String.fromCodePoint(parseInt(int, 16)));
}
return result;
}
function makeCodeInterval(ints) {
let result = [];
for (const int of ints) {
if (Array.isArray(int)) {
result = result.concat(makeInterval(int, {}).map((x) => parseInt(x, 16)));
continue;
}
result.push(parseInt(int, 16));
}
return result;
}
const PROTO_INTERVALS = [
{
interval: ['1D400', '1D419'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLD
},
{
interval: ['1D41A', '1D433'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLD
},
{
interval: ['1D56C', '1D585'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLDFRAKTUR
},
{
interval: ['1D586', '1D59F'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLDFRAKTUR
},
{
interval: ['1D468', '1D481'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLDITALIC
},
{
interval: ['1D482', '1D49B'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLDITALIC
},
{
interval: ['1D4D0', '1D4E9'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLDSCRIPT
},
{
interval: ['1D4EA', '1D503'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLDSCRIPT
},
{
interval: ['1D538', '1D551'],
base: Base.LATINCAP,
subst: {
'1D53A': '2102',
'1D53F': '210D',
'1D545': '2115',
'1D547': '2119',
'1D548': '211A',
'1D549': '211D',
'1D551': '2124'
},
capital: true,
category: 'Lu',
font: Font.DOUBLESTRUCK
},
{
interval: ['1D552', '1D56B'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.DOUBLESTRUCK
},
{
interval: ['1D504', '1D51D'],
base: Base.LATINCAP,
subst: {
'1D506': '212D',
'1D50B': '210C',
'1D50C': '2111',
'1D515': '211C',
'1D51D': '2128'
},
capital: true,
category: 'Lu',
font: Font.FRAKTUR
},
{
interval: ['1D51E', '1D537'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.FRAKTUR
},
{
interval: ['FF21', 'FF3A'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.FULLWIDTH
},
{
interval: ['FF41', 'FF5A'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.FULLWIDTH
},
{
interval: ['1D434', '1D44D'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.ITALIC
},
{
interval: ['1D44E', '1D467'],
base: Base.LATINSMALL,
subst: { '1D455': '210E' },
capital: false,
category: 'Ll',
font: Font.ITALIC
},
{
interval: ['1D670', '1D689'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.MONOSPACE
},
{
interval: ['1D68A', '1D6A3'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.MONOSPACE
},
{
interval: ['0041', '005A'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.NORMAL
},
{
interval: ['0061', '007A'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.NORMAL
},
{
interval: ['1D49C', '1D4B5'],
base: Base.LATINCAP,
subst: {
'1D49D': '212C',
'1D4A0': '2130',
'1D4A1': '2131',
'1D4A3': '210B',
'1D4A4': '2110',
'1D4A7': '2112',
'1D4A8': '2133',
'1D4AD': '211B'
},
capital: true,
category: 'Lu',
font: Font.SCRIPT
},
{
interval: ['1D4B6', '1D4CF'],
base: Base.LATINSMALL,
subst: { '1D4BA': '212F', '1D4BC': '210A', '1D4C4': '2134' },
capital: false,
category: 'Ll',
font: Font.SCRIPT
},
{
interval: ['1D5A0', '1D5B9'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIF
},
{
interval: ['1D5BA', '1D5D3'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIF
},
{
interval: ['1D608', '1D621'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIFITALIC
},
{
interval: ['1D622', '1D63B'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIFITALIC
},
{
interval: ['1D5D4', '1D5ED'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIFBOLD
},
{
interval: ['1D5EE', '1D607'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIFBOLD
},
{
interval: ['1D63C', '1D655'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIFBOLDITALIC
},
{
interval: ['1D656', '1D66F'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIFBOLDITALIC
},
{
interval: ['0391', '03A9'],
base: Base.GREEKCAP,
subst: { '03A2': '03F4' },
capital: true,
category: 'Lu',
font: Font.NORMAL
},
{
interval: ['03B0', '03D0'],
base: Base.GREEKSMALL,
subst: {
'03B0': '2207',
'03CA': '2202',
'03CB': '03F5',
'03CC': '03D1',
'03CD': '03F0',
'03CE': '03D5',
'03CF': '03F1',
'03D0': '03D6'
},
capital: false,
category: 'Ll',
font: Font.NORMAL
},
{
interval: ['1D6A8', '1D6C0'],
base: Base.GREEKCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLD
},
{
interval: ['1D6C1', '1D6E1'],
base: Base.GREEKSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLD
},
{
interval: ['1D6E2', '1D6FA'],
base: Base.GREEKCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.ITALIC
},
{
interval: ['1D6FB', '1D71B'],
base: Base.GREEKSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.ITALIC
},
{
interval: ['1D71C', '1D734'],
base: Base.GREEKCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.BOLDITALIC
},
{
interval: ['1D735', '1D755'],
base: Base.GREEKSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.BOLDITALIC
},
{
interval: ['1D756', '1D76E'],
base: Base.GREEKCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIFBOLD
},
{
interval: ['1D76F', '1D78F'],
base: Base.GREEKSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIFBOLD
},
{
interval: ['1D790', '1D7A8'],
base: Base.GREEKCAP,
subst: {},
capital: true,
category: 'Lu',
font: Font.SANSSERIFBOLDITALIC
},
{
interval: ['1D7A9', '1D7C9'],
base: Base.GREEKSMALL,
subst: {},
capital: false,
category: 'Ll',
font: Font.SANSSERIFBOLDITALIC
},
{
interval: ['0030', '0039'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.NORMAL
},
{
interval: ['2070', '2079'],
base: Base.DIGIT,
subst: { 2071: '00B9', 2072: '00B2', 2073: '00B3' },
offset: 0,
category: 'No',
font: Embellish.SUPER
},
{
interval: ['2080', '2089'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'No',
font: Embellish.SUB
},
{
interval: ['245F', '2473'],
base: Base.DIGIT,
subst: { '245F': '24EA' },
offset: 0,
category: 'No',
font: Embellish.CIRCLED
},
{
interval: ['3251', '325F'],
base: Base.DIGIT,
subst: {},
offset: 21,
category: 'No',
font: Embellish.CIRCLED
},
{
interval: ['32B1', '32BF'],
base: Base.DIGIT,
subst: {},
offset: 36,
category: 'No',
font: Embellish.CIRCLED
},
{
interval: ['2474', '2487'],
base: Base.DIGIT,
subst: {},
offset: 1,
category: 'No',
font: Embellish.PARENTHESIZED
},
{
interval: ['2487', '249B'],
base: Base.DIGIT,
subst: { 2487: '1F100' },
offset: 0,
category: 'No',
font: Embellish.PERIOD
},
{
interval: ['2775', '277F'],
base: Base.DIGIT,
subst: { 2775: '24FF' },
offset: 0,
category: 'No',
font: Embellish.NEGATIVECIRCLED
},
{
interval: ['24EB', '24F4'],
base: Base.DIGIT,
subst: {},
offset: 11,
category: 'No',
font: Embellish.NEGATIVECIRCLED
},
{
interval: ['24F5', '24FE'],
base: Base.DIGIT,
subst: {},
offset: 1,
category: 'No',
font: Embellish.DOUBLECIRCLED
},
{
interval: ['277F', '2789'],
base: Base.DIGIT,
subst: { '277F': '1F10B' },
offset: 0,
category: 'No',
font: Embellish.CIRCLEDSANSSERIF
},
{
interval: ['2789', '2793'],
base: Base.DIGIT,
subst: { 2789: '1F10C' },
offset: 0,
category: 'No',
font: Embellish.NEGATIVECIRCLEDSANSSERIF
},
{
interval: ['FF10', 'FF19'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.FULLWIDTH
},
{
interval: ['1D7CE', '1D7D7'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.BOLD
},
{
interval: ['1D7D8', '1D7E1'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.DOUBLESTRUCK
},
{
interval: ['1D7E2', '1D7EB'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.SANSSERIF
},
{
interval: ['1D7EC', '1D7F5'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.SANSSERIFBOLD
},
{
interval: ['1D7F6', '1D7FF'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'Nd',
font: Font.MONOSPACE
},
{
interval: ['1F101', '1F10A'],
base: Base.DIGIT,
subst: {},
offset: 0,
category: 'No',
font: Embellish.COMMA
},
{
interval: ['24B6', '24CF'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'So',
font: Embellish.CIRCLED
},
{
interval: ['24D0', '24E9'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'So',
font: Embellish.CIRCLED
},
{
interval: ['1F110', '1F129'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'So',
font: Embellish.PARENTHESIZED
},
{
interval: ['249C', '24B5'],
base: Base.LATINSMALL,
subst: {},
capital: false,
category: 'So',
font: Embellish.PARENTHESIZED
},
{
interval: ['1F130', '1F149'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'So',
font: Embellish.SQUARED
},
{
interval: ['1F170', '1F189'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'So',
font: Embellish.NEGATIVESQUARED
},
{
interval: ['1F150', '1F169'],
base: Base.LATINCAP,
subst: {},
capital: true,
category: 'So',
font: Embellish.NEGATIVECIRCLED
}
];
exports.INTERVALS = new Map();
function alphabetName(base, font) {
const capFont = font
.split('-')
.map((x) => x[0].toUpperCase() + x.slice(1))
.join('');
return base + capFont;
}
for (const proto of PROTO_INTERVALS) {
const key = alphabetName(proto.base, proto.font);
const interval = makeCharInterval(proto.interval, proto.subst);
let alphabet = exports.INTERVALS.get(key);
if (alphabet) {
alphabet.unicode = alphabet.unicode.concat(interval);
continue;
}
alphabet = proto;
alphabet.unicode = interval;
exports.INTERVALS.set(key, alphabet);
}

View File

@@ -0,0 +1,2 @@
export declare function generateBase(): void;
export declare function generate(locale: string): void;

View File

@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateBase = generateBase;
exports.generate = generate;
const Alphabet = require("./alphabet.js");
const engine_js_1 = require("../common/engine.js");
const L10n = require("../l10n/l10n.js");
const locale_js_1 = require("../l10n/locale.js");
const locale_util_js_1 = require("../l10n/locale_util.js");
const MathCompoundStore = require("../rule_engine/math_compound_store.js");
const Domains = {
small: ['default'],
capital: ['default'],
digit: ['default']
};
function makeDomains() {
const alph = locale_js_1.LOCALE.ALPHABETS;
const combineKeys = (obj1, obj2) => {
const result = {};
Object.keys(obj1).forEach((k) => (result[k] = true));
Object.keys(obj2).forEach((k) => (result[k] = true));
return Object.keys(result);
};
Domains.small = combineKeys(alph.smallPrefix, alph.letterTrans);
Domains.capital = combineKeys(alph.capPrefix, alph.letterTrans);
Domains.digit = combineKeys(alph.digitPrefix, alph.digitTrans);
}
function generateBase() {
for (const int of Alphabet.INTERVALS.values()) {
const letters = int.unicode;
for (const letter of letters) {
MathCompoundStore.baseStores.set(letter, {
key: letter,
category: int.category
});
}
}
}
function generate(locale) {
const oldLocale = engine_js_1.Engine.getInstance().locale;
engine_js_1.Engine.getInstance().locale = locale;
L10n.setLocale();
MathCompoundStore.changeLocale({ locale: locale });
makeDomains();
for (const int of Alphabet.INTERVALS.values()) {
const letters = int.unicode;
if ('offset' in int) {
numberRules(letters, int.font, int.offset || 0);
}
else {
const alphabet = locale_js_1.LOCALE.ALPHABETS[int.base];
alphabetRules(letters, alphabet, int.font, !!int.capital);
}
}
engine_js_1.Engine.getInstance().locale = oldLocale;
L10n.setLocale();
}
function getFont(font) {
const realFont = font === 'normal' || font === 'fullwidth'
? ''
: locale_js_1.LOCALE.MESSAGES.font[font] || locale_js_1.LOCALE.MESSAGES.embellish[font] || '';
return (0, locale_util_js_1.localeFontCombiner)(realFont);
}
function alphabetRules(unicodes, letters, font, cap) {
const realFont = getFont(font);
for (let i = 0, unicode, letter; (unicode = unicodes[i]), (letter = letters[i]); i++) {
const prefixes = cap
? locale_js_1.LOCALE.ALPHABETS.capPrefix
: locale_js_1.LOCALE.ALPHABETS.smallPrefix;
const domains = cap ? Domains.capital : Domains.small;
makeLetter(realFont.combiner, unicode, letter, realFont.font, prefixes, locale_js_1.LOCALE.ALPHABETS.letterTrans, domains);
}
}
function numberRules(unicodes, font, offset) {
const realFont = getFont(font);
for (let i = 0, unicode; (unicode = unicodes[i]); i++) {
const prefixes = locale_js_1.LOCALE.ALPHABETS.digitPrefix;
const num = i + offset;
makeLetter(realFont.combiner, unicode, num, realFont.font, prefixes, locale_js_1.LOCALE.ALPHABETS.digitTrans, Domains.digit);
}
}
function makeLetter(combiner, unicode, letter, font, prefixes, transformers, domains) {
for (let i = 0, domain; (domain = domains[i]); i++) {
const transformer = domain in transformers ? transformers[domain] : transformers['default'];
const prefix = domain in prefixes ? prefixes[domain] : prefixes['default'];
MathCompoundStore.defineRule(domain, 'default', unicode, combiner(transformer(letter), font, prefix));
}
}

View File

@@ -0,0 +1,33 @@
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
import { AxisMap, AxisProperties, DefaultComparator, DynamicProperties } from '../rule_engine/dynamic_cstr.js';
import { SemanticNode } from '../semantic_tree/semantic_node.js';
export declare class ClearspeakPreferences extends DynamicCstr {
preference: {
[key: string]: string;
};
private static AUTO;
static comparator(): Comparator;
static fromPreference(pref: string): AxisMap;
static toPreference(pref: AxisMap): string;
static getLocalePreferences(opt_dynamic?: {
[key: string]: AxisProperties;
}): {
[key: string]: AxisProperties;
};
static currentPreference(): string;
static relevantPreferences(node: SemanticNode): string;
static findPreference(prefs: string, kind: string): string;
static addPreference(prefs: string, kind: string, value: string): string;
private static getLocalePreferences_;
constructor(cstr: AxisMap, preference: {
[key: string]: string;
});
equal(cstr: ClearspeakPreferences): boolean;
}
declare class Comparator extends DefaultComparator {
preference: AxisMap;
constructor(cstr: DynamicCstr, props: DynamicProperties);
match(cstr: DynamicCstr): boolean;
compare(cstr1: DynamicCstr, cstr2: DynamicCstr): 0 | 1 | -1;
}
export {};

View File

@@ -0,0 +1,323 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClearspeakPreferences = void 0;
const engine_js_1 = require("../common/engine.js");
const EngineConst = require("../common/engine_const.js");
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const dynamic_cstr_js_2 = require("../rule_engine/dynamic_cstr.js");
const MathCompoundStore = require("../rule_engine/math_compound_store.js");
const speech_rule_engine_js_1 = require("../rule_engine/speech_rule_engine.js");
const semantic_meaning_js_1 = require("../semantic_tree/semantic_meaning.js");
class ClearspeakPreferences extends dynamic_cstr_js_1.DynamicCstr {
static comparator() {
return new Comparator(engine_js_1.Engine.getInstance().dynamicCstr, dynamic_cstr_js_2.DynamicProperties.createProp([dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUES[dynamic_cstr_js_2.Axis.LOCALE]], [dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUES[dynamic_cstr_js_2.Axis.MODALITY]], [dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUES[dynamic_cstr_js_2.Axis.DOMAIN]], [dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUES[dynamic_cstr_js_2.Axis.STYLE]]));
}
static fromPreference(pref) {
const pairs = pref.split(':');
const preferences = {};
const properties = PREFERENCES.getProperties();
const validKeys = Object.keys(properties);
for (let i = 0, key; (key = pairs[i]); i++) {
const pair = key.split('_');
if (validKeys.indexOf(pair[0]) === -1) {
continue;
}
const value = pair[1];
if (value &&
value !== ClearspeakPreferences.AUTO &&
properties[pair[0]].indexOf(value) !== -1) {
preferences[pair[0]] = pair[1];
}
}
return preferences;
}
static toPreference(pref) {
const keys = Object.keys(pref);
const str = [];
for (let i = 0; i < keys.length; i++) {
str.push(keys[i] + '_' + pref[keys[i]]);
}
return str.length ? str.join(':') : dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUE;
}
static getLocalePreferences(opt_dynamic) {
const dynamic = opt_dynamic ||
MathCompoundStore.enumerate(speech_rule_engine_js_1.SpeechRuleEngine.getInstance().enumerate());
return ClearspeakPreferences.getLocalePreferences_(dynamic);
}
static currentPreference() {
return EngineConst.DOMAIN_TO_STYLES['clearspeak'];
}
static relevantPreferences(node) {
const roles = SEMANTIC_MAPPING_[node.type];
if (!roles) {
return 'ImpliedTimes';
}
return roles[node.role] || roles[''] || 'ImpliedTimes';
}
static findPreference(prefs, kind) {
if (prefs === 'default') {
return ClearspeakPreferences.AUTO;
}
const parsed = ClearspeakPreferences.fromPreference(prefs);
return parsed[kind] || ClearspeakPreferences.AUTO;
}
static addPreference(prefs, kind, value) {
if (prefs === 'default') {
return kind + '_' + value;
}
const parsed = ClearspeakPreferences.fromPreference(prefs);
parsed[kind] = value;
return ClearspeakPreferences.toPreference(parsed);
}
static getLocalePreferences_(dynamic) {
const result = {};
for (const locale of Object.keys(dynamic)) {
if (!dynamic[locale]['speech'] ||
!dynamic[locale]['speech']['clearspeak']) {
continue;
}
const locPrefs = Object.keys(dynamic[locale]['speech']['clearspeak']);
if (locPrefs.length < 3)
continue;
const prefs = (result[locale] = {});
for (const axis in PREFERENCES.getProperties()) {
const allSty = PREFERENCES.getProperties()[axis];
const values = [axis + '_Auto'];
if (allSty) {
for (const sty of allSty) {
if (locPrefs.indexOf(axis + '_' + sty) !== -1) {
values.push(axis + '_' + sty);
}
}
}
prefs[axis] = values;
}
}
return result;
}
constructor(cstr, preference) {
super(cstr);
this.preference = preference;
}
equal(cstr) {
const top = super.equal(cstr);
if (!top) {
return false;
}
const keys = Object.keys(this.preference);
const preference = cstr.preference;
if (keys.length !== Object.keys(preference).length) {
return false;
}
for (let i = 0, key; (key = keys[i]); i++) {
if (this.preference[key] !== preference[key]) {
return false;
}
}
return true;
}
}
exports.ClearspeakPreferences = ClearspeakPreferences;
ClearspeakPreferences.AUTO = 'Auto';
const PREFERENCES = new dynamic_cstr_js_2.DynamicProperties({
AbsoluteValue: ['Auto', 'AbsEnd', 'Cardinality', 'Determinant'],
Bar: ['Auto', 'Conjugate'],
Caps: ['Auto', 'SayCaps'],
CombinationPermutation: ['Auto', 'ChoosePermute'],
Currency: ['Auto', 'Position', 'Prefix'],
Ellipses: ['Auto', 'AndSoOn'],
Enclosed: ['Auto', 'EndEnclose'],
Exponent: [
'Auto',
'AfterPower',
'Ordinal',
'OrdinalPower',
'Exponent'
],
Fraction: [
'Auto',
'EndFrac',
'FracOver',
'General',
'GeneralEndFrac',
'Ordinal',
'Over',
'OverEndFrac',
'Per'
],
Functions: [
'Auto',
'None',
'Reciprocal'
],
ImpliedTimes: ['Auto', 'MoreImpliedTimes', 'None'],
Log: ['Auto', 'LnAsNaturalLog'],
Matrix: [
'Auto',
'Combinatoric',
'EndMatrix',
'EndVector',
'SilentColNum',
'SpeakColNum',
'Vector'
],
MultiLineLabel: [
'Auto',
'Case',
'Constraint',
'Equation',
'Line',
'None',
'Row',
'Step'
],
MultiLineOverview: ['Auto', 'None'],
MultiLinePausesBetweenColumns: ['Auto', 'Long', 'Short'],
MultsymbolDot: ['Auto', 'Dot'],
MultsymbolX: ['Auto', 'By', 'Cross'],
Paren: [
'Auto',
'CoordPoint',
'Interval',
'Silent',
'Speak',
'SpeakNestingLevel'
],
Prime: ['Auto', 'Angle', 'Length'],
Roots: ['Auto', 'PosNegSqRoot', 'PosNegSqRootEnd', 'RootEnd'],
SetMemberSymbol: ['Auto', 'Belongs', 'Element', 'Member', 'In'],
Sets: ['Auto', 'SilentBracket', 'woAll'],
TriangleSymbol: ['Auto', 'Delta'],
Trig: [
'Auto',
'ArcTrig',
'TrigInverse',
'Reciprocal'
],
VerticalLine: ['Auto', 'Divides', 'Given', 'SuchThat']
});
class Comparator extends dynamic_cstr_js_2.DefaultComparator {
constructor(cstr, props) {
super(cstr, props);
this.preference =
cstr instanceof ClearspeakPreferences ? cstr.preference : {};
}
match(cstr) {
if (!(cstr instanceof ClearspeakPreferences)) {
return super.match(cstr);
}
if (cstr.getComponents()[dynamic_cstr_js_2.Axis.STYLE] === 'default') {
return true;
}
const keys = Object.keys(cstr.preference);
for (let i = 0, key; (key = keys[i]); i++) {
if (this.preference[key] !== cstr.preference[key]) {
return false;
}
}
return true;
}
compare(cstr1, cstr2) {
const top = super.compare(cstr1, cstr2);
if (top !== 0) {
return top;
}
const pref1 = cstr1 instanceof ClearspeakPreferences;
const pref2 = cstr2 instanceof ClearspeakPreferences;
if (!pref1 && pref2) {
return 1;
}
if (pref1 && !pref2) {
return -1;
}
if (!pref1 && !pref2) {
return 0;
}
const length1 = Object.keys(cstr1.preference).length;
const length2 = Object.keys(cstr2.preference).length;
return length1 > length2 ? -1 : length1 < length2 ? 1 : 0;
}
}
class Parser extends dynamic_cstr_js_2.DynamicCstrParser {
constructor() {
super([dynamic_cstr_js_2.Axis.LOCALE, dynamic_cstr_js_2.Axis.MODALITY, dynamic_cstr_js_2.Axis.DOMAIN, dynamic_cstr_js_2.Axis.STYLE]);
}
parse(str) {
const initial = super.parse(str);
let style = initial.getValue(dynamic_cstr_js_2.Axis.STYLE);
const locale = initial.getValue(dynamic_cstr_js_2.Axis.LOCALE);
const modality = initial.getValue(dynamic_cstr_js_2.Axis.MODALITY);
let pref = {};
if (style !== dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUE) {
pref = this.fromPreference(style);
style = this.toPreference(pref);
}
return new ClearspeakPreferences({
locale: locale,
modality: modality,
domain: 'clearspeak',
style: style
}, pref);
}
fromPreference(pref) {
return ClearspeakPreferences.fromPreference(pref);
}
toPreference(pref) {
return ClearspeakPreferences.toPreference(pref);
}
}
const REVERSE_MAPPING = [
[
'AbsoluteValue',
semantic_meaning_js_1.SemanticType.FENCED,
semantic_meaning_js_1.SemanticRole.NEUTRAL,
semantic_meaning_js_1.SemanticRole.METRIC
],
['Bar', semantic_meaning_js_1.SemanticType.OVERSCORE, semantic_meaning_js_1.SemanticRole.OVERACCENT],
['Caps', semantic_meaning_js_1.SemanticType.IDENTIFIER, semantic_meaning_js_1.SemanticRole.LATINLETTER],
['CombinationPermutation', semantic_meaning_js_1.SemanticType.APPL, semantic_meaning_js_1.SemanticRole.UNKNOWN],
['Ellipses', semantic_meaning_js_1.SemanticType.PUNCTUATION, semantic_meaning_js_1.SemanticRole.ELLIPSIS],
['Exponent', semantic_meaning_js_1.SemanticType.SUPERSCRIPT, ''],
['Fraction', semantic_meaning_js_1.SemanticType.FRACTION, ''],
['Functions', semantic_meaning_js_1.SemanticType.APPL, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC],
['ImpliedTimes', semantic_meaning_js_1.SemanticType.OPERATOR, semantic_meaning_js_1.SemanticRole.IMPLICIT],
['Log', semantic_meaning_js_1.SemanticType.APPL, semantic_meaning_js_1.SemanticRole.PREFIXFUNC],
['Matrix', semantic_meaning_js_1.SemanticType.MATRIX, ''],
['Matrix', semantic_meaning_js_1.SemanticType.VECTOR, ''],
['MultiLineLabel', semantic_meaning_js_1.SemanticType.MULTILINE, semantic_meaning_js_1.SemanticRole.LABEL],
['MultiLineOverview', semantic_meaning_js_1.SemanticType.MULTILINE, semantic_meaning_js_1.SemanticRole.TABLE],
['MultiLinePausesBetweenColumns', semantic_meaning_js_1.SemanticType.MULTILINE, semantic_meaning_js_1.SemanticRole.TABLE],
['MultiLineLabel', semantic_meaning_js_1.SemanticType.TABLE, semantic_meaning_js_1.SemanticRole.LABEL],
['MultiLineOverview', semantic_meaning_js_1.SemanticType.TABLE, semantic_meaning_js_1.SemanticRole.TABLE],
['MultiLinePausesBetweenColumns', semantic_meaning_js_1.SemanticType.TABLE, semantic_meaning_js_1.SemanticRole.TABLE],
['MultiLineLabel', semantic_meaning_js_1.SemanticType.CASES, semantic_meaning_js_1.SemanticRole.LABEL],
['MultiLineOverview', semantic_meaning_js_1.SemanticType.CASES, semantic_meaning_js_1.SemanticRole.TABLE],
['MultiLinePausesBetweenColumns', semantic_meaning_js_1.SemanticType.CASES, semantic_meaning_js_1.SemanticRole.TABLE],
['MultsymbolDot', semantic_meaning_js_1.SemanticType.OPERATOR, semantic_meaning_js_1.SemanticRole.MULTIPLICATION],
['MultsymbolX', semantic_meaning_js_1.SemanticType.OPERATOR, semantic_meaning_js_1.SemanticRole.MULTIPLICATION],
['Paren', semantic_meaning_js_1.SemanticType.FENCED, semantic_meaning_js_1.SemanticRole.LEFTRIGHT],
['Prime', semantic_meaning_js_1.SemanticType.SUPERSCRIPT, semantic_meaning_js_1.SemanticRole.PRIME],
['Roots', semantic_meaning_js_1.SemanticType.ROOT, ''],
['Roots', semantic_meaning_js_1.SemanticType.SQRT, ''],
['SetMemberSymbol', semantic_meaning_js_1.SemanticType.RELATION, semantic_meaning_js_1.SemanticRole.ELEMENT],
['Sets', semantic_meaning_js_1.SemanticType.FENCED, semantic_meaning_js_1.SemanticRole.SETEXT],
['TriangleSymbol', semantic_meaning_js_1.SemanticType.IDENTIFIER, semantic_meaning_js_1.SemanticRole.GREEKLETTER],
['Trig', semantic_meaning_js_1.SemanticType.APPL, semantic_meaning_js_1.SemanticRole.PREFIXFUNC],
['VerticalLine', semantic_meaning_js_1.SemanticType.PUNCTUATED, semantic_meaning_js_1.SemanticRole.VBAR]
];
const SEMANTIC_MAPPING_ = (function () {
const result = {};
for (let i = 0, triple; (triple = REVERSE_MAPPING[i]); i++) {
const pref = triple[0];
let role = result[triple[1]];
if (!role) {
role = {};
result[triple[1]] = role;
}
role[triple[2]] = pref;
}
return result;
})();
engine_js_1.Engine.getInstance().comparators['clearspeak'] =
ClearspeakPreferences.comparator;
engine_js_1.Engine.getInstance().parsers['clearspeak'] = new Parser();

View File

@@ -0,0 +1 @@
export declare function ClearspeakRules(): void;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClearspeakRules = ClearspeakRules;
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const StoreUtil = require("../rule_engine/store_util.js");
const ClearspeakUtil = require("./clearspeak_util.js");
const MathspeakUtil = require("./mathspeak_util.js");
const NumbersUtil = require("./numbers_util.js");
const SpeechRules = require("./speech_rules.js");
function ClearspeakRules() {
SpeechRules.addStore(dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.clearspeak', '', {
CTFpauseSeparator: StoreUtil.pauseSeparator,
CTFnodeCounter: ClearspeakUtil.nodeCounter,
CTFcontentIterator: StoreUtil.contentIterator,
CSFvulgarFraction: NumbersUtil.vulgarFraction,
CQFvulgarFractionSmall: ClearspeakUtil.isSmallVulgarFraction,
CQFcellsSimple: ClearspeakUtil.allCellsSimple,
CSFordinalExponent: ClearspeakUtil.ordinalExponent,
CSFwordOrdinal: ClearspeakUtil.wordOrdinal,
CQFmatchingFences: ClearspeakUtil.matchingFences,
CSFnestingDepth: ClearspeakUtil.nestingDepth,
CQFfencedArguments: ClearspeakUtil.fencedArguments,
CQFsimpleArguments: ClearspeakUtil.simpleArguments,
CQFspaceoutNumber: MathspeakUtil.spaceoutNumber
});
}

View File

@@ -0,0 +1,10 @@
import { Span } from '../audio/span.js';
export declare function nodeCounter(nodes: Element[], context: string | null): () => string;
export declare function allCellsSimple(node: Element): Element[];
export declare function isSmallVulgarFraction(node: Element): Element[];
export declare function ordinalExponent(node: Element): Span[];
export declare function nestingDepth(node: Element): Span[];
export declare function matchingFences(node: Element): Element[];
export declare function fencedArguments(node: Element): Element[];
export declare function simpleArguments(node: Element): Element[];
export declare function wordOrdinal(node: Element): Span[];

View File

@@ -0,0 +1,297 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nodeCounter = nodeCounter;
exports.allCellsSimple = allCellsSimple;
exports.isSmallVulgarFraction = isSmallVulgarFraction;
exports.ordinalExponent = ordinalExponent;
exports.nestingDepth = nestingDepth;
exports.matchingFences = matchingFences;
exports.fencedArguments = fencedArguments;
exports.simpleArguments = simpleArguments;
exports.wordOrdinal = wordOrdinal;
const span_js_1 = require("../audio/span.js");
const DomUtil = require("../common/dom_util.js");
const engine_js_1 = require("../common/engine.js");
const XpathUtil = require("../common/xpath_util.js");
const locale_js_1 = require("../l10n/locale.js");
const transformers_js_1 = require("../l10n/transformers.js");
const grammar_js_1 = require("../rule_engine/grammar.js");
const StoreUtil = require("../rule_engine/store_util.js");
const semantic_annotations_js_1 = require("../semantic_tree/semantic_annotations.js");
const semantic_annotator_js_1 = require("../semantic_tree/semantic_annotator.js");
const semantic_attr_js_1 = require("../semantic_tree/semantic_attr.js");
const semantic_meaning_js_1 = require("../semantic_tree/semantic_meaning.js");
function nodeCounter(nodes, context) {
const split = context.split('-');
const func = StoreUtil.nodeCounter(nodes, split[0] || '');
const sep = split[1] || '';
const init = split[2] || '';
let first = true;
return function () {
const result = func();
if (first) {
first = false;
return init + result + sep;
}
else {
return result + sep;
}
};
}
function isSimpleExpression(node) {
return (isSimpleNumber_(node) ||
isSimpleLetters_(node) ||
isSimpleDegree_(node) ||
isSimpleNegative_(node) ||
isSimpleFunction_(node));
}
function isSimpleFunction_(node) {
return (node.type === semantic_meaning_js_1.SemanticType.APPL &&
(node.childNodes[0].role === semantic_meaning_js_1.SemanticRole.PREFIXFUNC ||
node.childNodes[0].role === semantic_meaning_js_1.SemanticRole.SIMPLEFUNC) &&
(isSimple_(node.childNodes[1]) ||
(node.childNodes[1].type === semantic_meaning_js_1.SemanticType.FENCED &&
isSimple_(node.childNodes[1].childNodes[0]))));
}
function isSimpleNegative_(node) {
return (node.type === semantic_meaning_js_1.SemanticType.PREFIXOP &&
node.role === semantic_meaning_js_1.SemanticRole.NEGATIVE &&
isSimple_(node.childNodes[0]) &&
node.childNodes[0].type !== semantic_meaning_js_1.SemanticType.PREFIXOP &&
node.childNodes[0].type !== semantic_meaning_js_1.SemanticType.APPL &&
node.childNodes[0].type !== semantic_meaning_js_1.SemanticType.PUNCTUATED);
}
function isSimpleDegree_(node) {
return (node.type === semantic_meaning_js_1.SemanticType.PUNCTUATED &&
node.role === semantic_meaning_js_1.SemanticRole.ENDPUNCT &&
node.childNodes.length === 2 &&
node.childNodes[1].role === semantic_meaning_js_1.SemanticRole.DEGREE &&
(isLetter_(node.childNodes[0]) ||
isNumber_(node.childNodes[0]) ||
(node.childNodes[0].type === semantic_meaning_js_1.SemanticType.PREFIXOP &&
node.childNodes[0].role === semantic_meaning_js_1.SemanticRole.NEGATIVE &&
(isLetter_(node.childNodes[0].childNodes[0]) ||
isNumber_(node.childNodes[0].childNodes[0])))));
}
function isSimpleLetters_(node) {
return (isLetter_(node) ||
(node.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
node.role === semantic_meaning_js_1.SemanticRole.IMPLICIT &&
((node.childNodes.length === 2 &&
(isLetter_(node.childNodes[0]) ||
isSimpleNumber_(node.childNodes[0])) &&
isLetter_(node.childNodes[1])) ||
(node.childNodes.length === 3 &&
isSimpleNumber_(node.childNodes[0]) &&
isLetter_(node.childNodes[1]) &&
isLetter_(node.childNodes[2])))));
}
function isSimple_(node) {
return node.hasAnnotation('clearspeak', 'simple');
}
function isLetter_(node) {
return (node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER &&
(node.role === semantic_meaning_js_1.SemanticRole.LATINLETTER ||
node.role === semantic_meaning_js_1.SemanticRole.GREEKLETTER ||
node.role === semantic_meaning_js_1.SemanticRole.OTHERLETTER ||
node.role === semantic_meaning_js_1.SemanticRole.SIMPLEFUNC));
}
function isNumber_(node) {
return (node.type === semantic_meaning_js_1.SemanticType.NUMBER &&
(node.role === semantic_meaning_js_1.SemanticRole.INTEGER || node.role === semantic_meaning_js_1.SemanticRole.FLOAT));
}
function isSimpleNumber_(node) {
return isNumber_(node) || isSimpleFraction_(node);
}
function isSimpleFraction_(node) {
if (hasPreference('Fraction_Over') || hasPreference('Fraction_FracOver')) {
return false;
}
if (node.type !== semantic_meaning_js_1.SemanticType.FRACTION ||
node.role !== semantic_meaning_js_1.SemanticRole.VULGAR) {
return false;
}
if (hasPreference('Fraction_Ordinal')) {
return true;
}
const enumerator = parseInt(node.childNodes[0].textContent, 10);
const denominator = parseInt(node.childNodes[1].textContent, 10);
return (enumerator > 0 && enumerator < 20 && denominator > 0 && denominator < 11);
}
function hasPreference(pref) {
return engine_js_1.Engine.getInstance().style === pref;
}
(0, semantic_annotations_js_1.register)(new semantic_annotator_js_1.SemanticAnnotator('clearspeak', 'simple', function (node) {
return isSimpleExpression(node) ? 'simple' : '';
}));
function simpleNode(node) {
if (!node.hasAttribute('annotation')) {
return false;
}
const annotation = node.getAttribute('annotation');
return !!/clearspeak:simple$|clearspeak:simple;/.exec(annotation);
}
function simpleCell_(node) {
if (simpleNode(node)) {
return true;
}
if (node.tagName !== semantic_meaning_js_1.SemanticType.SUBSCRIPT) {
return false;
}
const children = node.childNodes[0].childNodes;
const index = children[1];
return (children[0].tagName === semantic_meaning_js_1.SemanticType.IDENTIFIER &&
(isInteger_(index) ||
(index.tagName === semantic_meaning_js_1.SemanticType.INFIXOP &&
index.hasAttribute('role') &&
index.getAttribute('role') === semantic_meaning_js_1.SemanticRole.IMPLICIT &&
allIndices_(index))));
}
function isInteger_(node) {
return (node.tagName === semantic_meaning_js_1.SemanticType.NUMBER &&
node.hasAttribute('role') &&
node.getAttribute('role') === semantic_meaning_js_1.SemanticRole.INTEGER);
}
function allIndices_(node) {
const nodes = XpathUtil.evalXPath('children/*', node);
return nodes.every((x) => isInteger_(x) || x.tagName === semantic_meaning_js_1.SemanticType.IDENTIFIER);
}
function allCellsSimple(node) {
const xpath = node.tagName === semantic_meaning_js_1.SemanticType.MATRIX
? 'children/row/children/cell/children/*'
: 'children/line/children/*';
const nodes = XpathUtil.evalXPath(xpath, node);
const result = nodes.every(simpleCell_);
return result ? [node] : [];
}
function isSmallVulgarFraction(node) {
return (0, transformers_js_1.vulgarFractionSmall)(node, 20, 11) ? [node] : [];
}
function isUnitExpression(node) {
return ((node.type === semantic_meaning_js_1.SemanticType.TEXT && node.role !== semantic_meaning_js_1.SemanticRole.LABEL) ||
(node.type === semantic_meaning_js_1.SemanticType.PUNCTUATED &&
node.role === semantic_meaning_js_1.SemanticRole.TEXT &&
isNumber_(node.childNodes[0]) &&
allTextLastContent_(node.childNodes.slice(1))) ||
(node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER &&
node.role === semantic_meaning_js_1.SemanticRole.UNIT) ||
(node.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
(node.role === semantic_meaning_js_1.SemanticRole.IMPLICIT || node.role === semantic_meaning_js_1.SemanticRole.UNIT)));
}
function allTextLastContent_(nodes) {
for (let i = 0; i < nodes.length - 1; i++) {
if (!(nodes[i].type === semantic_meaning_js_1.SemanticType.TEXT && nodes[i].textContent === '')) {
return false;
}
}
return nodes[nodes.length - 1].type === semantic_meaning_js_1.SemanticType.TEXT;
}
(0, semantic_annotations_js_1.register)(new semantic_annotator_js_1.SemanticAnnotator('clearspeak', 'unit', function (node) {
return isUnitExpression(node) ? 'unit' : '';
}));
function ordinalExponent(node) {
const num = parseInt(node.textContent, 10);
return [
span_js_1.Span.stringEmpty(isNaN(num)
? node.textContent
: num > 10
? locale_js_1.LOCALE.NUMBERS.numericOrdinal(num)
: locale_js_1.LOCALE.NUMBERS.wordOrdinal(num))
];
}
let NESTING_DEPTH = null;
function nestingDepth(node) {
let count = 0;
const fence = node.textContent;
const index = node.getAttribute('role') === 'open' ? 0 : 1;
let parent = node.parentNode;
while (parent) {
if (parent.tagName === semantic_meaning_js_1.SemanticType.FENCED &&
parent.childNodes[0].childNodes[index].textContent === fence) {
count++;
}
parent = parent.parentNode;
}
NESTING_DEPTH = count > 1 ? locale_js_1.LOCALE.NUMBERS.wordOrdinal(count) : '';
return [span_js_1.Span.stringEmpty(NESTING_DEPTH)];
}
function matchingFences(node) {
const sibling = node.previousSibling;
let left, right;
if (sibling) {
left = sibling;
right = node;
}
else {
left = node;
right = node.nextSibling;
}
if (!right) {
return [];
}
return (0, semantic_attr_js_1.isMatchingFence)(left.textContent, right.textContent) ? [node] : [];
}
function insertNesting(text, correction) {
if (!correction || !text) {
return text;
}
const start = text.match(/^(open|close) /);
if (!start) {
return correction + ' ' + text;
}
return start[0] + correction + ' ' + text.substring(start[0].length);
}
grammar_js_1.Grammar.getInstance().setCorrection('insertNesting', insertNesting);
function fencedArguments(node) {
const content = DomUtil.toArray(node.parentNode.childNodes);
const children = XpathUtil.evalXPath('../../children/*', node);
const index = content.indexOf(node);
return fencedFactor_(children[index]) || fencedFactor_(children[index + 1])
? [node]
: [];
}
function simpleArguments(node) {
const content = DomUtil.toArray(node.parentNode.childNodes);
const children = XpathUtil.evalXPath('../../children/*', node);
const index = content.indexOf(node);
return simpleFactor_(children[index]) &&
children[index + 1] &&
(simpleFactor_(children[index + 1]) ||
children[index + 1].tagName === semantic_meaning_js_1.SemanticType.ROOT ||
children[index + 1].tagName === semantic_meaning_js_1.SemanticType.SQRT ||
(children[index + 1].tagName === semantic_meaning_js_1.SemanticType.SUPERSCRIPT &&
children[index + 1].childNodes[0].childNodes[0] &&
(children[index + 1].childNodes[0].childNodes[0]
.tagName === semantic_meaning_js_1.SemanticType.NUMBER ||
children[index + 1].childNodes[0].childNodes[0]
.tagName === semantic_meaning_js_1.SemanticType.IDENTIFIER) &&
(children[index + 1].childNodes[0].childNodes[1].textContent === '2' ||
children[index + 1].childNodes[0].childNodes[1].textContent === '3')))
? [node]
: [];
}
function simpleFactor_(node) {
return (!!node &&
(node.tagName === semantic_meaning_js_1.SemanticType.NUMBER ||
node.tagName === semantic_meaning_js_1.SemanticType.IDENTIFIER ||
node.tagName === semantic_meaning_js_1.SemanticType.FUNCTION ||
node.tagName === semantic_meaning_js_1.SemanticType.APPL ||
node.tagName === semantic_meaning_js_1.SemanticType.FRACTION));
}
function fencedFactor_(node) {
return (node &&
(node.tagName === semantic_meaning_js_1.SemanticType.FENCED ||
(node.hasAttribute('role') &&
node.getAttribute('role') === semantic_meaning_js_1.SemanticRole.LEFTRIGHT) ||
layoutFactor_(node)));
}
function layoutFactor_(node) {
return (!!node &&
(node.tagName === semantic_meaning_js_1.SemanticType.MATRIX ||
node.tagName === semantic_meaning_js_1.SemanticType.VECTOR));
}
function wordOrdinal(node) {
return [
span_js_1.Span.stringEmpty(locale_js_1.LOCALE.NUMBERS.wordOrdinal(parseInt(node.textContent, 10)))
];
}

View File

@@ -0,0 +1,4 @@
export declare function loadLocale(locale?: string): Promise<string>;
export declare function standardLoader(): typeof loadFile;
declare function loadFile(locale: string): Promise<string>;
export {};

View File

@@ -0,0 +1,176 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadLocale = loadLocale;
exports.standardLoader = standardLoader;
const BrowserUtil = require("../common/browser_util.js");
const engine_js_1 = require("../common/engine.js");
const EngineConst = require("../common/engine_const.js");
const FileUtil = require("../common/file_util.js");
const system_external_js_1 = require("../common/system_external.js");
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const MathCompoundStore = require("../rule_engine/math_compound_store.js");
const speech_rule_engine_js_1 = require("../rule_engine/speech_rule_engine.js");
const l10n_js_1 = require("../l10n/l10n.js");
const AlphabetGenerator = require("./alphabet_generator.js");
const addSymbols = {
functions: MathCompoundStore.addFunctionRules,
symbols: MathCompoundStore.addSymbolRules,
units: MathCompoundStore.addUnitRules,
si: (x) => x.forEach(MathCompoundStore.setSiPrefixes),
messages: l10n_js_1.completeLocale,
rules: speech_rule_engine_js_1.SpeechRuleEngine.addStore,
characters: MathCompoundStore.addCharacterRules
};
let _init = false;
function loadLocale() {
return __awaiter(this, arguments, void 0, function* (locale = engine_js_1.Engine.getInstance().locale) {
if (!_init) {
AlphabetGenerator.generateBase();
_loadLocale(dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE);
_init = true;
}
return engine_js_1.EnginePromise.promises[dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE].then(() => __awaiter(this, void 0, void 0, function* () {
const defLoc = engine_js_1.Engine.getInstance().defaultLocale;
if (defLoc) {
_loadLocale(defLoc);
return engine_js_1.EnginePromise.promises[defLoc].then(() => __awaiter(this, void 0, void 0, function* () {
_loadLocale(locale);
return engine_js_1.EnginePromise.promises[locale];
}));
}
_loadLocale(locale);
return engine_js_1.EnginePromise.promises[locale];
}));
});
}
function _loadLocale(locale = engine_js_1.Engine.getInstance().locale) {
if (!engine_js_1.EnginePromise.loaded[locale]) {
engine_js_1.EnginePromise.loaded[locale] = [false, false];
MathCompoundStore.reset();
retrieveMaps(locale);
}
}
function loadMethod() {
if (engine_js_1.Engine.getInstance().customLoader) {
return engine_js_1.Engine.getInstance().customLoader;
}
return standardLoader();
}
function standardLoader() {
switch (engine_js_1.Engine.getInstance().mode) {
case EngineConst.Mode.ASYNC:
return loadFile;
case EngineConst.Mode.HTTP:
return loadAjax;
case EngineConst.Mode.SYNC:
default:
return loadFileSync;
}
}
function retrieveFiles(locale) {
const loader = loadMethod();
const promise = new Promise((res) => {
const inner = loader(locale);
inner.then((str) => {
parseMaps(str);
engine_js_1.EnginePromise.loaded[locale] = [true, true];
res(locale);
}, (_err) => {
engine_js_1.EnginePromise.loaded[locale] = [true, false];
console.error(`Unable to load locale: ${locale}`);
engine_js_1.Engine.getInstance().locale = engine_js_1.Engine.getInstance().defaultLocale;
res(locale);
});
});
engine_js_1.EnginePromise.promises[locale] = promise;
}
function parseMaps(json) {
const js = typeof json === 'string'
? JSON.parse(json)
: json;
addMaps(js);
}
function addMaps(json, opt_locale) {
let generate = true;
for (let i = 0, key; (key = Object.keys(json)[i]); i++) {
const info = key.split('/');
if (opt_locale && opt_locale !== info[0]) {
continue;
}
if (generate && info[1] === 'symbols' && info[0] !== 'base') {
AlphabetGenerator.generate(info[0]);
generate = false;
}
addSymbols[info[1]](json[key]);
}
}
function retrieveMaps(locale) {
if (engine_js_1.Engine.getInstance().isIE &&
engine_js_1.Engine.getInstance().mode === EngineConst.Mode.HTTP) {
getJsonIE_(locale);
return;
}
retrieveFiles(locale);
}
function getJsonIE_(locale, opt_count) {
let count = opt_count || 1;
if (!BrowserUtil.mapsForIE) {
if (count <= 5) {
setTimeout((() => getJsonIE_(locale, count++)).bind(this), 300);
}
return;
}
addMaps(BrowserUtil.mapsForIE, locale);
}
function loadFile(locale) {
const file = FileUtil.localePath(locale);
return new Promise((res, rej) => {
system_external_js_1.SystemExternal.fs.readFile(file, 'utf8', (err, json) => {
if (err) {
return rej(err);
}
res(json);
});
});
}
function loadFileSync(locale) {
const file = FileUtil.localePath(locale);
return new Promise((res, rej) => {
let str = '{}';
try {
str = system_external_js_1.SystemExternal.fs.readFileSync(file, 'utf8');
}
catch (err) {
return rej(err);
}
res(str);
});
}
function loadAjax(locale) {
const file = FileUtil.localePath(locale);
const httpRequest = new XMLHttpRequest();
return new Promise((res, rej) => {
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4) {
const status = httpRequest.status;
if (status === 0 || (status >= 200 && status < 400)) {
res(httpRequest.responseText);
}
else {
rej(status);
}
}
};
httpRequest.open('GET', file, true);
httpRequest.send();
});
}

View File

@@ -0,0 +1,7 @@
import { Span } from '../audio/span.js';
export declare function baselineVerbose(node: Element): Span[];
export declare function baselineBrief(node: Element): Span[];
export declare function leftSuperscriptVerbose(node: Element): Span[];
export declare function leftSubscriptVerbose(node: Element): Span[];
export declare function leftSuperscriptBrief(node: Element): Span[];
export declare function leftSubscriptBrief(node: Element): Span[];

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.baselineVerbose = baselineVerbose;
exports.baselineBrief = baselineBrief;
exports.leftSuperscriptVerbose = leftSuperscriptVerbose;
exports.leftSubscriptVerbose = leftSubscriptVerbose;
exports.leftSuperscriptBrief = leftSuperscriptBrief;
exports.leftSubscriptBrief = leftSubscriptBrief;
const MathspeakUtil = require("./mathspeak_util.js");
function baselineVerbose(node) {
const baseline = MathspeakUtil.baselineVerbose(node);
baseline[0].speech = baseline[0].speech.replace(/-$/, '');
return baseline;
}
function baselineBrief(node) {
const baseline = MathspeakUtil.baselineBrief(node);
baseline[0].speech = baseline[0].speech.replace(/-$/, '');
return baseline;
}
function leftSuperscriptVerbose(node) {
const leftIndex = MathspeakUtil.superscriptVerbose(node);
leftIndex[0].speech = leftIndex[0].speech.replace(/^exposant/, 'exposant gauche');
return leftIndex;
}
function leftSubscriptVerbose(node) {
const leftIndex = MathspeakUtil.subscriptVerbose(node);
leftIndex[0].speech = leftIndex[0].speech.replace(/^indice/, 'indice gauche');
return leftIndex;
}
function leftSuperscriptBrief(node) {
const leftIndex = MathspeakUtil.superscriptBrief(node);
leftIndex[0].speech = leftIndex[0].speech.replace(/^sup/, 'sup gauche');
return leftIndex;
}
function leftSubscriptBrief(node) {
const leftIndex = MathspeakUtil.subscriptBrief(node);
leftIndex[0].speech = leftIndex[0].speech.replace(/^sub/, 'sub gauche');
return leftIndex;
}

View File

@@ -0,0 +1,26 @@
import { Span } from '../audio/span.js';
export declare function nestedFraction(node: Element, expr: string, opt_end?: string): string;
export declare function openingFractionVerbose(node: Element): Span[];
export declare function closingFractionVerbose(node: Element): Span[];
export declare function openingFractionBrief(node: Element): Span[];
export declare function closingFractionBrief(node: Element): Span[];
export declare function openingFractionSbrief(node: Element): Span[];
export declare function closingFractionSbrief(node: Element): Span[];
export declare function overFractionSbrief(node: Element): Span[];
export declare function isSimpleIndex(node: Element): Element[];
export declare function nestedRadical(node: Element, prefix: string, postfix: string): string;
export declare function openingRadicalVerbose(node: Element): Span[];
export declare function closingRadicalVerbose(node: Element): Span[];
export declare function openingRadicalBrief(node: Element): Span[];
export declare function closingRadicalBrief(node: Element): Span[];
export declare function openingRadicalSbrief(node: Element): Span[];
export declare function getRootIndex(node: Element): string;
export declare function indexRadical(node: Element, postfix: string): string;
export declare function indexRadicalVerbose(node: Element): Span[];
export declare function indexRadicalBrief(node: Element): Span[];
export declare function indexRadicalSbrief(node: Element): Span[];
export declare function ordinalConversion(node: Element): Span[];
export declare function decreasedOrdinalConversion(node: Element): Span[];
export declare function listOrdinalConversion(node: Element): Span[];
export declare function checkDepth(node: Element): Element[];
export declare function getDepthValue(node: Element, roleList: string[]): number;

View File

@@ -0,0 +1,151 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nestedFraction = nestedFraction;
exports.openingFractionVerbose = openingFractionVerbose;
exports.closingFractionVerbose = closingFractionVerbose;
exports.openingFractionBrief = openingFractionBrief;
exports.closingFractionBrief = closingFractionBrief;
exports.openingFractionSbrief = openingFractionSbrief;
exports.closingFractionSbrief = closingFractionSbrief;
exports.overFractionSbrief = overFractionSbrief;
exports.isSimpleIndex = isSimpleIndex;
exports.nestedRadical = nestedRadical;
exports.openingRadicalVerbose = openingRadicalVerbose;
exports.closingRadicalVerbose = closingRadicalVerbose;
exports.openingRadicalBrief = openingRadicalBrief;
exports.closingRadicalBrief = closingRadicalBrief;
exports.openingRadicalSbrief = openingRadicalSbrief;
exports.getRootIndex = getRootIndex;
exports.indexRadical = indexRadical;
exports.indexRadicalVerbose = indexRadicalVerbose;
exports.indexRadicalBrief = indexRadicalBrief;
exports.indexRadicalSbrief = indexRadicalSbrief;
exports.ordinalConversion = ordinalConversion;
exports.decreasedOrdinalConversion = decreasedOrdinalConversion;
exports.listOrdinalConversion = listOrdinalConversion;
exports.checkDepth = checkDepth;
exports.getDepthValue = getDepthValue;
const span_js_1 = require("../audio/span.js");
const MathspeakUtil = require("./mathspeak_util.js");
const locale_js_1 = require("../l10n/locale.js");
const XpathUtil = require("../common/xpath_util.js");
function nestedFraction(node, expr, opt_end) {
const depth = MathspeakUtil.fractionNestingDepth(node);
const annotation = [...Array(depth)].map((_x) => expr);
if (opt_end) {
annotation.unshift(opt_end);
}
return annotation.join(locale_js_1.LOCALE.MESSAGES.regexp.JOINER_FRAC);
}
function openingFractionVerbose(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.START, locale_js_1.LOCALE.MESSAGES.MS.FRAC_V));
}
function closingFractionVerbose(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.END, locale_js_1.LOCALE.MESSAGES.MS.FRAC_V));
}
function openingFractionBrief(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.START, locale_js_1.LOCALE.MESSAGES.MS.FRAC_B));
}
function closingFractionBrief(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.END, locale_js_1.LOCALE.MESSAGES.MS.FRAC_B));
}
function openingFractionSbrief(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
if (depth === 1) {
return span_js_1.Span.singleton(locale_js_1.LOCALE.MESSAGES.MS.FRAC_S);
}
return span_js_1.Span.singleton(locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.MESSAGES.MS.FRAC_S));
}
function closingFractionSbrief(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
if (depth === 1) {
return span_js_1.Span.singleton(locale_js_1.LOCALE.MESSAGES.MS.ENDFRAC);
}
return span_js_1.Span.singleton(locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.MESSAGES.MS.ENDFRAC));
}
function overFractionSbrief(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
if (depth === 1) {
return span_js_1.Span.singleton(locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER);
}
return span_js_1.Span.singleton(locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER));
}
function isSimpleIndex(node) {
const index = XpathUtil.evalXPath('children/*[1]', node)[0]
.toString()
.match(/[^>>]+<\/[^>]*>/g);
return index.length === 1 ? [node] : [];
}
function nestedRadical(node, prefix, postfix) {
const depth = MathspeakUtil.radicalNestingDepth(node);
if (depth === 1)
return postfix;
return locale_js_1.LOCALE.FUNCTIONS.combineNestedRadical(locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), prefix, postfix);
}
function openingRadicalVerbose(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NESTED, locale_js_1.LOCALE.MESSAGES.MS.STARTROOT));
}
function closingRadicalVerbose(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NESTED, locale_js_1.LOCALE.MESSAGES.MS.ENDROOT));
}
function openingRadicalBrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.STARTROOT));
}
function closingRadicalBrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.ENDROOT));
}
function openingRadicalSbrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.ROOT));
}
function getRootIndex(node) {
const content = XpathUtil.evalXPath('children/*[1]', node)[0].textContent.trim();
return locale_js_1.LOCALE.MESSAGES.MSroots[content] || content + '제곱근';
}
function indexRadical(node, postfix) {
const index = getRootIndex(node);
return index ? index : postfix;
}
function indexRadicalVerbose(node) {
return span_js_1.Span.singleton(indexRadical(node, locale_js_1.LOCALE.MESSAGES.MS.ROOTINDEX));
}
function indexRadicalBrief(node) {
return span_js_1.Span.singleton(indexRadical(node, locale_js_1.LOCALE.MESSAGES.MS.ROOTINDEX));
}
function indexRadicalSbrief(node) {
return span_js_1.Span.singleton(indexRadical(node, locale_js_1.LOCALE.MESSAGES.MS.INDEX));
}
function ordinalConversion(node) {
const children = XpathUtil.evalXPath('children/*', node);
return span_js_1.Span.singleton(locale_js_1.LOCALE.NUMBERS.wordOrdinal(children.length));
}
function decreasedOrdinalConversion(node) {
const children = XpathUtil.evalXPath('children/*', node);
return span_js_1.Span.singleton(locale_js_1.LOCALE.NUMBERS.wordOrdinal(children.length - 1));
}
function listOrdinalConversion(node) {
const children = XpathUtil.evalXPath('children/*', node);
const content = XpathUtil.evalXPath('content/*', node);
return span_js_1.Span.singleton(locale_js_1.LOCALE.NUMBERS.wordOrdinal(children.length - content.length));
}
function checkDepth(node) {
const roleList = [];
const depth = getDepthValue(node, roleList);
return depth > 3 ? [] : [node];
}
function getDepthValue(node, roleList) {
const role = node.getAttribute('role');
const index = roleList.indexOf(role) > -1;
if (!index) {
roleList.push(role);
}
const children = XpathUtil.evalXPath('children/*', node);
let max = 0, cur = 0;
if (children.length) {
children.forEach((child) => {
cur = getDepthValue(child, roleList);
max = cur > max ? cur : max;
});
return max + 1;
}
return 0;
}

View File

@@ -0,0 +1 @@
export declare function MathspeakRules(): void;

View File

@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MathspeakRules = MathspeakRules;
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const StoreUtil = require("../rule_engine/store_util.js");
const MathspeakFrenchUtil = require("./mathspeak_french_util.js");
const MathspeakKoreanUtil = require("./mathspeak_korean_util.js");
const MathspeakUtil = require("./mathspeak_util.js");
const NumbersUtil = require("./numbers_util.js");
const SpeechRules = require("./speech_rules.js");
const UnitUtil = require("./unit_util.js");
function MathspeakRules() {
SpeechRules.addStore(dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.mathspeak', '', {
CQFspaceoutNumber: MathspeakUtil.spaceoutNumber,
CQFspaceoutIdentifier: MathspeakUtil.spaceoutIdentifier,
CSFspaceoutText: MathspeakUtil.spaceoutText,
CSFopenFracVerbose: MathspeakUtil.openingFractionVerbose,
CSFcloseFracVerbose: MathspeakUtil.closingFractionVerbose,
CSFoverFracVerbose: MathspeakUtil.overFractionVerbose,
CSFopenFracBrief: MathspeakUtil.openingFractionBrief,
CSFcloseFracBrief: MathspeakUtil.closingFractionBrief,
CSFopenFracSbrief: MathspeakUtil.openingFractionSbrief,
CSFcloseFracSbrief: MathspeakUtil.closingFractionSbrief,
CSFoverFracSbrief: MathspeakUtil.overFractionSbrief,
CSFvulgarFraction: NumbersUtil.vulgarFraction,
CQFvulgarFractionSmall: MathspeakUtil.isSmallVulgarFraction,
CSFopenRadicalVerbose: MathspeakUtil.openingRadicalVerbose,
CSFcloseRadicalVerbose: MathspeakUtil.closingRadicalVerbose,
CSFindexRadicalVerbose: MathspeakUtil.indexRadicalVerbose,
CSFopenRadicalBrief: MathspeakUtil.openingRadicalBrief,
CSFcloseRadicalBrief: MathspeakUtil.closingRadicalBrief,
CSFindexRadicalBrief: MathspeakUtil.indexRadicalBrief,
CSFopenRadicalSbrief: MathspeakUtil.openingRadicalSbrief,
CSFindexRadicalSbrief: MathspeakUtil.indexRadicalSbrief,
CQFisSmallRoot: MathspeakUtil.smallRoot,
CSFsuperscriptVerbose: MathspeakUtil.superscriptVerbose,
CSFsuperscriptBrief: MathspeakUtil.superscriptBrief,
CSFsubscriptVerbose: MathspeakUtil.subscriptVerbose,
CSFsubscriptBrief: MathspeakUtil.subscriptBrief,
CSFbaselineVerbose: MathspeakUtil.baselineVerbose,
CSFbaselineBrief: MathspeakUtil.baselineBrief,
CSFleftsuperscriptVerbose: MathspeakUtil.superscriptVerbose,
CSFleftsubscriptVerbose: MathspeakUtil.subscriptVerbose,
CSFrightsuperscriptVerbose: MathspeakUtil.superscriptVerbose,
CSFrightsubscriptVerbose: MathspeakUtil.subscriptVerbose,
CSFleftsuperscriptBrief: MathspeakUtil.superscriptBrief,
CSFleftsubscriptBrief: MathspeakUtil.subscriptBrief,
CSFrightsuperscriptBrief: MathspeakUtil.superscriptBrief,
CSFrightsubscriptBrief: MathspeakUtil.subscriptBrief,
CSFunderscript: MathspeakUtil.nestedUnderscript,
CSFoverscript: MathspeakUtil.nestedOverscript,
CSFendscripts: MathspeakUtil.endscripts,
CTFordinalCounter: NumbersUtil.ordinalCounter,
CTFwordCounter: NumbersUtil.wordCounter,
CTFcontentIterator: StoreUtil.contentIterator,
CQFdetIsSimple: MathspeakUtil.determinantIsSimple,
CSFRemoveParens: MathspeakUtil.removeParens,
CQFresetNesting: MathspeakUtil.resetNestingDepth,
CGFbaselineConstraint: MathspeakUtil.generateBaselineConstraint,
CGFtensorRules: MathspeakUtil.generateTensorRules
});
SpeechRules.addStore('es.speech.mathspeak', dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.mathspeak', {
CTFunitMultipliers: UnitUtil.unitMultipliers,
CQFoneLeft: UnitUtil.oneLeft
});
SpeechRules.addStore('fr.speech.mathspeak', dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.mathspeak', {
CSFbaselineVerbose: MathspeakFrenchUtil.baselineVerbose,
CSFbaselineBrief: MathspeakFrenchUtil.baselineBrief,
CSFleftsuperscriptVerbose: MathspeakFrenchUtil.leftSuperscriptVerbose,
CSFleftsubscriptVerbose: MathspeakFrenchUtil.leftSubscriptVerbose,
CSFleftsuperscriptBrief: MathspeakFrenchUtil.leftSuperscriptBrief,
CSFleftsubscriptBrief: MathspeakFrenchUtil.leftSubscriptBrief
});
SpeechRules.addStore('ko.speech.mathspeak', dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.mathspeak', {
CSFopenFracVerbose: MathspeakKoreanUtil.openingFractionVerbose,
CSFcloseFracVerbose: MathspeakKoreanUtil.closingFractionVerbose,
CSFopenFracBrief: MathspeakKoreanUtil.openingFractionBrief,
CSFcloseFracBrief: MathspeakKoreanUtil.closingFractionBrief,
CSFopenFracSbrief: MathspeakKoreanUtil.openingFractionSbrief,
CSFoverFracSbrief: MathspeakKoreanUtil.overFractionSbrief,
CSFcloseFracSbrief: MathspeakKoreanUtil.closingFractionSbrief,
CQFisSimpleIndex: MathspeakKoreanUtil.isSimpleIndex,
CSFindexRadicalVerbose: MathspeakKoreanUtil.indexRadicalVerbose,
CSFindexRadicalBrief: MathspeakKoreanUtil.indexRadicalBrief,
CSFindexRadicalSbrief: MathspeakKoreanUtil.indexRadicalSbrief,
CSFopenRadicalVerbose: MathspeakKoreanUtil.openingRadicalVerbose,
CSFcloseRadicalVerbose: MathspeakKoreanUtil.closingRadicalVerbose,
CSFopenRadicalBrief: MathspeakKoreanUtil.openingRadicalBrief,
CSFcloseRadicalBrief: MathspeakKoreanUtil.closingRadicalBrief,
CSFopenRadicalSbrief: MathspeakKoreanUtil.openingRadicalSbrief
});
}

View File

@@ -0,0 +1,43 @@
import { Span } from '../audio/span.js';
import { SpeechRuleStore } from '../rule_engine/speech_rule_store.js';
export declare function spaceoutText(node: Element): Span[];
export declare function spaceoutNumber(node: Element): Element[];
export declare function spaceoutIdentifier(node: Element): Element[];
export declare function resetNestingDepth(node: Element): Element[];
export declare function fractionNestingDepth(node: Element): number;
export declare function openingFractionVerbose(node: Element): Span[];
export declare function closingFractionVerbose(node: Element): Span[];
export declare function overFractionVerbose(node: Element): Span[];
export declare function openingFractionBrief(node: Element): Span[];
export declare function closingFractionBrief(node: Element): Span[];
export declare function openingFractionSbrief(node: Element): Span[];
export declare function closingFractionSbrief(node: Element): Span[];
export declare function overFractionSbrief(node: Element): Span[];
export declare function isSmallVulgarFraction(node: Element): Element[];
export declare function nestedSubSuper(node: Element, init: string, replace: {
sup: string;
sub: string;
}): string;
export declare function subscriptVerbose(node: Element): Span[];
export declare function subscriptBrief(node: Element): Span[];
export declare function superscriptVerbose(node: Element): Span[];
export declare function superscriptBrief(node: Element): Span[];
export declare function baselineVerbose(node: Element): Span[];
export declare function baselineBrief(node: Element): Span[];
export declare function radicalNestingDepth(node: Element): number;
export declare function openingRadicalVerbose(node: Element): Span[];
export declare function closingRadicalVerbose(node: Element): Span[];
export declare function indexRadicalVerbose(node: Element): Span[];
export declare function openingRadicalBrief(node: Element): Span[];
export declare function closingRadicalBrief(node: Element): Span[];
export declare function indexRadicalBrief(node: Element): Span[];
export declare function openingRadicalSbrief(node: Element): Span[];
export declare function indexRadicalSbrief(node: Element): Span[];
export declare function nestedUnderscript(node: Element): Span[];
export declare function endscripts(_node: Element): Span[];
export declare function nestedOverscript(node: Element): Span[];
export declare function determinantIsSimple(node: Element): Element[];
export declare function generateBaselineConstraint(): string[];
export declare function removeParens(node: Element): Span[];
export declare function generateTensorRules(store: SpeechRuleStore, brief?: boolean): void;
export declare function smallRoot(node: Element): Element[];

View File

@@ -0,0 +1,482 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.spaceoutText = spaceoutText;
exports.spaceoutNumber = spaceoutNumber;
exports.spaceoutIdentifier = spaceoutIdentifier;
exports.resetNestingDepth = resetNestingDepth;
exports.fractionNestingDepth = fractionNestingDepth;
exports.openingFractionVerbose = openingFractionVerbose;
exports.closingFractionVerbose = closingFractionVerbose;
exports.overFractionVerbose = overFractionVerbose;
exports.openingFractionBrief = openingFractionBrief;
exports.closingFractionBrief = closingFractionBrief;
exports.openingFractionSbrief = openingFractionSbrief;
exports.closingFractionSbrief = closingFractionSbrief;
exports.overFractionSbrief = overFractionSbrief;
exports.isSmallVulgarFraction = isSmallVulgarFraction;
exports.nestedSubSuper = nestedSubSuper;
exports.subscriptVerbose = subscriptVerbose;
exports.subscriptBrief = subscriptBrief;
exports.superscriptVerbose = superscriptVerbose;
exports.superscriptBrief = superscriptBrief;
exports.baselineVerbose = baselineVerbose;
exports.baselineBrief = baselineBrief;
exports.radicalNestingDepth = radicalNestingDepth;
exports.openingRadicalVerbose = openingRadicalVerbose;
exports.closingRadicalVerbose = closingRadicalVerbose;
exports.indexRadicalVerbose = indexRadicalVerbose;
exports.openingRadicalBrief = openingRadicalBrief;
exports.closingRadicalBrief = closingRadicalBrief;
exports.indexRadicalBrief = indexRadicalBrief;
exports.openingRadicalSbrief = openingRadicalSbrief;
exports.indexRadicalSbrief = indexRadicalSbrief;
exports.nestedUnderscript = nestedUnderscript;
exports.endscripts = endscripts;
exports.nestedOverscript = nestedOverscript;
exports.determinantIsSimple = determinantIsSimple;
exports.generateBaselineConstraint = generateBaselineConstraint;
exports.removeParens = removeParens;
exports.generateTensorRules = generateTensorRules;
exports.smallRoot = smallRoot;
const span_js_1 = require("../audio/span.js");
const BaseUtil = require("../common/base_util.js");
const DomUtil = require("../common/dom_util.js");
const XpathUtil = require("../common/xpath_util.js");
const locale_js_1 = require("../l10n/locale.js");
const semantic_meaning_js_1 = require("../semantic_tree/semantic_meaning.js");
const semantic_processor_js_1 = require("../semantic_tree/semantic_processor.js");
let nestingDepth = {};
function spaceoutText(node) {
return Array.from(node.textContent).map(span_js_1.Span.stringEmpty);
}
function spaceoutNodes(node, correction) {
const content = Array.from(node.textContent);
const result = [];
const processor = semantic_processor_js_1.SemanticProcessor.getInstance();
const doc = node.ownerDocument;
for (let i = 0, chr; (chr = content[i]); i++) {
const leaf = processor
.getNodeFactory()
.makeLeafNode(chr, semantic_meaning_js_1.SemanticFont.UNKNOWN);
const sn = processor.identifierNode(leaf, semantic_meaning_js_1.SemanticFont.UNKNOWN, '');
correction(sn);
result.push(sn.xml(doc));
}
return result;
}
function spaceoutNumber(node) {
return spaceoutNodes(node, function (sn) {
if (!sn.textContent.match(/\W/)) {
sn.type = semantic_meaning_js_1.SemanticType.NUMBER;
}
});
}
function spaceoutIdentifier(node) {
return spaceoutNodes(node, function (sn) {
sn.font = semantic_meaning_js_1.SemanticFont.UNKNOWN;
sn.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
});
}
const nestingBarriers = [
semantic_meaning_js_1.SemanticType.CASES,
semantic_meaning_js_1.SemanticType.CELL,
semantic_meaning_js_1.SemanticType.INTEGRAL,
semantic_meaning_js_1.SemanticType.LINE,
semantic_meaning_js_1.SemanticType.MATRIX,
semantic_meaning_js_1.SemanticType.MULTILINE,
semantic_meaning_js_1.SemanticType.OVERSCORE,
semantic_meaning_js_1.SemanticType.ROOT,
semantic_meaning_js_1.SemanticType.ROW,
semantic_meaning_js_1.SemanticType.SQRT,
semantic_meaning_js_1.SemanticType.SUBSCRIPT,
semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
semantic_meaning_js_1.SemanticType.TABLE,
semantic_meaning_js_1.SemanticType.UNDERSCORE,
semantic_meaning_js_1.SemanticType.VECTOR
];
function resetNestingDepth(node) {
nestingDepth = {};
return [node];
}
function getNestingDepth(type, node, tags, opt_barrierTags, opt_barrierAttrs, opt_func) {
opt_barrierTags = opt_barrierTags || nestingBarriers;
opt_barrierAttrs = opt_barrierAttrs || {};
opt_func =
opt_func ||
function (_node) {
return false;
};
const xmlText = DomUtil.serializeXml(node);
if (!nestingDepth[type]) {
nestingDepth[type] = {};
}
if (nestingDepth[type][xmlText]) {
return nestingDepth[type][xmlText];
}
if (opt_func(node) || tags.indexOf(node.tagName) < 0) {
return 0;
}
const depth = computeNestingDepth_(node, tags, BaseUtil.setdifference(opt_barrierTags, tags), opt_barrierAttrs, opt_func, 0);
nestingDepth[type][xmlText] = depth;
return depth;
}
function containsAttr(node, attrs) {
if (!node.attributes) {
return false;
}
const attributes = DomUtil.toArray(node.attributes);
for (let i = 0, attr; (attr = attributes[i]); i++) {
if (attrs[attr.nodeName] === attr.nodeValue) {
return true;
}
}
return false;
}
function computeNestingDepth_(node, tags, barriers, attrs, func, depth) {
if (func(node) ||
barriers.indexOf(node.tagName) > -1 ||
containsAttr(node, attrs)) {
return depth;
}
if (tags.indexOf(node.tagName) > -1) {
depth++;
}
if (!node.childNodes || node.childNodes.length === 0) {
return depth;
}
const children = DomUtil.toArray(node.childNodes);
return Math.max.apply(null, children.map(function (subNode) {
return computeNestingDepth_(subNode, tags, barriers, attrs, func, depth);
}));
}
function fractionNestingDepth(node) {
return getNestingDepth('fraction', node, ['fraction'], nestingBarriers, {}, locale_js_1.LOCALE.FUNCTIONS.fracNestDepth);
}
function nestedFraction(node, expr, opt_end) {
const depth = fractionNestingDepth(node);
const annotation = Array(depth).fill(expr);
if (opt_end) {
annotation.push(opt_end);
}
return annotation.join(locale_js_1.LOCALE.MESSAGES.regexp.JOINER_FRAC);
}
function openingFractionVerbose(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.START, locale_js_1.LOCALE.MESSAGES.MS.FRAC_V));
}
function closingFractionVerbose(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.END, locale_js_1.LOCALE.MESSAGES.MS.FRAC_V), { kind: 'LAST' });
}
function overFractionVerbose(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER), {});
}
function openingFractionBrief(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.START, locale_js_1.LOCALE.MESSAGES.MS.FRAC_B));
}
function closingFractionBrief(node) {
return span_js_1.Span.singleton(nestedFraction(node, locale_js_1.LOCALE.MESSAGES.MS.END, locale_js_1.LOCALE.MESSAGES.MS.FRAC_B), { kind: 'LAST' });
}
function openingFractionSbrief(node) {
const depth = fractionNestingDepth(node);
return span_js_1.Span.singleton(depth === 1
? locale_js_1.LOCALE.MESSAGES.MS.FRAC_S
: locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.FRAC_S));
}
function closingFractionSbrief(node) {
const depth = fractionNestingDepth(node);
return span_js_1.Span.singleton(depth === 1
? locale_js_1.LOCALE.MESSAGES.MS.ENDFRAC
: locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.ENDFRAC), { kind: 'LAST' });
}
function overFractionSbrief(node) {
const depth = fractionNestingDepth(node);
return span_js_1.Span.singleton(depth === 1
? locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER
: locale_js_1.LOCALE.FUNCTIONS.combineNestedFraction(locale_js_1.LOCALE.MESSAGES.MS.NEST_FRAC, locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER));
}
function isSmallVulgarFraction(node) {
return locale_js_1.LOCALE.FUNCTIONS.fracNestDepth(node) ? [node] : [];
}
function nestedSubSuper(node, init, replace) {
while (node.parentNode) {
const children = node.parentNode;
const parent = children.parentNode;
if (!parent) {
break;
}
const nodeRole = node.getAttribute && node.getAttribute('role');
if ((parent.tagName === semantic_meaning_js_1.SemanticType.SUBSCRIPT &&
node === children.childNodes[1]) ||
(parent.tagName === semantic_meaning_js_1.SemanticType.TENSOR &&
nodeRole &&
(nodeRole === semantic_meaning_js_1.SemanticRole.LEFTSUB ||
nodeRole === semantic_meaning_js_1.SemanticRole.RIGHTSUB))) {
init = replace.sub + locale_js_1.LOCALE.MESSAGES.regexp.JOINER_SUBSUPER + init;
}
if ((parent.tagName === semantic_meaning_js_1.SemanticType.SUPERSCRIPT &&
node === children.childNodes[1]) ||
(parent.tagName === semantic_meaning_js_1.SemanticType.TENSOR &&
nodeRole &&
(nodeRole === semantic_meaning_js_1.SemanticRole.LEFTSUPER ||
nodeRole === semantic_meaning_js_1.SemanticRole.RIGHTSUPER))) {
init = replace.sup + locale_js_1.LOCALE.MESSAGES.regexp.JOINER_SUBSUPER + init;
}
node = parent;
}
return init.trim();
}
function subscriptVerbose(node) {
return span_js_1.Span.singleton(nestedSubSuper(node, locale_js_1.LOCALE.MESSAGES.MS.SUBSCRIPT, {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUPER,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
}));
}
function subscriptBrief(node) {
return span_js_1.Span.singleton(nestedSubSuper(node, locale_js_1.LOCALE.MESSAGES.MS.SUB, {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUP,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
}));
}
function superscriptVerbose(node) {
return span_js_1.Span.singleton(nestedSubSuper(node, locale_js_1.LOCALE.MESSAGES.MS.SUPERSCRIPT, {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUPER,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
}));
}
function superscriptBrief(node) {
return span_js_1.Span.singleton(nestedSubSuper(node, locale_js_1.LOCALE.MESSAGES.MS.SUP, {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUP,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
}));
}
function baselineVerbose(node) {
const baseline = nestedSubSuper(node, '', {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUPER,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
});
return span_js_1.Span.singleton(!baseline
? locale_js_1.LOCALE.MESSAGES.MS.BASELINE
: baseline
.replace(new RegExp(locale_js_1.LOCALE.MESSAGES.MS.SUB + '$'), locale_js_1.LOCALE.MESSAGES.MS.SUBSCRIPT)
.replace(new RegExp(locale_js_1.LOCALE.MESSAGES.MS.SUPER + '$'), locale_js_1.LOCALE.MESSAGES.MS.SUPERSCRIPT));
}
function baselineBrief(node) {
const baseline = nestedSubSuper(node, '', {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUP,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
});
return span_js_1.Span.singleton(baseline || locale_js_1.LOCALE.MESSAGES.MS.BASE);
}
function radicalNestingDepth(node) {
return getNestingDepth('radical', node, ['sqrt', 'root'], nestingBarriers, {});
}
function nestedRadical(node, prefix, postfix) {
const depth = radicalNestingDepth(node);
const index = getRootIndex(node);
postfix = index ? locale_js_1.LOCALE.FUNCTIONS.combineRootIndex(postfix, index) : postfix;
return depth === 1
? postfix
: locale_js_1.LOCALE.FUNCTIONS.combineNestedRadical(prefix, locale_js_1.LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), postfix);
}
function getRootIndex(node) {
const content = node.tagName === 'sqrt'
? '2'
:
XpathUtil.evalXPath('children/*[1]', node)[0].textContent.trim();
return locale_js_1.LOCALE.MESSAGES.MSroots[content] || '';
}
function openingRadicalVerbose(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NESTED, locale_js_1.LOCALE.MESSAGES.MS.STARTROOT));
}
function closingRadicalVerbose(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NESTED, locale_js_1.LOCALE.MESSAGES.MS.ENDROOT));
}
function indexRadicalVerbose(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NESTED, locale_js_1.LOCALE.MESSAGES.MS.ROOTINDEX));
}
function openingRadicalBrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.STARTROOT));
}
function closingRadicalBrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.ENDROOT));
}
function indexRadicalBrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.ROOTINDEX));
}
function openingRadicalSbrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.ROOT));
}
function indexRadicalSbrief(node) {
return span_js_1.Span.singleton(nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.NEST_ROOT, locale_js_1.LOCALE.MESSAGES.MS.INDEX));
}
function underscoreNestingDepth(node) {
return getNestingDepth('underscore', node, ['underscore'], nestingBarriers, {}, function (node) {
return (node.tagName &&
node.tagName === semantic_meaning_js_1.SemanticType.UNDERSCORE &&
node.childNodes[0].childNodes[1].getAttribute('role') ===
semantic_meaning_js_1.SemanticRole.UNDERACCENT);
});
}
function nestedUnderscript(node) {
const depth = underscoreNestingDepth(node);
return span_js_1.Span.singleton(Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.UNDER) + locale_js_1.LOCALE.MESSAGES.MS.UNDERSCRIPT);
}
function overscoreNestingDepth(node) {
return getNestingDepth('overscore', node, ['overscore'], nestingBarriers, {}, function (node) {
return (node.tagName &&
node.tagName === semantic_meaning_js_1.SemanticType.OVERSCORE &&
node.childNodes[0].childNodes[1].getAttribute('role') ===
semantic_meaning_js_1.SemanticRole.OVERACCENT);
});
}
function endscripts(_node) {
return span_js_1.Span.singleton(locale_js_1.LOCALE.MESSAGES.MS.ENDSCRIPTS);
}
function nestedOverscript(node) {
const depth = overscoreNestingDepth(node);
return span_js_1.Span.singleton(Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.OVER) + locale_js_1.LOCALE.MESSAGES.MS.OVERSCRIPT);
}
function determinantIsSimple(node) {
if (node.tagName !== semantic_meaning_js_1.SemanticType.MATRIX ||
node.getAttribute('role') !== semantic_meaning_js_1.SemanticRole.DETERMINANT) {
return [];
}
const cells = XpathUtil.evalXPath('children/row/children/cell/children/*', node);
for (let i = 0, cell; (cell = cells[i]); i++) {
if (cell.tagName === semantic_meaning_js_1.SemanticType.NUMBER) {
continue;
}
if (cell.tagName === semantic_meaning_js_1.SemanticType.IDENTIFIER) {
const role = cell.getAttribute('role');
if (role === semantic_meaning_js_1.SemanticRole.LATINLETTER ||
role === semantic_meaning_js_1.SemanticRole.GREEKLETTER ||
role === semantic_meaning_js_1.SemanticRole.OTHERLETTER) {
continue;
}
}
return [];
}
return [node];
}
function generateBaselineConstraint() {
const ignoreElems = ['subscript', 'superscript', 'tensor'];
const mainElems = ['relseq', 'multrel'];
const breakElems = ['fraction', 'punctuation', 'fenced', 'sqrt', 'root'];
const ancestrify = (elemList) => elemList.map((elem) => 'ancestor::' + elem);
const notify = (elem) => 'not(' + elem + ')';
const prefix = 'ancestor::*/following-sibling::*';
const middle = notify(ancestrify(ignoreElems).join(' or '));
const mainList = ancestrify(mainElems);
const breakList = ancestrify(breakElems);
let breakCstrs = [];
for (let i = 0, brk; (brk = breakList[i]); i++) {
breakCstrs = breakCstrs.concat(mainList.map(function (elem) {
return brk + '/' + elem;
}));
}
const postfix = notify(breakCstrs.join(' | '));
return [[prefix, middle, postfix].join(' and ')];
}
function removeParens(node) {
if (!node.childNodes.length ||
!node.childNodes[0].childNodes.length ||
!node.childNodes[0].childNodes[0].childNodes.length) {
return span_js_1.Span.singleton('');
}
const content = node.childNodes[0].childNodes[0].childNodes[0].textContent;
return span_js_1.Span.singleton(content.match(/^\(.+\)$/) ? content.slice(1, -1) : content);
}
const componentString = new Map([
[3, 'CSFleftsuperscript'],
[4, 'CSFleftsubscript'],
[2, 'CSFbaseline'],
[1, 'CSFrightsubscript'],
[0, 'CSFrightsuperscript']
]);
const childNumber = new Map([
[4, 2],
[3, 3],
[2, 1],
[1, 4],
[0, 5]
]);
function generateTensorRuleStrings_(constellation) {
const constraints = [];
let verbString = '';
let briefString = '';
let constel = parseInt(constellation, 2);
for (let i = 0; i < 5; i++) {
const childString = 'children/*[' + childNumber.get(i) + ']';
if (constel & 1) {
const compString = componentString.get(i % 5);
verbString =
'[t] ' + compString + 'Verbose; [n] ' + childString + ';' + verbString;
briefString =
'[t] ' + compString + 'Brief; [n] ' + childString + ';' + briefString;
}
else {
constraints.unshift('name(' + childString + ')="empty"');
}
constel >>= 1;
}
return [constraints, verbString, briefString];
}
function generateTensorRules(store, brief = true) {
const constellations = [
'11111',
'11110',
'11101',
'11100',
'10111',
'10110',
'10101',
'10100',
'01111',
'01110',
'01101',
'01100'
];
for (const constel of constellations) {
let name = 'tensor' + constel;
let [components, verbStr, briefStr] = generateTensorRuleStrings_(constel);
store.defineRule(name, 'default', verbStr, 'self::tensor', ...components);
if (brief) {
store.defineRule(name, 'brief', briefStr, 'self::tensor', ...components);
store.defineRule(name, 'sbrief', briefStr, 'self::tensor', ...components);
}
if (!(parseInt(constel, 2) & 3)) {
continue;
}
const baselineStr = componentString.get(2);
verbStr += '; [t]' + baselineStr + 'Verbose';
briefStr += '; [t]' + baselineStr + 'Brief';
name = name + '-baseline';
const cstr = '((.//*[not(*)])[last()]/@id)!=(((.//ancestor::fraction|' +
'ancestor::root|ancestor::sqrt|ancestor::cell|ancestor::line|' +
'ancestor::stree)[1]//*[not(*)])[last()]/@id)';
store.defineRule(name, 'default', verbStr, 'self::tensor', cstr, ...components);
if (brief) {
store.defineRule(name, 'brief', briefStr, 'self::tensor', cstr, ...components);
store.defineRule(name, 'sbrief', briefStr, 'self::tensor', cstr, ...components);
}
}
}
function smallRoot(node) {
let max = Object.keys(locale_js_1.LOCALE.MESSAGES.MSroots).length;
if (!max) {
return [];
}
else {
max++;
}
if (!node.childNodes ||
node.childNodes.length === 0 ||
!node.childNodes[0].childNodes) {
return [];
}
const index = node.childNodes[0].childNodes[0].textContent;
if (!/^\d+$/.test(index)) {
return [];
}
const num = parseInt(index, 10);
return num > 1 && num <= max ? [node] : [];
}

View File

@@ -0,0 +1,13 @@
import { AuditoryDescription } from '../audio/auditory_description.js';
import { Span } from '../audio/span.js';
export declare function openingFraction(node: Element): Span[];
export declare function closingFraction(node: Element): Span[];
export declare function overFraction(node: Element): Span[];
export declare function overBevelledFraction(node: Element): Span[];
export declare function hyperFractionBoundary(node: Element): Element[];
export declare function openingRadical(node: Element): Span[];
export declare function closingRadical(node: Element): Span[];
export declare function indexRadical(node: Element): Span[];
export declare function relationIterator(nodes: Element[], context: string): () => AuditoryDescription[];
export declare function implicitIterator(nodes: Element[], context: string): () => AuditoryDescription[];
export declare function contentIterator(nodes: Element[], context: string): () => AuditoryDescription[];

View File

@@ -0,0 +1,265 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.openingFraction = openingFraction;
exports.closingFraction = closingFraction;
exports.overFraction = overFraction;
exports.overBevelledFraction = overBevelledFraction;
exports.hyperFractionBoundary = hyperFractionBoundary;
exports.openingRadical = openingRadical;
exports.closingRadical = closingRadical;
exports.indexRadical = indexRadical;
exports.relationIterator = relationIterator;
exports.implicitIterator = implicitIterator;
exports.contentIterator = contentIterator;
const auditory_description_js_1 = require("../audio/auditory_description.js");
const span_js_1 = require("../audio/span.js");
const DomUtil = require("../common/dom_util.js");
const XpathUtil = require("../common/xpath_util.js");
const grammar_js_1 = require("../rule_engine/grammar.js");
const engine_js_1 = require("../common/engine.js");
const semantic_annotations_js_1 = require("../semantic_tree/semantic_annotations.js");
const semantic_annotator_js_1 = require("../semantic_tree/semantic_annotator.js");
const semantic_meaning_js_1 = require("../semantic_tree/semantic_meaning.js");
const locale_js_1 = require("../l10n/locale.js");
const MathspeakUtil = require("./mathspeak_util.js");
const store_util_js_1 = require("../rule_engine/store_util.js");
function openingFraction(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
return span_js_1.Span.singleton(new Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
locale_js_1.LOCALE.MESSAGES.MS.FRACTION_START);
}
function closingFraction(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
return span_js_1.Span.singleton(new Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
locale_js_1.LOCALE.MESSAGES.MS.FRACTION_END);
}
function overFraction(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
return span_js_1.Span.singleton(new Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
locale_js_1.LOCALE.MESSAGES.MS.FRACTION_OVER);
}
function overBevelledFraction(node) {
const depth = MathspeakUtil.fractionNestingDepth(node);
return span_js_1.Span.singleton(new Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
'⠸' +
locale_js_1.LOCALE.MESSAGES.MS.FRACTION_OVER);
}
function hyperFractionBoundary(node) {
return locale_js_1.LOCALE.MESSAGES.regexp.HYPER ===
MathspeakUtil.fractionNestingDepth(node).toString()
? [node]
: [];
}
function nestedRadical(node, postfix) {
const depth = radicalNestingDepth(node);
return span_js_1.Span.singleton(depth === 1
? postfix
: new Array(depth).join(locale_js_1.LOCALE.MESSAGES.MS.NESTED) + postfix);
}
function radicalNestingDepth(node, opt_depth) {
const depth = opt_depth || 0;
if (!node.parentNode) {
return depth;
}
return radicalNestingDepth(node.parentNode, node.tagName === 'root' || node.tagName === 'sqrt' ? depth + 1 : depth);
}
function openingRadical(node) {
return nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.STARTROOT);
}
function closingRadical(node) {
return nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.ENDROOT);
}
function indexRadical(node) {
return nestedRadical(node, locale_js_1.LOCALE.MESSAGES.MS.ROOTINDEX);
}
function enlargeFence(text) {
const start = '⠠';
if (text.length === 1) {
return start + text;
}
const neut = '⠳';
const split = text.split('');
if (split.every(function (x) {
return x === neut;
})) {
return start + split.join(start);
}
return text.slice(0, -1) + start + text.slice(-1);
}
grammar_js_1.Grammar.getInstance().setCorrection('enlargeFence', enlargeFence);
const NUMBER_PROPAGATORS = [
semantic_meaning_js_1.SemanticType.MULTIREL,
semantic_meaning_js_1.SemanticType.RELSEQ,
semantic_meaning_js_1.SemanticType.APPL,
semantic_meaning_js_1.SemanticType.ROW,
semantic_meaning_js_1.SemanticType.LINE
];
const NUMBER_INHIBITORS = [
semantic_meaning_js_1.SemanticType.SUBSCRIPT,
semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
semantic_meaning_js_1.SemanticType.OVERSCORE,
semantic_meaning_js_1.SemanticType.UNDERSCORE
];
function checkParent(node, info) {
const parent = node.parent;
if (!parent) {
return false;
}
const type = parent.type;
if (NUMBER_PROPAGATORS.indexOf(type) !== -1 ||
(type === semantic_meaning_js_1.SemanticType.PREFIXOP &&
parent.role === semantic_meaning_js_1.SemanticRole.NEGATIVE &&
!info.script &&
!info.enclosed) ||
(type === semantic_meaning_js_1.SemanticType.PREFIXOP &&
parent.role === semantic_meaning_js_1.SemanticRole.GEOMETRY)) {
return true;
}
if (type === semantic_meaning_js_1.SemanticType.PUNCTUATED) {
if (!info.enclosed || parent.role === semantic_meaning_js_1.SemanticRole.TEXT) {
return true;
}
}
return false;
}
function propagateNumber(node, info) {
if (!node.childNodes.length) {
if (checkParent(node, info)) {
info.number = true;
info.script = false;
info.enclosed = false;
}
return [
info['number'] ? 'number' : '',
{ number: false, enclosed: info.enclosed, script: info.script }
];
}
if (NUMBER_INHIBITORS.indexOf(node.type) !== -1) {
info.script = true;
}
if (node.type === semantic_meaning_js_1.SemanticType.FENCED) {
info.number = false;
info.enclosed = true;
return ['', info];
}
if (node.type === semantic_meaning_js_1.SemanticType.PREFIXOP &&
node.role !== semantic_meaning_js_1.SemanticRole.GEOMETRY &&
node.role !== semantic_meaning_js_1.SemanticRole.NEGATIVE) {
info.number = false;
return ['', info];
}
if (checkParent(node, info)) {
info.number = true;
info.enclosed = false;
}
return ['', info];
}
(0, semantic_annotations_js_1.register)(new semantic_annotator_js_1.SemanticVisitor('nemeth', 'number', propagateNumber, { number: true }));
function annotateDepth(node) {
if (!node.parent) {
return [1];
}
const depth = parseInt(node.parent.annotation['depth'][0]);
return [depth + 1];
}
(0, semantic_annotations_js_1.register)(new semantic_annotator_js_1.SemanticVisitor('depth', 'depth', annotateDepth));
(0, semantic_annotations_js_1.activate)('depth', 'depth');
function relationIterator(nodes, context) {
var _a;
const childNodes = nodes.slice(0);
let first = true;
const parentNode = nodes[0].parentNode.parentNode;
const match = (_a = parentNode.getAttribute('annotation')) === null || _a === void 0 ? void 0 : _a.match(/depth:(\d+)/);
const depth = match ? match[1] : '';
let contentNodes;
if (nodes.length > 0) {
contentNodes = XpathUtil.evalXPath('./content/*', parentNode);
}
else {
contentNodes = [];
}
return function () {
const content = contentNodes.shift();
const leftChild = childNodes.shift();
const rightChild = childNodes[0];
const contextDescr = context
? [auditory_description_js_1.AuditoryDescription.create({ text: context }, { translate: true })]
: [];
if (!content) {
return contextDescr;
}
const base = leftChild
? MathspeakUtil.nestedSubSuper(leftChild, '', {
sup: locale_js_1.LOCALE.MESSAGES.MS.SUPER,
sub: locale_js_1.LOCALE.MESSAGES.MS.SUB
})
: '';
const left = (leftChild && DomUtil.tagName(leftChild) !== 'EMPTY') ||
(first && parentNode && parentNode.previousSibling)
? [
auditory_description_js_1.AuditoryDescription.create({ text: locale_js_1.LOCALE.MESSAGES.regexp.SPACE + base }, {})
]
: [];
const right = (rightChild && DomUtil.tagName(rightChild) !== 'EMPTY') ||
(!contentNodes.length && parentNode && parentNode.nextSibling)
? [
auditory_description_js_1.AuditoryDescription.create({ text: locale_js_1.LOCALE.MESSAGES.regexp.SPACE }, {})
]
: [];
const descrs = engine_js_1.Engine.evaluateNode(content);
descrs.unshift(new auditory_description_js_1.AuditoryDescription({ text: '', layout: `beginrel${depth}` }));
descrs.push(new auditory_description_js_1.AuditoryDescription({ text: '', layout: `endrel${depth}` }));
first = false;
return contextDescr.concat(left, descrs, right);
};
}
function implicitIterator(nodes, context) {
const childNodes = nodes.slice(0);
let contentNodes;
if (nodes.length > 0) {
contentNodes = XpathUtil.evalXPath('../../content/*', nodes[0]);
}
else {
contentNodes = [];
}
return function () {
const leftChild = childNodes.shift();
const rightChild = childNodes[0];
const content = contentNodes.shift();
const contextDescr = context
? [auditory_description_js_1.AuditoryDescription.create({ text: context }, { translate: true })]
: [];
if (!content) {
return contextDescr;
}
const left = leftChild && DomUtil.tagName(leftChild) === 'NUMBER';
const right = rightChild && DomUtil.tagName(rightChild) === 'NUMBER';
return contextDescr.concat(left && right && content.getAttribute('role') === semantic_meaning_js_1.SemanticRole.SPACE
? [
auditory_description_js_1.AuditoryDescription.create({ text: locale_js_1.LOCALE.MESSAGES.regexp.SPACE }, {})
]
: []);
};
}
function ignoreEnglish(text) {
return (0, grammar_js_1.correctFont)(text, locale_js_1.LOCALE.ALPHABETS.languagePrefix.english);
}
grammar_js_1.Grammar.getInstance().setCorrection('ignoreEnglish', ignoreEnglish);
function contentIterator(nodes, context) {
var _a;
const func = (0, store_util_js_1.contentIterator)(nodes, context);
const parentNode = nodes[0].parentNode.parentNode;
const match = (_a = parentNode.getAttribute('annotation')) === null || _a === void 0 ? void 0 : _a.match(/depth:(\d+)/);
const depth = match ? match[1] : '';
return function () {
const descrs = func();
descrs.unshift(new auditory_description_js_1.AuditoryDescription({ text: '', layout: `beginrel${depth}` }));
descrs.push(new auditory_description_js_1.AuditoryDescription({ text: '', layout: `endrel${depth}` }));
return descrs;
};
}
function literal(text) {
const evalStr = (e) => engine_js_1.Engine.getInstance().evaluator(e, engine_js_1.Engine.getInstance().dynamicCstr);
return Array.from(text).map(evalStr).join('');
}
grammar_js_1.Grammar.getInstance().setCorrection('literal', literal);

View File

@@ -0,0 +1,5 @@
import { Span } from '../audio/span.js';
export declare function ordinalCounter(_node: Element, context: string): () => string;
export declare function wordCounter(_node: Element, context: string): () => string;
export declare function vulgarFraction(node: Element): Span[];
export declare function ordinalPosition(node: Element): Span[];

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ordinalCounter = ordinalCounter;
exports.wordCounter = wordCounter;
exports.vulgarFraction = vulgarFraction;
exports.ordinalPosition = ordinalPosition;
const span_js_1 = require("../audio/span.js");
const DomUtil = require("../common/dom_util.js");
const locale_js_1 = require("../l10n/locale.js");
const transformers_js_1 = require("../l10n/transformers.js");
function ordinalCounter(_node, context) {
let counter = 0;
return function () {
return locale_js_1.LOCALE.NUMBERS.numericOrdinal(++counter) + ' ' + context;
};
}
function wordCounter(_node, context) {
let counter = 0;
return function () {
return locale_js_1.LOCALE.NUMBERS.numberToOrdinal(++counter, false) + ' ' + context;
};
}
function vulgarFraction(node) {
const conversion = (0, transformers_js_1.convertVulgarFraction)(node, locale_js_1.LOCALE.MESSAGES.MS.FRAC_OVER);
if (conversion.convertible &&
conversion.enumerator &&
conversion.denominator) {
return [
span_js_1.Span.node(locale_js_1.LOCALE.NUMBERS.numberToWords(conversion.enumerator), node.childNodes[0].childNodes[0], { separator: '' }),
span_js_1.Span.stringAttr(locale_js_1.LOCALE.NUMBERS.vulgarSep, { separator: '' }),
span_js_1.Span.node(locale_js_1.LOCALE.NUMBERS.numberToOrdinal(conversion.denominator, conversion.enumerator !== 1), node.childNodes[0].childNodes[1])
];
}
return [span_js_1.Span.node(conversion.content || '', node)];
}
function ordinalPosition(node) {
const children = DomUtil.toArray(node.parentNode.childNodes);
return span_js_1.Span.singleton(locale_js_1.LOCALE.NUMBERS.numericOrdinal(children.indexOf(node) + 1).toString());
}

View File

@@ -0,0 +1,3 @@
export declare function PrefixRules(): void;
export declare function OtherRules(): void;
export declare function BrailleRules(): void;

View File

@@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrefixRules = PrefixRules;
exports.OtherRules = OtherRules;
exports.BrailleRules = BrailleRules;
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const StoreUtil = require("../rule_engine/store_util.js");
const MathspeakKoreanUtil = require("./mathspeak_korean_util.js");
const MathspeakUtil = require("./mathspeak_util.js");
const NemethUtil = require("./nemeth_util.js");
const NumbersUtil = require("./numbers_util.js");
const SpeechRules = require("./speech_rules.js");
function PrefixRules() {
SpeechRules.addStore('en.prefix.default', '', {
CSFordinalPosition: NumbersUtil.ordinalPosition
});
}
function OtherRules() {
SpeechRules.addStore('en.speech.chromevox', '', {
CTFnodeCounter: StoreUtil.nodeCounter,
CTFcontentIterator: StoreUtil.contentIterator
});
SpeechRules.addStore('en.speech.emacspeak', 'en.speech.chromevox', {
CQFvulgarFractionSmall: MathspeakUtil.isSmallVulgarFraction,
CSFvulgarFraction: NumbersUtil.vulgarFraction
});
SpeechRules.addStore('ko.summary.', 'ko.speech.mathspeak', {
CSFordinalConversion: MathspeakKoreanUtil.ordinalConversion,
CSFdecreasedOrdinalConversion: MathspeakKoreanUtil.decreasedOrdinalConversion,
CSFlistOrdinalConversion: MathspeakKoreanUtil.listOrdinalConversion
});
}
function BrailleRules() {
SpeechRules.addStore('nemeth.braille.default', dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE + '.speech.mathspeak', {
CSFopenFraction: NemethUtil.openingFraction,
CSFcloseFraction: NemethUtil.closingFraction,
CSFoverFraction: NemethUtil.overFraction,
CSFoverBevFraction: NemethUtil.overBevelledFraction,
CQFhyperFraction: NemethUtil.hyperFractionBoundary,
CSFopenRadical: NemethUtil.openingRadical,
CSFcloseRadical: NemethUtil.closingRadical,
CSFindexRadical: NemethUtil.indexRadical,
CSFsubscript: MathspeakUtil.subscriptVerbose,
CSFsuperscript: MathspeakUtil.superscriptVerbose,
CSFbaseline: MathspeakUtil.baselineVerbose,
CGFtensorRules: (st) => MathspeakUtil.generateTensorRules(st, false),
CTFcontentIterator: NemethUtil.contentIterator,
CTFrelationIterator: NemethUtil.relationIterator,
CTFimplicitIterator: NemethUtil.implicitIterator
});
SpeechRules.addStore('euro.braille.default', 'nemeth.braille.default', {});
}

View File

@@ -0,0 +1 @@
export declare function init(): void;

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.init = init;
const clearspeak_rules_js_1 = require("./clearspeak_rules.js");
const mathspeak_rules_js_1 = require("./mathspeak_rules.js");
const other_rules_js_1 = require("./other_rules.js");
let INIT = false;
function init() {
if (INIT) {
return;
}
(0, mathspeak_rules_js_1.MathspeakRules)();
(0, clearspeak_rules_js_1.ClearspeakRules)();
(0, other_rules_js_1.PrefixRules)();
(0, other_rules_js_1.OtherRules)();
(0, other_rules_js_1.BrailleRules)();
INIT = true;
}

View File

@@ -0,0 +1,7 @@
import { SpeechRuleFunction } from '../rule_engine/speech_rule_functions.js';
export declare function addStore(constr: string, inherit: string, store: {
[key: string]: SpeechRuleFunction;
}): void;
export declare function getStore(locale: string, modality: string, domain: string): {
[key: string]: SpeechRuleFunction;
};

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addStore = addStore;
exports.getStore = getStore;
const dynamic_cstr_js_1 = require("../rule_engine/dynamic_cstr.js");
const funcStore = new Map();
function addStore(constr, inherit, store) {
const values = {};
if (inherit) {
const inherits = funcStore.get(inherit) || {};
Object.assign(values, inherits);
}
funcStore.set(constr, Object.assign(values, store));
}
function getStore(locale, modality, domain) {
return (funcStore.get([locale, modality, domain].join('.')) ||
funcStore.get([dynamic_cstr_js_1.DynamicCstr.DEFAULT_VALUES[dynamic_cstr_js_1.Axis.LOCALE], modality, domain].join('.')) ||
funcStore.get([dynamic_cstr_js_1.DynamicCstr.BASE_LOCALE, modality, domain].join('.')) ||
{});
}

View File

@@ -0,0 +1,3 @@
import { AuditoryDescription } from '../audio/auditory_description.js';
export declare function unitMultipliers(nodes: Element[], _context: string): () => AuditoryDescription[];
export declare function oneLeft(node: Element): Element[];

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unitMultipliers = unitMultipliers;
exports.oneLeft = oneLeft;
const auditory_description_js_1 = require("../audio/auditory_description.js");
const XpathUtil = require("../common/xpath_util.js");
const locale_js_1 = require("../l10n/locale.js");
const semantic_meaning_js_1 = require("../semantic_tree/semantic_meaning.js");
function unitMultipliers(nodes, _context) {
const children = nodes;
let counter = 0;
return function () {
const descr = auditory_description_js_1.AuditoryDescription.create({
text: rightMostUnit(children[counter]) &&
leftMostUnit(children[counter + 1])
? locale_js_1.LOCALE.MESSAGES.unitTimes
: ''
}, {});
counter++;
return [descr];
};
}
const SCRIPT_ELEMENTS = [
semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
semantic_meaning_js_1.SemanticType.SUBSCRIPT,
semantic_meaning_js_1.SemanticType.OVERSCORE,
semantic_meaning_js_1.SemanticType.UNDERSCORE
];
function rightMostUnit(node) {
while (node) {
if (node.getAttribute('role') === 'unit') {
return true;
}
const tag = node.tagName;
const children = XpathUtil.evalXPath('children/*', node);
node = (SCRIPT_ELEMENTS.indexOf(tag) !== -1
? children[0]
: children[children.length - 1]);
}
return false;
}
function leftMostUnit(node) {
while (node) {
if (node.getAttribute('role') === 'unit') {
return true;
}
const children = XpathUtil.evalXPath('children/*', node);
node = children[0];
}
return false;
}
function oneLeft(node) {
while (node) {
if (node.tagName === 'number' && node.textContent === '1') {
return [node];
}
if (node.tagName !== 'infixop' ||
(node.getAttribute('role') !== 'multiplication' &&
node.getAttribute('role') !== 'implicit')) {
return [];
}
node = XpathUtil.evalXPath('children/*', node)[0];
}
return [];
}