add initial marp implementation with sample content and build configuration
This commit is contained in:
14
node_modules/speech-rule-engine/js/audio/abstract_audio_renderer.d.ts
generated
vendored
Normal file
14
node_modules/speech-rule-engine/js/audio/abstract_audio_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { KeyCode } from '../common/event_util.js';
|
||||
import { AudioRenderer } from './audio_renderer.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { Span } from './span.js';
|
||||
export declare abstract class AbstractAudioRenderer implements AudioRenderer {
|
||||
private separator_;
|
||||
abstract markup(descrs: AuditoryDescription[]): string;
|
||||
set separator(sep: string);
|
||||
get separator(): string;
|
||||
error(_key: KeyCode | string): string | null;
|
||||
merge(spans: Span[]): string;
|
||||
finalize(str: string): string;
|
||||
pauseValue(value: string): number;
|
||||
}
|
||||
51
node_modules/speech-rule-engine/js/audio/abstract_audio_renderer.js
generated
vendored
Normal file
51
node_modules/speech-rule-engine/js/audio/abstract_audio_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AbstractAudioRenderer = void 0;
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
class AbstractAudioRenderer {
|
||||
constructor() {
|
||||
this.separator_ = ' ';
|
||||
}
|
||||
set separator(sep) {
|
||||
this.separator_ = sep;
|
||||
}
|
||||
get separator() {
|
||||
return engine_js_1.Engine.getInstance().modality === 'braille' ? '' : this.separator_;
|
||||
}
|
||||
error(_key) {
|
||||
return null;
|
||||
}
|
||||
merge(spans) {
|
||||
let str = '';
|
||||
const len = spans.length - 1;
|
||||
for (let i = 0, span; (span = spans[i]); i++) {
|
||||
str += span.speech;
|
||||
if (i < len) {
|
||||
const sep = span.attributes['separator'];
|
||||
str += sep !== undefined ? sep : this.separator;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
finalize(str) {
|
||||
return str;
|
||||
}
|
||||
pauseValue(value) {
|
||||
let numeric;
|
||||
switch (value) {
|
||||
case 'long':
|
||||
numeric = 750;
|
||||
break;
|
||||
case 'medium':
|
||||
numeric = 500;
|
||||
break;
|
||||
case 'short':
|
||||
numeric = 250;
|
||||
break;
|
||||
default:
|
||||
numeric = parseInt(value, 10);
|
||||
}
|
||||
return Math.floor((numeric * engine_js_1.Engine.getInstance().getRate()) / 100);
|
||||
}
|
||||
}
|
||||
exports.AbstractAudioRenderer = AbstractAudioRenderer;
|
||||
11
node_modules/speech-rule-engine/js/audio/acss_renderer.d.ts
generated
vendored
Normal file
11
node_modules/speech-rule-engine/js/audio/acss_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import * as AudioUtil from './audio_util.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { MarkupRenderer } from './markup_renderer.js';
|
||||
export declare class AcssRenderer extends MarkupRenderer {
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
error(key: number): string;
|
||||
prosodyElement(key: EngineConst.personalityProps, value: number): string;
|
||||
pause(pause: AudioUtil.Pause): string;
|
||||
private prosody_;
|
||||
}
|
||||
67
node_modules/speech-rule-engine/js/audio/acss_renderer.js
generated
vendored
Normal file
67
node_modules/speech-rule-engine/js/audio/acss_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AcssRenderer = void 0;
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const EventUtil = require("../common/event_util.js");
|
||||
const AudioUtil = require("./audio_util.js");
|
||||
const markup_renderer_js_1 = require("./markup_renderer.js");
|
||||
class AcssRenderer extends markup_renderer_js_1.MarkupRenderer {
|
||||
markup(descrs) {
|
||||
this.setScaleFunction(-2, 2, 0, 10, 0);
|
||||
const markup = AudioUtil.personalityMarkup(descrs);
|
||||
const result = [];
|
||||
const currentPers = { open: [] };
|
||||
let pause = null;
|
||||
let isString = false;
|
||||
for (let i = 0, descr; (descr = markup[i]); i++) {
|
||||
if (AudioUtil.isMarkupElement(descr)) {
|
||||
AudioUtil.mergeMarkup(currentPers, descr);
|
||||
continue;
|
||||
}
|
||||
if (AudioUtil.isPauseElement(descr)) {
|
||||
if (isString) {
|
||||
pause = AudioUtil.mergePause(pause, descr, Math.max);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const str = '"' + this.merge(descr.span) + '"';
|
||||
isString = true;
|
||||
if (pause) {
|
||||
result.push(this.pause(pause));
|
||||
pause = null;
|
||||
}
|
||||
const prosody = this.prosody_(currentPers);
|
||||
result.push(prosody ? '(text (' + prosody + ') ' + str + ')' : str);
|
||||
}
|
||||
return '(exp ' + result.join(' ') + ')';
|
||||
}
|
||||
error(key) {
|
||||
return '(error "' + EventUtil.Move.get(key) + '")';
|
||||
}
|
||||
prosodyElement(key, value) {
|
||||
value = this.applyScaleFunction(value);
|
||||
switch (key) {
|
||||
case EngineConst.personalityProps.RATE:
|
||||
return '(richness . ' + value + ')';
|
||||
case EngineConst.personalityProps.PITCH:
|
||||
return '(average-pitch . ' + value + ')';
|
||||
case EngineConst.personalityProps.VOLUME:
|
||||
return '(stress . ' + value + ')';
|
||||
}
|
||||
return '(value . ' + value + ')';
|
||||
}
|
||||
pause(pause) {
|
||||
return ('(pause . ' +
|
||||
this.pauseValue(pause[EngineConst.personalityProps.PAUSE]) +
|
||||
')');
|
||||
}
|
||||
prosody_(pros) {
|
||||
const keys = pros.open;
|
||||
const result = [];
|
||||
for (let i = 0, key; (key = keys[i]); i++) {
|
||||
result.push(this.prosodyElement(key, pros[key]));
|
||||
}
|
||||
return result.join(' ');
|
||||
}
|
||||
}
|
||||
exports.AcssRenderer = AcssRenderer;
|
||||
10
node_modules/speech-rule-engine/js/audio/audio_renderer.d.ts
generated
vendored
Normal file
10
node_modules/speech-rule-engine/js/audio/audio_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { KeyCode } from '../common/event_util.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { Span } from './span.js';
|
||||
export interface AudioRenderer {
|
||||
separator: string;
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
error(key: KeyCode | string): string | null;
|
||||
merge(strs: Span[]): string;
|
||||
finalize(str: string): string;
|
||||
}
|
||||
2
node_modules/speech-rule-engine/js/audio/audio_renderer.js
generated
vendored
Normal file
2
node_modules/speech-rule-engine/js/audio/audio_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
19
node_modules/speech-rule-engine/js/audio/audio_util.d.ts
generated
vendored
Normal file
19
node_modules/speech-rule-engine/js/audio/audio_util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
export interface Tags {
|
||||
open?: EngineConst.personalityProps[];
|
||||
close?: EngineConst.personalityProps[];
|
||||
[personality: string]: any;
|
||||
}
|
||||
export type PauseValue = number | string;
|
||||
export interface Pause {
|
||||
pause: PauseValue;
|
||||
[personality: string]: any;
|
||||
}
|
||||
export type Markup = Pause | Tags;
|
||||
export declare function mergePause(oldPause: Pause | null, newPause: Pause, opt_merge?: (p1: PauseValue, p2: PauseValue) => PauseValue): Pause;
|
||||
export declare function mergeMarkup(oldPers: Tags, newPers: Tags): void;
|
||||
export declare function sortClose(open: EngineConst.personalityProps[], descrs: Tags[]): EngineConst.personalityProps[];
|
||||
export declare function personalityMarkup(descrs: AuditoryDescription[]): Markup[];
|
||||
export declare function isMarkupElement(element: Markup): boolean;
|
||||
export declare function isPauseElement(element: Markup): boolean;
|
||||
300
node_modules/speech-rule-engine/js/audio/audio_util.js
generated
vendored
Normal file
300
node_modules/speech-rule-engine/js/audio/audio_util.js
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mergePause = mergePause;
|
||||
exports.mergeMarkup = mergeMarkup;
|
||||
exports.sortClose = sortClose;
|
||||
exports.personalityMarkup = personalityMarkup;
|
||||
exports.isMarkupElement = isMarkupElement;
|
||||
exports.isPauseElement = isPauseElement;
|
||||
const base_util_js_1 = require("../common/base_util.js");
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const span_js_1 = require("./span.js");
|
||||
function mergePause(oldPause, newPause, opt_merge) {
|
||||
if (!oldPause) {
|
||||
return newPause;
|
||||
}
|
||||
return { pause: mergePause_(oldPause.pause, newPause.pause, opt_merge) };
|
||||
}
|
||||
function mergePause_(oldPause, newPause, opt_merge) {
|
||||
const merge = opt_merge ||
|
||||
function (x, y) {
|
||||
if (typeof x === 'number' && typeof y === 'number') {
|
||||
return x + y;
|
||||
}
|
||||
if (typeof x === 'number') {
|
||||
return y;
|
||||
}
|
||||
if (typeof y === 'number') {
|
||||
return x;
|
||||
}
|
||||
return [oldPause, newPause].sort()[0];
|
||||
};
|
||||
return merge.call(null, oldPause, newPause);
|
||||
}
|
||||
function mergeMarkup(oldPers, newPers) {
|
||||
delete oldPers.open;
|
||||
newPers.close.forEach((x) => delete oldPers[x]);
|
||||
newPers.open.forEach((x) => (oldPers[x] = newPers[x]));
|
||||
const keys = Object.keys(oldPers);
|
||||
oldPers.open = keys;
|
||||
}
|
||||
function sortClose(open, descrs) {
|
||||
if (open.length <= 1) {
|
||||
return open;
|
||||
}
|
||||
const result = [];
|
||||
for (let i = 0, descr; (descr = descrs[i]), open.length; i++) {
|
||||
if (!descr.close || !descr.close.length) {
|
||||
continue;
|
||||
}
|
||||
descr.close.forEach(function (x) {
|
||||
const index = open.indexOf(x);
|
||||
if (index !== -1) {
|
||||
result.unshift(x);
|
||||
open.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
let PersonalityRanges_ = {};
|
||||
let LastOpen_ = [];
|
||||
function personalityMarkup(descrs) {
|
||||
PersonalityRanges_ = {};
|
||||
LastOpen_ = [];
|
||||
let result = [];
|
||||
const currentPers = {};
|
||||
for (let i = 0, descr; (descr = descrs[i]); i++) {
|
||||
let pause = null;
|
||||
const span = descr.descriptionSpan();
|
||||
const pers = descr.personality;
|
||||
const join = pers[EngineConst.personalityProps.JOIN];
|
||||
delete pers[EngineConst.personalityProps.JOIN];
|
||||
if (typeof pers[EngineConst.personalityProps.PAUSE] !== 'undefined') {
|
||||
pause = {
|
||||
[EngineConst.personalityProps.PAUSE]: pers[EngineConst.personalityProps.PAUSE]
|
||||
};
|
||||
delete pers[EngineConst.personalityProps.PAUSE];
|
||||
}
|
||||
const diff = personalityDiff_(pers, currentPers);
|
||||
appendMarkup_(result, span, diff, join, pause, true);
|
||||
}
|
||||
result = result.concat(finaliseMarkup_());
|
||||
result = simplifyMarkup_(result);
|
||||
result = engine_js_1.Engine.getInstance().cleanpause ? cleanPause(result) : result;
|
||||
return result;
|
||||
}
|
||||
function cleanPause(markup) {
|
||||
while (isPauseElement(markup[0])) {
|
||||
markup.shift();
|
||||
}
|
||||
while (isPauseElement(markup[markup.length - 1])) {
|
||||
markup.pop();
|
||||
}
|
||||
return markup;
|
||||
}
|
||||
function appendElement_(markup, element) {
|
||||
const last = markup[markup.length - 1];
|
||||
if (!last) {
|
||||
markup.push(element);
|
||||
return;
|
||||
}
|
||||
if (isSpanElement(element) && isSpanElement(last)) {
|
||||
if (typeof last.join === 'undefined') {
|
||||
last.span = last.span.concat(element.span);
|
||||
return;
|
||||
}
|
||||
const lstr = last['span'].pop();
|
||||
const fstr = element['span'].shift();
|
||||
last['span'].push(lstr + last.join + fstr);
|
||||
last['span'] = last['span'].concat(element.span);
|
||||
last.join = element.join;
|
||||
return;
|
||||
}
|
||||
if (isPauseElement(element) && isPauseElement(last)) {
|
||||
last.pause = mergePause_(last.pause, element.pause);
|
||||
return;
|
||||
}
|
||||
markup.push(element);
|
||||
}
|
||||
function simplifyMarkup_(markup) {
|
||||
const lastPers = {};
|
||||
const result = [];
|
||||
for (let i = 0, element; (element = markup[i]); i++) {
|
||||
if (!isMarkupElement(element)) {
|
||||
appendElement_(result, element);
|
||||
continue;
|
||||
}
|
||||
if (!element.close || element.close.length !== 1 || element.open.length) {
|
||||
copyValues_(element, lastPers);
|
||||
result.push(element);
|
||||
continue;
|
||||
}
|
||||
let nextElement = markup[i + 1];
|
||||
if (!nextElement || isSpanElement(nextElement)) {
|
||||
copyValues_(element, lastPers);
|
||||
result.push(element);
|
||||
continue;
|
||||
}
|
||||
const pauseElement = isPauseElement(nextElement) ? nextElement : null;
|
||||
if (pauseElement) {
|
||||
nextElement = markup[i + 2];
|
||||
}
|
||||
if (nextElement &&
|
||||
isMarkupElement(nextElement) &&
|
||||
nextElement.open[0] === element.close[0] &&
|
||||
!nextElement.close.length &&
|
||||
nextElement[nextElement.open[0]] === lastPers[nextElement.open[0]]) {
|
||||
if (pauseElement) {
|
||||
appendElement_(result, pauseElement);
|
||||
i = i + 2;
|
||||
}
|
||||
else {
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
copyValues_(element, lastPers);
|
||||
result.push(element);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function copyValues_(from, to) {
|
||||
if (from['rate']) {
|
||||
to['rate'] = from['rate'];
|
||||
}
|
||||
if (from['pitch']) {
|
||||
to['pitch'] = from['pitch'];
|
||||
}
|
||||
if (from['volume']) {
|
||||
to['volume'] = from['volume'];
|
||||
}
|
||||
}
|
||||
function finaliseMarkup_() {
|
||||
const final = [];
|
||||
for (let i = LastOpen_.length - 1; i >= 0; i--) {
|
||||
const pers = LastOpen_[i];
|
||||
if (pers.length) {
|
||||
const markup = { open: [], close: [] };
|
||||
for (let j = 0; j < pers.length; j++) {
|
||||
const per = pers[j];
|
||||
markup.close.push(per);
|
||||
markup[per] = 0;
|
||||
}
|
||||
final.push(markup);
|
||||
}
|
||||
}
|
||||
return final;
|
||||
}
|
||||
function isMarkupElement(element) {
|
||||
return typeof element === 'object' && element.open;
|
||||
}
|
||||
function isPauseElement(element) {
|
||||
return (typeof element === 'object' &&
|
||||
Object.keys(element).length === 1 &&
|
||||
Object.keys(element)[0] === EngineConst.personalityProps.PAUSE);
|
||||
}
|
||||
function isSpanElement(element) {
|
||||
const keys = Object.keys(element);
|
||||
return (typeof element === 'object' &&
|
||||
((keys.length === 1 && keys[0] === 'span') ||
|
||||
(keys.length === 2 &&
|
||||
((keys[0] === 'span' && keys[1] === 'join') ||
|
||||
(keys[1] === 'span' && keys[0] === 'join')))));
|
||||
}
|
||||
function appendMarkup_(markup, span, pers, join, pause, merge = false) {
|
||||
if (merge) {
|
||||
const last = markup[markup.length - 1];
|
||||
let oldJoin;
|
||||
if (last) {
|
||||
oldJoin = last[EngineConst.personalityProps.JOIN];
|
||||
}
|
||||
if (last && !span.speech && pause && isPauseElement(last)) {
|
||||
const pauseProp = EngineConst.personalityProps.PAUSE;
|
||||
last[pauseProp] = mergePause_(last[pauseProp], pause[pauseProp]);
|
||||
pause = null;
|
||||
}
|
||||
if (last &&
|
||||
span.speech &&
|
||||
Object.keys(pers).length === 0 &&
|
||||
isSpanElement(last)) {
|
||||
if (typeof oldJoin !== 'undefined') {
|
||||
const lastSpan = last['span'].pop();
|
||||
span = span_js_1.Span.stringAttr(lastSpan.speech + oldJoin + span.speech, lastSpan.attributes);
|
||||
}
|
||||
last['span'].push(span);
|
||||
span = span_js_1.Span.empty();
|
||||
last[EngineConst.personalityProps.JOIN] = join;
|
||||
}
|
||||
}
|
||||
if (Object.keys(pers).length !== 0) {
|
||||
markup.push(pers);
|
||||
}
|
||||
if (span.speech) {
|
||||
markup.push({ span: [span], join: join });
|
||||
}
|
||||
if (pause) {
|
||||
markup.push(pause);
|
||||
}
|
||||
}
|
||||
function personalityDiff_(current, old) {
|
||||
if (!old) {
|
||||
return current;
|
||||
}
|
||||
const result = {};
|
||||
for (const prop of EngineConst.personalityPropList) {
|
||||
const currentValue = current[prop];
|
||||
const oldValue = old[prop];
|
||||
if ((!currentValue && !oldValue) ||
|
||||
(currentValue && oldValue && currentValue === oldValue)) {
|
||||
continue;
|
||||
}
|
||||
const value = currentValue || 0;
|
||||
if (!isMarkupElement(result)) {
|
||||
result.open = [];
|
||||
result.close = [];
|
||||
}
|
||||
if (!currentValue) {
|
||||
result.close.push(prop);
|
||||
}
|
||||
if (!oldValue) {
|
||||
result.open.push(prop);
|
||||
}
|
||||
if (oldValue && currentValue) {
|
||||
result.close.push(prop);
|
||||
result.open.push(prop);
|
||||
}
|
||||
old[prop] = value;
|
||||
result[prop] = value;
|
||||
PersonalityRanges_[prop]
|
||||
? PersonalityRanges_[prop].push(value)
|
||||
: (PersonalityRanges_[prop] = [value]);
|
||||
}
|
||||
if (isMarkupElement(result)) {
|
||||
let c = result.close.slice();
|
||||
while (c.length > 0) {
|
||||
let lo = LastOpen_.pop();
|
||||
const loNew = (0, base_util_js_1.setdifference)(lo, c);
|
||||
c = (0, base_util_js_1.setdifference)(c, lo);
|
||||
lo = loNew;
|
||||
if (c.length === 0) {
|
||||
if (lo.length !== 0) {
|
||||
LastOpen_.push(lo);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (lo.length === 0) {
|
||||
continue;
|
||||
}
|
||||
result.close = result.close.concat(lo);
|
||||
result.open = result.open.concat(lo);
|
||||
for (let i = 0, open; (open = lo[i]); i++) {
|
||||
result[open] = old[open];
|
||||
}
|
||||
}
|
||||
LastOpen_.push(result.open);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
66
node_modules/speech-rule-engine/js/audio/auditory_description.d.ts
generated
vendored
Normal file
66
node_modules/speech-rule-engine/js/audio/auditory_description.d.ts
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Span } from './span.js';
|
||||
interface AudioDescr {
|
||||
context?: string;
|
||||
text: string;
|
||||
userValue?: string;
|
||||
annotation?: string;
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
personality?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
layout?: string;
|
||||
}
|
||||
interface AudioFlags {
|
||||
adjust?: boolean;
|
||||
preprocess?: boolean;
|
||||
correct?: boolean;
|
||||
translate?: boolean;
|
||||
}
|
||||
export declare class AuditoryItem {
|
||||
data: AuditoryDescription;
|
||||
prev: AuditoryItem;
|
||||
next: AuditoryItem;
|
||||
constructor(data?: AuditoryDescription);
|
||||
}
|
||||
export declare class AuditoryList extends Set<AuditoryItem> {
|
||||
annotations: AuditoryItem[];
|
||||
private anchor;
|
||||
constructor(descrs: AuditoryDescription[]);
|
||||
first(): AuditoryItem;
|
||||
last(): AuditoryItem;
|
||||
push(item: AuditoryItem): void;
|
||||
pop(): AuditoryItem;
|
||||
delete(item: AuditoryItem): boolean;
|
||||
insertAfter(descr: AuditoryDescription, item: AuditoryItem): void;
|
||||
insertBefore(descr: AuditoryDescription, item: AuditoryItem): void;
|
||||
prevText(item: AuditoryItem): AuditoryItem;
|
||||
[Symbol.iterator](): IterableIterator<AuditoryItem>;
|
||||
nextText(item: AuditoryItem): AuditoryItem;
|
||||
clear(): void;
|
||||
empty(): boolean;
|
||||
toList(): AuditoryDescription[];
|
||||
}
|
||||
export declare class AuditoryDescription {
|
||||
context: string;
|
||||
text: string;
|
||||
userValue: string;
|
||||
annotation: string;
|
||||
attributes: {
|
||||
[key: string]: string;
|
||||
};
|
||||
personality: {
|
||||
[key: string]: string;
|
||||
};
|
||||
layout: string;
|
||||
static create(args: AudioDescr, flags?: AudioFlags): AuditoryDescription;
|
||||
constructor({ context, text, userValue, annotation, attributes, personality, layout }: AudioDescr);
|
||||
isEmpty(): boolean;
|
||||
clone(): AuditoryDescription;
|
||||
toString(): string;
|
||||
descriptionString(): string;
|
||||
descriptionSpan(): Span;
|
||||
equals(that: AuditoryDescription): boolean;
|
||||
}
|
||||
export {};
|
||||
185
node_modules/speech-rule-engine/js/audio/auditory_description.js
generated
vendored
Normal file
185
node_modules/speech-rule-engine/js/audio/auditory_description.js
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AuditoryDescription = exports.AuditoryList = exports.AuditoryItem = void 0;
|
||||
const grammar_js_1 = require("../rule_engine/grammar.js");
|
||||
const span_js_1 = require("./span.js");
|
||||
class AuditoryItem {
|
||||
constructor(data = null) {
|
||||
this.data = data;
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
}
|
||||
}
|
||||
exports.AuditoryItem = AuditoryItem;
|
||||
class AuditoryList extends Set {
|
||||
constructor(descrs) {
|
||||
super();
|
||||
this.annotations = [];
|
||||
this.anchor = new AuditoryItem();
|
||||
this.anchor.next = this.anchor;
|
||||
this.anchor.prev = this.anchor;
|
||||
descrs.forEach((d) => {
|
||||
const item = new AuditoryItem(d);
|
||||
if (d.annotation) {
|
||||
this.annotations.push(item);
|
||||
}
|
||||
this.push(item);
|
||||
});
|
||||
}
|
||||
first() {
|
||||
return this.empty ? null : this.anchor.next;
|
||||
}
|
||||
last() {
|
||||
return this.empty ? null : this.anchor.prev;
|
||||
}
|
||||
push(item) {
|
||||
item.next = this.anchor;
|
||||
item.prev = this.anchor.prev;
|
||||
item.prev.next = item;
|
||||
this.anchor.prev = item;
|
||||
super.add(item);
|
||||
}
|
||||
pop() {
|
||||
const item = this.last();
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
this.delete(item);
|
||||
return item;
|
||||
}
|
||||
delete(item) {
|
||||
if (!this.has(item)) {
|
||||
return false;
|
||||
}
|
||||
super.delete(item);
|
||||
item.prev.next = item.next;
|
||||
item.next = item.prev;
|
||||
return true;
|
||||
}
|
||||
insertAfter(descr, item) {
|
||||
this.insertBefore(descr, item.next);
|
||||
}
|
||||
insertBefore(descr, item) {
|
||||
const nitem = new AuditoryItem(descr);
|
||||
if (!item || !this.has(item)) {
|
||||
this.push(nitem);
|
||||
return;
|
||||
}
|
||||
item.prev.next = nitem;
|
||||
nitem.prev = item.prev;
|
||||
nitem.next = item;
|
||||
item.prev = nitem;
|
||||
}
|
||||
prevText(item) {
|
||||
do {
|
||||
item = item.prev;
|
||||
} while (item !== this.anchor && !item.data.text);
|
||||
return item === this.anchor ? null : item;
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
let current = this.anchor.next;
|
||||
while (current !== this.anchor) {
|
||||
yield current;
|
||||
current = current.next;
|
||||
}
|
||||
}
|
||||
nextText(item) {
|
||||
while (item !== this.anchor && !item.data.text) {
|
||||
item = item.next;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
clear() {
|
||||
this.anchor.next = this.anchor;
|
||||
this.anchor.prev = this.anchor;
|
||||
super.clear();
|
||||
}
|
||||
empty() {
|
||||
return this.anchor.prev === this.anchor && this.anchor === this.anchor.next;
|
||||
}
|
||||
toList() {
|
||||
const result = [];
|
||||
let item = this.anchor.next;
|
||||
while (item !== this.anchor) {
|
||||
result.push(item.data);
|
||||
item = item.next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.AuditoryList = AuditoryList;
|
||||
class AuditoryDescription {
|
||||
static create(args, flags = {}) {
|
||||
args.text = grammar_js_1.Grammar.getInstance().apply(args.text, flags);
|
||||
return new AuditoryDescription(args);
|
||||
}
|
||||
constructor({ context, text, userValue, annotation, attributes, personality, layout }) {
|
||||
this.context = context || '';
|
||||
this.text = text || '';
|
||||
this.userValue = userValue || '';
|
||||
this.annotation = annotation || '';
|
||||
this.attributes = attributes || {};
|
||||
this.personality = personality || {};
|
||||
this.layout = layout || '';
|
||||
}
|
||||
isEmpty() {
|
||||
return (this.context.length === 0 &&
|
||||
this.text.length === 0 &&
|
||||
this.userValue.length === 0 &&
|
||||
this.annotation.length === 0);
|
||||
}
|
||||
clone() {
|
||||
let personality;
|
||||
if (this.personality) {
|
||||
personality = {};
|
||||
for (const [key, val] of Object.entries(this.personality)) {
|
||||
personality[key] = val;
|
||||
}
|
||||
}
|
||||
let attributes;
|
||||
if (this.attributes) {
|
||||
attributes = {};
|
||||
for (const [key, val] of Object.entries(this.attributes)) {
|
||||
attributes[key] = val;
|
||||
}
|
||||
}
|
||||
return new AuditoryDescription({
|
||||
context: this.context,
|
||||
text: this.text,
|
||||
userValue: this.userValue,
|
||||
annotation: this.annotation,
|
||||
personality: personality,
|
||||
attributes: attributes,
|
||||
layout: this.layout
|
||||
});
|
||||
}
|
||||
toString() {
|
||||
return ('AuditoryDescription(context="' +
|
||||
this.context +
|
||||
'" ' +
|
||||
' text="' +
|
||||
this.text +
|
||||
'" ' +
|
||||
' userValue="' +
|
||||
this.userValue +
|
||||
'" ' +
|
||||
' annotation="' +
|
||||
this.annotation +
|
||||
'")');
|
||||
}
|
||||
descriptionString() {
|
||||
return this.context && this.text
|
||||
? this.context + ' ' + this.text
|
||||
: this.context || this.text;
|
||||
}
|
||||
descriptionSpan() {
|
||||
return span_js_1.Span.stringAttr(this.descriptionString(), this.attributes);
|
||||
}
|
||||
equals(that) {
|
||||
return (this.context === that.context &&
|
||||
this.text === that.text &&
|
||||
this.userValue === that.userValue &&
|
||||
this.annotation === that.annotation);
|
||||
}
|
||||
}
|
||||
exports.AuditoryDescription = AuditoryDescription;
|
||||
12
node_modules/speech-rule-engine/js/audio/aural_rendering.d.ts
generated
vendored
Normal file
12
node_modules/speech-rule-engine/js/audio/aural_rendering.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { AudioRenderer } from './audio_renderer.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { Span } from './span.js';
|
||||
export declare function setSeparator(sep: string): void;
|
||||
export declare function getSeparator(): string;
|
||||
export declare function markup(descrs: AuditoryDescription[]): string;
|
||||
export declare function merge(strs: (Span | string)[]): string;
|
||||
export declare function finalize(str: string): string;
|
||||
export declare function error(key: string): string;
|
||||
export declare function registerRenderer(type: EngineConst.Markup, renderer: AudioRenderer): void;
|
||||
export declare function isXml(): boolean;
|
||||
78
node_modules/speech-rule-engine/js/audio/aural_rendering.js
generated
vendored
Normal file
78
node_modules/speech-rule-engine/js/audio/aural_rendering.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.setSeparator = setSeparator;
|
||||
exports.getSeparator = getSeparator;
|
||||
exports.markup = markup;
|
||||
exports.merge = merge;
|
||||
exports.finalize = finalize;
|
||||
exports.error = error;
|
||||
exports.registerRenderer = registerRenderer;
|
||||
exports.isXml = isXml;
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const acss_renderer_js_1 = require("./acss_renderer.js");
|
||||
const layout_renderer_js_1 = require("./layout_renderer.js");
|
||||
const punctuation_renderer_js_1 = require("./punctuation_renderer.js");
|
||||
const sable_renderer_js_1 = require("./sable_renderer.js");
|
||||
const span_js_1 = require("./span.js");
|
||||
const ssml_renderer_js_1 = require("./ssml_renderer.js");
|
||||
const string_renderer_js_1 = require("./string_renderer.js");
|
||||
const xml_renderer_js_1 = require("./xml_renderer.js");
|
||||
const xmlInstance = new ssml_renderer_js_1.SsmlRenderer();
|
||||
const renderers = new Map([
|
||||
[EngineConst.Markup.NONE, new string_renderer_js_1.StringRenderer()],
|
||||
[EngineConst.Markup.COUNTING, new string_renderer_js_1.CountingRenderer()],
|
||||
[EngineConst.Markup.PUNCTUATION, new punctuation_renderer_js_1.PunctuationRenderer()],
|
||||
[EngineConst.Markup.LAYOUT, new layout_renderer_js_1.LayoutRenderer()],
|
||||
[EngineConst.Markup.ACSS, new acss_renderer_js_1.AcssRenderer()],
|
||||
[EngineConst.Markup.SABLE, new sable_renderer_js_1.SableRenderer()],
|
||||
[EngineConst.Markup.VOICEXML, xmlInstance],
|
||||
[EngineConst.Markup.SSML, xmlInstance]
|
||||
]);
|
||||
function setSeparator(sep) {
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
if (renderer) {
|
||||
renderer.separator = sep;
|
||||
}
|
||||
}
|
||||
function getSeparator() {
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
return renderer ? renderer.separator : '';
|
||||
}
|
||||
function markup(descrs) {
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
if (!renderer) {
|
||||
return '';
|
||||
}
|
||||
return renderer.markup(descrs);
|
||||
}
|
||||
function merge(strs) {
|
||||
const span = strs.map((s) => {
|
||||
return typeof s === 'string' ? span_js_1.Span.stringEmpty(s) : s;
|
||||
});
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
if (!renderer) {
|
||||
return strs.join();
|
||||
}
|
||||
return renderer.merge(span);
|
||||
}
|
||||
function finalize(str) {
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
if (!renderer) {
|
||||
return str;
|
||||
}
|
||||
return renderer.finalize(str);
|
||||
}
|
||||
function error(key) {
|
||||
const renderer = renderers.get(engine_js_1.Engine.getInstance().markup);
|
||||
if (!renderer) {
|
||||
return '';
|
||||
}
|
||||
return renderer.error(key);
|
||||
}
|
||||
function registerRenderer(type, renderer) {
|
||||
renderers.set(type, renderer);
|
||||
}
|
||||
function isXml() {
|
||||
return renderers.get(engine_js_1.Engine.getInstance().markup) instanceof xml_renderer_js_1.XmlRenderer;
|
||||
}
|
||||
17
node_modules/speech-rule-engine/js/audio/layout_renderer.d.ts
generated
vendored
Normal file
17
node_modules/speech-rule-engine/js/audio/layout_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import * as AudioUtil from './audio_util.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { XmlRenderer } from './xml_renderer.js';
|
||||
export declare class LayoutRenderer extends XmlRenderer {
|
||||
static options: {
|
||||
cayleyshort: boolean;
|
||||
linebreaks: boolean;
|
||||
};
|
||||
finalize(str: string): string;
|
||||
pause(_pause: AudioUtil.Pause): string;
|
||||
prosodyElement(attr: string, value: number): string;
|
||||
closeTag(tag: string): string;
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
private processContent;
|
||||
private values;
|
||||
private layoutValue;
|
||||
}
|
||||
372
node_modules/speech-rule-engine/js/audio/layout_renderer.js
generated
vendored
Normal file
372
node_modules/speech-rule-engine/js/audio/layout_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LayoutRenderer = void 0;
|
||||
const debugger_js_1 = require("../common/debugger.js");
|
||||
const DomUtil = require("../common/dom_util.js");
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const AudioUtil = require("./audio_util.js");
|
||||
const xml_renderer_js_1 = require("./xml_renderer.js");
|
||||
class LayoutRenderer extends xml_renderer_js_1.XmlRenderer {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.values = new Map();
|
||||
}
|
||||
finalize(str) {
|
||||
setRelValues(this.values.get('rel'));
|
||||
return setTwoDim(str);
|
||||
}
|
||||
pause(_pause) {
|
||||
return '';
|
||||
}
|
||||
prosodyElement(attr, value) {
|
||||
return attr === EngineConst.personalityProps.LAYOUT ? `<${value}>` : '';
|
||||
}
|
||||
closeTag(tag) {
|
||||
return `</${tag}>`;
|
||||
}
|
||||
markup(descrs) {
|
||||
this.values.clear();
|
||||
const result = [];
|
||||
let content = [];
|
||||
for (const descr of descrs) {
|
||||
if (!descr.layout) {
|
||||
content.push(descr);
|
||||
continue;
|
||||
}
|
||||
result.push(this.processContent(content));
|
||||
content = [];
|
||||
const [pref, layout, value] = this.layoutValue(descr.layout);
|
||||
if (pref === 'begin') {
|
||||
result.push('<' + layout + (value ? ` value="${value}"` : '') + '>');
|
||||
continue;
|
||||
}
|
||||
if (pref === 'end') {
|
||||
result.push('</' + layout + '>');
|
||||
continue;
|
||||
}
|
||||
console.warn('Something went wrong with layout markup: ' + layout);
|
||||
}
|
||||
result.push(this.processContent(content));
|
||||
return result.join('');
|
||||
}
|
||||
processContent(content) {
|
||||
const result = [];
|
||||
const markup = AudioUtil.personalityMarkup(content);
|
||||
for (let i = 0, descr; (descr = markup[i]); i++) {
|
||||
if (descr.span) {
|
||||
result.push(this.merge(descr.span));
|
||||
continue;
|
||||
}
|
||||
if (AudioUtil.isPauseElement(descr)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return result.join('');
|
||||
}
|
||||
layoutValue(layout) {
|
||||
const match = layout.match(/^(begin|end|)(.*\D)(\d*)$/);
|
||||
const value = match[3];
|
||||
if (!value) {
|
||||
return [match[1], match[2], ''];
|
||||
}
|
||||
layout = match[2];
|
||||
if (!this.values.has(layout)) {
|
||||
this.values.set(layout, {});
|
||||
}
|
||||
this.values.get(layout)[value] = true;
|
||||
return [match[1], layout, value];
|
||||
}
|
||||
}
|
||||
exports.LayoutRenderer = LayoutRenderer;
|
||||
LayoutRenderer.options = {
|
||||
cayleyshort: engine_js_1.Engine.getInstance().cayleyshort,
|
||||
linebreaks: engine_js_1.Engine.getInstance().linebreaks
|
||||
};
|
||||
let twodExpr = '';
|
||||
const handlers = {
|
||||
TABLE: handleTable,
|
||||
CASES: handleCases,
|
||||
CAYLEY: handleCayley,
|
||||
MATRIX: handleMatrix,
|
||||
CELL: recurseTree,
|
||||
FENCE: recurseTree,
|
||||
ROW: recurseTree,
|
||||
FRACTION: handleFraction,
|
||||
NUMERATOR: handleFractionPart,
|
||||
DENOMINATOR: handleFractionPart,
|
||||
REL: handleRelation,
|
||||
OP: handleRelation
|
||||
};
|
||||
function applyHandler(element) {
|
||||
const tag = DomUtil.tagName(element);
|
||||
const handler = handlers[tag];
|
||||
return handler ? handler(element) : element.textContent;
|
||||
}
|
||||
const relValues = new Map();
|
||||
function setRelValues(values) {
|
||||
relValues.clear();
|
||||
if (!values)
|
||||
return;
|
||||
const keys = Object.keys(values)
|
||||
.map((x) => parseInt(x))
|
||||
.sort();
|
||||
for (let i = 0, key; (key = keys[i]); i++) {
|
||||
relValues.set(key, i + 1);
|
||||
}
|
||||
}
|
||||
function setTwoDim(str) {
|
||||
twodExpr = '';
|
||||
const dom = DomUtil.parseInput(`<all>${str}</all>`);
|
||||
debugger_js_1.Debugger.getInstance().output(DomUtil.formatXml(dom.toString()));
|
||||
twodExpr = recurseTree(dom);
|
||||
return twodExpr;
|
||||
}
|
||||
function combineContent(str1, str2) {
|
||||
if (!str1 || !str2) {
|
||||
return str1 + str2;
|
||||
}
|
||||
const height1 = strHeight(str1);
|
||||
const height2 = strHeight(str2);
|
||||
const diff = height1 - height2;
|
||||
str1 = diff < 0 ? padCell(str1, height2, strWidth(str1)) : str1;
|
||||
str2 = diff > 0 ? padCell(str2, height1, strWidth(str2)) : str2;
|
||||
const lines1 = str1.split(/\r\n|\r|\n/);
|
||||
const lines2 = str2.split(/\r\n|\r|\n/);
|
||||
const result = [];
|
||||
for (let i = 0; i < lines1.length; i++) {
|
||||
result.push(lines1[i] + lines2[i]);
|
||||
}
|
||||
return result.join('\n');
|
||||
}
|
||||
function recurseTree(dom) {
|
||||
let result = '';
|
||||
for (const child of Array.from(dom.childNodes)) {
|
||||
if (child.nodeType === DomUtil.NodeType.TEXT_NODE) {
|
||||
result = combineContent(result, child.textContent);
|
||||
continue;
|
||||
}
|
||||
result = combineContent(result, applyHandler(child));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function strHeight(str) {
|
||||
return str.split(/\r\n|\r|\n/).length;
|
||||
}
|
||||
function strWidth(str) {
|
||||
return str.split(/\r\n|\r|\n/).reduce((max, x) => Math.max(x.length, max), 0);
|
||||
}
|
||||
function padHeight(str, height) {
|
||||
const padding = height - strHeight(str);
|
||||
return str + (padding > 0 ? new Array(padding + 1).join('\n') : '');
|
||||
}
|
||||
function padWidth(str, width) {
|
||||
const lines = str.split(/\r\n|\r|\n/);
|
||||
const result = [];
|
||||
for (const line of lines) {
|
||||
const padding = width - line.length;
|
||||
result.push(line + (padding > 0 ? new Array(padding + 1).join('⠀') : ''));
|
||||
}
|
||||
return result.join('\n');
|
||||
}
|
||||
function padCell(str, height, width) {
|
||||
str = padHeight(str, height);
|
||||
return padWidth(str, width);
|
||||
}
|
||||
function assembleRows(matrix) {
|
||||
const children = Array.from(matrix.childNodes);
|
||||
const mat = [];
|
||||
for (const row of children) {
|
||||
if (row.nodeType !== DomUtil.NodeType.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
mat.push(handleRow(row));
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
function getMaxParameters(mat) {
|
||||
const maxHeight = mat.reduce((max, x) => Math.max(x.height, max), 0);
|
||||
const maxWidth = [];
|
||||
for (let i = 0; i < mat[0].width.length; i++) {
|
||||
maxWidth.push(mat.map((x) => x.width[i]).reduce((max, x) => Math.max(max, x), 0));
|
||||
}
|
||||
return [maxHeight, maxWidth];
|
||||
}
|
||||
function combineCells(mat, maxWidth) {
|
||||
const newMat = [];
|
||||
for (const row of mat) {
|
||||
if (row.height === 0) {
|
||||
continue;
|
||||
}
|
||||
const newCells = [];
|
||||
for (let i = 0; i < row.cells.length; i++) {
|
||||
newCells.push(padCell(row.cells[i], row.height, maxWidth[i]));
|
||||
}
|
||||
row.cells = newCells;
|
||||
newMat.push(row);
|
||||
}
|
||||
return newMat;
|
||||
}
|
||||
function combineRows(mat, maxHeight) {
|
||||
if (maxHeight === 1) {
|
||||
return mat
|
||||
.map((row) => row.lfence + row.cells.join(row.sep) + row.rfence)
|
||||
.join('\n');
|
||||
}
|
||||
const result = [];
|
||||
for (const row of mat) {
|
||||
const sep = verticalArrange(row.sep, row.height);
|
||||
let str = row.cells.shift();
|
||||
while (row.cells.length) {
|
||||
str = combineContent(str, sep);
|
||||
str = combineContent(str, row.cells.shift());
|
||||
}
|
||||
str = combineContent(verticalArrange(row.lfence, row.height), str);
|
||||
str = combineContent(str, verticalArrange(row.rfence, row.height));
|
||||
result.push(str);
|
||||
result.push(row.lfence + new Array(strWidth(str) - 3).join(row.sep) + row.rfence);
|
||||
}
|
||||
return result.slice(0, -1).join('\n');
|
||||
}
|
||||
function verticalArrange(char, height) {
|
||||
let str = '';
|
||||
while (height) {
|
||||
str += char + '\n';
|
||||
height--;
|
||||
}
|
||||
return str.slice(0, -1);
|
||||
}
|
||||
function getFence(node) {
|
||||
if (node.nodeType === DomUtil.NodeType.ELEMENT_NODE &&
|
||||
DomUtil.tagName(node) === 'FENCE') {
|
||||
return applyHandler(node);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function handleMatrix(matrix) {
|
||||
let mat = assembleRows(matrix);
|
||||
const [maxHeight, maxWidth] = getMaxParameters(mat);
|
||||
mat = combineCells(mat, maxWidth);
|
||||
return combineRows(mat, maxHeight);
|
||||
}
|
||||
function handleTable(table) {
|
||||
let mat = assembleRows(table);
|
||||
mat.forEach((row) => {
|
||||
row.cells = row.cells.slice(1).slice(0, -1);
|
||||
row.width = row.width.slice(1).slice(0, -1);
|
||||
});
|
||||
const [maxHeight, maxWidth] = getMaxParameters(mat);
|
||||
mat = combineCells(mat, maxWidth);
|
||||
return combineRows(mat, maxHeight);
|
||||
}
|
||||
function handleCases(cases) {
|
||||
let mat = assembleRows(cases);
|
||||
mat.forEach((row) => {
|
||||
row.cells = row.cells.slice(0, -1);
|
||||
row.width = row.width.slice(0, -1);
|
||||
});
|
||||
const [maxHeight, maxWidth] = getMaxParameters(mat);
|
||||
mat = combineCells(mat, maxWidth);
|
||||
return combineRows(mat, maxHeight);
|
||||
}
|
||||
function handleCayley(cayley) {
|
||||
let mat = assembleRows(cayley);
|
||||
mat.forEach((row) => {
|
||||
row.cells = row.cells.slice(1).slice(0, -1);
|
||||
row.width = row.width.slice(1).slice(0, -1);
|
||||
row.sep = row.sep + row.sep;
|
||||
});
|
||||
const [maxHeight, maxWidth] = getMaxParameters(mat);
|
||||
const bar = {
|
||||
lfence: '',
|
||||
rfence: '',
|
||||
cells: maxWidth.map((x) => '⠐' + new Array(x).join('⠒')),
|
||||
width: maxWidth,
|
||||
height: 1,
|
||||
sep: mat[0].sep
|
||||
};
|
||||
if (engine_js_1.Engine.getInstance().cayleyshort && mat[0].cells[0] === '⠀') {
|
||||
bar.cells[0] = '⠀';
|
||||
}
|
||||
mat.splice(1, 0, bar);
|
||||
mat = combineCells(mat, maxWidth);
|
||||
return combineRows(mat, maxHeight);
|
||||
}
|
||||
function handleRow(row) {
|
||||
const children = Array.from(row.childNodes);
|
||||
const lfence = getFence(children[0]);
|
||||
const rfence = getFence(children[children.length - 1]);
|
||||
if (lfence) {
|
||||
children.shift();
|
||||
}
|
||||
if (rfence) {
|
||||
children.pop();
|
||||
}
|
||||
let sep = '';
|
||||
const cells = [];
|
||||
for (const child of children) {
|
||||
if (child.nodeType === DomUtil.NodeType.TEXT_NODE) {
|
||||
sep = child.textContent;
|
||||
continue;
|
||||
}
|
||||
const result = applyHandler(child);
|
||||
cells.push(result);
|
||||
}
|
||||
return {
|
||||
lfence: lfence,
|
||||
rfence: rfence,
|
||||
sep: sep,
|
||||
cells: cells,
|
||||
height: cells.reduce((max, x) => Math.max(strHeight(x), max), 0),
|
||||
width: cells.map(strWidth)
|
||||
};
|
||||
}
|
||||
function centerCell(cell, width) {
|
||||
const cw = strWidth(cell);
|
||||
const center = (width - cw) / 2;
|
||||
const [lpad, rpad] = Math.floor(center) === center
|
||||
? [center, center]
|
||||
: [Math.floor(center), Math.ceil(center)];
|
||||
const lines = cell.split(/\r\n|\r|\n/);
|
||||
const result = [];
|
||||
const [lstr, rstr] = [
|
||||
new Array(lpad + 1).join('⠀'),
|
||||
new Array(rpad + 1).join('⠀')
|
||||
];
|
||||
for (const line of lines) {
|
||||
result.push(lstr + line + rstr);
|
||||
}
|
||||
return result.join('\n');
|
||||
}
|
||||
function handleFraction(frac) {
|
||||
const [open, num, , den, close] = Array.from(frac.childNodes);
|
||||
const numerator = applyHandler(num);
|
||||
const denominator = applyHandler(den);
|
||||
const nwidth = strWidth(numerator);
|
||||
const dwidth = strWidth(denominator);
|
||||
let maxWidth = Math.max(nwidth, dwidth);
|
||||
const bar = open + new Array(maxWidth + 1).join('⠒') + close;
|
||||
maxWidth = bar.length;
|
||||
return (`${centerCell(numerator, maxWidth)}\n${bar}\n` +
|
||||
`${centerCell(denominator, maxWidth)}`);
|
||||
}
|
||||
function handleFractionPart(prt) {
|
||||
const fchild = prt.firstChild;
|
||||
const content = recurseTree(prt);
|
||||
if (fchild && fchild.nodeType === DomUtil.NodeType.ELEMENT_NODE) {
|
||||
if (DomUtil.tagName(fchild) === 'ENGLISH') {
|
||||
return '⠰' + content;
|
||||
}
|
||||
if (DomUtil.tagName(fchild) === 'NUMBER') {
|
||||
return '⠼' + content;
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
function handleRelation(rel) {
|
||||
if (!engine_js_1.Engine.getInstance().linebreaks) {
|
||||
return recurseTree(rel);
|
||||
}
|
||||
const value = relValues.get(parseInt(rel.getAttribute('value')));
|
||||
return (value ? `<br value="${value}"/>` : '') + recurseTree(rel);
|
||||
}
|
||||
11
node_modules/speech-rule-engine/js/audio/markup_renderer.d.ts
generated
vendored
Normal file
11
node_modules/speech-rule-engine/js/audio/markup_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { AbstractAudioRenderer } from './abstract_audio_renderer.js';
|
||||
import { Pause } from './audio_util.js';
|
||||
export declare abstract class MarkupRenderer extends AbstractAudioRenderer {
|
||||
protected ignoreElements: string[];
|
||||
private scaleFunction;
|
||||
abstract pause(pause: Pause): void;
|
||||
abstract prosodyElement(key: string, value: number): void;
|
||||
setScaleFunction(a: number, b: number, c: number, d: number, decimals?: number): void;
|
||||
applyScaleFunction(value: number): number;
|
||||
protected ignoreElement(key: string): boolean;
|
||||
}
|
||||
28
node_modules/speech-rule-engine/js/audio/markup_renderer.js
generated
vendored
Normal file
28
node_modules/speech-rule-engine/js/audio/markup_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MarkupRenderer = void 0;
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const abstract_audio_renderer_js_1 = require("./abstract_audio_renderer.js");
|
||||
class MarkupRenderer extends abstract_audio_renderer_js_1.AbstractAudioRenderer {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.ignoreElements = [EngineConst.personalityProps.LAYOUT];
|
||||
this.scaleFunction = null;
|
||||
}
|
||||
setScaleFunction(a, b, c, d, decimals = 0) {
|
||||
this.scaleFunction = (x) => {
|
||||
const delta = (x - a) / (b - a);
|
||||
const num = c * (1 - delta) + d * delta;
|
||||
return +(Math.round((num + 'e+' + decimals)) +
|
||||
'e-' +
|
||||
decimals);
|
||||
};
|
||||
}
|
||||
applyScaleFunction(value) {
|
||||
return this.scaleFunction ? this.scaleFunction(value) : value;
|
||||
}
|
||||
ignoreElement(key) {
|
||||
return this.ignoreElements.indexOf(key) !== -1;
|
||||
}
|
||||
}
|
||||
exports.MarkupRenderer = MarkupRenderer;
|
||||
8
node_modules/speech-rule-engine/js/audio/punctuation_renderer.d.ts
generated
vendored
Normal file
8
node_modules/speech-rule-engine/js/audio/punctuation_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { AbstractAudioRenderer } from './abstract_audio_renderer.js';
|
||||
import * as AudioUtil from './audio_util.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
export declare class PunctuationRenderer extends AbstractAudioRenderer {
|
||||
private static PAUSE_PUNCTUATION;
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
pause(pause: AudioUtil.PauseValue): string;
|
||||
}
|
||||
54
node_modules/speech-rule-engine/js/audio/punctuation_renderer.js
generated
vendored
Normal file
54
node_modules/speech-rule-engine/js/audio/punctuation_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PunctuationRenderer = void 0;
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const abstract_audio_renderer_js_1 = require("./abstract_audio_renderer.js");
|
||||
const AudioUtil = require("./audio_util.js");
|
||||
class PunctuationRenderer extends abstract_audio_renderer_js_1.AbstractAudioRenderer {
|
||||
markup(descrs) {
|
||||
const markup = AudioUtil.personalityMarkup(descrs);
|
||||
let str = '';
|
||||
let pause = null;
|
||||
let span = false;
|
||||
for (let i = 0, descr; (descr = markup[i]); i++) {
|
||||
if (AudioUtil.isMarkupElement(descr)) {
|
||||
continue;
|
||||
}
|
||||
if (AudioUtil.isPauseElement(descr)) {
|
||||
pause = descr;
|
||||
continue;
|
||||
}
|
||||
if (pause) {
|
||||
str += this.pause(pause[EngineConst.personalityProps.PAUSE]);
|
||||
pause = null;
|
||||
}
|
||||
str += (span ? this.separator : '') + this.merge(descr.span);
|
||||
span = true;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
pause(pause) {
|
||||
let newPause;
|
||||
if (typeof pause === 'number') {
|
||||
if (pause <= 250) {
|
||||
newPause = 'short';
|
||||
}
|
||||
else if (pause <= 500) {
|
||||
newPause = 'medium';
|
||||
}
|
||||
else {
|
||||
newPause = 'long';
|
||||
}
|
||||
}
|
||||
else {
|
||||
newPause = pause;
|
||||
}
|
||||
return PunctuationRenderer.PAUSE_PUNCTUATION.get(newPause) || '';
|
||||
}
|
||||
}
|
||||
exports.PunctuationRenderer = PunctuationRenderer;
|
||||
PunctuationRenderer.PAUSE_PUNCTUATION = new Map([
|
||||
['short', ','],
|
||||
['medium', ';'],
|
||||
['long', '.']
|
||||
]);
|
||||
9
node_modules/speech-rule-engine/js/audio/sable_renderer.d.ts
generated
vendored
Normal file
9
node_modules/speech-rule-engine/js/audio/sable_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { Pause } from './audio_util.js';
|
||||
import { XmlRenderer } from './xml_renderer.js';
|
||||
export declare class SableRenderer extends XmlRenderer {
|
||||
finalize(str: string): string;
|
||||
pause(pause: Pause): string;
|
||||
prosodyElement(tag: EngineConst.personalityProps, value: number): string;
|
||||
closeTag(tag: string): string;
|
||||
}
|
||||
39
node_modules/speech-rule-engine/js/audio/sable_renderer.js
generated
vendored
Normal file
39
node_modules/speech-rule-engine/js/audio/sable_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SableRenderer = void 0;
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const xml_renderer_js_1 = require("./xml_renderer.js");
|
||||
class SableRenderer extends xml_renderer_js_1.XmlRenderer {
|
||||
finalize(str) {
|
||||
return ('<?xml version="1.0"?>' +
|
||||
'<!DOCTYPE SABLE PUBLIC "-//SABLE//DTD SABLE speech mark up//EN"' +
|
||||
' "Sable.v0_2.dtd" []><SABLE>' +
|
||||
this.separator +
|
||||
str +
|
||||
this.separator +
|
||||
'</SABLE>');
|
||||
}
|
||||
pause(pause) {
|
||||
return ('<BREAK ' +
|
||||
'MSEC="' +
|
||||
this.pauseValue(pause[EngineConst.personalityProps.PAUSE]) +
|
||||
'"/>');
|
||||
}
|
||||
prosodyElement(tag, value) {
|
||||
value = this.applyScaleFunction(value);
|
||||
switch (tag) {
|
||||
case EngineConst.personalityProps.PITCH:
|
||||
return '<PITCH RANGE="' + value + '%">';
|
||||
case EngineConst.personalityProps.RATE:
|
||||
return '<RATE SPEED="' + value + '%">';
|
||||
case EngineConst.personalityProps.VOLUME:
|
||||
return '<VOLUME LEVEL="' + value + '%">';
|
||||
default:
|
||||
return '<' + tag.toUpperCase() + ' VALUE="' + value + '">';
|
||||
}
|
||||
}
|
||||
closeTag(tag) {
|
||||
return '</' + tag.toUpperCase() + '>';
|
||||
}
|
||||
}
|
||||
exports.SableRenderer = SableRenderer;
|
||||
15
node_modules/speech-rule-engine/js/audio/span.d.ts
generated
vendored
Normal file
15
node_modules/speech-rule-engine/js/audio/span.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
export type SpanAttrs = {
|
||||
[key: string]: string;
|
||||
};
|
||||
export declare class Span {
|
||||
speech: string;
|
||||
attributes: SpanAttrs;
|
||||
constructor(speech: string, attributes: SpanAttrs);
|
||||
static empty(): Span;
|
||||
static stringEmpty(str: string): Span;
|
||||
static stringAttr(str: string, attr: SpanAttrs): Span;
|
||||
static singleton(str: string, def?: SpanAttrs): Span[];
|
||||
static node(str: string, node: Element, def?: SpanAttrs): Span;
|
||||
static attributeList: string[];
|
||||
static getAttributes(node: Element): SpanAttrs;
|
||||
}
|
||||
37
node_modules/speech-rule-engine/js/audio/span.js
generated
vendored
Normal file
37
node_modules/speech-rule-engine/js/audio/span.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Span = void 0;
|
||||
class Span {
|
||||
constructor(speech, attributes) {
|
||||
this.speech = speech;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
static empty() {
|
||||
return new Span('', {});
|
||||
}
|
||||
static stringEmpty(str) {
|
||||
return new Span(str, {});
|
||||
}
|
||||
static stringAttr(str, attr) {
|
||||
return new Span(str, attr);
|
||||
}
|
||||
static singleton(str, def = {}) {
|
||||
return [Span.stringAttr(str, def)];
|
||||
}
|
||||
static node(str, node, def = {}) {
|
||||
const attr = Span.getAttributes(node);
|
||||
Object.assign(attr, def);
|
||||
return new Span(str, attr);
|
||||
}
|
||||
static getAttributes(node) {
|
||||
const attrs = {};
|
||||
for (const attr of Span.attributeList) {
|
||||
if (node.hasAttribute(attr)) {
|
||||
attrs[attr] = node.getAttribute(attr);
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
exports.Span = Span;
|
||||
Span.attributeList = ['id', 'extid'];
|
||||
17
node_modules/speech-rule-engine/js/audio/ssml_renderer.d.ts
generated
vendored
Normal file
17
node_modules/speech-rule-engine/js/audio/ssml_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Pause } from './audio_util.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { Span } from './span.js';
|
||||
import { XmlRenderer } from './xml_renderer.js';
|
||||
export declare class SsmlRenderer extends XmlRenderer {
|
||||
finalize(str: string): string;
|
||||
pause(pause: Pause): string;
|
||||
prosodyElement(attr: string, value: number): string;
|
||||
closeTag(_tag: string): string;
|
||||
static MARK_ONCE: boolean;
|
||||
static MARK_KIND: boolean;
|
||||
private static CHARACTER_ATTR;
|
||||
private static MARKS;
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
merge(spans: Span[]): string;
|
||||
private isEmptySpan;
|
||||
}
|
||||
86
node_modules/speech-rule-engine/js/audio/ssml_renderer.js
generated
vendored
Normal file
86
node_modules/speech-rule-engine/js/audio/ssml_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SsmlRenderer = void 0;
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const EngineConst = require("../common/engine_const.js");
|
||||
const xml_renderer_js_1 = require("./xml_renderer.js");
|
||||
class SsmlRenderer extends xml_renderer_js_1.XmlRenderer {
|
||||
finalize(str) {
|
||||
return ('<?xml version="1.0"?><speak version="1.1"' +
|
||||
' xmlns="http://www.w3.org/2001/10/synthesis"' +
|
||||
` xml:lang="${engine_js_1.Engine.getInstance().locale}">` +
|
||||
'<prosody rate="' +
|
||||
engine_js_1.Engine.getInstance().getRate() +
|
||||
'%">' +
|
||||
this.separator +
|
||||
str +
|
||||
this.separator +
|
||||
'</prosody></speak>');
|
||||
}
|
||||
pause(pause) {
|
||||
return ('<break ' +
|
||||
'time="' +
|
||||
this.pauseValue(pause[EngineConst.personalityProps.PAUSE]) +
|
||||
'ms"/>');
|
||||
}
|
||||
prosodyElement(attr, value) {
|
||||
value = Math.floor(this.applyScaleFunction(value));
|
||||
const valueStr = value < 0 ? value.toString() : '+' + value.toString();
|
||||
return ('<prosody ' +
|
||||
attr.toLowerCase() +
|
||||
'="' +
|
||||
valueStr +
|
||||
(attr === EngineConst.personalityProps.VOLUME ? '>' : '%">'));
|
||||
}
|
||||
closeTag(_tag) {
|
||||
return '</prosody>';
|
||||
}
|
||||
markup(descrs) {
|
||||
SsmlRenderer.MARKS = {};
|
||||
return super.markup(descrs);
|
||||
}
|
||||
merge(spans) {
|
||||
const result = [];
|
||||
let lastMark = '';
|
||||
for (let i = 0; i < spans.length; i++) {
|
||||
const span = spans[i];
|
||||
if (this.isEmptySpan(span))
|
||||
continue;
|
||||
const kind = SsmlRenderer.MARK_KIND ? span.attributes['kind'] : '';
|
||||
const id = engine_js_1.Engine.getInstance().automark
|
||||
? span.attributes['id']
|
||||
: engine_js_1.Engine.getInstance().mark
|
||||
? span.attributes['extid']
|
||||
: '';
|
||||
if (id &&
|
||||
id !== lastMark &&
|
||||
!(SsmlRenderer.MARK_ONCE && SsmlRenderer.MARKS[id])) {
|
||||
result.push(kind ? `<mark name="${id}" kind="${kind}"/>` : `<mark name="${id}"/>`);
|
||||
lastMark = id;
|
||||
SsmlRenderer.MARKS[id] = true;
|
||||
}
|
||||
if (engine_js_1.Engine.getInstance().character &&
|
||||
span.speech.length === 1 &&
|
||||
span.speech.match(/[a-zA-Z]/)) {
|
||||
result.push('<say-as interpret-as="' +
|
||||
SsmlRenderer.CHARACTER_ATTR +
|
||||
'">' +
|
||||
span.speech +
|
||||
'</say-as>');
|
||||
}
|
||||
else {
|
||||
result.push(span.speech);
|
||||
}
|
||||
}
|
||||
return result.join(this.separator);
|
||||
}
|
||||
isEmptySpan(span) {
|
||||
const sep = span.attributes['separator'];
|
||||
return span.speech.match(/^\s*$/) && (!sep || sep.match(/^\s*$/));
|
||||
}
|
||||
}
|
||||
exports.SsmlRenderer = SsmlRenderer;
|
||||
SsmlRenderer.MARK_ONCE = false;
|
||||
SsmlRenderer.MARK_KIND = true;
|
||||
SsmlRenderer.CHARACTER_ATTR = 'character';
|
||||
SsmlRenderer.MARKS = {};
|
||||
8
node_modules/speech-rule-engine/js/audio/string_renderer.d.ts
generated
vendored
Normal file
8
node_modules/speech-rule-engine/js/audio/string_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { AbstractAudioRenderer } from './abstract_audio_renderer.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
export declare class StringRenderer extends AbstractAudioRenderer {
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
}
|
||||
export declare class CountingRenderer extends StringRenderer {
|
||||
finalize(str: string): string;
|
||||
}
|
||||
39
node_modules/speech-rule-engine/js/audio/string_renderer.js
generated
vendored
Normal file
39
node_modules/speech-rule-engine/js/audio/string_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CountingRenderer = exports.StringRenderer = void 0;
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const abstract_audio_renderer_js_1 = require("./abstract_audio_renderer.js");
|
||||
const audio_util_js_1 = require("./audio_util.js");
|
||||
class StringRenderer extends abstract_audio_renderer_js_1.AbstractAudioRenderer {
|
||||
markup(descrs) {
|
||||
let str = '';
|
||||
const markup = (0, audio_util_js_1.personalityMarkup)(descrs);
|
||||
const clean = markup.filter((x) => x.span);
|
||||
if (!clean.length) {
|
||||
return str;
|
||||
}
|
||||
const len = clean.length - 1;
|
||||
for (let i = 0, descr; (descr = clean[i]); i++) {
|
||||
if (descr.span) {
|
||||
str += this.merge(descr.span);
|
||||
}
|
||||
if (i >= len) {
|
||||
continue;
|
||||
}
|
||||
const join = descr.join;
|
||||
str += typeof join === 'undefined' ? this.separator : join;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
exports.StringRenderer = StringRenderer;
|
||||
class CountingRenderer extends StringRenderer {
|
||||
finalize(str) {
|
||||
const output = super.finalize(str);
|
||||
const count = engine_js_1.Engine.getInstance().modality === 'braille' ? '⣿⠀⣿⠀⣿⠀⣿⠀⣿⠀' : '0123456789';
|
||||
let second = new Array(Math.trunc(output.length / 10) + 1).join(count);
|
||||
second += count.slice(0, output.length % 10);
|
||||
return output + '\n' + second;
|
||||
}
|
||||
}
|
||||
exports.CountingRenderer = CountingRenderer;
|
||||
7
node_modules/speech-rule-engine/js/audio/xml_renderer.d.ts
generated
vendored
Normal file
7
node_modules/speech-rule-engine/js/audio/xml_renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import * as EngineConst from '../common/engine_const.js';
|
||||
import { AuditoryDescription } from './auditory_description.js';
|
||||
import { MarkupRenderer } from './markup_renderer.js';
|
||||
export declare abstract class XmlRenderer extends MarkupRenderer {
|
||||
abstract closeTag(tag: EngineConst.personalityProps): void;
|
||||
markup(descrs: AuditoryDescription[]): string;
|
||||
}
|
||||
42
node_modules/speech-rule-engine/js/audio/xml_renderer.js
generated
vendored
Normal file
42
node_modules/speech-rule-engine/js/audio/xml_renderer.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlRenderer = void 0;
|
||||
const engine_js_1 = require("../common/engine.js");
|
||||
const AudioUtil = require("./audio_util.js");
|
||||
const markup_renderer_js_1 = require("./markup_renderer.js");
|
||||
class XmlRenderer extends markup_renderer_js_1.MarkupRenderer {
|
||||
markup(descrs) {
|
||||
this.setScaleFunction(-2, 2, -100, 100, 2);
|
||||
const markup = AudioUtil.personalityMarkup(descrs);
|
||||
const result = [];
|
||||
const currentOpen = [];
|
||||
for (let i = 0, descr; (descr = markup[i]); i++) {
|
||||
if (descr.span) {
|
||||
result.push(this.merge(descr.span));
|
||||
continue;
|
||||
}
|
||||
if (AudioUtil.isPauseElement(descr)) {
|
||||
result.push(this.pause(descr));
|
||||
continue;
|
||||
}
|
||||
if (descr.close.length) {
|
||||
for (let j = 0; j < descr.close.length; j++) {
|
||||
const last = currentOpen.pop();
|
||||
if (descr.close.indexOf(last) === -1) {
|
||||
throw new engine_js_1.SREError('Unknown closing markup element: ' + last);
|
||||
}
|
||||
result.push(this.closeTag(last));
|
||||
}
|
||||
}
|
||||
if (descr.open.length) {
|
||||
const open = AudioUtil.sortClose(descr.open.slice(), markup.slice(i + 1));
|
||||
open.forEach((o) => {
|
||||
result.push(this.prosodyElement(o, descr[o]));
|
||||
currentOpen.push(o);
|
||||
});
|
||||
}
|
||||
}
|
||||
return result.join(' ');
|
||||
}
|
||||
}
|
||||
exports.XmlRenderer = XmlRenderer;
|
||||
Reference in New Issue
Block a user