add initial marp implementation with sample content and build configuration
This commit is contained in:
80
node_modules/speech-rule-engine/mjs/rule_engine/base_rule_store.d.ts
generated
vendored
Normal file
80
node_modules/speech-rule-engine/mjs/rule_engine/base_rule_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { AxisOrder, DynamicCstr, DynamicCstrParser } from './dynamic_cstr.js';
|
||||
import { Action, Precondition, SpeechRule } from './speech_rule.js';
|
||||
import { SpeechRuleContext } from './speech_rule_context.js';
|
||||
import { SpeechRuleEvaluator } from './speech_rule_evaluator.js';
|
||||
import { SpeechRuleFunction } from './speech_rule_functions.js';
|
||||
import { SpeechRuleStore } from './speech_rule_store.js';
|
||||
export declare abstract class BaseRuleStore implements SpeechRuleEvaluator, SpeechRuleStore {
|
||||
context: SpeechRuleContext;
|
||||
parseOrder: AxisOrder;
|
||||
parser: DynamicCstrParser;
|
||||
locale: string;
|
||||
modality: string;
|
||||
domain: string;
|
||||
parseMethods: any;
|
||||
initialized: boolean;
|
||||
inherits: BaseRuleStore;
|
||||
kind: string;
|
||||
customTranscriptions: {
|
||||
[key: string]: string;
|
||||
};
|
||||
protected preconditions: Map<string, Condition>;
|
||||
private speechRules_;
|
||||
private rank;
|
||||
private static compareStaticConstraints_;
|
||||
private static comparePreconditions_;
|
||||
constructor();
|
||||
defineRule(name: string, dynamic: string, action: string, prec: string, ...args: string[]): SpeechRule;
|
||||
addRule(rule: SpeechRule): void;
|
||||
deleteRule(rule: SpeechRule): void;
|
||||
findRule(pred: (rule: SpeechRule) => boolean): SpeechRule;
|
||||
findAllRules(pred: (rule: SpeechRule) => boolean): SpeechRule[];
|
||||
evaluateDefault(node: Node): AuditoryDescription[];
|
||||
evaluateWhitespace(_str: string): AuditoryDescription[];
|
||||
evaluateCustom(str: string): AuditoryDescription;
|
||||
evaluateCharacter(str: string): AuditoryDescription;
|
||||
abstract evaluateString(str: string): AuditoryDescription[];
|
||||
abstract initialize(): void;
|
||||
removeDuplicates(rule: SpeechRule): void;
|
||||
getSpeechRules(): SpeechRule[];
|
||||
setSpeechRules(rules: SpeechRule[]): void;
|
||||
getPreconditions(): Map<string, Condition>;
|
||||
parseCstr(cstr: string): DynamicCstr;
|
||||
parsePrecondition(query: string, rest: string[]): Precondition;
|
||||
parseAction(action: string): Action;
|
||||
parse(ruleSet: RulesJson): void;
|
||||
parseRules(rules: string[][]): void;
|
||||
generateRules(generator: string): void;
|
||||
defineAction(name: string, action: string): void;
|
||||
getFullPreconditions(name: string): Condition;
|
||||
definePrecondition(name: string, dynamic: string, prec: string, ...args: string[]): void;
|
||||
inheritRules(): void;
|
||||
ignoreRules(name: string, ...cstrs: string[]): void;
|
||||
private parsePrecondition_;
|
||||
}
|
||||
declare class Condition {
|
||||
private base;
|
||||
private _conditions;
|
||||
private constraints;
|
||||
private allCstr;
|
||||
constructor(base: DynamicCstr, condition: Precondition);
|
||||
get conditions(): [DynamicCstr, Precondition][];
|
||||
addConstraint(dynamic: DynamicCstr): void;
|
||||
addBaseCondition(cond: Precondition): void;
|
||||
addFullCondition(cond: Precondition): void;
|
||||
private addCondition;
|
||||
}
|
||||
export interface RulesJson {
|
||||
modality?: string;
|
||||
domain?: string;
|
||||
locale?: string;
|
||||
kind?: string;
|
||||
inherits?: string;
|
||||
functions?: {
|
||||
[key: string]: SpeechRuleFunction;
|
||||
};
|
||||
rules?: any[];
|
||||
annotators?: any[];
|
||||
}
|
||||
export {};
|
||||
316
node_modules/speech-rule-engine/mjs/rule_engine/base_rule_store.js
generated
vendored
Normal file
316
node_modules/speech-rule-engine/mjs/rule_engine/base_rule_store.js
generated
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { Axis, DynamicCstr, DynamicCstrParser } from './dynamic_cstr.js';
|
||||
import { Action, Precondition, SpeechRule } from './speech_rule.js';
|
||||
import { SpeechRuleContext } from './speech_rule_context.js';
|
||||
export class BaseRuleStore {
|
||||
static compareStaticConstraints_(cstr1, cstr2) {
|
||||
if (cstr1.length !== cstr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, cstr; (cstr = cstr1[i]); i++) {
|
||||
if (cstr2.indexOf(cstr) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static comparePreconditions_(rule1, rule2) {
|
||||
const prec1 = rule1.precondition;
|
||||
const prec2 = rule2.precondition;
|
||||
if (prec1.query !== prec2.query) {
|
||||
return false;
|
||||
}
|
||||
return BaseRuleStore.compareStaticConstraints_(prec1.constraints, prec2.constraints);
|
||||
}
|
||||
constructor() {
|
||||
this.context = new SpeechRuleContext();
|
||||
this.parseOrder = DynamicCstr.DEFAULT_ORDER;
|
||||
this.parser = new DynamicCstrParser(this.parseOrder);
|
||||
this.locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
|
||||
this.modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
|
||||
this.domain = '';
|
||||
this.initialized = false;
|
||||
this.inherits = null;
|
||||
this.kind = 'standard';
|
||||
this.customTranscriptions = {};
|
||||
this.preconditions = new Map();
|
||||
this.speechRules_ = [];
|
||||
this.rank = 0;
|
||||
this.parseMethods = {
|
||||
Rule: this.defineRule,
|
||||
Generator: this.generateRules,
|
||||
Action: this.defineAction,
|
||||
Precondition: this.definePrecondition,
|
||||
Ignore: this.ignoreRules
|
||||
};
|
||||
}
|
||||
defineRule(name, dynamic, action, prec, ...args) {
|
||||
const postc = this.parseAction(action);
|
||||
const fullPrec = this.parsePrecondition(prec, args);
|
||||
const dynamicCstr = this.parseCstr(dynamic);
|
||||
if (!(postc && fullPrec && dynamicCstr)) {
|
||||
console.error(`Rule Error: ${prec}, (${dynamic}): ${action}`);
|
||||
return null;
|
||||
}
|
||||
const rule = new SpeechRule(name, dynamicCstr, fullPrec, postc);
|
||||
rule.precondition.rank = this.rank++;
|
||||
this.addRule(rule);
|
||||
return rule;
|
||||
}
|
||||
addRule(rule) {
|
||||
rule.context = this.context;
|
||||
this.speechRules_.unshift(rule);
|
||||
}
|
||||
deleteRule(rule) {
|
||||
const index = this.speechRules_.indexOf(rule);
|
||||
if (index !== -1) {
|
||||
this.speechRules_.splice(index, 1);
|
||||
}
|
||||
}
|
||||
findRule(pred) {
|
||||
for (let i = 0, rule; (rule = this.speechRules_[i]); i++) {
|
||||
if (pred(rule)) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
findAllRules(pred) {
|
||||
return this.speechRules_.filter(pred);
|
||||
}
|
||||
evaluateDefault(node) {
|
||||
const rest = node.textContent.slice(0);
|
||||
if (rest.match(/^\s+$/)) {
|
||||
return this.evaluateWhitespace(rest);
|
||||
}
|
||||
return this.evaluateString(rest);
|
||||
}
|
||||
evaluateWhitespace(_str) {
|
||||
return [];
|
||||
}
|
||||
evaluateCustom(str) {
|
||||
const trans = this.customTranscriptions[str];
|
||||
return trans !== undefined
|
||||
? AuditoryDescription.create({ text: trans }, { adjust: true, translate: false })
|
||||
: null;
|
||||
}
|
||||
evaluateCharacter(str) {
|
||||
return (this.evaluateCustom(str) ||
|
||||
AuditoryDescription.create({ text: str }, { adjust: true, translate: true }));
|
||||
}
|
||||
removeDuplicates(rule) {
|
||||
for (let i = this.speechRules_.length - 1, oldRule; (oldRule = this.speechRules_[i]); i--) {
|
||||
if (oldRule !== rule &&
|
||||
rule.dynamicCstr.equal(oldRule.dynamicCstr) &&
|
||||
BaseRuleStore.comparePreconditions_(oldRule, rule)) {
|
||||
this.speechRules_.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
getSpeechRules() {
|
||||
return this.speechRules_;
|
||||
}
|
||||
setSpeechRules(rules) {
|
||||
this.speechRules_ = rules;
|
||||
}
|
||||
getPreconditions() {
|
||||
return this.preconditions;
|
||||
}
|
||||
parseCstr(cstr) {
|
||||
try {
|
||||
return this.parser.parse(this.locale +
|
||||
'.' +
|
||||
this.modality +
|
||||
(this.domain ? '.' + this.domain : '') +
|
||||
'.' +
|
||||
cstr);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.name === 'RuleError') {
|
||||
console.error('Rule Error ', `Illegal Dynamic Constraint: ${cstr}.`, err.message);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
parsePrecondition(query, rest) {
|
||||
try {
|
||||
const queryCstr = this.parsePrecondition_(query);
|
||||
query = queryCstr[0];
|
||||
let restCstr = queryCstr.slice(1);
|
||||
for (const cstr of rest) {
|
||||
restCstr = restCstr.concat(this.parsePrecondition_(cstr));
|
||||
}
|
||||
return new Precondition(query, ...restCstr);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.name === 'RuleError') {
|
||||
console.error('Rule Error ', `Illegal preconditions: ${query}, ${rest}.`, err.message);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
parseAction(action) {
|
||||
try {
|
||||
return Action.fromString(action);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.name === 'RuleError') {
|
||||
console.error('Rule Error ', `Illegal action: ${action}.`, err.message);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
parse(ruleSet) {
|
||||
this.modality = ruleSet.modality || this.modality;
|
||||
this.locale = ruleSet.locale || this.locale;
|
||||
this.domain = ruleSet.domain || this.domain;
|
||||
this.context.parse(ruleSet.functions || []);
|
||||
if (ruleSet.kind !== 'actions') {
|
||||
this.kind = ruleSet.kind || this.kind;
|
||||
this.inheritRules();
|
||||
}
|
||||
this.parseRules(ruleSet.rules || []);
|
||||
}
|
||||
parseRules(rules) {
|
||||
for (let i = 0, rule; (rule = rules[i]); i++) {
|
||||
const type = rule[0];
|
||||
const method = this.parseMethods[type];
|
||||
if (type && method) {
|
||||
method.apply(this, rule.slice(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
generateRules(generator) {
|
||||
const method = this.context.customGenerators.lookup(generator);
|
||||
if (method) {
|
||||
method(this);
|
||||
}
|
||||
}
|
||||
defineAction(name, action) {
|
||||
let postc;
|
||||
try {
|
||||
postc = Action.fromString(action);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.name === 'RuleError') {
|
||||
console.error('Action Error ', action, err.message);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
const prec = this.getFullPreconditions(name);
|
||||
if (!prec) {
|
||||
console.error(`Action Error: No precondition for action ${name}`);
|
||||
return;
|
||||
}
|
||||
this.ignoreRules(name);
|
||||
const regexp = new RegExp('^\\w+\\.\\w+\\.' + (this.domain ? '\\w+\\.' : ''));
|
||||
prec.conditions.forEach(([dynamic, prec]) => {
|
||||
const newDynamic = this.parseCstr(dynamic.toString().replace(regexp, ''));
|
||||
this.addRule(new SpeechRule(name, newDynamic, prec, postc));
|
||||
});
|
||||
}
|
||||
getFullPreconditions(name) {
|
||||
const prec = this.preconditions.get(name);
|
||||
if (prec || !this.inherits) {
|
||||
return prec;
|
||||
}
|
||||
return this.inherits.getFullPreconditions(name);
|
||||
}
|
||||
definePrecondition(name, dynamic, prec, ...args) {
|
||||
const fullPrec = this.parsePrecondition(prec, args);
|
||||
const dynamicCstr = this.parseCstr(dynamic);
|
||||
if (!(fullPrec && dynamicCstr)) {
|
||||
console.error(`Precondition Error: ${prec}, (${dynamic})`);
|
||||
return;
|
||||
}
|
||||
fullPrec.rank = this.rank++;
|
||||
this.preconditions.set(name, new Condition(dynamicCstr, fullPrec));
|
||||
}
|
||||
inheritRules() {
|
||||
if (!this.inherits || !this.inherits.getSpeechRules().length) {
|
||||
return;
|
||||
}
|
||||
const regexp = new RegExp('^\\w+\\.\\w+\\.' + (this.domain ? '\\w+\\.' : ''));
|
||||
this.inherits.getSpeechRules().forEach((rule) => {
|
||||
const newDynamic = this.parseCstr(rule.dynamicCstr.toString().replace(regexp, ''));
|
||||
this.addRule(new SpeechRule(rule.name, newDynamic, rule.precondition, rule.action));
|
||||
});
|
||||
}
|
||||
ignoreRules(name, ...cstrs) {
|
||||
let rules = this.findAllRules((r) => r.name === name);
|
||||
if (!cstrs.length) {
|
||||
rules.forEach(this.deleteRule.bind(this));
|
||||
return;
|
||||
}
|
||||
let rest = [];
|
||||
for (const cstr of cstrs) {
|
||||
const dynamic = this.parseCstr(cstr);
|
||||
for (const rule of rules) {
|
||||
if (dynamic.equal(rule.dynamicCstr)) {
|
||||
this.deleteRule(rule);
|
||||
}
|
||||
else {
|
||||
rest.push(rule);
|
||||
}
|
||||
}
|
||||
rules = rest;
|
||||
rest = [];
|
||||
}
|
||||
}
|
||||
parsePrecondition_(cstr) {
|
||||
const generator = this.context.customGenerators.lookup(cstr);
|
||||
return generator ? generator() : [cstr];
|
||||
}
|
||||
}
|
||||
class Condition {
|
||||
constructor(base, condition) {
|
||||
this.base = base;
|
||||
this._conditions = [];
|
||||
this.constraints = [];
|
||||
this.allCstr = {};
|
||||
this.constraints.push(base);
|
||||
this.addCondition(base, condition);
|
||||
}
|
||||
get conditions() {
|
||||
return this._conditions;
|
||||
}
|
||||
addConstraint(dynamic) {
|
||||
if (this.constraints.filter((cstr) => cstr.equal(dynamic)).length) {
|
||||
return;
|
||||
}
|
||||
this.constraints.push(dynamic);
|
||||
const newConds = [];
|
||||
for (const [dyn, pre] of this.conditions) {
|
||||
if (this.base.equal(dyn)) {
|
||||
newConds.push([dynamic, pre]);
|
||||
}
|
||||
}
|
||||
this._conditions = this._conditions.concat(newConds);
|
||||
}
|
||||
addBaseCondition(cond) {
|
||||
this.addCondition(this.base, cond);
|
||||
}
|
||||
addFullCondition(cond) {
|
||||
this.constraints.forEach((cstr) => this.addCondition(cstr, cond));
|
||||
}
|
||||
addCondition(dynamic, cond) {
|
||||
const condStr = dynamic.toString() + ' ' + cond.toString();
|
||||
if (this.allCstr.condStr) {
|
||||
return;
|
||||
}
|
||||
this.allCstr[condStr] = true;
|
||||
this._conditions.push([dynamic, cond]);
|
||||
}
|
||||
}
|
||||
22
node_modules/speech-rule-engine/mjs/rule_engine/braille_store.d.ts
generated
vendored
Normal file
22
node_modules/speech-rule-engine/mjs/rule_engine/braille_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { MathStore } from './math_store.js';
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
export declare class BrailleStore extends MathStore {
|
||||
modality: string;
|
||||
customTranscriptions: {
|
||||
[key: string]: string;
|
||||
};
|
||||
evaluateString(str: string): AuditoryDescription[];
|
||||
annotations(): void;
|
||||
}
|
||||
export declare class EuroStore extends BrailleStore {
|
||||
locale: string;
|
||||
customTranscriptions: {};
|
||||
customCommands: {
|
||||
[key: string]: string;
|
||||
};
|
||||
evaluateString(str: string): AuditoryDescription[];
|
||||
protected cleanup(commands: string[]): string;
|
||||
private lastSpecial;
|
||||
private specialChars;
|
||||
private addSpace;
|
||||
}
|
||||
109
node_modules/speech-rule-engine/mjs/rule_engine/braille_store.js
generated
vendored
Normal file
109
node_modules/speech-rule-engine/mjs/rule_engine/braille_store.js
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
import { MathStore } from './math_store.js';
|
||||
import { activate } from '../semantic_tree/semantic_annotations.js';
|
||||
import { SemanticMap } from '../semantic_tree/semantic_attr.js';
|
||||
import { SemanticType, SemanticRole } from '../semantic_tree/semantic_meaning.js';
|
||||
export class BrailleStore extends MathStore {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.modality = 'braille';
|
||||
this.customTranscriptions = {
|
||||
'\u22ca': '⠈⠡⠳'
|
||||
};
|
||||
}
|
||||
evaluateString(str) {
|
||||
const descs = [];
|
||||
const text = Array.from(str);
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
descs.push(this.evaluateCharacter(text[i]));
|
||||
}
|
||||
return descs;
|
||||
}
|
||||
annotations() {
|
||||
for (let i = 0, annotator; (annotator = this.annotators[i]); i++) {
|
||||
activate(this.locale, annotator);
|
||||
}
|
||||
}
|
||||
}
|
||||
export class EuroStore extends BrailleStore {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.locale = 'euro';
|
||||
this.customTranscriptions = {};
|
||||
this.customCommands = {
|
||||
'\\cdot': '*',
|
||||
'\\lt': '<',
|
||||
'\\gt': '>'
|
||||
};
|
||||
this.lastSpecial = false;
|
||||
this.specialChars = ['^', '_', '{', '}'];
|
||||
}
|
||||
evaluateString(str) {
|
||||
const regexp = /(\\[a-z]+|\\{|\\}|\\\\)/i;
|
||||
const split = str.split(regexp);
|
||||
const cleaned = this.cleanup(split);
|
||||
return super.evaluateString(cleaned);
|
||||
}
|
||||
cleanup(commands) {
|
||||
const cleaned = [];
|
||||
let intext = false;
|
||||
let lastcom = null;
|
||||
for (let command of commands) {
|
||||
if (command.match(/^\\/)) {
|
||||
if (command === '\\text') {
|
||||
intext = true;
|
||||
}
|
||||
if (this.addSpace(SemanticMap.LatexCommands.get(command))) {
|
||||
cleaned.push(' ');
|
||||
}
|
||||
command = this.customCommands[command] || command;
|
||||
const newcom = command.match(/^\\/);
|
||||
if (newcom && command.match(/^\\[a-zA-Z]+$/) && lastcom) {
|
||||
cleaned.push(' ');
|
||||
}
|
||||
lastcom = newcom ? command : null;
|
||||
cleaned.push(command);
|
||||
continue;
|
||||
}
|
||||
const rest = command.split('');
|
||||
for (const char of rest) {
|
||||
if (intext) {
|
||||
cleaned.push(char);
|
||||
intext = char !== '}';
|
||||
lastcom = null;
|
||||
continue;
|
||||
}
|
||||
if (char.match(/[a-z]/i) && lastcom) {
|
||||
lastcom = null;
|
||||
cleaned.push(' ');
|
||||
cleaned.push(char);
|
||||
continue;
|
||||
}
|
||||
if (char.match(/\s/))
|
||||
continue;
|
||||
if (this.addSpace(char)) {
|
||||
cleaned.push(' ');
|
||||
}
|
||||
cleaned.push(char);
|
||||
lastcom = null;
|
||||
}
|
||||
}
|
||||
return cleaned.join('');
|
||||
}
|
||||
addSpace(char) {
|
||||
if (!char)
|
||||
return false;
|
||||
if (this.specialChars.indexOf(char) !== -1) {
|
||||
this.lastSpecial = true;
|
||||
return false;
|
||||
}
|
||||
if (this.lastSpecial) {
|
||||
this.lastSpecial = false;
|
||||
return false;
|
||||
}
|
||||
const meaning = SemanticMap.Meaning.get(char);
|
||||
return (meaning.type === SemanticType.OPERATOR ||
|
||||
meaning.type === SemanticType.RELATION ||
|
||||
(meaning.type === SemanticType.PUNCTUATION &&
|
||||
meaning.role === SemanticRole.COLON));
|
||||
}
|
||||
}
|
||||
66
node_modules/speech-rule-engine/mjs/rule_engine/dynamic_cstr.d.ts
generated
vendored
Normal file
66
node_modules/speech-rule-engine/mjs/rule_engine/dynamic_cstr.d.ts
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
export declare enum Axis {
|
||||
DOMAIN = "domain",
|
||||
STYLE = "style",
|
||||
LOCALE = "locale",
|
||||
TOPIC = "topic",
|
||||
MODALITY = "modality"
|
||||
}
|
||||
export type AxisProperties = {
|
||||
[key: string]: string[];
|
||||
};
|
||||
export type AxisOrder = Axis[];
|
||||
export type AxisMap = {
|
||||
[key: string]: string;
|
||||
};
|
||||
export declare class DynamicProperties {
|
||||
private properties;
|
||||
protected order: AxisOrder;
|
||||
static createProp(...cstrList: string[][]): DynamicProperties;
|
||||
constructor(properties: AxisProperties, order?: AxisOrder);
|
||||
getProperties(): AxisProperties;
|
||||
getOrder(): AxisOrder;
|
||||
getAxes(): AxisOrder;
|
||||
getProperty(key: Axis): string[];
|
||||
updateProperties(props: AxisProperties): void;
|
||||
allProperties(): string[][];
|
||||
toString(): string;
|
||||
}
|
||||
export declare class DynamicCstr extends DynamicProperties {
|
||||
static DEFAULT_ORDER: AxisOrder;
|
||||
static BASE_LOCALE: string;
|
||||
static DEFAULT_VALUE: string;
|
||||
static DEFAULT_VALUES: AxisMap;
|
||||
private components;
|
||||
static createCstr(...cstrList: string[]): DynamicCstr;
|
||||
static defaultCstr(): DynamicCstr;
|
||||
static validOrder(order: AxisOrder): boolean;
|
||||
constructor(components_: AxisMap, order?: AxisOrder);
|
||||
getComponents(): AxisMap;
|
||||
getValue(key: Axis): string;
|
||||
getValues(): string[];
|
||||
allProperties(): string[][];
|
||||
toString(): string;
|
||||
equal(cstr: DynamicCstr): boolean;
|
||||
}
|
||||
export declare class DynamicCstrParser {
|
||||
private order;
|
||||
constructor(order: AxisOrder);
|
||||
parse(str: string): DynamicCstr;
|
||||
}
|
||||
export interface Comparator {
|
||||
getReference(): DynamicCstr;
|
||||
setReference(cstr: DynamicCstr, opt_props?: DynamicProperties): void;
|
||||
match(cstr: DynamicCstr): boolean;
|
||||
compare(cstr1: DynamicCstr, cstr2: DynamicCstr): number;
|
||||
}
|
||||
export declare class DefaultComparator implements Comparator {
|
||||
private reference;
|
||||
private fallback;
|
||||
private order;
|
||||
constructor(reference: DynamicCstr, fallback?: DynamicProperties);
|
||||
getReference(): DynamicCstr;
|
||||
setReference(cstr: DynamicCstr, props?: DynamicProperties): void;
|
||||
match(cstr: DynamicCstr): boolean;
|
||||
compare(cstr1: DynamicCstr, cstr2: DynamicCstr): 0 | 1 | -1;
|
||||
toString(): string;
|
||||
}
|
||||
206
node_modules/speech-rule-engine/mjs/rule_engine/dynamic_cstr.js
generated
vendored
Normal file
206
node_modules/speech-rule-engine/mjs/rule_engine/dynamic_cstr.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
export var Axis;
|
||||
(function (Axis) {
|
||||
Axis["DOMAIN"] = "domain";
|
||||
Axis["STYLE"] = "style";
|
||||
Axis["LOCALE"] = "locale";
|
||||
Axis["TOPIC"] = "topic";
|
||||
Axis["MODALITY"] = "modality";
|
||||
})(Axis || (Axis = {}));
|
||||
export class DynamicProperties {
|
||||
static createProp(...cstrList) {
|
||||
const axes = DynamicCstr.DEFAULT_ORDER;
|
||||
const dynamicCstr = {};
|
||||
for (let i = 0, l = cstrList.length, k = axes.length; i < l && i < k; i++) {
|
||||
dynamicCstr[axes[i]] = cstrList[i];
|
||||
}
|
||||
return new DynamicProperties(dynamicCstr);
|
||||
}
|
||||
constructor(properties, order = Object.keys(properties)) {
|
||||
this.properties = properties;
|
||||
this.order = order;
|
||||
}
|
||||
getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
getAxes() {
|
||||
return this.order;
|
||||
}
|
||||
getProperty(key) {
|
||||
return this.properties[key];
|
||||
}
|
||||
updateProperties(props) {
|
||||
this.properties = props;
|
||||
}
|
||||
allProperties() {
|
||||
const propLists = [];
|
||||
this.order.forEach((key) => propLists.push(this.getProperty(key).slice()));
|
||||
return propLists;
|
||||
}
|
||||
toString() {
|
||||
const cstrStrings = [];
|
||||
this.order.forEach((key) => cstrStrings.push(key + ': ' + this.getProperty(key).toString()));
|
||||
return cstrStrings.join('\n');
|
||||
}
|
||||
}
|
||||
export class DynamicCstr extends DynamicProperties {
|
||||
static createCstr(...cstrList) {
|
||||
const axes = DynamicCstr.DEFAULT_ORDER;
|
||||
const dynamicCstr = {};
|
||||
for (let i = 0, l = cstrList.length, k = axes.length; i < l && i < k; i++) {
|
||||
dynamicCstr[axes[i]] = cstrList[i];
|
||||
}
|
||||
return new DynamicCstr(dynamicCstr);
|
||||
}
|
||||
static defaultCstr() {
|
||||
return DynamicCstr.createCstr.apply(null, DynamicCstr.DEFAULT_ORDER.map(function (x) {
|
||||
return DynamicCstr.DEFAULT_VALUES[x];
|
||||
}));
|
||||
}
|
||||
static validOrder(order) {
|
||||
const axes = DynamicCstr.DEFAULT_ORDER.slice();
|
||||
return order.every((x) => {
|
||||
const index = axes.indexOf(x);
|
||||
return index !== -1 && axes.splice(index, 1);
|
||||
});
|
||||
}
|
||||
constructor(components_, order) {
|
||||
const properties = {};
|
||||
for (const [key, value] of Object.entries(components_)) {
|
||||
properties[key] = [value];
|
||||
}
|
||||
super(properties, order);
|
||||
this.components = components_;
|
||||
}
|
||||
getComponents() {
|
||||
return this.components;
|
||||
}
|
||||
getValue(key) {
|
||||
return this.components[key];
|
||||
}
|
||||
getValues() {
|
||||
return this.order.map((key) => this.getValue(key));
|
||||
}
|
||||
allProperties() {
|
||||
const propLists = super.allProperties();
|
||||
for (let i = 0, props, key; (props = propLists[i]), (key = this.order[i]); i++) {
|
||||
const value = this.getValue(key);
|
||||
if (props.indexOf(value) === -1) {
|
||||
props.unshift(value);
|
||||
}
|
||||
}
|
||||
return propLists;
|
||||
}
|
||||
toString() {
|
||||
return this.getValues().join('.');
|
||||
}
|
||||
equal(cstr) {
|
||||
const keys1 = cstr.getAxes();
|
||||
if (this.order.length !== keys1.length) {
|
||||
return false;
|
||||
}
|
||||
for (let j = 0, key; (key = keys1[j]); j++) {
|
||||
const comp2 = this.getValue(key);
|
||||
if (!comp2 || cstr.getValue(key) !== comp2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DynamicCstr.DEFAULT_ORDER = [
|
||||
Axis.LOCALE,
|
||||
Axis.MODALITY,
|
||||
Axis.DOMAIN,
|
||||
Axis.STYLE,
|
||||
Axis.TOPIC
|
||||
];
|
||||
DynamicCstr.BASE_LOCALE = 'base';
|
||||
DynamicCstr.DEFAULT_VALUE = 'default';
|
||||
DynamicCstr.DEFAULT_VALUES = {
|
||||
[Axis.LOCALE]: 'en',
|
||||
[Axis.DOMAIN]: DynamicCstr.DEFAULT_VALUE,
|
||||
[Axis.STYLE]: DynamicCstr.DEFAULT_VALUE,
|
||||
[Axis.TOPIC]: DynamicCstr.DEFAULT_VALUE,
|
||||
[Axis.MODALITY]: 'speech'
|
||||
};
|
||||
export class DynamicCstrParser {
|
||||
constructor(order) {
|
||||
this.order = order;
|
||||
}
|
||||
parse(str) {
|
||||
const order = str.split('.');
|
||||
const cstr = {};
|
||||
if (order.length > this.order.length) {
|
||||
throw new Error('Invalid dynamic constraint: ' + cstr);
|
||||
}
|
||||
let j = 0;
|
||||
for (let i = 0, key; (key = this.order[i]), order.length; i++, j++) {
|
||||
const value = order.shift();
|
||||
cstr[key] = value;
|
||||
}
|
||||
return new DynamicCstr(cstr, this.order.slice(0, j));
|
||||
}
|
||||
}
|
||||
export class DefaultComparator {
|
||||
constructor(reference, fallback = new DynamicProperties(reference.getProperties(), reference.getOrder())) {
|
||||
this.reference = reference;
|
||||
this.fallback = fallback;
|
||||
this.order = this.reference.getOrder();
|
||||
}
|
||||
getReference() {
|
||||
return this.reference;
|
||||
}
|
||||
setReference(cstr, props) {
|
||||
this.reference = cstr;
|
||||
this.fallback =
|
||||
props || new DynamicProperties(cstr.getProperties(), cstr.getOrder());
|
||||
this.order = this.reference.getOrder();
|
||||
}
|
||||
match(cstr) {
|
||||
const keys1 = cstr.getAxes();
|
||||
return (keys1.length === this.reference.getAxes().length &&
|
||||
keys1.every((key) => {
|
||||
const value = cstr.getValue(key);
|
||||
return (value === this.reference.getValue(key) ||
|
||||
this.fallback.getProperty(key).indexOf(value) !== -1);
|
||||
}));
|
||||
}
|
||||
compare(cstr1, cstr2) {
|
||||
let ignore = false;
|
||||
for (let i = 0, key; (key = this.order[i]); i++) {
|
||||
const value1 = cstr1.getValue(key);
|
||||
const value2 = cstr2.getValue(key);
|
||||
if (!ignore) {
|
||||
const ref = this.reference.getValue(key);
|
||||
if (ref === value1 && ref !== value2) {
|
||||
return -1;
|
||||
}
|
||||
if (ref === value2 && ref !== value1) {
|
||||
return 1;
|
||||
}
|
||||
if (ref === value1 && ref === value2) {
|
||||
continue;
|
||||
}
|
||||
if (ref !== value1 && ref !== value2) {
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
const prop = this.fallback.getProperty(key);
|
||||
const index1 = prop.indexOf(value1);
|
||||
const index2 = prop.indexOf(value2);
|
||||
if (index1 < index2) {
|
||||
return -1;
|
||||
}
|
||||
if (index2 < index1) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
toString() {
|
||||
return this.reference.toString() + '\n' + this.fallback.toString();
|
||||
}
|
||||
}
|
||||
48
node_modules/speech-rule-engine/mjs/rule_engine/grammar.d.ts
generated
vendored
Normal file
48
node_modules/speech-rule-engine/mjs/rule_engine/grammar.d.ts
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
type Value = boolean | string;
|
||||
export type State = {
|
||||
[key: string]: Value;
|
||||
};
|
||||
interface Flags {
|
||||
adjust?: boolean;
|
||||
preprocess?: boolean;
|
||||
correct?: boolean;
|
||||
translate?: boolean;
|
||||
}
|
||||
type Correction = (text: string, parameter?: Value) => string;
|
||||
export declare const ATTRIBUTE = "grammar";
|
||||
export declare class Grammar {
|
||||
private static instance;
|
||||
currentFlags: Flags;
|
||||
private parameters_;
|
||||
private corrections_;
|
||||
private preprocessors_;
|
||||
private stateStack_;
|
||||
private singles;
|
||||
static getInstance(): Grammar;
|
||||
static parseInput(grammar: string): State;
|
||||
static parseState(stateStr: string): State;
|
||||
private static translateString;
|
||||
private static translateUnit;
|
||||
private static prepareUnit;
|
||||
private static cleanUnit;
|
||||
clear(): void;
|
||||
setParameter(parameter: string, value: Value): Value;
|
||||
getParameter(parameter: string): Value;
|
||||
setCorrection(correction: string, func: Correction): void;
|
||||
setPreprocessor(preprocessor: string, func: Correction): void;
|
||||
getCorrection(correction: string): Correction;
|
||||
getState(): string;
|
||||
processSingles(): void;
|
||||
pushState(assignment: {
|
||||
[key: string]: Value;
|
||||
}): void;
|
||||
popState(): void;
|
||||
setAttribute(node: Element): void;
|
||||
preprocess(text: string): string;
|
||||
correct(text: string): string;
|
||||
apply(text: string, opt_flags?: Flags): string;
|
||||
private runProcessors;
|
||||
private constructor();
|
||||
}
|
||||
export declare function correctFont(text: string, correction: string): string;
|
||||
export {};
|
||||
230
node_modules/speech-rule-engine/mjs/rule_engine/grammar.js
generated
vendored
Normal file
230
node_modules/speech-rule-engine/mjs/rule_engine/grammar.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
import * as LocaleUtil from '../l10n/locale_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
export const ATTRIBUTE = 'grammar';
|
||||
export class Grammar {
|
||||
static getInstance() {
|
||||
Grammar.instance = Grammar.instance || new Grammar();
|
||||
return Grammar.instance;
|
||||
}
|
||||
static parseInput(grammar) {
|
||||
const attributes = {};
|
||||
const components = grammar.split(':');
|
||||
for (const component of components) {
|
||||
const comp = component.split('=');
|
||||
const key = comp[0].trim();
|
||||
if (comp[1]) {
|
||||
attributes[key] = comp[1].trim();
|
||||
continue;
|
||||
}
|
||||
key.match(/^!/)
|
||||
? (attributes[key.slice(1)] = false)
|
||||
: (attributes[key] = true);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
static parseState(stateStr) {
|
||||
const state = {};
|
||||
const corrections = stateStr.split(' ');
|
||||
for (const correction of corrections) {
|
||||
const corr = correction.split(':');
|
||||
const key = corr[0];
|
||||
const value = corr[1];
|
||||
state[key] = value ? value : true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
static translateString(text) {
|
||||
if (text.match(/:unit$/)) {
|
||||
return Grammar.translateUnit(text);
|
||||
}
|
||||
const engine = Engine.getInstance();
|
||||
let result = engine.evaluator(text, engine.dynamicCstr);
|
||||
result = result === null ? text : result;
|
||||
if (Grammar.getInstance().getParameter('plural')) {
|
||||
result = LOCALE.FUNCTIONS.plural(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static translateUnit(text) {
|
||||
text = Grammar.prepareUnit(text);
|
||||
const engine = Engine.getInstance();
|
||||
const plural = Grammar.getInstance().getParameter('plural');
|
||||
const strict = engine.strict;
|
||||
const baseCstr = `${engine.locale}.${engine.modality}.default`;
|
||||
engine.strict = true;
|
||||
let cstr;
|
||||
let result;
|
||||
if (plural) {
|
||||
cstr = engine.defaultParser.parse(baseCstr + '.plural');
|
||||
result = engine.evaluator(text, cstr);
|
||||
}
|
||||
if (result) {
|
||||
engine.strict = strict;
|
||||
return result;
|
||||
}
|
||||
cstr = engine.defaultParser.parse(baseCstr + '.default');
|
||||
result = engine.evaluator(text, cstr);
|
||||
engine.strict = strict;
|
||||
if (!result) {
|
||||
return Grammar.cleanUnit(text);
|
||||
}
|
||||
if (plural) {
|
||||
result = LOCALE.FUNCTIONS.plural(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static prepareUnit(text) {
|
||||
const match = text.match(/:unit$/);
|
||||
return match
|
||||
? text.slice(0, match.index).replace(/\s+/g, ' ') +
|
||||
text.slice(match.index)
|
||||
: text;
|
||||
}
|
||||
static cleanUnit(text) {
|
||||
if (text.match(/:unit$/)) {
|
||||
return text.replace(/:unit$/, '');
|
||||
}
|
||||
return text;
|
||||
}
|
||||
clear() {
|
||||
this.parameters_ = {};
|
||||
this.stateStack_ = [];
|
||||
}
|
||||
setParameter(parameter, value) {
|
||||
const oldValue = this.parameters_[parameter];
|
||||
value
|
||||
? (this.parameters_[parameter] = value)
|
||||
: delete this.parameters_[parameter];
|
||||
return oldValue;
|
||||
}
|
||||
getParameter(parameter) {
|
||||
return this.parameters_[parameter];
|
||||
}
|
||||
setCorrection(correction, func) {
|
||||
this.corrections_[correction] = func;
|
||||
}
|
||||
setPreprocessor(preprocessor, func) {
|
||||
this.preprocessors_[preprocessor] = func;
|
||||
}
|
||||
getCorrection(correction) {
|
||||
return this.corrections_[correction];
|
||||
}
|
||||
getState() {
|
||||
const pairs = [];
|
||||
for (const [key, val] of Object.entries(this.parameters_)) {
|
||||
pairs.push(typeof val === 'string' ? key + ':' + val : key);
|
||||
}
|
||||
return pairs.join(' ');
|
||||
}
|
||||
processSingles() {
|
||||
const assignment = {};
|
||||
for (const single of this.singles) {
|
||||
assignment[single] = false;
|
||||
}
|
||||
this.singles = [];
|
||||
this.pushState(assignment);
|
||||
}
|
||||
pushState(assignment) {
|
||||
for (let [key, value] of Object.entries(assignment)) {
|
||||
if (key.match(/^\?/)) {
|
||||
delete assignment[key];
|
||||
key = key.slice(1);
|
||||
this.singles.push(key);
|
||||
}
|
||||
assignment[key] = this.setParameter(key, value);
|
||||
}
|
||||
this.stateStack_.push(assignment);
|
||||
}
|
||||
popState() {
|
||||
const assignment = this.stateStack_.pop();
|
||||
for (const [key, val] of Object.entries(assignment)) {
|
||||
this.setParameter(key, val);
|
||||
}
|
||||
}
|
||||
setAttribute(node) {
|
||||
if (node && node.nodeType === DomUtil.NodeType.ELEMENT_NODE) {
|
||||
const state = this.getState();
|
||||
if (state) {
|
||||
node.setAttribute(ATTRIBUTE, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
preprocess(text) {
|
||||
return this.runProcessors(text, this.preprocessors_);
|
||||
}
|
||||
correct(text) {
|
||||
return this.runProcessors(text, this.corrections_);
|
||||
}
|
||||
apply(text, opt_flags) {
|
||||
this.currentFlags = opt_flags || {};
|
||||
text =
|
||||
this.currentFlags.adjust || this.currentFlags.preprocess
|
||||
? Grammar.getInstance().preprocess(text)
|
||||
: text;
|
||||
if (this.parameters_['translate'] || this.currentFlags.translate) {
|
||||
text = Grammar.translateString(text);
|
||||
}
|
||||
text =
|
||||
this.currentFlags.adjust || this.currentFlags.correct
|
||||
? Grammar.getInstance().correct(text)
|
||||
: text;
|
||||
this.currentFlags = {};
|
||||
return text;
|
||||
}
|
||||
runProcessors(text, funcs) {
|
||||
for (const [key, val] of Object.entries(this.parameters_)) {
|
||||
const func = funcs[key];
|
||||
if (!func) {
|
||||
continue;
|
||||
}
|
||||
text = val === true ? func(text) : func(text, val);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
constructor() {
|
||||
this.currentFlags = {};
|
||||
this.parameters_ = {};
|
||||
this.corrections_ = {};
|
||||
this.preprocessors_ = {};
|
||||
this.stateStack_ = [];
|
||||
this.singles = [];
|
||||
}
|
||||
}
|
||||
export function correctFont(text, correction) {
|
||||
if (!correction || !text) {
|
||||
return text;
|
||||
}
|
||||
const regexp = LOCALE.FUNCTIONS.fontRegexp(LocaleUtil.localFont(correction));
|
||||
return text.replace(regexp, '');
|
||||
}
|
||||
function correctCaps(text) {
|
||||
let cap = LOCALE.ALPHABETS.capPrefix[Engine.getInstance().domain];
|
||||
if (typeof cap === 'undefined') {
|
||||
cap = LOCALE.ALPHABETS.capPrefix['default'];
|
||||
}
|
||||
return correctFont(text, cap);
|
||||
}
|
||||
function addAnnotation(text, annotation) {
|
||||
return text + ':' + annotation;
|
||||
}
|
||||
function numbersToAlpha(text) {
|
||||
return text.match(/\d+/)
|
||||
? LOCALE.NUMBERS.numberToWords(parseInt(text, 10))
|
||||
: text;
|
||||
}
|
||||
function noTranslateText(text) {
|
||||
if (text.match(new RegExp('^[' + LOCALE.MESSAGES.regexp.TEXT + ']+$'))) {
|
||||
Grammar.getInstance().currentFlags['translate'] = false;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
Grammar.getInstance().setCorrection('localFont', LocaleUtil.localFont);
|
||||
Grammar.getInstance().setCorrection('localRole', LocaleUtil.localRole);
|
||||
Grammar.getInstance().setCorrection('localEnclose', LocaleUtil.localEnclose);
|
||||
Grammar.getInstance().setCorrection('ignoreFont', correctFont);
|
||||
Grammar.getInstance().setPreprocessor('annotation', addAnnotation);
|
||||
Grammar.getInstance().setPreprocessor('noTranslateText', noTranslateText);
|
||||
Grammar.getInstance().setCorrection('ignoreCaps', correctCaps);
|
||||
Grammar.getInstance().setPreprocessor('numbers2alpha', numbersToAlpha);
|
||||
21
node_modules/speech-rule-engine/mjs/rule_engine/math_compound_store.d.ts
generated
vendored
Normal file
21
node_modules/speech-rule-engine/mjs/rule_engine/math_compound_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BaseJson, MathSimpleStore, SiJson, MappingsJson, SimpleRule, UnicodeJson } from './math_simple_store.js';
|
||||
import { DynamicCstr } from './dynamic_cstr.js';
|
||||
export declare function changeLocale(json: UnicodeJson): boolean;
|
||||
export declare function setSiPrefixes(prefixes: SiJson): void;
|
||||
export declare const subStores: Map<string, MathSimpleStore>;
|
||||
export declare const baseStores: Map<string, BaseJson>;
|
||||
export declare function defineRules(base: string, str: string, mappings: MappingsJson): void;
|
||||
export declare function defineRule(domain: string, style: string, str: string, content: string): void;
|
||||
export declare function addSymbolRules(json: UnicodeJson[]): void;
|
||||
export declare const addCharacterRules: (json: UnicodeJson[]) => void;
|
||||
export declare function addFunctionRules(json: UnicodeJson[]): void;
|
||||
export declare function addUnitRules(json: UnicodeJson[]): void;
|
||||
export declare function lookupRule(node: string, dynamic: DynamicCstr): SimpleRule;
|
||||
export declare function lookupCategory(character: string): string;
|
||||
export declare function lookupString(text: string, dynamic: DynamicCstr): string;
|
||||
export declare function enumerate(info?: {
|
||||
[key: string]: any;
|
||||
}): {
|
||||
[key: string]: any;
|
||||
};
|
||||
export declare function reset(): void;
|
||||
168
node_modules/speech-rule-engine/mjs/rule_engine/math_compound_store.js
generated
vendored
Normal file
168
node_modules/speech-rule-engine/mjs/rule_engine/math_compound_store.js
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
import { Engine } from '../common/engine.js';
|
||||
import { locales } from '../l10n/l10n.js';
|
||||
import { addFunctionSemantic } from '../semantic_tree/semantic_attr.js';
|
||||
import { MathSimpleStore } from './math_simple_store.js';
|
||||
import { Axis, DynamicCstr } from './dynamic_cstr.js';
|
||||
let locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
|
||||
let modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
|
||||
export function changeLocale(json) {
|
||||
if (!json['locale'] && !json['modality']) {
|
||||
return false;
|
||||
}
|
||||
locale = json['locale'] || locale;
|
||||
modality = json['modality'] || modality;
|
||||
return true;
|
||||
}
|
||||
let siPrefixes = {};
|
||||
export function setSiPrefixes(prefixes) {
|
||||
siPrefixes = prefixes;
|
||||
}
|
||||
export const subStores = new Map();
|
||||
export const baseStores = new Map();
|
||||
function getSubStore(base, key) {
|
||||
let store = subStores.get(key);
|
||||
if (store) {
|
||||
return store;
|
||||
}
|
||||
store = new MathSimpleStore();
|
||||
store.base = baseStores.get(base);
|
||||
subStores.set(key, store);
|
||||
return store;
|
||||
}
|
||||
function completeWithBase(json) {
|
||||
const base = baseStores.get(json.key);
|
||||
if (!base) {
|
||||
return;
|
||||
}
|
||||
const names = json.names;
|
||||
Object.assign(json, base);
|
||||
if (names && base.names) {
|
||||
json.names = json.names.concat(names);
|
||||
}
|
||||
}
|
||||
export function defineRules(base, str, mappings) {
|
||||
const store = getSubStore(base, str);
|
||||
store.defineRulesFromMappings(locale, modality, mappings);
|
||||
}
|
||||
export function defineRule(domain, style, str, content) {
|
||||
const store = getSubStore(str, str);
|
||||
store.defineRuleFromStrings(locale, modality, domain, style, content);
|
||||
}
|
||||
export function addSymbolRules(json) {
|
||||
for (const rule of json) {
|
||||
if (changeLocale(rule)) {
|
||||
continue;
|
||||
}
|
||||
const key = MathSimpleStore.parseUnicode(rule['key']);
|
||||
if (locale === 'base') {
|
||||
baseStores.set(key, rule);
|
||||
continue;
|
||||
}
|
||||
defineRules(key, key, rule['mappings']);
|
||||
}
|
||||
}
|
||||
function addCharacterRule(json) {
|
||||
if (changeLocale(json)) {
|
||||
return;
|
||||
}
|
||||
for (const [key, value] of Object.entries(json)) {
|
||||
defineRule('default', 'default', key, value);
|
||||
}
|
||||
}
|
||||
export const addCharacterRules = (json) => json.forEach(addCharacterRule);
|
||||
function addFunctionRule(json) {
|
||||
for (let j = 0, name; (name = json.names[j]); j++) {
|
||||
defineRules(json.key, name, json.mappings);
|
||||
}
|
||||
}
|
||||
export function addFunctionRules(json) {
|
||||
for (const rule of json) {
|
||||
if (changeLocale(rule)) {
|
||||
continue;
|
||||
}
|
||||
addFunctionSemantic(rule.key, rule.names || []);
|
||||
if (locale === 'base') {
|
||||
baseStores.set(rule.key, rule);
|
||||
continue;
|
||||
}
|
||||
completeWithBase(rule);
|
||||
addFunctionRule(rule);
|
||||
}
|
||||
}
|
||||
export function addUnitRules(json) {
|
||||
for (const rule of json) {
|
||||
if (changeLocale(rule)) {
|
||||
continue;
|
||||
}
|
||||
rule.key += ':unit';
|
||||
if (locale === 'base') {
|
||||
baseStores.set(rule.key, rule);
|
||||
continue;
|
||||
}
|
||||
completeWithBase(rule);
|
||||
if (rule.names) {
|
||||
rule.names = rule.names.map(function (name) {
|
||||
return name + ':unit';
|
||||
});
|
||||
}
|
||||
if (rule.si) {
|
||||
addSiUnitRule(rule);
|
||||
}
|
||||
addFunctionRule(rule);
|
||||
}
|
||||
}
|
||||
function addSiUnitRule(json) {
|
||||
for (const key of Object.keys(siPrefixes)) {
|
||||
const newJson = Object.assign({}, json);
|
||||
newJson.mappings = {};
|
||||
const prefix = siPrefixes[key];
|
||||
newJson['names'] = newJson['names'].map(function (name) {
|
||||
return key + name;
|
||||
});
|
||||
for (const domain of Object.keys(json['mappings'])) {
|
||||
newJson.mappings[domain] = {};
|
||||
for (const style of Object.keys(json['mappings'][domain])) {
|
||||
newJson['mappings'][domain][style] = locales[locale]().FUNCTIONS.si(prefix, json['mappings'][domain][style]);
|
||||
}
|
||||
}
|
||||
addFunctionRule(newJson);
|
||||
}
|
||||
}
|
||||
export function lookupRule(node, dynamic) {
|
||||
const store = subStores.get(node);
|
||||
return store ? store.lookupRule(null, dynamic) : null;
|
||||
}
|
||||
export function lookupCategory(character) {
|
||||
const store = subStores.get(character);
|
||||
return (store === null || store === void 0 ? void 0 : store.base) ? store.base.category : '';
|
||||
}
|
||||
export function lookupString(text, dynamic) {
|
||||
const rule = lookupRule(text, dynamic);
|
||||
if (!rule) {
|
||||
return null;
|
||||
}
|
||||
return rule.action;
|
||||
}
|
||||
Engine.getInstance().evaluator = lookupString;
|
||||
export function enumerate(info = {}) {
|
||||
for (const store of subStores.values()) {
|
||||
for (const [, rules] of store.rules.entries()) {
|
||||
for (const { cstr: dynamic } of rules) {
|
||||
info = enumerate_(dynamic.getValues(), info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
function enumerate_(dynamic, info) {
|
||||
info = info || {};
|
||||
if (!dynamic.length) {
|
||||
return info;
|
||||
}
|
||||
info[dynamic[0]] = enumerate_(dynamic.slice(1), info[dynamic[0]]);
|
||||
return info;
|
||||
}
|
||||
export function reset() {
|
||||
locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
|
||||
modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
|
||||
}
|
||||
38
node_modules/speech-rule-engine/mjs/rule_engine/math_simple_store.d.ts
generated
vendored
Normal file
38
node_modules/speech-rule-engine/mjs/rule_engine/math_simple_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { DynamicCstr } from './dynamic_cstr.js';
|
||||
export interface MappingsJson {
|
||||
default: {
|
||||
[key: string]: string;
|
||||
};
|
||||
[domainName: string]: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
export interface BaseJson {
|
||||
key: string;
|
||||
category: string;
|
||||
names?: string[];
|
||||
si?: boolean;
|
||||
}
|
||||
export interface UnicodeJson extends BaseJson {
|
||||
mappings: MappingsJson;
|
||||
modality?: string;
|
||||
locale?: string;
|
||||
domain?: string;
|
||||
}
|
||||
export interface SiJson {
|
||||
[key: string]: string;
|
||||
}
|
||||
export interface SimpleRule {
|
||||
cstr: DynamicCstr;
|
||||
action: string;
|
||||
}
|
||||
export declare class MathSimpleStore {
|
||||
base: BaseJson;
|
||||
rules: Map<string, SimpleRule[]>;
|
||||
static parseUnicode(num: string): string;
|
||||
private static testDynamicConstraints_;
|
||||
defineRulesFromMappings(locale: string, modality: string, mapping: MappingsJson): void;
|
||||
getRules(key: string): SimpleRule[];
|
||||
defineRuleFromStrings(locale: string, modality: string, domain: string, style: string, content: string): void;
|
||||
lookupRule(_node: Node, dynamic: DynamicCstr): SimpleRule;
|
||||
}
|
||||
60
node_modules/speech-rule-engine/mjs/rule_engine/math_simple_store.js
generated
vendored
Normal file
60
node_modules/speech-rule-engine/mjs/rule_engine/math_simple_store.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Engine } from '../common/engine.js';
|
||||
import { Axis } from './dynamic_cstr.js';
|
||||
export class MathSimpleStore {
|
||||
constructor() {
|
||||
this.rules = new Map();
|
||||
}
|
||||
static parseUnicode(num) {
|
||||
const keyValue = parseInt(num, 16);
|
||||
return String.fromCodePoint(keyValue);
|
||||
}
|
||||
static testDynamicConstraints_(dynamic, rule) {
|
||||
if (Engine.getInstance().strict) {
|
||||
return rule.cstr.equal(dynamic);
|
||||
}
|
||||
return Engine.getInstance().comparator.match(rule.cstr);
|
||||
}
|
||||
defineRulesFromMappings(locale, modality, mapping) {
|
||||
for (const [domain, styles] of Object.entries(mapping)) {
|
||||
for (const [style, content] of Object.entries(styles)) {
|
||||
this.defineRuleFromStrings(locale, modality, domain, style, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
getRules(key) {
|
||||
let store = this.rules.get(key);
|
||||
if (!store) {
|
||||
store = [];
|
||||
this.rules.set(key, store);
|
||||
}
|
||||
return store;
|
||||
}
|
||||
defineRuleFromStrings(locale, modality, domain, style, content) {
|
||||
let store = this.getRules(locale);
|
||||
const parser = Engine.getInstance().parsers[domain] ||
|
||||
Engine.getInstance().defaultParser;
|
||||
const comp = Engine.getInstance().comparators[domain];
|
||||
const cstr = `${locale}.${modality}.${domain}.${style}`;
|
||||
const dynamic = parser.parse(cstr);
|
||||
const comparator = comp ? comp() : Engine.getInstance().comparator;
|
||||
const oldCstr = comparator.getReference();
|
||||
comparator.setReference(dynamic);
|
||||
const rule = { cstr: dynamic, action: content };
|
||||
store = store.filter((r) => !dynamic.equal(r.cstr));
|
||||
store.push(rule);
|
||||
this.rules.set(locale, store);
|
||||
comparator.setReference(oldCstr);
|
||||
}
|
||||
lookupRule(_node, dynamic) {
|
||||
let rules = this.getRules(dynamic.getValue(Axis.LOCALE));
|
||||
rules = rules.filter(function (rule) {
|
||||
return MathSimpleStore.testDynamicConstraints_(dynamic, rule);
|
||||
});
|
||||
if (rules.length === 1) {
|
||||
return rules[0];
|
||||
}
|
||||
return rules.length
|
||||
? rules.sort((r1, r2) => Engine.getInstance().comparator.compare(r1.cstr, r2.cstr))[0]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
24
node_modules/speech-rule-engine/mjs/rule_engine/math_store.d.ts
generated
vendored
Normal file
24
node_modules/speech-rule-engine/mjs/rule_engine/math_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { BaseRuleStore, RulesJson } from './base_rule_store.js';
|
||||
export declare class MathStore extends BaseRuleStore {
|
||||
annotators: string[];
|
||||
constructor();
|
||||
initialize(): void;
|
||||
annotations(): void;
|
||||
defineAlias(name: string, prec: string, ...args: string[]): void;
|
||||
defineRulesAlias(name: string, query: string, ...args: string[]): void;
|
||||
defineSpecializedRule(name: string, oldDynamic: string, newDynamic: string, opt_action?: string): void;
|
||||
defineSpecialized(name: string, _old: string, dynamic: string): void;
|
||||
evaluateString(str: string): AuditoryDescription[];
|
||||
parse(ruleSet: RulesJson): void;
|
||||
private addAlias_;
|
||||
static regexp: {
|
||||
NUMBER: string;
|
||||
DECIMAL_MARK: string;
|
||||
DIGIT_GROUP: string;
|
||||
};
|
||||
protected matchNumber(str: string): {
|
||||
number: string;
|
||||
length: number;
|
||||
} | null;
|
||||
}
|
||||
162
node_modules/speech-rule-engine/mjs/rule_engine/math_store.js
generated
vendored
Normal file
162
node_modules/speech-rule-engine/mjs/rule_engine/math_store.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
import * as BaseUtil from '../common/base_util.js';
|
||||
import { LOCALE } from '../l10n/locale.js';
|
||||
import { activate } from '../semantic_tree/semantic_annotations.js';
|
||||
import { BaseRuleStore } from './base_rule_store.js';
|
||||
import { Action, OutputError, SpeechRule } from './speech_rule.js';
|
||||
export class MathStore extends BaseRuleStore {
|
||||
constructor() {
|
||||
super();
|
||||
this.annotators = [];
|
||||
this.parseMethods['Alias'] = this.defineAlias;
|
||||
this.parseMethods['SpecializedRule'] = this.defineSpecializedRule;
|
||||
this.parseMethods['Specialized'] = this.defineSpecialized;
|
||||
}
|
||||
initialize() {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
this.annotations();
|
||||
this.initialized = true;
|
||||
}
|
||||
annotations() {
|
||||
for (let i = 0, annotator; (annotator = this.annotators[i]); i++) {
|
||||
activate(this.domain, annotator);
|
||||
}
|
||||
}
|
||||
defineAlias(name, prec, ...args) {
|
||||
const fullPrec = this.parsePrecondition(prec, args);
|
||||
if (!fullPrec) {
|
||||
console.error(`Precondition Error: ${prec} ${args}`);
|
||||
return;
|
||||
}
|
||||
const condition = this.preconditions.get(name);
|
||||
if (!condition) {
|
||||
console.error(`Alias Error: No precondition by the name of ${name}`);
|
||||
return;
|
||||
}
|
||||
condition.addFullCondition(fullPrec);
|
||||
}
|
||||
defineRulesAlias(name, query, ...args) {
|
||||
const rules = this.findAllRules(function (rule) {
|
||||
return rule.name === name;
|
||||
});
|
||||
if (rules.length === 0) {
|
||||
throw new OutputError('Rule with name ' + name + ' does not exist.');
|
||||
}
|
||||
const keep = [];
|
||||
const findKeep = (rule) => {
|
||||
const cstr = rule.dynamicCstr.toString();
|
||||
const action = rule.action.toString();
|
||||
for (let i = 0, k; (k = keep[i]); i++) {
|
||||
if (k.action === action && k.cstr === cstr) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
keep.push({ cstr: cstr, action: action });
|
||||
return true;
|
||||
};
|
||||
rules.forEach((rule) => {
|
||||
if (findKeep(rule)) {
|
||||
this.addAlias_(rule, query, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
defineSpecializedRule(name, oldDynamic, newDynamic, opt_action) {
|
||||
const dynamicCstr = this.parseCstr(oldDynamic);
|
||||
const rule = this.findRule((rule) => rule.name === name && dynamicCstr.equal(rule.dynamicCstr));
|
||||
const newCstr = this.parseCstr(newDynamic);
|
||||
if (!rule && opt_action) {
|
||||
throw new OutputError('Rule named ' + name + ' with style ' + oldDynamic + ' does not exist.');
|
||||
}
|
||||
const action = opt_action ? Action.fromString(opt_action) : rule.action;
|
||||
const newRule = new SpeechRule(rule.name, newCstr, rule.precondition, action);
|
||||
this.addRule(newRule);
|
||||
}
|
||||
defineSpecialized(name, _old, dynamic) {
|
||||
const cstr = this.parseCstr(dynamic);
|
||||
if (!cstr) {
|
||||
console.error(`Dynamic Constraint Error: ${dynamic}`);
|
||||
return;
|
||||
}
|
||||
const condition = this.preconditions.get(name);
|
||||
if (!condition) {
|
||||
console.error(`Alias Error: No precondition by the name of ${name}`);
|
||||
return;
|
||||
}
|
||||
condition.addConstraint(cstr);
|
||||
}
|
||||
evaluateString(str) {
|
||||
const descs = [];
|
||||
if (str.match(/^\s+$/)) {
|
||||
return descs;
|
||||
}
|
||||
let num = this.matchNumber(str);
|
||||
if (num && num.length === str.length) {
|
||||
descs.push(this.evaluateCharacter(num.number));
|
||||
return descs;
|
||||
}
|
||||
const split = BaseUtil.removeEmpty(str.replace(/\s/g, ' ').split(' '));
|
||||
for (let i = 0, s; (s = split[i]); i++) {
|
||||
if (s.length === 1) {
|
||||
descs.push(this.evaluateCharacter(s));
|
||||
}
|
||||
else if (s.match(new RegExp('^[' + LOCALE.MESSAGES.regexp.TEXT + ']+$'))) {
|
||||
descs.push(this.evaluateCharacter(s));
|
||||
}
|
||||
else {
|
||||
let rest = s;
|
||||
while (rest) {
|
||||
num = this.matchNumber(rest);
|
||||
const alpha = rest.match(new RegExp('^[' + LOCALE.MESSAGES.regexp.TEXT + ']+'));
|
||||
if (num) {
|
||||
descs.push(this.evaluateCharacter(num.number));
|
||||
rest = rest.substring(num.length);
|
||||
}
|
||||
else if (alpha) {
|
||||
descs.push(this.evaluateCharacter(alpha[0]));
|
||||
rest = rest.substring(alpha[0].length);
|
||||
}
|
||||
else {
|
||||
const chars = Array.from(rest);
|
||||
const chr = chars[0];
|
||||
descs.push(this.evaluateCharacter(chr));
|
||||
rest = chars.slice(1).join('');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return descs;
|
||||
}
|
||||
parse(ruleSet) {
|
||||
super.parse(ruleSet);
|
||||
this.annotators = ruleSet['annotators'] || [];
|
||||
}
|
||||
addAlias_(rule, query, cstrList) {
|
||||
const prec = this.parsePrecondition(query, cstrList);
|
||||
const newRule = new SpeechRule(rule.name, rule.dynamicCstr, prec, rule.action);
|
||||
newRule.name = rule.name;
|
||||
this.addRule(newRule);
|
||||
}
|
||||
matchNumber(str) {
|
||||
const locNum = str.match(new RegExp('^' + LOCALE.MESSAGES.regexp.NUMBER));
|
||||
const enNum = str.match(new RegExp('^' + MathStore.regexp.NUMBER));
|
||||
if (!locNum && !enNum) {
|
||||
return null;
|
||||
}
|
||||
const isEn = enNum && enNum[0] === str;
|
||||
const isLoc = (locNum && locNum[0] === str) || !isEn;
|
||||
if (isLoc) {
|
||||
return locNum ? { number: locNum[0], length: locNum[0].length } : null;
|
||||
}
|
||||
const num = enNum[0]
|
||||
.replace(new RegExp(MathStore.regexp.DIGIT_GROUP, 'g'), 'X')
|
||||
.replace(new RegExp(MathStore.regexp.DECIMAL_MARK, 'g'), LOCALE.MESSAGES.regexp.DECIMAL_MARK)
|
||||
.replace(/X/g, LOCALE.MESSAGES.regexp.DIGIT_GROUP.replace(/\\/g, ''));
|
||||
return { number: num, length: enNum[0].length };
|
||||
}
|
||||
}
|
||||
MathStore.regexp = {
|
||||
NUMBER: '((\\d{1,3})(?=(,| ))((,| )\\d{3})*(\\.\\d+)?)|^\\d*\\.\\d+|^\\d+',
|
||||
DECIMAL_MARK: '\\.',
|
||||
DIGIT_GROUP: ','
|
||||
};
|
||||
71
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule.d.ts
generated
vendored
Normal file
71
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule.d.ts
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import { SREError } from '../common/engine.js';
|
||||
import { DynamicCstr } from './dynamic_cstr.js';
|
||||
import * as Grammar from './grammar.js';
|
||||
import { SpeechRuleContext } from './speech_rule_context.js';
|
||||
export declare class SpeechRule {
|
||||
name: string;
|
||||
dynamicCstr: DynamicCstr;
|
||||
precondition: Precondition;
|
||||
action: Action;
|
||||
context: SpeechRuleContext;
|
||||
constructor(name: string, dynamicCstr: DynamicCstr, precondition: Precondition, action: Action);
|
||||
toString(): string;
|
||||
}
|
||||
export declare enum ActionType {
|
||||
NODE = "NODE",
|
||||
MULTI = "MULTI",
|
||||
TEXT = "TEXT",
|
||||
PERSONALITY = "PERSONALITY"
|
||||
}
|
||||
interface ComponentType {
|
||||
type: ActionType;
|
||||
content?: string;
|
||||
attributes?: Attributes;
|
||||
grammar?: Grammar.State;
|
||||
}
|
||||
export declare class Component {
|
||||
type: ActionType;
|
||||
content: string;
|
||||
attributes: Attributes;
|
||||
grammar: Grammar.State;
|
||||
static grammarFromString(grammar: string): Grammar.State;
|
||||
static fromString(input: string): Component;
|
||||
static attributesFromString(attrs: string): {
|
||||
[key: string]: string | Grammar.State;
|
||||
};
|
||||
constructor({ type, content, attributes, grammar }: ComponentType);
|
||||
toString(): string;
|
||||
grammarToString(): string;
|
||||
getGrammar(): string[];
|
||||
attributesToString(): string;
|
||||
getAttributes(): string[];
|
||||
}
|
||||
type Attributes = {
|
||||
[key: string]: string;
|
||||
};
|
||||
export declare class Action {
|
||||
components: Component[];
|
||||
static fromString(input: string): Action;
|
||||
private static naiveSpan;
|
||||
private static addNaiveSpan;
|
||||
constructor(components: Component[]);
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Precondition {
|
||||
query: string;
|
||||
private static queryPriorities;
|
||||
private static attributePriorities;
|
||||
constraints: string[];
|
||||
priority: number;
|
||||
rank: number;
|
||||
private static constraintValue;
|
||||
toString(): string;
|
||||
constructor(query: string, ...cstr: string[]);
|
||||
private calculatePriority;
|
||||
private presetPriority;
|
||||
}
|
||||
export declare class OutputError extends SREError {
|
||||
name: string;
|
||||
constructor(msg: string);
|
||||
}
|
||||
export {};
|
||||
330
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule.js
generated
vendored
Normal file
330
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule.js
generated
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
import { SREError } from '../common/engine.js';
|
||||
import * as Grammar from './grammar.js';
|
||||
export class SpeechRule {
|
||||
constructor(name, dynamicCstr, precondition, action) {
|
||||
this.name = name;
|
||||
this.dynamicCstr = dynamicCstr;
|
||||
this.precondition = precondition;
|
||||
this.action = action;
|
||||
this.context = null;
|
||||
}
|
||||
toString() {
|
||||
return (this.name +
|
||||
' | ' +
|
||||
this.dynamicCstr.toString() +
|
||||
' | ' +
|
||||
this.precondition.toString() +
|
||||
' ==> ' +
|
||||
this.action.toString());
|
||||
}
|
||||
}
|
||||
export var ActionType;
|
||||
(function (ActionType) {
|
||||
ActionType["NODE"] = "NODE";
|
||||
ActionType["MULTI"] = "MULTI";
|
||||
ActionType["TEXT"] = "TEXT";
|
||||
ActionType["PERSONALITY"] = "PERSONALITY";
|
||||
})(ActionType || (ActionType = {}));
|
||||
function actionFromString(str) {
|
||||
switch (str) {
|
||||
case '[n]':
|
||||
return ActionType.NODE;
|
||||
case '[m]':
|
||||
return ActionType.MULTI;
|
||||
case '[t]':
|
||||
return ActionType.TEXT;
|
||||
case '[p]':
|
||||
return ActionType.PERSONALITY;
|
||||
default:
|
||||
throw 'Parse error: ' + str;
|
||||
}
|
||||
}
|
||||
function actionToString(speechType) {
|
||||
switch (speechType) {
|
||||
case ActionType.NODE:
|
||||
return '[n]';
|
||||
case ActionType.MULTI:
|
||||
return '[m]';
|
||||
case ActionType.TEXT:
|
||||
return '[t]';
|
||||
case ActionType.PERSONALITY:
|
||||
return '[p]';
|
||||
default:
|
||||
throw 'Unknown type error: ' + speechType;
|
||||
}
|
||||
}
|
||||
export class Component {
|
||||
static grammarFromString(grammar) {
|
||||
return Grammar.Grammar.parseInput(grammar);
|
||||
}
|
||||
static fromString(input) {
|
||||
const output = {
|
||||
type: actionFromString(input.substring(0, 3))
|
||||
};
|
||||
let rest = input.slice(3).trim();
|
||||
if (!rest) {
|
||||
throw new OutputError('Missing content.');
|
||||
}
|
||||
switch (output.type) {
|
||||
case ActionType.TEXT:
|
||||
if (rest[0] === '"') {
|
||||
const quotedString = splitString(rest, '\\(')[0].trim();
|
||||
if (quotedString.slice(-1) !== '"') {
|
||||
throw new OutputError('Invalid string syntax.');
|
||||
}
|
||||
output.content = quotedString;
|
||||
rest = rest.slice(quotedString.length).trim();
|
||||
if (rest.indexOf('(') === -1) {
|
||||
rest = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ActionType.NODE:
|
||||
case ActionType.MULTI:
|
||||
{
|
||||
const bracket = rest.indexOf(' (');
|
||||
if (bracket === -1) {
|
||||
output.content = rest.trim();
|
||||
rest = '';
|
||||
break;
|
||||
}
|
||||
output.content = rest.substring(0, bracket).trim();
|
||||
rest = rest.slice(bracket).trim();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (rest) {
|
||||
const attributes = Component.attributesFromString(rest);
|
||||
if (attributes.grammar) {
|
||||
output.grammar = attributes.grammar;
|
||||
delete attributes.grammar;
|
||||
}
|
||||
if (Object.keys(attributes).length) {
|
||||
output.attributes = attributes;
|
||||
}
|
||||
}
|
||||
return new Component(output);
|
||||
}
|
||||
static attributesFromString(attrs) {
|
||||
if (attrs[0] !== '(' || attrs.slice(-1) !== ')') {
|
||||
throw new OutputError('Invalid attribute expression: ' + attrs);
|
||||
}
|
||||
const attributes = {};
|
||||
const attribs = splitString(attrs.slice(1, -1), ',');
|
||||
for (const attr of attribs) {
|
||||
const colon = attr.indexOf(':');
|
||||
if (colon === -1) {
|
||||
attributes[attr.trim()] = 'true';
|
||||
}
|
||||
else {
|
||||
const key = attr.substring(0, colon).trim();
|
||||
const value = attr.slice(colon + 1).trim();
|
||||
attributes[key] =
|
||||
key === Grammar.ATTRIBUTE
|
||||
? Component.grammarFromString(value)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
constructor({ type, content, attributes, grammar }) {
|
||||
this.type = type;
|
||||
this.content = content;
|
||||
this.attributes = attributes;
|
||||
this.grammar = grammar;
|
||||
}
|
||||
toString() {
|
||||
let strs = '';
|
||||
strs += actionToString(this.type);
|
||||
strs += this.content ? ' ' + this.content : '';
|
||||
const attrs = this.attributesToString();
|
||||
strs += attrs ? ' ' + attrs : '';
|
||||
return strs;
|
||||
}
|
||||
grammarToString() {
|
||||
return this.getGrammar().join(':');
|
||||
}
|
||||
getGrammar() {
|
||||
if (!this.grammar) {
|
||||
return [];
|
||||
}
|
||||
const attribs = [];
|
||||
for (const [key, val] of Object.entries(this.grammar)) {
|
||||
attribs.push(val === true ? key : val === false ? `!${key}` : `${key}=${val}`);
|
||||
}
|
||||
return attribs;
|
||||
}
|
||||
attributesToString() {
|
||||
const attribs = this.getAttributes();
|
||||
const grammar = this.grammarToString();
|
||||
if (grammar) {
|
||||
attribs.push('grammar:' + grammar);
|
||||
}
|
||||
return attribs.length > 0 ? '(' + attribs.join(', ') + ')' : '';
|
||||
}
|
||||
getAttributes() {
|
||||
if (!this.attributes) {
|
||||
return [];
|
||||
}
|
||||
const attribs = [];
|
||||
for (const [key, val] of Object.entries(this.attributes)) {
|
||||
attribs.push(val === 'true' ? key : `${key}:${val}`);
|
||||
}
|
||||
return attribs;
|
||||
}
|
||||
}
|
||||
export class Action {
|
||||
static fromString(input) {
|
||||
const comps = splitString(input, ';')
|
||||
.filter(function (x) {
|
||||
return x.match(/\S/);
|
||||
})
|
||||
.map(function (x) {
|
||||
return x.trim();
|
||||
});
|
||||
const newComps = [];
|
||||
for (let i = 0, m = comps.length; i < m; i++) {
|
||||
const comp = Component.fromString(comps[i]);
|
||||
if (comp) {
|
||||
newComps.push(comp);
|
||||
}
|
||||
}
|
||||
Action.naiveSpan(newComps);
|
||||
return new Action(newComps);
|
||||
}
|
||||
static naiveSpan(comps) {
|
||||
var _a;
|
||||
let first = false;
|
||||
for (let i = 0, comp; (comp = comps[i]); i++) {
|
||||
if (first &&
|
||||
(comp.type !== ActionType.TEXT ||
|
||||
(comp.content[0] !== '"' && !comp.content.match(/^CSF/))))
|
||||
continue;
|
||||
if (!first && comp.type === ActionType.PERSONALITY)
|
||||
continue;
|
||||
if (!first) {
|
||||
first = true;
|
||||
continue;
|
||||
}
|
||||
if ((_a = comp.attributes) === null || _a === void 0 ? void 0 : _a.span)
|
||||
continue;
|
||||
const next = comps[i + 1];
|
||||
if (next && next.type !== ActionType.NODE)
|
||||
continue;
|
||||
Action.addNaiveSpan(comp, next ? next.content : 'LAST');
|
||||
}
|
||||
}
|
||||
static addNaiveSpan(comp, span) {
|
||||
if (!comp.attributes) {
|
||||
comp.attributes = {};
|
||||
}
|
||||
comp.attributes['span'] = span;
|
||||
}
|
||||
constructor(components) {
|
||||
this.components = components;
|
||||
}
|
||||
toString() {
|
||||
const comps = this.components.map(function (c) {
|
||||
return c.toString();
|
||||
});
|
||||
return comps.join('; ');
|
||||
}
|
||||
}
|
||||
export class Precondition {
|
||||
static constraintValue(constr, priorities) {
|
||||
for (let i = 0, regexp; (regexp = priorities[i]); i++) {
|
||||
if (constr.match(regexp)) {
|
||||
return ++i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
toString() {
|
||||
const constrs = this.constraints.join(', ');
|
||||
return `${this.query}, ${constrs} (${this.priority}, ${this.rank})`;
|
||||
}
|
||||
constructor(query, ...cstr) {
|
||||
this.query = query;
|
||||
this.constraints = cstr;
|
||||
const [exists, user] = this.presetPriority();
|
||||
this.priority = exists ? user : this.calculatePriority();
|
||||
}
|
||||
calculatePriority() {
|
||||
const query = Precondition.constraintValue(this.query, Precondition.queryPriorities);
|
||||
if (!query) {
|
||||
return 0;
|
||||
}
|
||||
const match = this.query.match(/^self::.+\[(.+)\]/);
|
||||
let attr = 0;
|
||||
if ((match === null || match === void 0 ? void 0 : match.length) && match[1]) {
|
||||
const inner = match[1];
|
||||
attr = Precondition.constraintValue(inner, Precondition.attributePriorities);
|
||||
}
|
||||
return query * 100 + attr * 10;
|
||||
}
|
||||
presetPriority() {
|
||||
if (!this.constraints.length) {
|
||||
return [false, 0];
|
||||
}
|
||||
const last = this.constraints[this.constraints.length - 1].match(/^priority=(.*$)/);
|
||||
if (!last) {
|
||||
return [false, 0];
|
||||
}
|
||||
this.constraints.pop();
|
||||
const numb = parseFloat(last[1]);
|
||||
return [true, isNaN(numb) ? 0 : numb];
|
||||
}
|
||||
}
|
||||
Precondition.queryPriorities = [
|
||||
/^self::\*$/,
|
||||
/^self::[\w-]+$/,
|
||||
/^self::\*\[.+\]$/,
|
||||
/^self::[\w-]+\[.+\]$/
|
||||
];
|
||||
Precondition.attributePriorities = [
|
||||
/^@[\w-]+$/,
|
||||
/^@[\w-]+!=".+"$/,
|
||||
/^not\(contains\(@[\w-]+,\s*".+"\)\)$/,
|
||||
/^contains\(@[\w-]+,".+"\)$/,
|
||||
/^@[\w-]+=".+"$/
|
||||
];
|
||||
export class OutputError extends SREError {
|
||||
constructor(msg) {
|
||||
super(msg);
|
||||
this.name = 'RuleError';
|
||||
}
|
||||
}
|
||||
function splitString(str, sep) {
|
||||
const strList = [];
|
||||
let prefix = '';
|
||||
while (str !== '') {
|
||||
const sepPos = str.search(sep);
|
||||
if (sepPos === -1) {
|
||||
if ((str.match(/"/g) || []).length % 2 !== 0) {
|
||||
throw new OutputError('Invalid string in expression: ' + str);
|
||||
}
|
||||
strList.push(prefix + str);
|
||||
prefix = '';
|
||||
str = '';
|
||||
}
|
||||
else if ((str.substring(0, sepPos).match(/"/g) || []).length % 2 === 0) {
|
||||
strList.push(prefix + str.substring(0, sepPos));
|
||||
prefix = '';
|
||||
str = str.substring(sepPos + 1);
|
||||
}
|
||||
else {
|
||||
const nextQuot = str.substring(sepPos).search('"');
|
||||
if (nextQuot === -1) {
|
||||
throw new OutputError('Invalid string in expression: ' + str);
|
||||
}
|
||||
else {
|
||||
prefix = prefix + str.substring(0, sepPos + nextQuot + 1);
|
||||
str = str.substring(sepPos + nextQuot + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prefix) {
|
||||
strList.push(prefix);
|
||||
}
|
||||
return strList;
|
||||
}
|
||||
18
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_context.d.ts
generated
vendored
Normal file
18
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_context.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Span, SpanAttrs } from '../audio/span.js';
|
||||
import * as srf from './speech_rule_functions.js';
|
||||
export declare class SpeechRuleContext {
|
||||
customQueries: srf.CustomQueries;
|
||||
customStrings: srf.CustomStrings;
|
||||
contextFunctions: srf.ContextFunctions;
|
||||
customGenerators: srf.CustomGenerators;
|
||||
applyCustomQuery(node: Element, funcName: string): Element[];
|
||||
applySelector(node: Element, expr: string): Element[];
|
||||
applyQuery(node: Element, expr: string): Element;
|
||||
applyConstraint(node: Element, expr: string): boolean;
|
||||
constructString(node: Element, expr: string): string;
|
||||
constructSpan(node: Element, expr: string, def: SpanAttrs): Span[];
|
||||
private constructString_;
|
||||
parse(functions: [string, srf.SpeechRuleFunction][] | {
|
||||
[key: string]: srf.SpeechRuleFunction;
|
||||
}): void;
|
||||
}
|
||||
84
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_context.js
generated
vendored
Normal file
84
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_context.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Span } from '../audio/span.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import * as srf from './speech_rule_functions.js';
|
||||
export class SpeechRuleContext {
|
||||
constructor() {
|
||||
this.customQueries = new srf.CustomQueries();
|
||||
this.customStrings = new srf.CustomStrings();
|
||||
this.contextFunctions = new srf.ContextFunctions();
|
||||
this.customGenerators = new srf.CustomGenerators();
|
||||
}
|
||||
applyCustomQuery(node, funcName) {
|
||||
const func = this.customQueries.lookup(funcName);
|
||||
return func ? func(node) : null;
|
||||
}
|
||||
applySelector(node, expr) {
|
||||
const result = this.applyCustomQuery(node, expr);
|
||||
return result || XpathUtil.evalXPath(expr, node);
|
||||
}
|
||||
applyQuery(node, expr) {
|
||||
const results = this.applySelector(node, expr);
|
||||
if (results.length > 0) {
|
||||
return results[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
applyConstraint(node, expr) {
|
||||
const result = this.applyQuery(node, expr);
|
||||
return !!result || XpathUtil.evaluateBoolean(expr, node);
|
||||
}
|
||||
constructString(node, expr) {
|
||||
const result = this.constructString_(node, expr);
|
||||
return Array.isArray(result)
|
||||
? result.map((x) => x.speech).join('')
|
||||
: result;
|
||||
}
|
||||
constructSpan(node, expr, def) {
|
||||
const result = this.constructString_(node, expr);
|
||||
if (Array.isArray(result)) {
|
||||
const last = result[result.length - 1];
|
||||
last.attributes = Object.assign({}, def, last.attributes);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return [Span.node(result, node, def)];
|
||||
}
|
||||
}
|
||||
constructString_(node, expr) {
|
||||
if (!expr) {
|
||||
return '';
|
||||
}
|
||||
if (expr.charAt(0) === '"') {
|
||||
return expr.slice(1, -1);
|
||||
}
|
||||
const func = this.customStrings.lookup(expr);
|
||||
if (func) {
|
||||
return func(node);
|
||||
}
|
||||
return XpathUtil.evaluateString(expr, node);
|
||||
}
|
||||
parse(functions) {
|
||||
const functs = Array.isArray(functions)
|
||||
? functions
|
||||
: Object.entries(functions);
|
||||
for (const func of functs) {
|
||||
const kind = func[0].slice(0, 3);
|
||||
switch (kind) {
|
||||
case 'CQF':
|
||||
this.customQueries.add(func[0], func[1]);
|
||||
break;
|
||||
case 'CSF':
|
||||
this.customStrings.add(func[0], func[1]);
|
||||
break;
|
||||
case 'CTF':
|
||||
this.contextFunctions.add(func[0], func[1]);
|
||||
break;
|
||||
case 'CGF':
|
||||
this.customGenerators.add(func[0], func[1]);
|
||||
break;
|
||||
default:
|
||||
console.error('FunctionError: Invalid function name ' + func[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_engine.d.ts
generated
vendored
Normal file
43
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_engine.d.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { BaseRuleStore } from './base_rule_store.js';
|
||||
import { RulesJson } from './base_rule_store.js';
|
||||
import { DynamicCstr } from './dynamic_cstr.js';
|
||||
import { State as GrammarState } from './grammar.js';
|
||||
import { SpeechRule } from './speech_rule.js';
|
||||
import { SpeechRuleContext } from './speech_rule_context.js';
|
||||
import { Trie } from '../indexing/trie.js';
|
||||
export declare class SpeechRuleEngine {
|
||||
private static instance;
|
||||
trie: Trie;
|
||||
private evaluators_;
|
||||
static getInstance(): SpeechRuleEngine;
|
||||
static debugSpeechRule(rule: SpeechRule, node: Element): void;
|
||||
static debugNamedSpeechRule(name: string, node: Element): void;
|
||||
evaluateNode(node: Element): AuditoryDescription[];
|
||||
toString(): string;
|
||||
runInSetting(settings: {
|
||||
[feature: string]: string | boolean;
|
||||
}, callback: () => AuditoryDescription[]): AuditoryDescription[];
|
||||
static addStore(set: RulesJson): void;
|
||||
processGrammar(context: SpeechRuleContext, node: Element, grammar: GrammarState): void;
|
||||
addEvaluator(store: BaseRuleStore): void;
|
||||
getEvaluator(locale: string, modality: string): (p1: Element) => AuditoryDescription[];
|
||||
enumerate(opt_info?: {
|
||||
[key: string]: any;
|
||||
}): {
|
||||
[key: string]: any;
|
||||
};
|
||||
private constructor();
|
||||
private evaluateNode_;
|
||||
private evaluateTree_;
|
||||
private evaluateNodeList_;
|
||||
private addLayout;
|
||||
private addPersonality_;
|
||||
private addExternalAttributes_;
|
||||
private addRelativePersonality_;
|
||||
private updateConstraint_;
|
||||
private makeSet_;
|
||||
lookupRule(node: Element, dynamic: DynamicCstr): SpeechRule;
|
||||
lookupRules(node: Element, dynamic: DynamicCstr): SpeechRule[];
|
||||
private pickMostConstraint_;
|
||||
}
|
||||
474
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_engine.js
generated
vendored
Normal file
474
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_engine.js
generated
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
import { AuditoryDescription, AuditoryList } from '../audio/auditory_description.js';
|
||||
import { Span } from '../audio/span.js';
|
||||
import { Debugger } from '../common/debugger.js';
|
||||
import * as DomUtil from '../common/dom_util.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { evalXPath, updateEvaluator } from '../common/xpath_util.js';
|
||||
import * as SpeechRules from '../speech_rules/speech_rules.js';
|
||||
import * as SpeechRuleStores from '../speech_rules/speech_rule_stores.js';
|
||||
import { BrailleStore, EuroStore } from './braille_store.js';
|
||||
import { Axis, DynamicCstr } from './dynamic_cstr.js';
|
||||
import { Grammar } from './grammar.js';
|
||||
import { MathStore } from './math_store.js';
|
||||
import { ActionType } from './speech_rule.js';
|
||||
import { Trie } from '../indexing/trie.js';
|
||||
export class SpeechRuleEngine {
|
||||
static getInstance() {
|
||||
SpeechRuleEngine.instance =
|
||||
SpeechRuleEngine.instance || new SpeechRuleEngine();
|
||||
return SpeechRuleEngine.instance;
|
||||
}
|
||||
static debugSpeechRule(rule, node) {
|
||||
const prec = rule.precondition;
|
||||
const queryResult = rule.context.applyQuery(node, prec.query);
|
||||
Debugger.getInstance().output(prec.query, queryResult ? queryResult.toString() : queryResult);
|
||||
prec.constraints.forEach((cstr) => Debugger.getInstance().output(cstr, rule.context.applyConstraint(node, cstr)));
|
||||
}
|
||||
static debugNamedSpeechRule(name, node) {
|
||||
const rules = SpeechRuleEngine.getInstance().trie.collectRules();
|
||||
const allRules = rules.filter((rule) => rule.name == name);
|
||||
for (let i = 0, rule; (rule = allRules[i]); i++) {
|
||||
Debugger.getInstance().output('Rule', name, 'DynamicCstr:', rule.dynamicCstr.toString(), 'number', i);
|
||||
SpeechRuleEngine.debugSpeechRule(rule, node);
|
||||
}
|
||||
}
|
||||
evaluateNode(node) {
|
||||
updateEvaluator(node);
|
||||
const timeIn = new Date().getTime();
|
||||
let result = [];
|
||||
try {
|
||||
result = this.evaluateNode_(node);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
console.error('Something went wrong computing speech.');
|
||||
Debugger.getInstance().output(err);
|
||||
}
|
||||
const timeOut = new Date().getTime();
|
||||
Debugger.getInstance().output('Time:', timeOut - timeIn);
|
||||
return result;
|
||||
}
|
||||
toString() {
|
||||
const allRules = this.trie.collectRules();
|
||||
return allRules.map((rule) => rule.toString()).join('\n');
|
||||
}
|
||||
runInSetting(settings, callback) {
|
||||
const engine = Engine.getInstance();
|
||||
const save = {};
|
||||
for (const [key, val] of Object.entries(settings)) {
|
||||
save[key] = engine[key];
|
||||
engine[key] = val;
|
||||
}
|
||||
engine.setDynamicCstr();
|
||||
const result = callback();
|
||||
for (const [key, val] of Object.entries(save)) {
|
||||
engine[key] = val;
|
||||
}
|
||||
engine.setDynamicCstr();
|
||||
return result;
|
||||
}
|
||||
static addStore(set) {
|
||||
const store = storeFactory(set);
|
||||
if (store.kind !== 'abstract') {
|
||||
store
|
||||
.getSpeechRules()
|
||||
.forEach((x) => SpeechRuleEngine.getInstance().trie.addRule(x));
|
||||
}
|
||||
SpeechRuleEngine.getInstance().addEvaluator(store);
|
||||
}
|
||||
processGrammar(context, node, grammar) {
|
||||
const assignment = {};
|
||||
for (const [key, val] of Object.entries(grammar)) {
|
||||
assignment[key] =
|
||||
typeof val === 'string' ? context.constructString(node, val) : val;
|
||||
}
|
||||
Grammar.getInstance().pushState(assignment);
|
||||
}
|
||||
addEvaluator(store) {
|
||||
const fun = store.evaluateDefault.bind(store);
|
||||
const loc = this.evaluators_[store.locale];
|
||||
if (loc) {
|
||||
loc[store.modality] = fun;
|
||||
return;
|
||||
}
|
||||
const mod = {};
|
||||
mod[store.modality] = fun;
|
||||
this.evaluators_[store.locale] = mod;
|
||||
}
|
||||
getEvaluator(locale, modality) {
|
||||
const loc = this.evaluators_[locale] ||
|
||||
this.evaluators_[DynamicCstr.DEFAULT_VALUES[Axis.LOCALE]];
|
||||
return loc[modality] || loc[DynamicCstr.DEFAULT_VALUES[Axis.MODALITY]];
|
||||
}
|
||||
enumerate(opt_info) {
|
||||
return this.trie.enumerate(opt_info);
|
||||
}
|
||||
constructor() {
|
||||
this.trie = null;
|
||||
this.evaluators_ = {};
|
||||
this.trie = new Trie();
|
||||
}
|
||||
evaluateNode_(node) {
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
this.updateConstraint_();
|
||||
let result = this.evaluateTree_(node);
|
||||
result = processAnnotations(result);
|
||||
return result;
|
||||
}
|
||||
evaluateTree_(node) {
|
||||
const engine = Engine.getInstance();
|
||||
let result;
|
||||
Debugger.getInstance().output(engine.mode !== EngineConst.Mode.HTTP ? node.toString() : node);
|
||||
Grammar.getInstance().setAttribute(node);
|
||||
const rule = this.lookupRule(node, engine.dynamicCstr);
|
||||
if (!rule) {
|
||||
if (engine.strict) {
|
||||
return [];
|
||||
}
|
||||
result = this.getEvaluator(engine.locale, engine.modality)(node);
|
||||
if (node.attributes) {
|
||||
this.addPersonality_(result, {}, false, node);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Debugger.getInstance().generateOutput(() => [
|
||||
'Apply Rule:',
|
||||
rule.name,
|
||||
rule.dynamicCstr.toString(),
|
||||
engine.mode === EngineConst.Mode.HTTP
|
||||
? DomUtil.serializeXml(node)
|
||||
: node.toString()
|
||||
]);
|
||||
Grammar.getInstance().processSingles();
|
||||
const context = rule.context;
|
||||
const components = rule.action.components;
|
||||
result = [];
|
||||
for (let i = 0, component; (component = components[i]); i++) {
|
||||
let descrs = [];
|
||||
const content = component.content || '';
|
||||
const attributes = component.attributes || {};
|
||||
let multi = false;
|
||||
if (component.grammar) {
|
||||
this.processGrammar(context, node, component.grammar);
|
||||
}
|
||||
let saveEngine = null;
|
||||
if (attributes.engine) {
|
||||
saveEngine = Engine.getInstance().dynamicCstr.getComponents();
|
||||
const features = Object.assign({}, saveEngine, Grammar.parseInput(attributes.engine));
|
||||
Engine.getInstance().setDynamicCstr(features);
|
||||
this.updateConstraint_();
|
||||
}
|
||||
switch (component.type) {
|
||||
case ActionType.NODE:
|
||||
{
|
||||
const selected = context.applyQuery(node, content);
|
||||
if (selected) {
|
||||
descrs = this.evaluateTree_(selected);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ActionType.MULTI:
|
||||
{
|
||||
multi = true;
|
||||
const selects = context.applySelector(node, content);
|
||||
if (selects.length > 0) {
|
||||
descrs = this.evaluateNodeList_(context, selects, attributes['sepFunc'], context.constructString(node, attributes['separator']), attributes['ctxtFunc'], context.constructString(node, attributes['context']));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ActionType.TEXT:
|
||||
{
|
||||
const xpath = attributes['span'];
|
||||
let attrs = {};
|
||||
if (xpath) {
|
||||
const nodes = evalXPath(xpath, node);
|
||||
attrs = nodes.length
|
||||
? Span.getAttributes(nodes[0])
|
||||
: { kind: xpath };
|
||||
}
|
||||
const str = context.constructSpan(node, content, attrs);
|
||||
descrs = str.map(function (span) {
|
||||
return AuditoryDescription.create({ text: span.speech, attributes: span.attributes }, { adjust: true });
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ActionType.PERSONALITY:
|
||||
default:
|
||||
descrs = [AuditoryDescription.create({ text: content })];
|
||||
}
|
||||
if (descrs[0] && !multi) {
|
||||
if (attributes['context']) {
|
||||
descrs[0]['context'] =
|
||||
context.constructString(node, attributes['context']) +
|
||||
(descrs[0]['context'] || '');
|
||||
}
|
||||
if (attributes['annotation']) {
|
||||
descrs[0]['annotation'] = attributes['annotation'];
|
||||
}
|
||||
}
|
||||
this.addLayout(descrs, attributes, multi);
|
||||
if (component.grammar) {
|
||||
Grammar.getInstance().popState();
|
||||
}
|
||||
result = result.concat(this.addPersonality_(descrs, attributes, multi, node));
|
||||
if (saveEngine) {
|
||||
Engine.getInstance().setDynamicCstr(saveEngine);
|
||||
this.updateConstraint_();
|
||||
}
|
||||
}
|
||||
Grammar.getInstance().popState();
|
||||
return result;
|
||||
}
|
||||
evaluateNodeList_(context, nodes, sepFunc, sepStr, ctxtFunc, ctxtStr) {
|
||||
if (!nodes.length) {
|
||||
return [];
|
||||
}
|
||||
const sep = sepStr || '';
|
||||
const cont = ctxtStr || '';
|
||||
const cFunc = context.contextFunctions.lookup(ctxtFunc);
|
||||
const ctxtClosure = cFunc
|
||||
? cFunc(nodes, cont)
|
||||
: function () {
|
||||
return cont;
|
||||
};
|
||||
const sFunc = context.contextFunctions.lookup(sepFunc);
|
||||
const sepClosure = sFunc
|
||||
? sFunc(nodes, sep)
|
||||
: function () {
|
||||
return [
|
||||
AuditoryDescription.create({ text: sep }, { translate: true })
|
||||
];
|
||||
};
|
||||
let result = [];
|
||||
for (let i = 0, node; (node = nodes[i]); i++) {
|
||||
const descrs = this.evaluateTree_(node);
|
||||
if (descrs.length > 0) {
|
||||
descrs[0]['context'] = ctxtClosure() + (descrs[0]['context'] || '');
|
||||
result = result.concat(descrs);
|
||||
if (i < nodes.length - 1) {
|
||||
const text = sepClosure();
|
||||
result = result.concat(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
addLayout(descrs, props, _multi) {
|
||||
const layout = props.layout;
|
||||
if (!layout) {
|
||||
return;
|
||||
}
|
||||
if (layout.match(/^begin/)) {
|
||||
descrs.unshift(new AuditoryDescription({ text: '', layout: layout }));
|
||||
return;
|
||||
}
|
||||
if (layout.match(/^end/)) {
|
||||
descrs.push(new AuditoryDescription({ text: '', layout: layout }));
|
||||
return;
|
||||
}
|
||||
descrs.unshift(new AuditoryDescription({ text: '', layout: `begin${layout}` }));
|
||||
descrs.push(new AuditoryDescription({ text: '', layout: `end${layout}` }));
|
||||
}
|
||||
addPersonality_(descrs, props, multi, node) {
|
||||
const personality = {};
|
||||
let pause = null;
|
||||
for (const key of EngineConst.personalityPropList) {
|
||||
const value = props[key];
|
||||
if (typeof value === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
const numeral = parseFloat(value);
|
||||
const realValue = isNaN(numeral)
|
||||
? value.charAt(0) === '"'
|
||||
? value.slice(1, -1)
|
||||
: value
|
||||
: numeral;
|
||||
if (key === EngineConst.personalityProps.PAUSE) {
|
||||
pause = realValue;
|
||||
}
|
||||
else {
|
||||
personality[key] = realValue;
|
||||
}
|
||||
}
|
||||
for (let i = 0, descr; (descr = descrs[i]); i++) {
|
||||
this.addRelativePersonality_(descr, personality);
|
||||
this.addExternalAttributes_(descr, node);
|
||||
}
|
||||
if (multi && descrs.length) {
|
||||
delete descrs[descrs.length - 1].personality[EngineConst.personalityProps.JOIN];
|
||||
}
|
||||
if (pause && descrs.length) {
|
||||
const last = descrs[descrs.length - 1];
|
||||
if (last.text || Object.keys(last.personality).length) {
|
||||
descrs.push(AuditoryDescription.create({
|
||||
text: '',
|
||||
personality: { pause: pause }
|
||||
}));
|
||||
}
|
||||
else {
|
||||
last.personality[EngineConst.personalityProps.PAUSE] = pause;
|
||||
}
|
||||
}
|
||||
return descrs;
|
||||
}
|
||||
addExternalAttributes_(descr, node) {
|
||||
if (descr.attributes['id'] === undefined) {
|
||||
descr.attributes['id'] = node.getAttribute('id');
|
||||
}
|
||||
if (node.hasAttributes()) {
|
||||
const attrs = node.attributes;
|
||||
for (let i = attrs.length - 1; i >= 0; i--) {
|
||||
const key = attrs[i].name;
|
||||
if (!descr.attributes[key] && key.match(/^ext/)) {
|
||||
descr.attributes[key] = attrs[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addRelativePersonality_(descr, personality) {
|
||||
if (!descr['personality']) {
|
||||
descr['personality'] = personality;
|
||||
return descr;
|
||||
}
|
||||
const descrPersonality = descr['personality'];
|
||||
for (const [key, val] of Object.entries(personality)) {
|
||||
if (descrPersonality[key] &&
|
||||
typeof descrPersonality[key] == 'number' &&
|
||||
typeof val == 'number') {
|
||||
descrPersonality[key] = (descrPersonality[key] + val).toString();
|
||||
}
|
||||
else if (!descrPersonality[key]) {
|
||||
descrPersonality[key] = val;
|
||||
}
|
||||
}
|
||||
return descr;
|
||||
}
|
||||
updateConstraint_() {
|
||||
const dynamic = Engine.getInstance().dynamicCstr;
|
||||
const strict = Engine.getInstance().strict;
|
||||
const trie = this.trie;
|
||||
const props = {};
|
||||
let locale = dynamic.getValue(Axis.LOCALE);
|
||||
let modality = dynamic.getValue(Axis.MODALITY);
|
||||
let domain = dynamic.getValue(Axis.DOMAIN);
|
||||
if (!trie.hasSubtrie([locale, modality, domain])) {
|
||||
domain = DynamicCstr.DEFAULT_VALUES[Axis.DOMAIN];
|
||||
if (!trie.hasSubtrie([locale, modality, domain])) {
|
||||
modality = DynamicCstr.DEFAULT_VALUES[Axis.MODALITY];
|
||||
if (!trie.hasSubtrie([locale, modality, domain])) {
|
||||
locale = DynamicCstr.DEFAULT_VALUES[Axis.LOCALE];
|
||||
}
|
||||
}
|
||||
}
|
||||
props[Axis.LOCALE] = [locale];
|
||||
props[Axis.MODALITY] = [
|
||||
modality !== 'summary'
|
||||
? modality
|
||||
: DynamicCstr.DEFAULT_VALUES[Axis.MODALITY]
|
||||
];
|
||||
props[Axis.DOMAIN] = [
|
||||
modality !== 'speech' ? DynamicCstr.DEFAULT_VALUES[Axis.DOMAIN] : domain
|
||||
];
|
||||
const order = dynamic.getOrder();
|
||||
for (let i = 0, axis; (axis = order[i]); i++) {
|
||||
if (!props[axis]) {
|
||||
const value = dynamic.getValue(axis);
|
||||
const valueSet = this.makeSet_(value, dynamic.preference);
|
||||
const def = DynamicCstr.DEFAULT_VALUES[axis];
|
||||
if (!strict && value !== def) {
|
||||
valueSet.push(def);
|
||||
}
|
||||
props[axis] = valueSet;
|
||||
}
|
||||
}
|
||||
dynamic.updateProperties(props);
|
||||
}
|
||||
makeSet_(value, preferences) {
|
||||
if (!preferences || !Object.keys(preferences).length) {
|
||||
return [value];
|
||||
}
|
||||
return value.split(':');
|
||||
}
|
||||
lookupRule(node, dynamic) {
|
||||
if (!node ||
|
||||
(node.nodeType !== DomUtil.NodeType.ELEMENT_NODE &&
|
||||
node.nodeType !== DomUtil.NodeType.TEXT_NODE)) {
|
||||
return null;
|
||||
}
|
||||
const matchingRules = this.lookupRules(node, dynamic);
|
||||
return matchingRules.length > 0
|
||||
? this.pickMostConstraint_(dynamic, matchingRules)
|
||||
: null;
|
||||
}
|
||||
lookupRules(node, dynamic) {
|
||||
return this.trie.lookupRules(node, dynamic.allProperties());
|
||||
}
|
||||
pickMostConstraint_(_dynamic, rules) {
|
||||
const comparator = Engine.getInstance().comparator;
|
||||
rules.sort(function (r1, r2) {
|
||||
return (comparator.compare(r1.dynamicCstr, r2.dynamicCstr) ||
|
||||
r2.precondition.priority - r1.precondition.priority ||
|
||||
r2.precondition.constraints.length -
|
||||
r1.precondition.constraints.length ||
|
||||
r2.precondition.rank - r1.precondition.rank);
|
||||
});
|
||||
Debugger.getInstance().generateOutput((() => {
|
||||
return rules.map((x) => x.name + '(' + x.dynamicCstr.toString() + ')');
|
||||
}).bind(this));
|
||||
return rules[0];
|
||||
}
|
||||
}
|
||||
const stores = new Map();
|
||||
function getStore(locale, modality) {
|
||||
if (modality === 'braille' && locale === 'euro') {
|
||||
return new EuroStore();
|
||||
}
|
||||
if (modality === 'braille') {
|
||||
return new BrailleStore();
|
||||
}
|
||||
return new MathStore();
|
||||
}
|
||||
function storeFactory(set) {
|
||||
const name = `${set.locale}.${set.modality}.${set.domain}`;
|
||||
if (set.kind === 'actions') {
|
||||
const store = stores.get(name);
|
||||
store.parse(set);
|
||||
return store;
|
||||
}
|
||||
SpeechRuleStores.init();
|
||||
if (set && !set.functions) {
|
||||
set.functions = SpeechRules.getStore(set.locale, set.modality, set.domain);
|
||||
}
|
||||
const store = getStore(set.locale, set.modality);
|
||||
stores.set(name, store);
|
||||
if (set.inherits) {
|
||||
store.inherits = stores.get(`${set.inherits}.${set.modality}.${set.domain}`);
|
||||
}
|
||||
store.parse(set);
|
||||
store.initialize();
|
||||
return store;
|
||||
}
|
||||
Engine.nodeEvaluator = SpeechRuleEngine.getInstance().evaluateNode.bind(SpeechRuleEngine.getInstance());
|
||||
const punctuationMarks = ['⠆', '⠒', '⠲', '⠦', '⠴', '⠄'];
|
||||
function processAnnotations(descrs) {
|
||||
const alist = new AuditoryList(descrs);
|
||||
for (const item of alist.annotations) {
|
||||
const descr = item.data;
|
||||
if (descr.annotation === 'punctuation') {
|
||||
const prev = alist.prevText(item);
|
||||
if (!prev)
|
||||
continue;
|
||||
const last = prev.data;
|
||||
if (last.annotation !== 'punctuation' &&
|
||||
last.text !== '⠀' &&
|
||||
descr.text.length === 1 &&
|
||||
punctuationMarks.indexOf(descr.text) !== -1) {
|
||||
descr.text = '⠸' + descr.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
return alist.toList();
|
||||
}
|
||||
8
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_evaluator.d.ts
generated
vendored
Normal file
8
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_evaluator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
export interface SpeechRuleEvaluator {
|
||||
evaluateDefault(node: Node): void;
|
||||
evaluateWhitespace(str: string): AuditoryDescription[];
|
||||
evaluateString(str: string): AuditoryDescription[];
|
||||
evaluateCustom(str: string): AuditoryDescription;
|
||||
evaluateCharacter(str: string): AuditoryDescription;
|
||||
}
|
||||
1
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_evaluator.js
generated
vendored
Normal file
1
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_evaluator.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
31
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_functions.d.ts
generated
vendored
Normal file
31
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_functions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import { Span } from '../audio/span.js';
|
||||
declare abstract class FunctionsStore<S> {
|
||||
private prefix;
|
||||
private store;
|
||||
protected constructor(prefix: string, store: {
|
||||
[key: string]: S;
|
||||
});
|
||||
add(name: string, func: S): void;
|
||||
addStore(store: FunctionsStore<S>): void;
|
||||
lookup(name: string): S;
|
||||
private checkCustomFunctionSyntax_;
|
||||
}
|
||||
export type CustomQuery = (p1: Element) => Element[];
|
||||
export declare class CustomQueries extends FunctionsStore<CustomQuery> {
|
||||
constructor();
|
||||
}
|
||||
export type CustomString = (p1: Element) => Span[];
|
||||
export declare class CustomStrings extends FunctionsStore<CustomString> {
|
||||
constructor();
|
||||
}
|
||||
export type ContextFunction = (p1: Element[] | Element, p2: string | null) => () => string | AuditoryDescription[];
|
||||
export declare class ContextFunctions extends FunctionsStore<ContextFunction> {
|
||||
constructor();
|
||||
}
|
||||
export type CustomGenerator = (store?: any, flag?: boolean) => string[] | void;
|
||||
export declare class CustomGenerators extends FunctionsStore<CustomGenerator> {
|
||||
constructor();
|
||||
}
|
||||
export type SpeechRuleFunction = CustomQuery | CustomString | ContextFunction | CustomGenerator;
|
||||
export {};
|
||||
52
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_functions.js
generated
vendored
Normal file
52
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_functions.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
class FunctionsStore {
|
||||
constructor(prefix, store) {
|
||||
this.prefix = prefix;
|
||||
this.store = store;
|
||||
}
|
||||
add(name, func) {
|
||||
if (this.checkCustomFunctionSyntax_(name)) {
|
||||
this.store[name] = func;
|
||||
}
|
||||
}
|
||||
addStore(store) {
|
||||
const keys = Object.keys(store.store);
|
||||
for (let i = 0, key; (key = keys[i]); i++) {
|
||||
this.add(key, store.store[key]);
|
||||
}
|
||||
}
|
||||
lookup(name) {
|
||||
return this.store[name];
|
||||
}
|
||||
checkCustomFunctionSyntax_(name) {
|
||||
const reg = new RegExp('^' + this.prefix);
|
||||
if (!name.match(reg)) {
|
||||
console.error('FunctionError: Invalid function name. Expected prefix ' + this.prefix);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class CustomQueries extends FunctionsStore {
|
||||
constructor() {
|
||||
const store = {};
|
||||
super('CQF', store);
|
||||
}
|
||||
}
|
||||
export class CustomStrings extends FunctionsStore {
|
||||
constructor() {
|
||||
const store = {};
|
||||
super('CSF', store);
|
||||
}
|
||||
}
|
||||
export class ContextFunctions extends FunctionsStore {
|
||||
constructor() {
|
||||
const store = {};
|
||||
super('CTF', store);
|
||||
}
|
||||
}
|
||||
export class CustomGenerators extends FunctionsStore {
|
||||
constructor() {
|
||||
const store = {};
|
||||
super('CGF', store);
|
||||
}
|
||||
}
|
||||
10
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_store.d.ts
generated
vendored
Normal file
10
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { SpeechRule } from './speech_rule.js';
|
||||
import { SpeechRuleContext } from './speech_rule_context.js';
|
||||
export interface SpeechRuleStore {
|
||||
context: SpeechRuleContext;
|
||||
addRule(rule: SpeechRule): void;
|
||||
deleteRule(rule: SpeechRule): void;
|
||||
findRule(pred: (rule: SpeechRule) => boolean): SpeechRule;
|
||||
findAllRules(pred: (rule: SpeechRule) => boolean): SpeechRule[];
|
||||
defineRule(name: string, dynamic: string, action: string, pre: string, ...args: string[]): SpeechRule;
|
||||
}
|
||||
1
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_store.js
generated
vendored
Normal file
1
node_modules/speech-rule-engine/mjs/rule_engine/speech_rule_store.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
4
node_modules/speech-rule-engine/mjs/rule_engine/store_util.d.ts
generated
vendored
Normal file
4
node_modules/speech-rule-engine/mjs/rule_engine/store_util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
export declare function nodeCounter(nodes: Element[], context: string | null): () => string;
|
||||
export declare function pauseSeparator(_nodes: Element[], context: string): () => AuditoryDescription[];
|
||||
export declare function contentIterator(nodes: Element[], context: string): () => AuditoryDescription[];
|
||||
49
node_modules/speech-rule-engine/mjs/rule_engine/store_util.js
generated
vendored
Normal file
49
node_modules/speech-rule-engine/mjs/rule_engine/store_util.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { AuditoryDescription } from '../audio/auditory_description.js';
|
||||
import * as XpathUtil from '../common/xpath_util.js';
|
||||
import { Engine } from '../common/engine.js';
|
||||
export function nodeCounter(nodes, context) {
|
||||
const localLength = nodes.length;
|
||||
let localCounter = 0;
|
||||
let localContext = context;
|
||||
if (!context) {
|
||||
localContext = '';
|
||||
}
|
||||
return function () {
|
||||
if (localCounter < localLength) {
|
||||
localCounter += 1;
|
||||
}
|
||||
return localContext + ' ' + localCounter;
|
||||
};
|
||||
}
|
||||
export function pauseSeparator(_nodes, context) {
|
||||
const numeral = parseFloat(context);
|
||||
const value = isNaN(numeral) ? context : numeral;
|
||||
return function () {
|
||||
return [
|
||||
AuditoryDescription.create({
|
||||
text: '',
|
||||
personality: { pause: value }
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
export function contentIterator(nodes, context) {
|
||||
let contentNodes;
|
||||
if (nodes.length > 0) {
|
||||
contentNodes = XpathUtil.evalXPath('../../content/*', nodes[0]);
|
||||
}
|
||||
else {
|
||||
contentNodes = [];
|
||||
}
|
||||
return function () {
|
||||
const content = contentNodes.shift();
|
||||
const contextDescr = context
|
||||
? [AuditoryDescription.create({ text: context }, { translate: true })]
|
||||
: [];
|
||||
if (!content) {
|
||||
return contextDescr;
|
||||
}
|
||||
const descrs = Engine.evaluateNode(content);
|
||||
return contextDescr.concat(descrs);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user