add initial marp implementation with sample content and build configuration
This commit is contained in:
60
node_modules/speech-rule-engine/mjs/speech_rules/alphabet.d.ts
generated
vendored
Normal file
60
node_modules/speech-rule-engine/mjs/speech_rules/alphabet.d.ts
generated
vendored
Normal 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;
|
||||
692
node_modules/speech-rule-engine/mjs/speech_rules/alphabet.js
generated
vendored
Normal file
692
node_modules/speech-rule-engine/mjs/speech_rules/alphabet.js
generated
vendored
Normal file
@@ -0,0 +1,692 @@
|
||||
export 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 || (Font = {}));
|
||||
export 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 || (Embellish = {}));
|
||||
export var Base;
|
||||
(function (Base) {
|
||||
Base["LATINCAP"] = "latinCap";
|
||||
Base["LATINSMALL"] = "latinSmall";
|
||||
Base["GREEKCAP"] = "greekCap";
|
||||
Base["GREEKSMALL"] = "greekSmall";
|
||||
Base["DIGIT"] = "digit";
|
||||
})(Base || (Base = {}));
|
||||
function num2str(num) {
|
||||
const str = num.toString(16).toUpperCase();
|
||||
return str.length > 3 ? str : ('000' + str).slice(-4);
|
||||
}
|
||||
export 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)));
|
||||
}
|
||||
export 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;
|
||||
}
|
||||
export 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
|
||||
}
|
||||
];
|
||||
export const INTERVALS = new Map();
|
||||
export 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 = INTERVALS.get(key);
|
||||
if (alphabet) {
|
||||
alphabet.unicode = alphabet.unicode.concat(interval);
|
||||
continue;
|
||||
}
|
||||
alphabet = proto;
|
||||
alphabet.unicode = interval;
|
||||
INTERVALS.set(key, alphabet);
|
||||
}
|
||||
2
node_modules/speech-rule-engine/mjs/speech_rules/alphabet_generator.d.ts
generated
vendored
Normal file
2
node_modules/speech-rule-engine/mjs/speech_rules/alphabet_generator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export declare function generateBase(): void;
|
||||
export declare function generate(locale: string): void;
|
||||
84
node_modules/speech-rule-engine/mjs/speech_rules/alphabet_generator.js
generated
vendored
Normal file
84
node_modules/speech-rule-engine/mjs/speech_rules/alphabet_generator.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import * as Alphabet from './alphabet.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
import * as L10n from '../l10n/l10n.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { localeFontCombiner } from '../l10n/locale_util.js';
|
||||
import * as MathCompoundStore from '../rule_engine/math_compound_store.js';
|
||||
const Domains = {
|
||||
small: ['default'],
|
||||
capital: ['default'],
|
||||
digit: ['default']
|
||||
};
|
||||
function makeDomains() {
|
||||
const alph = 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);
|
||||
}
|
||||
export 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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
export function generate(locale) {
|
||||
const oldLocale = Engine.getInstance().locale;
|
||||
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.ALPHABETS[int.base];
|
||||
alphabetRules(letters, alphabet, int.font, !!int.capital);
|
||||
}
|
||||
}
|
||||
Engine.getInstance().locale = oldLocale;
|
||||
L10n.setLocale();
|
||||
}
|
||||
function getFont(font) {
|
||||
const realFont = font === 'normal' || font === 'fullwidth'
|
||||
? ''
|
||||
: LOCALE.MESSAGES.font[font] || LOCALE.MESSAGES.embellish[font] || '';
|
||||
return 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.ALPHABETS.capPrefix
|
||||
: LOCALE.ALPHABETS.smallPrefix;
|
||||
const domains = cap ? Domains.capital : Domains.small;
|
||||
makeLetter(realFont.combiner, unicode, letter, realFont.font, prefixes, 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.ALPHABETS.digitPrefix;
|
||||
const num = i + offset;
|
||||
makeLetter(realFont.combiner, unicode, num, realFont.font, prefixes, 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));
|
||||
}
|
||||
}
|
||||
33
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_preferences.d.ts
generated
vendored
Normal file
33
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_preferences.d.ts
generated
vendored
Normal 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 {};
|
||||
319
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_preferences.js
generated
vendored
Normal file
319
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_preferences.js
generated
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
import { Engine } from '../common/engine.js';
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
import { Axis, DefaultComparator, DynamicCstrParser, DynamicProperties } from '../rule_engine/dynamic_cstr.js';
|
||||
import * as MathCompoundStore from '../rule_engine/math_compound_store.js';
|
||||
import { SpeechRuleEngine } from '../rule_engine/speech_rule_engine.js';
|
||||
import { SemanticRole, SemanticType } from '../semantic_tree/semantic_meaning.js';
|
||||
export class ClearspeakPreferences extends DynamicCstr {
|
||||
static comparator() {
|
||||
return new Comparator(Engine.getInstance().dynamicCstr, DynamicProperties.createProp([DynamicCstr.DEFAULT_VALUES[Axis.LOCALE]], [DynamicCstr.DEFAULT_VALUES[Axis.MODALITY]], [DynamicCstr.DEFAULT_VALUES[Axis.DOMAIN]], [DynamicCstr.DEFAULT_VALUES[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(':') : DynamicCstr.DEFAULT_VALUE;
|
||||
}
|
||||
static getLocalePreferences(opt_dynamic) {
|
||||
const dynamic = opt_dynamic ||
|
||||
MathCompoundStore.enumerate(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;
|
||||
}
|
||||
}
|
||||
ClearspeakPreferences.AUTO = 'Auto';
|
||||
const PREFERENCES = new 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 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()[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 DynamicCstrParser {
|
||||
constructor() {
|
||||
super([Axis.LOCALE, Axis.MODALITY, Axis.DOMAIN, Axis.STYLE]);
|
||||
}
|
||||
parse(str) {
|
||||
const initial = super.parse(str);
|
||||
let style = initial.getValue(Axis.STYLE);
|
||||
const locale = initial.getValue(Axis.LOCALE);
|
||||
const modality = initial.getValue(Axis.MODALITY);
|
||||
let pref = {};
|
||||
if (style !== 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',
|
||||
SemanticType.FENCED,
|
||||
SemanticRole.NEUTRAL,
|
||||
SemanticRole.METRIC
|
||||
],
|
||||
['Bar', SemanticType.OVERSCORE, SemanticRole.OVERACCENT],
|
||||
['Caps', SemanticType.IDENTIFIER, SemanticRole.LATINLETTER],
|
||||
['CombinationPermutation', SemanticType.APPL, SemanticRole.UNKNOWN],
|
||||
['Ellipses', SemanticType.PUNCTUATION, SemanticRole.ELLIPSIS],
|
||||
['Exponent', SemanticType.SUPERSCRIPT, ''],
|
||||
['Fraction', SemanticType.FRACTION, ''],
|
||||
['Functions', SemanticType.APPL, SemanticRole.SIMPLEFUNC],
|
||||
['ImpliedTimes', SemanticType.OPERATOR, SemanticRole.IMPLICIT],
|
||||
['Log', SemanticType.APPL, SemanticRole.PREFIXFUNC],
|
||||
['Matrix', SemanticType.MATRIX, ''],
|
||||
['Matrix', SemanticType.VECTOR, ''],
|
||||
['MultiLineLabel', SemanticType.MULTILINE, SemanticRole.LABEL],
|
||||
['MultiLineOverview', SemanticType.MULTILINE, SemanticRole.TABLE],
|
||||
['MultiLinePausesBetweenColumns', SemanticType.MULTILINE, SemanticRole.TABLE],
|
||||
['MultiLineLabel', SemanticType.TABLE, SemanticRole.LABEL],
|
||||
['MultiLineOverview', SemanticType.TABLE, SemanticRole.TABLE],
|
||||
['MultiLinePausesBetweenColumns', SemanticType.TABLE, SemanticRole.TABLE],
|
||||
['MultiLineLabel', SemanticType.CASES, SemanticRole.LABEL],
|
||||
['MultiLineOverview', SemanticType.CASES, SemanticRole.TABLE],
|
||||
['MultiLinePausesBetweenColumns', SemanticType.CASES, SemanticRole.TABLE],
|
||||
['MultsymbolDot', SemanticType.OPERATOR, SemanticRole.MULTIPLICATION],
|
||||
['MultsymbolX', SemanticType.OPERATOR, SemanticRole.MULTIPLICATION],
|
||||
['Paren', SemanticType.FENCED, SemanticRole.LEFTRIGHT],
|
||||
['Prime', SemanticType.SUPERSCRIPT, SemanticRole.PRIME],
|
||||
['Roots', SemanticType.ROOT, ''],
|
||||
['Roots', SemanticType.SQRT, ''],
|
||||
['SetMemberSymbol', SemanticType.RELATION, SemanticRole.ELEMENT],
|
||||
['Sets', SemanticType.FENCED, SemanticRole.SETEXT],
|
||||
['TriangleSymbol', SemanticType.IDENTIFIER, SemanticRole.GREEKLETTER],
|
||||
['Trig', SemanticType.APPL, SemanticRole.PREFIXFUNC],
|
||||
['VerticalLine', SemanticType.PUNCTUATED, 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.getInstance().comparators['clearspeak'] =
|
||||
ClearspeakPreferences.comparator;
|
||||
Engine.getInstance().parsers['clearspeak'] = new Parser();
|
||||
1
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_rules.d.ts
generated
vendored
Normal file
1
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_rules.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function ClearspeakRules(): void;
|
||||
23
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_rules.js
generated
vendored
Normal file
23
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_rules.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
import * as StoreUtil from '../rule_engine/store_util.js';
|
||||
import * as ClearspeakUtil from './clearspeak_util.js';
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
import * as NumbersUtil from './numbers_util.js';
|
||||
import * as SpeechRules from './speech_rules.js';
|
||||
export function ClearspeakRules() {
|
||||
SpeechRules.addStore(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
|
||||
});
|
||||
}
|
||||
10
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_util.d.ts
generated
vendored
Normal file
10
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_util.d.ts
generated
vendored
Normal 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[];
|
||||
286
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_util.js
generated
vendored
Normal file
286
node_modules/speech-rule-engine/mjs/speech_rules/clearspeak_util.js
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { vulgarFractionSmall } from '../l10n/transformers.js';
|
||||
import { Grammar } from '../rule_engine/grammar.js';
|
||||
import * as StoreUtil from '../rule_engine/store_util.js';
|
||||
import { register } from '../semantic_tree/semantic_annotations.js';
|
||||
import { SemanticAnnotator } from '../semantic_tree/semantic_annotator.js';
|
||||
import { isMatchingFence } from '../semantic_tree/semantic_attr.js';
|
||||
import { SemanticRole, SemanticType } from '../semantic_tree/semantic_meaning.js';
|
||||
export 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 === SemanticType.APPL &&
|
||||
(node.childNodes[0].role === SemanticRole.PREFIXFUNC ||
|
||||
node.childNodes[0].role === SemanticRole.SIMPLEFUNC) &&
|
||||
(isSimple_(node.childNodes[1]) ||
|
||||
(node.childNodes[1].type === SemanticType.FENCED &&
|
||||
isSimple_(node.childNodes[1].childNodes[0]))));
|
||||
}
|
||||
function isSimpleNegative_(node) {
|
||||
return (node.type === SemanticType.PREFIXOP &&
|
||||
node.role === SemanticRole.NEGATIVE &&
|
||||
isSimple_(node.childNodes[0]) &&
|
||||
node.childNodes[0].type !== SemanticType.PREFIXOP &&
|
||||
node.childNodes[0].type !== SemanticType.APPL &&
|
||||
node.childNodes[0].type !== SemanticType.PUNCTUATED);
|
||||
}
|
||||
function isSimpleDegree_(node) {
|
||||
return (node.type === SemanticType.PUNCTUATED &&
|
||||
node.role === SemanticRole.ENDPUNCT &&
|
||||
node.childNodes.length === 2 &&
|
||||
node.childNodes[1].role === SemanticRole.DEGREE &&
|
||||
(isLetter_(node.childNodes[0]) ||
|
||||
isNumber_(node.childNodes[0]) ||
|
||||
(node.childNodes[0].type === SemanticType.PREFIXOP &&
|
||||
node.childNodes[0].role === SemanticRole.NEGATIVE &&
|
||||
(isLetter_(node.childNodes[0].childNodes[0]) ||
|
||||
isNumber_(node.childNodes[0].childNodes[0])))));
|
||||
}
|
||||
function isSimpleLetters_(node) {
|
||||
return (isLetter_(node) ||
|
||||
(node.type === SemanticType.INFIXOP &&
|
||||
node.role === 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 === SemanticType.IDENTIFIER &&
|
||||
(node.role === SemanticRole.LATINLETTER ||
|
||||
node.role === SemanticRole.GREEKLETTER ||
|
||||
node.role === SemanticRole.OTHERLETTER ||
|
||||
node.role === SemanticRole.SIMPLEFUNC));
|
||||
}
|
||||
function isNumber_(node) {
|
||||
return (node.type === SemanticType.NUMBER &&
|
||||
(node.role === SemanticRole.INTEGER || node.role === 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 !== SemanticType.FRACTION ||
|
||||
node.role !== 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.getInstance().style === pref;
|
||||
}
|
||||
register(new 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 !== SemanticType.SUBSCRIPT) {
|
||||
return false;
|
||||
}
|
||||
const children = node.childNodes[0].childNodes;
|
||||
const index = children[1];
|
||||
return (children[0].tagName === SemanticType.IDENTIFIER &&
|
||||
(isInteger_(index) ||
|
||||
(index.tagName === SemanticType.INFIXOP &&
|
||||
index.hasAttribute('role') &&
|
||||
index.getAttribute('role') === SemanticRole.IMPLICIT &&
|
||||
allIndices_(index))));
|
||||
}
|
||||
function isInteger_(node) {
|
||||
return (node.tagName === SemanticType.NUMBER &&
|
||||
node.hasAttribute('role') &&
|
||||
node.getAttribute('role') === SemanticRole.INTEGER);
|
||||
}
|
||||
function allIndices_(node) {
|
||||
const nodes = XpathUtil.evalXPath('children/*', node);
|
||||
return nodes.every((x) => isInteger_(x) || x.tagName === SemanticType.IDENTIFIER);
|
||||
}
|
||||
export function allCellsSimple(node) {
|
||||
const xpath = node.tagName === SemanticType.MATRIX
|
||||
? 'children/row/children/cell/children/*'
|
||||
: 'children/line/children/*';
|
||||
const nodes = XpathUtil.evalXPath(xpath, node);
|
||||
const result = nodes.every(simpleCell_);
|
||||
return result ? [node] : [];
|
||||
}
|
||||
export function isSmallVulgarFraction(node) {
|
||||
return vulgarFractionSmall(node, 20, 11) ? [node] : [];
|
||||
}
|
||||
function isUnitExpression(node) {
|
||||
return ((node.type === SemanticType.TEXT && node.role !== SemanticRole.LABEL) ||
|
||||
(node.type === SemanticType.PUNCTUATED &&
|
||||
node.role === SemanticRole.TEXT &&
|
||||
isNumber_(node.childNodes[0]) &&
|
||||
allTextLastContent_(node.childNodes.slice(1))) ||
|
||||
(node.type === SemanticType.IDENTIFIER &&
|
||||
node.role === SemanticRole.UNIT) ||
|
||||
(node.type === SemanticType.INFIXOP &&
|
||||
(node.role === SemanticRole.IMPLICIT || node.role === SemanticRole.UNIT)));
|
||||
}
|
||||
function allTextLastContent_(nodes) {
|
||||
for (let i = 0; i < nodes.length - 1; i++) {
|
||||
if (!(nodes[i].type === SemanticType.TEXT && nodes[i].textContent === '')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return nodes[nodes.length - 1].type === SemanticType.TEXT;
|
||||
}
|
||||
register(new SemanticAnnotator('clearspeak', 'unit', function (node) {
|
||||
return isUnitExpression(node) ? 'unit' : '';
|
||||
}));
|
||||
export function ordinalExponent(node) {
|
||||
const num = parseInt(node.textContent, 10);
|
||||
return [
|
||||
Span.stringEmpty(isNaN(num)
|
||||
? node.textContent
|
||||
: num > 10
|
||||
? LOCALE.NUMBERS.numericOrdinal(num)
|
||||
: LOCALE.NUMBERS.wordOrdinal(num))
|
||||
];
|
||||
}
|
||||
let NESTING_DEPTH = null;
|
||||
export 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 === SemanticType.FENCED &&
|
||||
parent.childNodes[0].childNodes[index].textContent === fence) {
|
||||
count++;
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
NESTING_DEPTH = count > 1 ? LOCALE.NUMBERS.wordOrdinal(count) : '';
|
||||
return [Span.stringEmpty(NESTING_DEPTH)];
|
||||
}
|
||||
export 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 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.getInstance().setCorrection('insertNesting', insertNesting);
|
||||
export 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]
|
||||
: [];
|
||||
}
|
||||
export 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 === SemanticType.ROOT ||
|
||||
children[index + 1].tagName === SemanticType.SQRT ||
|
||||
(children[index + 1].tagName === SemanticType.SUPERSCRIPT &&
|
||||
children[index + 1].childNodes[0].childNodes[0] &&
|
||||
(children[index + 1].childNodes[0].childNodes[0]
|
||||
.tagName === SemanticType.NUMBER ||
|
||||
children[index + 1].childNodes[0].childNodes[0]
|
||||
.tagName === 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 === SemanticType.NUMBER ||
|
||||
node.tagName === SemanticType.IDENTIFIER ||
|
||||
node.tagName === SemanticType.FUNCTION ||
|
||||
node.tagName === SemanticType.APPL ||
|
||||
node.tagName === SemanticType.FRACTION));
|
||||
}
|
||||
function fencedFactor_(node) {
|
||||
return (node &&
|
||||
(node.tagName === SemanticType.FENCED ||
|
||||
(node.hasAttribute('role') &&
|
||||
node.getAttribute('role') === SemanticRole.LEFTRIGHT) ||
|
||||
layoutFactor_(node)));
|
||||
}
|
||||
function layoutFactor_(node) {
|
||||
return (!!node &&
|
||||
(node.tagName === SemanticType.MATRIX ||
|
||||
node.tagName === SemanticType.VECTOR));
|
||||
}
|
||||
export function wordOrdinal(node) {
|
||||
return [
|
||||
Span.stringEmpty(LOCALE.NUMBERS.wordOrdinal(parseInt(node.textContent, 10)))
|
||||
];
|
||||
}
|
||||
4
node_modules/speech-rule-engine/mjs/speech_rules/math_map.d.ts
generated
vendored
Normal file
4
node_modules/speech-rule-engine/mjs/speech_rules/math_map.d.ts
generated
vendored
Normal 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 {};
|
||||
172
node_modules/speech-rule-engine/mjs/speech_rules/math_map.js
generated
vendored
Normal file
172
node_modules/speech-rule-engine/mjs/speech_rules/math_map.js
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
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());
|
||||
});
|
||||
};
|
||||
import * as BrowserUtil from '../common/browser_util.js';
|
||||
import { Engine, EnginePromise } from '../common/engine.js';
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import * as FileUtil from '../common/file_util.js';
|
||||
import { SystemExternal } from '../common/system_external.js';
|
||||
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
import * as MathCompoundStore from '../rule_engine/math_compound_store.js';
|
||||
import { SpeechRuleEngine } from '../rule_engine/speech_rule_engine.js';
|
||||
import { completeLocale } from '../l10n/l10n.js';
|
||||
import * as AlphabetGenerator from './alphabet_generator.js';
|
||||
const addSymbols = {
|
||||
functions: MathCompoundStore.addFunctionRules,
|
||||
symbols: MathCompoundStore.addSymbolRules,
|
||||
units: MathCompoundStore.addUnitRules,
|
||||
si: (x) => x.forEach(MathCompoundStore.setSiPrefixes),
|
||||
messages: completeLocale,
|
||||
rules: SpeechRuleEngine.addStore,
|
||||
characters: MathCompoundStore.addCharacterRules
|
||||
};
|
||||
let _init = false;
|
||||
export function loadLocale() {
|
||||
return __awaiter(this, arguments, void 0, function* (locale = Engine.getInstance().locale) {
|
||||
if (!_init) {
|
||||
AlphabetGenerator.generateBase();
|
||||
_loadLocale(DynamicCstr.BASE_LOCALE);
|
||||
_init = true;
|
||||
}
|
||||
return EnginePromise.promises[DynamicCstr.BASE_LOCALE].then(() => __awaiter(this, void 0, void 0, function* () {
|
||||
const defLoc = Engine.getInstance().defaultLocale;
|
||||
if (defLoc) {
|
||||
_loadLocale(defLoc);
|
||||
return EnginePromise.promises[defLoc].then(() => __awaiter(this, void 0, void 0, function* () {
|
||||
_loadLocale(locale);
|
||||
return EnginePromise.promises[locale];
|
||||
}));
|
||||
}
|
||||
_loadLocale(locale);
|
||||
return EnginePromise.promises[locale];
|
||||
}));
|
||||
});
|
||||
}
|
||||
function _loadLocale(locale = Engine.getInstance().locale) {
|
||||
if (!EnginePromise.loaded[locale]) {
|
||||
EnginePromise.loaded[locale] = [false, false];
|
||||
MathCompoundStore.reset();
|
||||
retrieveMaps(locale);
|
||||
}
|
||||
}
|
||||
function loadMethod() {
|
||||
if (Engine.getInstance().customLoader) {
|
||||
return Engine.getInstance().customLoader;
|
||||
}
|
||||
return standardLoader();
|
||||
}
|
||||
export function standardLoader() {
|
||||
switch (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);
|
||||
EnginePromise.loaded[locale] = [true, true];
|
||||
res(locale);
|
||||
}, (_err) => {
|
||||
EnginePromise.loaded[locale] = [true, false];
|
||||
console.error(`Unable to load locale: ${locale}`);
|
||||
Engine.getInstance().locale = Engine.getInstance().defaultLocale;
|
||||
res(locale);
|
||||
});
|
||||
});
|
||||
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.getInstance().isIE &&
|
||||
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) => {
|
||||
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 = 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();
|
||||
});
|
||||
}
|
||||
7
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_french_util.d.ts
generated
vendored
Normal file
7
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_french_util.d.ts
generated
vendored
Normal 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[];
|
||||
31
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_french_util.js
generated
vendored
Normal file
31
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_french_util.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
export function baselineVerbose(node) {
|
||||
const baseline = MathspeakUtil.baselineVerbose(node);
|
||||
baseline[0].speech = baseline[0].speech.replace(/-$/, '');
|
||||
return baseline;
|
||||
}
|
||||
export function baselineBrief(node) {
|
||||
const baseline = MathspeakUtil.baselineBrief(node);
|
||||
baseline[0].speech = baseline[0].speech.replace(/-$/, '');
|
||||
return baseline;
|
||||
}
|
||||
export function leftSuperscriptVerbose(node) {
|
||||
const leftIndex = MathspeakUtil.superscriptVerbose(node);
|
||||
leftIndex[0].speech = leftIndex[0].speech.replace(/^exposant/, 'exposant gauche');
|
||||
return leftIndex;
|
||||
}
|
||||
export function leftSubscriptVerbose(node) {
|
||||
const leftIndex = MathspeakUtil.subscriptVerbose(node);
|
||||
leftIndex[0].speech = leftIndex[0].speech.replace(/^indice/, 'indice gauche');
|
||||
return leftIndex;
|
||||
}
|
||||
export function leftSuperscriptBrief(node) {
|
||||
const leftIndex = MathspeakUtil.superscriptBrief(node);
|
||||
leftIndex[0].speech = leftIndex[0].speech.replace(/^sup/, 'sup gauche');
|
||||
return leftIndex;
|
||||
}
|
||||
export function leftSubscriptBrief(node) {
|
||||
const leftIndex = MathspeakUtil.subscriptBrief(node);
|
||||
leftIndex[0].speech = leftIndex[0].speech.replace(/^sub/, 'sub gauche');
|
||||
return leftIndex;
|
||||
}
|
||||
26
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_korean_util.d.ts
generated
vendored
Normal file
26
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_korean_util.d.ts
generated
vendored
Normal 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;
|
||||
124
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_korean_util.js
generated
vendored
Normal file
124
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_korean_util.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
export 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.MESSAGES.regexp.JOINER_FRAC);
|
||||
}
|
||||
export function openingFractionVerbose(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.START, LOCALE.MESSAGES.MS.FRAC_V));
|
||||
}
|
||||
export function closingFractionVerbose(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.END, LOCALE.MESSAGES.MS.FRAC_V));
|
||||
}
|
||||
export function openingFractionBrief(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.START, LOCALE.MESSAGES.MS.FRAC_B));
|
||||
}
|
||||
export function closingFractionBrief(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.END, LOCALE.MESSAGES.MS.FRAC_B));
|
||||
}
|
||||
export function openingFractionSbrief(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
if (depth === 1) {
|
||||
return Span.singleton(LOCALE.MESSAGES.MS.FRAC_S);
|
||||
}
|
||||
return Span.singleton(LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.MESSAGES.MS.FRAC_S));
|
||||
}
|
||||
export function closingFractionSbrief(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
if (depth === 1) {
|
||||
return Span.singleton(LOCALE.MESSAGES.MS.ENDFRAC);
|
||||
}
|
||||
return Span.singleton(LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.MESSAGES.MS.ENDFRAC));
|
||||
}
|
||||
export function overFractionSbrief(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
if (depth === 1) {
|
||||
return Span.singleton(LOCALE.MESSAGES.MS.FRAC_OVER);
|
||||
}
|
||||
return Span.singleton(LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.MESSAGES.MS.FRAC_OVER));
|
||||
}
|
||||
export function isSimpleIndex(node) {
|
||||
const index = XpathUtil.evalXPath('children/*[1]', node)[0]
|
||||
.toString()
|
||||
.match(/[^>>]+<\/[^>]*>/g);
|
||||
return index.length === 1 ? [node] : [];
|
||||
}
|
||||
export function nestedRadical(node, prefix, postfix) {
|
||||
const depth = MathspeakUtil.radicalNestingDepth(node);
|
||||
if (depth === 1)
|
||||
return postfix;
|
||||
return LOCALE.FUNCTIONS.combineNestedRadical(LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), prefix, postfix);
|
||||
}
|
||||
export function openingRadicalVerbose(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NESTED, LOCALE.MESSAGES.MS.STARTROOT));
|
||||
}
|
||||
export function closingRadicalVerbose(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NESTED, LOCALE.MESSAGES.MS.ENDROOT));
|
||||
}
|
||||
export function openingRadicalBrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.STARTROOT));
|
||||
}
|
||||
export function closingRadicalBrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.ENDROOT));
|
||||
}
|
||||
export function openingRadicalSbrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.ROOT));
|
||||
}
|
||||
export function getRootIndex(node) {
|
||||
const content = XpathUtil.evalXPath('children/*[1]', node)[0].textContent.trim();
|
||||
return LOCALE.MESSAGES.MSroots[content] || content + '제곱근';
|
||||
}
|
||||
export function indexRadical(node, postfix) {
|
||||
const index = getRootIndex(node);
|
||||
return index ? index : postfix;
|
||||
}
|
||||
export function indexRadicalVerbose(node) {
|
||||
return Span.singleton(indexRadical(node, LOCALE.MESSAGES.MS.ROOTINDEX));
|
||||
}
|
||||
export function indexRadicalBrief(node) {
|
||||
return Span.singleton(indexRadical(node, LOCALE.MESSAGES.MS.ROOTINDEX));
|
||||
}
|
||||
export function indexRadicalSbrief(node) {
|
||||
return Span.singleton(indexRadical(node, LOCALE.MESSAGES.MS.INDEX));
|
||||
}
|
||||
export function ordinalConversion(node) {
|
||||
const children = XpathUtil.evalXPath('children/*', node);
|
||||
return Span.singleton(LOCALE.NUMBERS.wordOrdinal(children.length));
|
||||
}
|
||||
export function decreasedOrdinalConversion(node) {
|
||||
const children = XpathUtil.evalXPath('children/*', node);
|
||||
return Span.singleton(LOCALE.NUMBERS.wordOrdinal(children.length - 1));
|
||||
}
|
||||
export function listOrdinalConversion(node) {
|
||||
const children = XpathUtil.evalXPath('children/*', node);
|
||||
const content = XpathUtil.evalXPath('content/*', node);
|
||||
return Span.singleton(LOCALE.NUMBERS.wordOrdinal(children.length - content.length));
|
||||
}
|
||||
export function checkDepth(node) {
|
||||
const roleList = [];
|
||||
const depth = getDepthValue(node, roleList);
|
||||
return depth > 3 ? [] : [node];
|
||||
}
|
||||
export 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;
|
||||
}
|
||||
1
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_rules.d.ts
generated
vendored
Normal file
1
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_rules.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function MathspeakRules(): void;
|
||||
89
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_rules.js
generated
vendored
Normal file
89
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_rules.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
import * as StoreUtil from '../rule_engine/store_util.js';
|
||||
import * as MathspeakFrenchUtil from './mathspeak_french_util.js';
|
||||
import * as MathspeakKoreanUtil from './mathspeak_korean_util.js';
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
import * as NumbersUtil from './numbers_util.js';
|
||||
import * as SpeechRules from './speech_rules.js';
|
||||
import * as UnitUtil from './unit_util.js';
|
||||
export function MathspeakRules() {
|
||||
SpeechRules.addStore(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', DynamicCstr.BASE_LOCALE + '.speech.mathspeak', {
|
||||
CTFunitMultipliers: UnitUtil.unitMultipliers,
|
||||
CQFoneLeft: UnitUtil.oneLeft
|
||||
});
|
||||
SpeechRules.addStore('fr.speech.mathspeak', 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', 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
|
||||
});
|
||||
}
|
||||
43
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_util.d.ts
generated
vendored
Normal file
43
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_util.d.ts
generated
vendored
Normal 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[];
|
||||
442
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_util.js
generated
vendored
Normal file
442
node_modules/speech-rule-engine/mjs/speech_rules/mathspeak_util.js
generated
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as BaseUtil from '../common/base_util.js';
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { SemanticFont, SemanticRole, SemanticType } from '../semantic_tree/semantic_meaning.js';
|
||||
import { SemanticProcessor } from '../semantic_tree/semantic_processor.js';
|
||||
let nestingDepth = {};
|
||||
export function spaceoutText(node) {
|
||||
return Array.from(node.textContent).map(Span.stringEmpty);
|
||||
}
|
||||
function spaceoutNodes(node, correction) {
|
||||
const content = Array.from(node.textContent);
|
||||
const result = [];
|
||||
const processor = SemanticProcessor.getInstance();
|
||||
const doc = node.ownerDocument;
|
||||
for (let i = 0, chr; (chr = content[i]); i++) {
|
||||
const leaf = processor
|
||||
.getNodeFactory()
|
||||
.makeLeafNode(chr, SemanticFont.UNKNOWN);
|
||||
const sn = processor.identifierNode(leaf, SemanticFont.UNKNOWN, '');
|
||||
correction(sn);
|
||||
result.push(sn.xml(doc));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export function spaceoutNumber(node) {
|
||||
return spaceoutNodes(node, function (sn) {
|
||||
if (!sn.textContent.match(/\W/)) {
|
||||
sn.type = SemanticType.NUMBER;
|
||||
}
|
||||
});
|
||||
}
|
||||
export function spaceoutIdentifier(node) {
|
||||
return spaceoutNodes(node, function (sn) {
|
||||
sn.font = SemanticFont.UNKNOWN;
|
||||
sn.type = SemanticType.IDENTIFIER;
|
||||
});
|
||||
}
|
||||
const nestingBarriers = [
|
||||
SemanticType.CASES,
|
||||
SemanticType.CELL,
|
||||
SemanticType.INTEGRAL,
|
||||
SemanticType.LINE,
|
||||
SemanticType.MATRIX,
|
||||
SemanticType.MULTILINE,
|
||||
SemanticType.OVERSCORE,
|
||||
SemanticType.ROOT,
|
||||
SemanticType.ROW,
|
||||
SemanticType.SQRT,
|
||||
SemanticType.SUBSCRIPT,
|
||||
SemanticType.SUPERSCRIPT,
|
||||
SemanticType.TABLE,
|
||||
SemanticType.UNDERSCORE,
|
||||
SemanticType.VECTOR
|
||||
];
|
||||
export 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);
|
||||
}));
|
||||
}
|
||||
export function fractionNestingDepth(node) {
|
||||
return getNestingDepth('fraction', node, ['fraction'], nestingBarriers, {}, 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.MESSAGES.regexp.JOINER_FRAC);
|
||||
}
|
||||
export function openingFractionVerbose(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.START, LOCALE.MESSAGES.MS.FRAC_V));
|
||||
}
|
||||
export function closingFractionVerbose(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.END, LOCALE.MESSAGES.MS.FRAC_V), { kind: 'LAST' });
|
||||
}
|
||||
export function overFractionVerbose(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.FRAC_OVER), {});
|
||||
}
|
||||
export function openingFractionBrief(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.START, LOCALE.MESSAGES.MS.FRAC_B));
|
||||
}
|
||||
export function closingFractionBrief(node) {
|
||||
return Span.singleton(nestedFraction(node, LOCALE.MESSAGES.MS.END, LOCALE.MESSAGES.MS.FRAC_B), { kind: 'LAST' });
|
||||
}
|
||||
export function openingFractionSbrief(node) {
|
||||
const depth = fractionNestingDepth(node);
|
||||
return Span.singleton(depth === 1
|
||||
? LOCALE.MESSAGES.MS.FRAC_S
|
||||
: LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.FRAC_S));
|
||||
}
|
||||
export function closingFractionSbrief(node) {
|
||||
const depth = fractionNestingDepth(node);
|
||||
return Span.singleton(depth === 1
|
||||
? LOCALE.MESSAGES.MS.ENDFRAC
|
||||
: LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.ENDFRAC), { kind: 'LAST' });
|
||||
}
|
||||
export function overFractionSbrief(node) {
|
||||
const depth = fractionNestingDepth(node);
|
||||
return Span.singleton(depth === 1
|
||||
? LOCALE.MESSAGES.MS.FRAC_OVER
|
||||
: LOCALE.FUNCTIONS.combineNestedFraction(LOCALE.MESSAGES.MS.NEST_FRAC, LOCALE.FUNCTIONS.radicalNestDepth(depth - 1), LOCALE.MESSAGES.MS.FRAC_OVER));
|
||||
}
|
||||
export function isSmallVulgarFraction(node) {
|
||||
return LOCALE.FUNCTIONS.fracNestDepth(node) ? [node] : [];
|
||||
}
|
||||
export 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 === SemanticType.SUBSCRIPT &&
|
||||
node === children.childNodes[1]) ||
|
||||
(parent.tagName === SemanticType.TENSOR &&
|
||||
nodeRole &&
|
||||
(nodeRole === SemanticRole.LEFTSUB ||
|
||||
nodeRole === SemanticRole.RIGHTSUB))) {
|
||||
init = replace.sub + LOCALE.MESSAGES.regexp.JOINER_SUBSUPER + init;
|
||||
}
|
||||
if ((parent.tagName === SemanticType.SUPERSCRIPT &&
|
||||
node === children.childNodes[1]) ||
|
||||
(parent.tagName === SemanticType.TENSOR &&
|
||||
nodeRole &&
|
||||
(nodeRole === SemanticRole.LEFTSUPER ||
|
||||
nodeRole === SemanticRole.RIGHTSUPER))) {
|
||||
init = replace.sup + LOCALE.MESSAGES.regexp.JOINER_SUBSUPER + init;
|
||||
}
|
||||
node = parent;
|
||||
}
|
||||
return init.trim();
|
||||
}
|
||||
export function subscriptVerbose(node) {
|
||||
return Span.singleton(nestedSubSuper(node, LOCALE.MESSAGES.MS.SUBSCRIPT, {
|
||||
sup: LOCALE.MESSAGES.MS.SUPER,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
}));
|
||||
}
|
||||
export function subscriptBrief(node) {
|
||||
return Span.singleton(nestedSubSuper(node, LOCALE.MESSAGES.MS.SUB, {
|
||||
sup: LOCALE.MESSAGES.MS.SUP,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
}));
|
||||
}
|
||||
export function superscriptVerbose(node) {
|
||||
return Span.singleton(nestedSubSuper(node, LOCALE.MESSAGES.MS.SUPERSCRIPT, {
|
||||
sup: LOCALE.MESSAGES.MS.SUPER,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
}));
|
||||
}
|
||||
export function superscriptBrief(node) {
|
||||
return Span.singleton(nestedSubSuper(node, LOCALE.MESSAGES.MS.SUP, {
|
||||
sup: LOCALE.MESSAGES.MS.SUP,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
}));
|
||||
}
|
||||
export function baselineVerbose(node) {
|
||||
const baseline = nestedSubSuper(node, '', {
|
||||
sup: LOCALE.MESSAGES.MS.SUPER,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
});
|
||||
return Span.singleton(!baseline
|
||||
? LOCALE.MESSAGES.MS.BASELINE
|
||||
: baseline
|
||||
.replace(new RegExp(LOCALE.MESSAGES.MS.SUB + '$'), LOCALE.MESSAGES.MS.SUBSCRIPT)
|
||||
.replace(new RegExp(LOCALE.MESSAGES.MS.SUPER + '$'), LOCALE.MESSAGES.MS.SUPERSCRIPT));
|
||||
}
|
||||
export function baselineBrief(node) {
|
||||
const baseline = nestedSubSuper(node, '', {
|
||||
sup: LOCALE.MESSAGES.MS.SUP,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
});
|
||||
return Span.singleton(baseline || LOCALE.MESSAGES.MS.BASE);
|
||||
}
|
||||
export 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.FUNCTIONS.combineRootIndex(postfix, index) : postfix;
|
||||
return depth === 1
|
||||
? postfix
|
||||
: LOCALE.FUNCTIONS.combineNestedRadical(prefix, 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.MESSAGES.MSroots[content] || '';
|
||||
}
|
||||
export function openingRadicalVerbose(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NESTED, LOCALE.MESSAGES.MS.STARTROOT));
|
||||
}
|
||||
export function closingRadicalVerbose(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NESTED, LOCALE.MESSAGES.MS.ENDROOT));
|
||||
}
|
||||
export function indexRadicalVerbose(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NESTED, LOCALE.MESSAGES.MS.ROOTINDEX));
|
||||
}
|
||||
export function openingRadicalBrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.STARTROOT));
|
||||
}
|
||||
export function closingRadicalBrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.ENDROOT));
|
||||
}
|
||||
export function indexRadicalBrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.ROOTINDEX));
|
||||
}
|
||||
export function openingRadicalSbrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.ROOT));
|
||||
}
|
||||
export function indexRadicalSbrief(node) {
|
||||
return Span.singleton(nestedRadical(node, LOCALE.MESSAGES.MS.NEST_ROOT, LOCALE.MESSAGES.MS.INDEX));
|
||||
}
|
||||
function underscoreNestingDepth(node) {
|
||||
return getNestingDepth('underscore', node, ['underscore'], nestingBarriers, {}, function (node) {
|
||||
return (node.tagName &&
|
||||
node.tagName === SemanticType.UNDERSCORE &&
|
||||
node.childNodes[0].childNodes[1].getAttribute('role') ===
|
||||
SemanticRole.UNDERACCENT);
|
||||
});
|
||||
}
|
||||
export function nestedUnderscript(node) {
|
||||
const depth = underscoreNestingDepth(node);
|
||||
return Span.singleton(Array(depth).join(LOCALE.MESSAGES.MS.UNDER) + LOCALE.MESSAGES.MS.UNDERSCRIPT);
|
||||
}
|
||||
function overscoreNestingDepth(node) {
|
||||
return getNestingDepth('overscore', node, ['overscore'], nestingBarriers, {}, function (node) {
|
||||
return (node.tagName &&
|
||||
node.tagName === SemanticType.OVERSCORE &&
|
||||
node.childNodes[0].childNodes[1].getAttribute('role') ===
|
||||
SemanticRole.OVERACCENT);
|
||||
});
|
||||
}
|
||||
export function endscripts(_node) {
|
||||
return Span.singleton(LOCALE.MESSAGES.MS.ENDSCRIPTS);
|
||||
}
|
||||
export function nestedOverscript(node) {
|
||||
const depth = overscoreNestingDepth(node);
|
||||
return Span.singleton(Array(depth).join(LOCALE.MESSAGES.MS.OVER) + LOCALE.MESSAGES.MS.OVERSCRIPT);
|
||||
}
|
||||
export function determinantIsSimple(node) {
|
||||
if (node.tagName !== SemanticType.MATRIX ||
|
||||
node.getAttribute('role') !== 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 === SemanticType.NUMBER) {
|
||||
continue;
|
||||
}
|
||||
if (cell.tagName === SemanticType.IDENTIFIER) {
|
||||
const role = cell.getAttribute('role');
|
||||
if (role === SemanticRole.LATINLETTER ||
|
||||
role === SemanticRole.GREEKLETTER ||
|
||||
role === SemanticRole.OTHERLETTER) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return [node];
|
||||
}
|
||||
export 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 ')];
|
||||
}
|
||||
export function removeParens(node) {
|
||||
if (!node.childNodes.length ||
|
||||
!node.childNodes[0].childNodes.length ||
|
||||
!node.childNodes[0].childNodes[0].childNodes.length) {
|
||||
return Span.singleton('');
|
||||
}
|
||||
const content = node.childNodes[0].childNodes[0].childNodes[0].textContent;
|
||||
return 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];
|
||||
}
|
||||
export 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
export function smallRoot(node) {
|
||||
let max = Object.keys(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] : [];
|
||||
}
|
||||
13
node_modules/speech-rule-engine/mjs/speech_rules/nemeth_util.d.ts
generated
vendored
Normal file
13
node_modules/speech-rule-engine/mjs/speech_rules/nemeth_util.d.ts
generated
vendored
Normal 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[];
|
||||
252
node_modules/speech-rule-engine/mjs/speech_rules/nemeth_util.js
generated
vendored
Normal file
252
node_modules/speech-rule-engine/mjs/speech_rules/nemeth_util.js
generated
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import { Grammar, correctFont } from '../rule_engine/grammar.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
import { register, activate } from '../semantic_tree/semantic_annotations.js';
|
||||
import { SemanticVisitor } from '../semantic_tree/semantic_annotator.js';
|
||||
import { SemanticRole, SemanticType } from '../semantic_tree/semantic_meaning.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
import { contentIterator as suCI } from '../rule_engine/store_util.js';
|
||||
export function openingFraction(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
return Span.singleton(new Array(depth).join(LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
|
||||
LOCALE.MESSAGES.MS.FRACTION_START);
|
||||
}
|
||||
export function closingFraction(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
return Span.singleton(new Array(depth).join(LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
|
||||
LOCALE.MESSAGES.MS.FRACTION_END);
|
||||
}
|
||||
export function overFraction(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
return Span.singleton(new Array(depth).join(LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
|
||||
LOCALE.MESSAGES.MS.FRACTION_OVER);
|
||||
}
|
||||
export function overBevelledFraction(node) {
|
||||
const depth = MathspeakUtil.fractionNestingDepth(node);
|
||||
return Span.singleton(new Array(depth).join(LOCALE.MESSAGES.MS.FRACTION_REPEAT) +
|
||||
'⠸' +
|
||||
LOCALE.MESSAGES.MS.FRACTION_OVER);
|
||||
}
|
||||
export function hyperFractionBoundary(node) {
|
||||
return LOCALE.MESSAGES.regexp.HYPER ===
|
||||
MathspeakUtil.fractionNestingDepth(node).toString()
|
||||
? [node]
|
||||
: [];
|
||||
}
|
||||
function nestedRadical(node, postfix) {
|
||||
const depth = radicalNestingDepth(node);
|
||||
return Span.singleton(depth === 1
|
||||
? postfix
|
||||
: new Array(depth).join(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);
|
||||
}
|
||||
export function openingRadical(node) {
|
||||
return nestedRadical(node, LOCALE.MESSAGES.MS.STARTROOT);
|
||||
}
|
||||
export function closingRadical(node) {
|
||||
return nestedRadical(node, LOCALE.MESSAGES.MS.ENDROOT);
|
||||
}
|
||||
export function indexRadical(node) {
|
||||
return nestedRadical(node, 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.getInstance().setCorrection('enlargeFence', enlargeFence);
|
||||
const NUMBER_PROPAGATORS = [
|
||||
SemanticType.MULTIREL,
|
||||
SemanticType.RELSEQ,
|
||||
SemanticType.APPL,
|
||||
SemanticType.ROW,
|
||||
SemanticType.LINE
|
||||
];
|
||||
const NUMBER_INHIBITORS = [
|
||||
SemanticType.SUBSCRIPT,
|
||||
SemanticType.SUPERSCRIPT,
|
||||
SemanticType.OVERSCORE,
|
||||
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 === SemanticType.PREFIXOP &&
|
||||
parent.role === SemanticRole.NEGATIVE &&
|
||||
!info.script &&
|
||||
!info.enclosed) ||
|
||||
(type === SemanticType.PREFIXOP &&
|
||||
parent.role === SemanticRole.GEOMETRY)) {
|
||||
return true;
|
||||
}
|
||||
if (type === SemanticType.PUNCTUATED) {
|
||||
if (!info.enclosed || parent.role === 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 === SemanticType.FENCED) {
|
||||
info.number = false;
|
||||
info.enclosed = true;
|
||||
return ['', info];
|
||||
}
|
||||
if (node.type === SemanticType.PREFIXOP &&
|
||||
node.role !== SemanticRole.GEOMETRY &&
|
||||
node.role !== SemanticRole.NEGATIVE) {
|
||||
info.number = false;
|
||||
return ['', info];
|
||||
}
|
||||
if (checkParent(node, info)) {
|
||||
info.number = true;
|
||||
info.enclosed = false;
|
||||
}
|
||||
return ['', info];
|
||||
}
|
||||
register(new 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];
|
||||
}
|
||||
register(new SemanticVisitor('depth', 'depth', annotateDepth));
|
||||
activate('depth', 'depth');
|
||||
export 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
|
||||
? [AuditoryDescription.create({ text: context }, { translate: true })]
|
||||
: [];
|
||||
if (!content) {
|
||||
return contextDescr;
|
||||
}
|
||||
const base = leftChild
|
||||
? MathspeakUtil.nestedSubSuper(leftChild, '', {
|
||||
sup: LOCALE.MESSAGES.MS.SUPER,
|
||||
sub: LOCALE.MESSAGES.MS.SUB
|
||||
})
|
||||
: '';
|
||||
const left = (leftChild && DomUtil.tagName(leftChild) !== 'EMPTY') ||
|
||||
(first && parentNode && parentNode.previousSibling)
|
||||
? [
|
||||
AuditoryDescription.create({ text: LOCALE.MESSAGES.regexp.SPACE + base }, {})
|
||||
]
|
||||
: [];
|
||||
const right = (rightChild && DomUtil.tagName(rightChild) !== 'EMPTY') ||
|
||||
(!contentNodes.length && parentNode && parentNode.nextSibling)
|
||||
? [
|
||||
AuditoryDescription.create({ text: LOCALE.MESSAGES.regexp.SPACE }, {})
|
||||
]
|
||||
: [];
|
||||
const descrs = Engine.evaluateNode(content);
|
||||
descrs.unshift(new AuditoryDescription({ text: '', layout: `beginrel${depth}` }));
|
||||
descrs.push(new AuditoryDescription({ text: '', layout: `endrel${depth}` }));
|
||||
first = false;
|
||||
return contextDescr.concat(left, descrs, right);
|
||||
};
|
||||
}
|
||||
export 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
|
||||
? [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') === SemanticRole.SPACE
|
||||
? [
|
||||
AuditoryDescription.create({ text: LOCALE.MESSAGES.regexp.SPACE }, {})
|
||||
]
|
||||
: []);
|
||||
};
|
||||
}
|
||||
function ignoreEnglish(text) {
|
||||
return correctFont(text, LOCALE.ALPHABETS.languagePrefix.english);
|
||||
}
|
||||
Grammar.getInstance().setCorrection('ignoreEnglish', ignoreEnglish);
|
||||
export function contentIterator(nodes, context) {
|
||||
var _a;
|
||||
const func = suCI(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 AuditoryDescription({ text: '', layout: `beginrel${depth}` }));
|
||||
descrs.push(new AuditoryDescription({ text: '', layout: `endrel${depth}` }));
|
||||
return descrs;
|
||||
};
|
||||
}
|
||||
function literal(text) {
|
||||
const evalStr = (e) => Engine.getInstance().evaluator(e, Engine.getInstance().dynamicCstr);
|
||||
return Array.from(text).map(evalStr).join('');
|
||||
}
|
||||
Grammar.getInstance().setCorrection('literal', literal);
|
||||
5
node_modules/speech-rule-engine/mjs/speech_rules/numbers_util.d.ts
generated
vendored
Normal file
5
node_modules/speech-rule-engine/mjs/speech_rules/numbers_util.d.ts
generated
vendored
Normal 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[];
|
||||
33
node_modules/speech-rule-engine/mjs/speech_rules/numbers_util.js
generated
vendored
Normal file
33
node_modules/speech-rule-engine/mjs/speech_rules/numbers_util.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { convertVulgarFraction } from '../l10n/transformers.js';
|
||||
export function ordinalCounter(_node, context) {
|
||||
let counter = 0;
|
||||
return function () {
|
||||
return LOCALE.NUMBERS.numericOrdinal(++counter) + ' ' + context;
|
||||
};
|
||||
}
|
||||
export function wordCounter(_node, context) {
|
||||
let counter = 0;
|
||||
return function () {
|
||||
return LOCALE.NUMBERS.numberToOrdinal(++counter, false) + ' ' + context;
|
||||
};
|
||||
}
|
||||
export function vulgarFraction(node) {
|
||||
const conversion = convertVulgarFraction(node, LOCALE.MESSAGES.MS.FRAC_OVER);
|
||||
if (conversion.convertible &&
|
||||
conversion.enumerator &&
|
||||
conversion.denominator) {
|
||||
return [
|
||||
Span.node(LOCALE.NUMBERS.numberToWords(conversion.enumerator), node.childNodes[0].childNodes[0], { separator: '' }),
|
||||
Span.stringAttr(LOCALE.NUMBERS.vulgarSep, { separator: '' }),
|
||||
Span.node(LOCALE.NUMBERS.numberToOrdinal(conversion.denominator, conversion.enumerator !== 1), node.childNodes[0].childNodes[1])
|
||||
];
|
||||
}
|
||||
return [Span.node(conversion.content || '', node)];
|
||||
}
|
||||
export function ordinalPosition(node) {
|
||||
const children = DomUtil.toArray(node.parentNode.childNodes);
|
||||
return Span.singleton(LOCALE.NUMBERS.numericOrdinal(children.indexOf(node) + 1).toString());
|
||||
}
|
||||
3
node_modules/speech-rule-engine/mjs/speech_rules/other_rules.d.ts
generated
vendored
Normal file
3
node_modules/speech-rule-engine/mjs/speech_rules/other_rules.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export declare function PrefixRules(): void;
|
||||
export declare function OtherRules(): void;
|
||||
export declare function BrailleRules(): void;
|
||||
47
node_modules/speech-rule-engine/mjs/speech_rules/other_rules.js
generated
vendored
Normal file
47
node_modules/speech-rule-engine/mjs/speech_rules/other_rules.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
import * as StoreUtil from '../rule_engine/store_util.js';
|
||||
import * as MathspeakKoreanUtil from './mathspeak_korean_util.js';
|
||||
import * as MathspeakUtil from './mathspeak_util.js';
|
||||
import * as NemethUtil from './nemeth_util.js';
|
||||
import * as NumbersUtil from './numbers_util.js';
|
||||
import * as SpeechRules from './speech_rules.js';
|
||||
export function PrefixRules() {
|
||||
SpeechRules.addStore('en.prefix.default', '', {
|
||||
CSFordinalPosition: NumbersUtil.ordinalPosition
|
||||
});
|
||||
}
|
||||
export 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
|
||||
});
|
||||
}
|
||||
export function BrailleRules() {
|
||||
SpeechRules.addStore('nemeth.braille.default', 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', {});
|
||||
}
|
||||
1
node_modules/speech-rule-engine/mjs/speech_rules/speech_rule_stores.d.ts
generated
vendored
Normal file
1
node_modules/speech-rule-engine/mjs/speech_rules/speech_rule_stores.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function init(): void;
|
||||
15
node_modules/speech-rule-engine/mjs/speech_rules/speech_rule_stores.js
generated
vendored
Normal file
15
node_modules/speech-rule-engine/mjs/speech_rules/speech_rule_stores.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ClearspeakRules } from './clearspeak_rules.js';
|
||||
import { MathspeakRules } from './mathspeak_rules.js';
|
||||
import { BrailleRules, OtherRules, PrefixRules } from './other_rules.js';
|
||||
let INIT = false;
|
||||
export function init() {
|
||||
if (INIT) {
|
||||
return;
|
||||
}
|
||||
MathspeakRules();
|
||||
ClearspeakRules();
|
||||
PrefixRules();
|
||||
OtherRules();
|
||||
BrailleRules();
|
||||
INIT = true;
|
||||
}
|
||||
7
node_modules/speech-rule-engine/mjs/speech_rules/speech_rules.d.ts
generated
vendored
Normal file
7
node_modules/speech-rule-engine/mjs/speech_rules/speech_rules.d.ts
generated
vendored
Normal 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;
|
||||
};
|
||||
16
node_modules/speech-rule-engine/mjs/speech_rules/speech_rules.js
generated
vendored
Normal file
16
node_modules/speech-rule-engine/mjs/speech_rules/speech_rules.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Axis, DynamicCstr } from '../rule_engine/dynamic_cstr.js';
|
||||
const funcStore = new Map();
|
||||
export 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));
|
||||
}
|
||||
export function getStore(locale, modality, domain) {
|
||||
return (funcStore.get([locale, modality, domain].join('.')) ||
|
||||
funcStore.get([DynamicCstr.DEFAULT_VALUES[Axis.LOCALE], modality, domain].join('.')) ||
|
||||
funcStore.get([DynamicCstr.BASE_LOCALE, modality, domain].join('.')) ||
|
||||
{});
|
||||
}
|
||||
3
node_modules/speech-rule-engine/mjs/speech_rules/unit_util.d.ts
generated
vendored
Normal file
3
node_modules/speech-rule-engine/mjs/speech_rules/unit_util.d.ts
generated
vendored
Normal 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[];
|
||||
61
node_modules/speech-rule-engine/mjs/speech_rules/unit_util.js
generated
vendored
Normal file
61
node_modules/speech-rule-engine/mjs/speech_rules/unit_util.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { SemanticType } from '../semantic_tree/semantic_meaning.js';
|
||||
export function unitMultipliers(nodes, _context) {
|
||||
const children = nodes;
|
||||
let counter = 0;
|
||||
return function () {
|
||||
const descr = AuditoryDescription.create({
|
||||
text: rightMostUnit(children[counter]) &&
|
||||
leftMostUnit(children[counter + 1])
|
||||
? LOCALE.MESSAGES.unitTimes
|
||||
: ''
|
||||
}, {});
|
||||
counter++;
|
||||
return [descr];
|
||||
};
|
||||
}
|
||||
const SCRIPT_ELEMENTS = [
|
||||
SemanticType.SUPERSCRIPT,
|
||||
SemanticType.SUBSCRIPT,
|
||||
SemanticType.OVERSCORE,
|
||||
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;
|
||||
}
|
||||
export 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 [];
|
||||
}
|
||||
Reference in New Issue
Block a user