hojas/node_modules/speech-rule-engine/js/semantic_tree/semantic_processor.js

1960 lines
89 KiB
JavaScript
Raw Normal View History

2026-05-14 10:56:04 +02:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticProcessor = void 0;
const DomUtil = require("../common/dom_util.js");
const semantic_attr_js_1 = require("./semantic_attr.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const semantic_heuristic_factory_js_1 = require("./semantic_heuristic_factory.js");
const semantic_node_factory_js_1 = require("./semantic_node_factory.js");
const SemanticPred = require("./semantic_pred.js");
const SemanticUtil = require("./semantic_util.js");
const semantic_util_js_1 = require("../semantic_tree/semantic_util.js");
class SemanticProcessor {
static getInstance() {
SemanticProcessor.instance =
SemanticProcessor.instance || new SemanticProcessor();
return SemanticProcessor.instance;
}
static tableToMultiline(table) {
if (!SemanticPred.tableIsMultiline(table)) {
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('rewrite_subcases', table, SemanticProcessor.classifyTable);
}
table.type = semantic_meaning_js_1.SemanticType.MULTILINE;
for (let i = 0, row; (row = table.childNodes[i]); i++) {
SemanticProcessor.rowToLine_(row, semantic_meaning_js_1.SemanticRole.MULTILINE);
}
if (table.childNodes.length === 1 &&
!SemanticPred.lineIsLabelled(table.childNodes[0]) &&
SemanticPred.isFencedElement(table.childNodes[0].childNodes[0])) {
SemanticProcessor.tableToMatrixOrVector_(SemanticProcessor.rewriteFencedLine_(table));
}
SemanticProcessor.binomialForm_(table);
SemanticProcessor.classifyMultiline(table);
return table;
}
static number(node) {
if (node.type === semantic_meaning_js_1.SemanticType.UNKNOWN ||
node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER) {
node.type = semantic_meaning_js_1.SemanticType.NUMBER;
}
SemanticProcessor.meaningFromContent(node, SemanticProcessor.numberRole_);
SemanticProcessor.exprFont_(node);
}
static classifyMultiline(multiline) {
let index = 0;
const length = multiline.childNodes.length;
let line;
while (index < length &&
(!(line = multiline.childNodes[index]) || !line.childNodes.length)) {
index++;
}
if (index >= length) {
return;
}
const firstRole = line.childNodes[0].role;
if (firstRole !== semantic_meaning_js_1.SemanticRole.UNKNOWN &&
multiline.childNodes.every(function (x) {
const cell = x.childNodes[0];
return (!cell ||
(cell.role === firstRole &&
(SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.RELATION) ||
SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.RELSEQ))));
})) {
multiline.role = firstRole;
}
}
static classifyTable(table) {
const columns = SemanticProcessor.computeColumns_(table);
SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.EQUALITY) ||
SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.INEQUALITY, [semantic_meaning_js_1.SemanticRole.EQUALITY]) ||
SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.ARROW) ||
SemanticProcessor.detectCaleyTable(table);
return table;
}
static detectCaleyTable(table) {
if (!table.mathmlTree) {
return false;
}
const tree = table.mathmlTree;
const cl = tree.getAttribute('columnlines');
const rl = tree.getAttribute('rowlines');
if (!cl || !rl) {
return false;
}
if (SemanticProcessor.cayleySpacing(cl) &&
SemanticProcessor.cayleySpacing(rl)) {
table.role = semantic_meaning_js_1.SemanticRole.CAYLEY;
return true;
}
return false;
}
static cayleySpacing(lines) {
const list = lines.split(' ');
return ((list[0] === 'solid' || list[0] === 'dashed') &&
list.slice(1).every((x) => x === 'none'));
}
static proof(node, semantics, parse) {
const attrs = SemanticProcessor.separateSemantics(semantics);
return SemanticProcessor.getInstance().proof(node, attrs, parse);
}
static findSemantics(node, attr, opt_value) {
const value = opt_value == null ? null : opt_value;
const semantics = SemanticProcessor.getSemantics(node);
if (!semantics) {
return false;
}
if (!semantics[attr]) {
return false;
}
return value == null ? true : semantics[attr] === value;
}
static getSemantics(node) {
const semantics = node.getAttribute('semantics');
if (!semantics) {
return null;
}
return SemanticProcessor.separateSemantics(semantics);
}
static removePrefix(name) {
const [, ...rest] = name.split('_');
return rest.join('_');
}
static separateSemantics(attr) {
const result = {};
attr.split(';').forEach(function (x) {
const [name, value] = x.split(':');
result[SemanticProcessor.removePrefix(name)] = value;
});
return result;
}
static matchSpaces_(nodes, ops) {
for (let i = 0, op; (op = ops[i]); i++) {
const node = nodes[i];
const mt1 = node.mathmlTree;
const mt2 = nodes[i + 1].mathmlTree;
if (!mt1 || !mt2) {
continue;
}
const sibling = mt1.nextSibling;
if (!sibling || sibling === mt2) {
continue;
}
const spacer = SemanticProcessor.getSpacer_(sibling);
if (spacer) {
op.mathml.push(spacer);
op.mathmlTree = spacer;
op.role = semantic_meaning_js_1.SemanticRole.SPACE;
}
}
}
static getSpacer_(node) {
if (DomUtil.tagName(node) === semantic_util_js_1.MMLTAGS.MSPACE) {
return node;
}
while (SemanticUtil.hasEmptyTag(node) && node.childNodes.length === 1) {
node = node.childNodes[0];
if (DomUtil.tagName(node) === semantic_util_js_1.MMLTAGS.MSPACE) {
return node;
}
}
return null;
}
static fenceToPunct_(fence) {
const newRole = SemanticProcessor.FENCE_TO_PUNCT_[fence.role];
if (!newRole) {
return;
}
while (fence.embellished) {
fence.embellished = semantic_meaning_js_1.SemanticType.PUNCTUATION;
if (!(SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.SUBSUP) ||
SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.UNDEROVER))) {
fence.role = newRole;
}
fence = fence.childNodes[0];
}
fence.type = semantic_meaning_js_1.SemanticType.PUNCTUATION;
fence.role = newRole;
}
static classifyFunction_(funcNode, restNodes) {
if (funcNode.type === semantic_meaning_js_1.SemanticType.APPL ||
funcNode.type === semantic_meaning_js_1.SemanticType.BIGOP ||
funcNode.type === semantic_meaning_js_1.SemanticType.INTEGRAL) {
return '';
}
if (restNodes[0] &&
restNodes[0].textContent === semantic_attr_js_1.NamedSymbol.functionApplication) {
SemanticProcessor.getInstance().funcAppls[funcNode.id] =
restNodes.shift();
let role = semantic_meaning_js_1.SemanticRole.SIMPLEFUNC;
semantic_heuristic_factory_js_1.SemanticHeuristics.run('simple2prefix', funcNode);
if (funcNode.role === semantic_meaning_js_1.SemanticRole.PREFIXFUNC ||
funcNode.role === semantic_meaning_js_1.SemanticRole.LIMFUNC) {
role = funcNode.role;
}
SemanticProcessor.propagateFunctionRole_(funcNode, role);
return 'prefix';
}
const kind = SemanticProcessor.CLASSIFY_FUNCTION_[funcNode.role];
return kind
? kind
: SemanticPred.isSimpleFunctionHead(funcNode)
? 'simple'
: '';
}
static propagateFunctionRole_(funcNode, tag) {
if (funcNode) {
if (funcNode.type === semantic_meaning_js_1.SemanticType.INFIXOP) {
return;
}
if (!(SemanticPred.isRole(funcNode, semantic_meaning_js_1.SemanticRole.SUBSUP) ||
SemanticPred.isRole(funcNode, semantic_meaning_js_1.SemanticRole.UNDEROVER))) {
funcNode.role = tag;
}
SemanticProcessor.propagateFunctionRole_(funcNode.childNodes[0], tag);
}
}
static getFunctionOp_(tree, pred) {
if (pred(tree)) {
return tree;
}
for (let i = 0, child; (child = tree.childNodes[i]); i++) {
const op = SemanticProcessor.getFunctionOp_(child, pred);
if (op) {
return op;
}
}
return null;
}
static tableToMatrixOrVector_(node) {
const matrix = node.childNodes[0];
SemanticPred.isType(matrix, semantic_meaning_js_1.SemanticType.MULTILINE)
? SemanticProcessor.tableToVector_(node)
: SemanticProcessor.tableToMatrix_(node);
node.contentNodes.forEach(matrix.appendContentNode.bind(matrix));
for (let i = 0, row; (row = matrix.childNodes[i]); i++) {
SemanticProcessor.assignRoleToRow_(row, SemanticProcessor.getComponentRoles_(matrix));
}
matrix.parent = null;
return matrix;
}
static tableToVector_(node) {
const vector = node.childNodes[0];
vector.type = semantic_meaning_js_1.SemanticType.VECTOR;
if (vector.childNodes.length === 1) {
SemanticProcessor.tableToSquare_(node);
return;
}
SemanticProcessor.binomialForm_(vector);
}
static binomialForm_(node) {
if (!SemanticPred.isRole(node, semantic_meaning_js_1.SemanticRole.UNKNOWN)) {
return;
}
if (SemanticPred.isBinomial(node)) {
node.role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
node.childNodes[0].role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
node.childNodes[1].role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
}
}
static tableToMatrix_(node) {
const matrix = node.childNodes[0];
matrix.type = semantic_meaning_js_1.SemanticType.MATRIX;
if (matrix.childNodes &&
matrix.childNodes.length > 0 &&
matrix.childNodes[0].childNodes &&
matrix.childNodes.length === matrix.childNodes[0].childNodes.length) {
SemanticProcessor.tableToSquare_(node);
return;
}
if (matrix.childNodes && matrix.childNodes.length === 1) {
matrix.role = semantic_meaning_js_1.SemanticRole.ROWVECTOR;
}
}
static tableToSquare_(node) {
const matrix = node.childNodes[0];
if (!SemanticPred.isRole(matrix, semantic_meaning_js_1.SemanticRole.UNKNOWN)) {
return;
}
if (SemanticPred.isNeutralFence(node)) {
matrix.role = semantic_meaning_js_1.SemanticRole.DETERMINANT;
return;
}
matrix.role = semantic_meaning_js_1.SemanticRole.SQUAREMATRIX;
}
static getComponentRoles_(node) {
const role = node.role;
if (role && role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
return role;
}
return node.type.toLowerCase() || semantic_meaning_js_1.SemanticRole.UNKNOWN;
}
static tableToCases_(table, openFence) {
for (let i = 0, row; (row = table.childNodes[i]); i++) {
SemanticProcessor.assignRoleToRow_(row, semantic_meaning_js_1.SemanticRole.CASES);
}
table.type = semantic_meaning_js_1.SemanticType.CASES;
table.appendContentNode(openFence);
if (SemanticPred.tableIsMultiline(table)) {
SemanticProcessor.binomialForm_(table);
}
return table;
}
static rewriteFencedLine_(table) {
const line = table.childNodes[0];
const fenced = table.childNodes[0].childNodes[0];
const element = table.childNodes[0].childNodes[0].childNodes[0];
fenced.parent = table.parent;
table.parent = fenced;
element.parent = line;
fenced.childNodes = [table];
line.childNodes = [element];
return fenced;
}
static rowToLine_(row, opt_role) {
const role = opt_role || semantic_meaning_js_1.SemanticRole.UNKNOWN;
if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.ROW)) {
row.type = semantic_meaning_js_1.SemanticType.LINE;
row.role = role;
if (row.childNodes.length === 1 &&
SemanticPred.isType(row.childNodes[0], semantic_meaning_js_1.SemanticType.CELL)) {
row.childNodes = row.childNodes[0].childNodes;
row.childNodes.forEach(function (x) {
x.parent = row;
});
}
}
}
static assignRoleToRow_(row, role) {
if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.LINE)) {
row.role = role;
return;
}
if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.ROW)) {
row.role = role;
row.childNodes.forEach(function (cell) {
if (SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.CELL)) {
cell.role = role;
}
});
}
}
static nextSeparatorFunction_(separators) {
let sepList;
if (separators) {
if (separators.match(/^\s+$/)) {
return null;
}
else {
sepList = separators
.replace(/\s/g, '')
.split('')
.filter(function (x) {
return x;
});
}
}
else {
sepList = [','];
}
return function () {
if (sepList.length > 1) {
return sepList.shift();
}
return sepList[0];
};
}
static meaningFromContent(node, func) {
const content = [...node.textContent].filter((x) => x.match(/[^\s]/));
const meaning = content.map((x) => semantic_attr_js_1.SemanticMap.Meaning.get(x));
func(node, content, meaning);
}
static numberRole_(node, content, meaning) {
if (node.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
return;
}
if (meaning.every(function (x) {
return ((x.type === semantic_meaning_js_1.SemanticType.NUMBER && x.role === semantic_meaning_js_1.SemanticRole.INTEGER) ||
(x.type === semantic_meaning_js_1.SemanticType.PUNCTUATION && x.role === semantic_meaning_js_1.SemanticRole.COMMA));
})) {
node.role = semantic_meaning_js_1.SemanticRole.INTEGER;
if (content[0] === '0') {
node.addAnnotation('general', 'basenumber');
}
return;
}
if (meaning.every(function (x) {
return ((x.type === semantic_meaning_js_1.SemanticType.NUMBER && x.role === semantic_meaning_js_1.SemanticRole.INTEGER) ||
x.type === semantic_meaning_js_1.SemanticType.PUNCTUATION);
})) {
node.role = semantic_meaning_js_1.SemanticRole.FLOAT;
return;
}
node.role = semantic_meaning_js_1.SemanticRole.OTHERNUMBER;
}
static exprFont_(node) {
if (node.font !== semantic_meaning_js_1.SemanticFont.UNKNOWN) {
return;
}
SemanticProcessor.compSemantics(node, 'font', semantic_meaning_js_1.SemanticFont);
}
static compSemantics(node, field, sem) {
const content = [...node.textContent];
const meaning = content.map((x) => semantic_attr_js_1.SemanticMap.Meaning.get(x));
const single = meaning.reduce(function (prev, curr) {
if (!prev ||
!curr[field] ||
curr[field] === sem.UNKNOWN ||
curr[field] === prev) {
return prev;
}
if (prev === sem.UNKNOWN) {
return curr[field];
}
return null;
}, sem.UNKNOWN);
if (single) {
node[field] = single;
}
}
static purgeFences_(partition) {
const rel = partition.rel;
const comp = partition.comp;
const newRel = [];
const newComp = [];
while (rel.length > 0) {
const currentRel = rel.shift();
let currentComp = comp.shift();
if (SemanticPred.isElligibleEmbellishedFence(currentRel)) {
newRel.push(currentRel);
newComp.push(currentComp);
continue;
}
SemanticProcessor.fenceToPunct_(currentRel);
currentComp.push(currentRel);
currentComp = currentComp.concat(comp.shift());
comp.unshift(currentComp);
}
newComp.push(comp.shift());
return { rel: newRel, comp: newComp };
}
static rewriteFencedNode_(fenced) {
const ofence = fenced.contentNodes[0];
const cfence = fenced.contentNodes[1];
let rewritten = SemanticProcessor.rewriteFence_(fenced, ofence);
fenced.contentNodes[0] = rewritten.fence;
rewritten = SemanticProcessor.rewriteFence_(rewritten.node, cfence);
fenced.contentNodes[1] = rewritten.fence;
fenced.contentNodes[0].parent = fenced;
fenced.contentNodes[1].parent = fenced;
rewritten.node.parent = null;
return rewritten.node;
}
static rewriteFence_(node, fence) {
if (!fence.embellished) {
return { node: node, fence: fence };
}
const newFence = fence.childNodes[0];
const rewritten = SemanticProcessor.rewriteFence_(node, newFence);
if (SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.SUPERSCRIPT) ||
SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.SUBSCRIPT) ||
SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.TENSOR)) {
if (!SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.SUBSUP)) {
fence.role = node.role;
}
if (newFence !== rewritten.node) {
fence.replaceChild(newFence, rewritten.node);
newFence.parent = node;
}
SemanticProcessor.propagateFencePointer_(fence, newFence);
return { node: fence, fence: rewritten.fence };
}
fence.replaceChild(newFence, rewritten.fence);
if (fence.mathmlTree && fence.mathml.indexOf(fence.mathmlTree) === -1) {
fence.mathml.push(fence.mathmlTree);
}
return { node: rewritten.node, fence: fence };
}
static propagateFencePointer_(oldNode, newNode) {
oldNode.fencePointer = newNode.fencePointer || newNode.id.toString();
oldNode.embellished = null;
}
static classifyByColumns_(table, columns, relation, alternatives = []) {
const relations = [relation].concat(alternatives);
const test1 = (x) => SemanticProcessor.isPureRelation_(x, relations);
const test2 = (x) => SemanticProcessor.isEndRelation_(x, relations) ||
SemanticProcessor.isPureRelation_(x, relations);
const test3 = (x) => SemanticProcessor.isEndRelation_(x, relations, true) ||
SemanticProcessor.isPureRelation_(x, relations);
if ((columns.length === 3 &&
SemanticProcessor.testColumns_(columns, 1, test1)) ||
(columns.length === 2 &&
(SemanticProcessor.testColumns_(columns, 1, test2) ||
SemanticProcessor.testColumns_(columns, 0, test3)))) {
table.role = relation;
return true;
}
return false;
}
static isEndRelation_(node, relations, opt_right) {
const position = opt_right ? node.childNodes.length - 1 : 0;
return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.RELSEQ) &&
relations.some((relation) => SemanticPred.isRole(node, relation)) &&
SemanticPred.isType(node.childNodes[position], semantic_meaning_js_1.SemanticType.EMPTY));
}
static isPureRelation_(node, relations) {
return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.RELATION) &&
relations.some((relation) => SemanticPred.isRole(node, relation)));
}
static computeColumns_(table) {
const columns = [];
for (let i = 0, row; (row = table.childNodes[i]); i++) {
for (let j = 0, cell; (cell = row.childNodes[j]); j++) {
const column = columns[j];
column ? columns[j].push(cell) : (columns[j] = [cell]);
}
}
return columns;
}
static testColumns_(columns, index, pred) {
const column = columns[index];
return column
? column.some(function (cell) {
return (cell.childNodes.length && pred(cell.childNodes[0]));
}) &&
column.every(function (cell) {
return (!cell.childNodes.length ||
pred(cell.childNodes[0]));
})
: false;
}
setNodeFactory(factory) {
SemanticProcessor.getInstance().factory_ = factory;
semantic_heuristic_factory_js_1.SemanticHeuristics.updateFactory(SemanticProcessor.getInstance().factory_);
}
getNodeFactory() {
return SemanticProcessor.getInstance().factory_;
}
identifierNode(leaf, font, unit) {
if (unit === 'MathML-Unit') {
leaf.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
leaf.role = semantic_meaning_js_1.SemanticRole.UNIT;
}
else if (!font &&
leaf.textContent.length === 1 &&
(leaf.role === semantic_meaning_js_1.SemanticRole.INTEGER ||
leaf.role === semantic_meaning_js_1.SemanticRole.LATINLETTER ||
leaf.role === semantic_meaning_js_1.SemanticRole.GREEKLETTER) &&
leaf.font === semantic_meaning_js_1.SemanticFont.NORMAL) {
leaf.font = semantic_meaning_js_1.SemanticFont.ITALIC;
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('simpleNamedFunction', leaf);
}
if (leaf.type === semantic_meaning_js_1.SemanticType.UNKNOWN) {
leaf.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
}
SemanticProcessor.exprFont_(leaf);
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('simpleNamedFunction', leaf);
}
implicitNode(nodes) {
nodes = SemanticProcessor.getInstance().getMixedNumbers_(nodes);
nodes = SemanticProcessor.getInstance().combineUnits_(nodes);
if (nodes.length === 1) {
return nodes[0];
}
const node = SemanticProcessor.getInstance().implicitNode_(nodes);
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('combine_juxtaposition', node);
}
text(leaf, type) {
SemanticProcessor.exprFont_(leaf);
leaf.type = semantic_meaning_js_1.SemanticType.TEXT;
if (type === semantic_util_js_1.MMLTAGS.ANNOTATIONXML) {
leaf.role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
return leaf;
}
if (type === semantic_util_js_1.MMLTAGS.MS) {
leaf.role = semantic_meaning_js_1.SemanticRole.STRING;
return leaf;
}
if (type === semantic_util_js_1.MMLTAGS.MSPACE || leaf.textContent.match(/^\s*$/)) {
leaf.role = semantic_meaning_js_1.SemanticRole.SPACE;
return leaf;
}
if (/\s/.exec(leaf.textContent)) {
leaf.role = semantic_meaning_js_1.SemanticRole.TEXT;
return leaf;
}
leaf.role = semantic_meaning_js_1.SemanticRole.UNKNOWN;
return leaf;
}
row(nodes) {
nodes = nodes.filter(function (x) {
return !SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.EMPTY);
});
if (nodes.length === 0) {
return SemanticProcessor.getInstance().factory_.makeEmptyNode();
}
nodes = SemanticProcessor.getInstance().getFencesInRow_(nodes);
nodes = SemanticProcessor.getInstance().tablesInRow(nodes);
nodes = SemanticProcessor.getInstance().getPunctuationInRow_(nodes);
nodes = SemanticProcessor.getInstance().getTextInRow_(nodes);
nodes = SemanticProcessor.getInstance().getFunctionsInRow_(nodes);
return SemanticProcessor.getInstance().relationsInRow_(nodes);
}
limitNode(mmlTag, children) {
if (!children.length) {
return SemanticProcessor.getInstance().factory_.makeEmptyNode();
}
let center = children[0];
let type = semantic_meaning_js_1.SemanticType.UNKNOWN;
if (!children[1]) {
return center;
}
let result;
semantic_heuristic_factory_js_1.SemanticHeuristics.run('op_with_limits', children);
if (SemanticPred.isLimitBase(center)) {
result = SemanticProcessor.MML_TO_LIMIT_[mmlTag];
const length = result.length;
type = result.type;
children = children.slice(0, result.length + 1);
if ((length === 1 && SemanticPred.isAccent(children[1])) ||
(length === 2 &&
SemanticPred.isAccent(children[1]) &&
SemanticPred.isAccent(children[2]))) {
result = SemanticProcessor.MML_TO_BOUNDS_[mmlTag];
return SemanticProcessor.getInstance().accentNode_(center, children, result.type, result.length, result.accent);
}
if (length === 2) {
if (SemanticPred.isAccent(children[1])) {
center = SemanticProcessor.getInstance().accentNode_(center, [center, children[1]], {
MSUBSUP: semantic_meaning_js_1.SemanticType.SUBSCRIPT,
MUNDEROVER: semantic_meaning_js_1.SemanticType.UNDERSCORE
}[mmlTag], 1, true);
return !children[2]
? center
: SemanticProcessor.getInstance().makeLimitNode_(center, [center, children[2]], null, semantic_meaning_js_1.SemanticType.LIMUPPER);
}
if (children[2] && SemanticPred.isAccent(children[2])) {
center = SemanticProcessor.getInstance().accentNode_(center, [center, children[2]], {
MSUBSUP: semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
MUNDEROVER: semantic_meaning_js_1.SemanticType.OVERSCORE
}[mmlTag], 1, true);
return SemanticProcessor.getInstance().makeLimitNode_(center, [center, children[1]], null, semantic_meaning_js_1.SemanticType.LIMLOWER);
}
if (!children[length]) {
type = semantic_meaning_js_1.SemanticType.LIMLOWER;
}
}
return SemanticProcessor.getInstance().makeLimitNode_(center, children, null, type);
}
result = SemanticProcessor.MML_TO_BOUNDS_[mmlTag];
return SemanticProcessor.getInstance().accentNode_(center, children, result.type, result.length, result.accent);
}
tablesInRow(nodes) {
let partition = SemanticUtil.partitionNodes(nodes, SemanticPred.tableIsMatrixOrVector);
let result = [];
for (let i = 0, matrix; (matrix = partition.rel[i]); i++) {
result = result.concat(partition.comp.shift());
result.push(SemanticProcessor.tableToMatrixOrVector_(matrix));
}
result = result.concat(partition.comp.shift());
partition = SemanticUtil.partitionNodes(result, SemanticPred.isTableOrMultiline);
result = [];
for (let i = 0, table; (table = partition.rel[i]); i++) {
const prevNodes = partition.comp.shift();
if (SemanticPred.tableIsCases(table, prevNodes)) {
SemanticProcessor.tableToCases_(table, prevNodes.pop());
}
result = result.concat(prevNodes);
result.push(table);
}
return result.concat(partition.comp.shift());
}
mfenced(open, close, sepValue, children) {
if (sepValue && children.length > 0) {
const separators = SemanticProcessor.nextSeparatorFunction_(sepValue);
const newChildren = [children.shift()];
children.forEach((child) => {
newChildren.push(SemanticProcessor.getInstance().factory_.makeContentNode(separators()));
newChildren.push(child);
});
children = newChildren;
}
if (open && close) {
return SemanticProcessor.getInstance().horizontalFencedNode_(SemanticProcessor.getInstance().factory_.makeContentNode(open), SemanticProcessor.getInstance().factory_.makeContentNode(close), children);
}
if (open) {
children.unshift(SemanticProcessor.getInstance().factory_.makeContentNode(open));
}
if (close) {
children.push(SemanticProcessor.getInstance().factory_.makeContentNode(close));
}
return SemanticProcessor.getInstance().row(children);
}
fractionLikeNode(denom, enume, linethickness, bevelled) {
let node;
if (!bevelled && SemanticUtil.isZeroLength(linethickness)) {
const child0 = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.LINE, [denom], []);
const child1 = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.LINE, [enume], []);
node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.MULTILINE, [child0, child1], []);
SemanticProcessor.binomialForm_(node);
SemanticProcessor.classifyMultiline(node);
return node;
}
else {
node = SemanticProcessor.getInstance().fractionNode_(denom, enume);
if (bevelled) {
node.addAnnotation('general', 'bevelled');
}
return node;
}
}
tensor(base, lsub, lsup, rsub, rsup) {
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.TENSOR, [
base,
SemanticProcessor.getInstance().scriptNode_(lsub, semantic_meaning_js_1.SemanticRole.LEFTSUB),
SemanticProcessor.getInstance().scriptNode_(lsup, semantic_meaning_js_1.SemanticRole.LEFTSUPER),
SemanticProcessor.getInstance().scriptNode_(rsub, semantic_meaning_js_1.SemanticRole.RIGHTSUB),
SemanticProcessor.getInstance().scriptNode_(rsup, semantic_meaning_js_1.SemanticRole.RIGHTSUPER)
], []);
newNode.role = base.role;
newNode.embellished = SemanticPred.isEmbellished(base);
return newNode;
}
pseudoTensor(base, sub, sup) {
const isEmpty = (x) => !SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.EMPTY);
const nonEmptySub = sub.filter(isEmpty).length;
const nonEmptySup = sup.filter(isEmpty).length;
if (!nonEmptySub && !nonEmptySup) {
return base;
}
const mmlTag = nonEmptySub
? nonEmptySup
? semantic_util_js_1.MMLTAGS.MSUBSUP
: semantic_util_js_1.MMLTAGS.MSUB
: semantic_util_js_1.MMLTAGS.MSUP;
const mmlchild = [base];
if (nonEmptySub) {
mmlchild.push(SemanticProcessor.getInstance().scriptNode_(sub, semantic_meaning_js_1.SemanticRole.RIGHTSUB, true));
}
if (nonEmptySup) {
mmlchild.push(SemanticProcessor.getInstance().scriptNode_(sup, semantic_meaning_js_1.SemanticRole.RIGHTSUPER, true));
}
return SemanticProcessor.getInstance().limitNode(mmlTag, mmlchild);
}
font(font) {
const mathjaxFont = SemanticProcessor.MATHJAX_FONTS[font];
return mathjaxFont ? mathjaxFont : font;
}
proof(node, semantics, parse) {
if (!semantics['inference'] && !semantics['axiom']) {
console.log('Noise');
}
if (semantics['axiom']) {
const cleaned = SemanticProcessor.getInstance().cleanInference(node.childNodes);
const axiom = cleaned.length
? SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, parse(cleaned), [])
: SemanticProcessor.getInstance().factory_.makeEmptyNode();
axiom.role = semantic_meaning_js_1.SemanticRole.AXIOM;
axiom.mathmlTree = node;
return axiom;
}
const inference = SemanticProcessor.getInstance().inference(node, semantics, parse);
if (semantics['proof']) {
inference.role = semantic_meaning_js_1.SemanticRole.PROOF;
inference.childNodes[0].role = semantic_meaning_js_1.SemanticRole.FINAL;
}
return inference;
}
inference(node, semantics, parse) {
if (semantics['inferenceRule']) {
const formulas = SemanticProcessor.getInstance().getFormulas(node, [], parse);
const inference = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, [formulas.conclusion, formulas.premises], []);
return inference;
}
const label = semantics['labelledRule'];
const children = DomUtil.toArray(node.childNodes);
const content = [];
if (label === 'left' || label === 'both') {
content.push(SemanticProcessor.getInstance().getLabel(node, children, parse, semantic_meaning_js_1.SemanticRole.LEFT));
}
if (label === 'right' || label === 'both') {
content.push(SemanticProcessor.getInstance().getLabel(node, children, parse, semantic_meaning_js_1.SemanticRole.RIGHT));
}
const formulas = SemanticProcessor.getInstance().getFormulas(node, children, parse);
const inference = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, [formulas.conclusion, formulas.premises], content);
inference.mathmlTree = node;
return inference;
}
getLabel(_node, children, parse, side) {
const label = SemanticProcessor.getInstance().findNestedRow(children, 'prooflabel', side);
const sem = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.RULELABEL, parse(DomUtil.toArray(label.childNodes)), []);
sem.role = side;
sem.mathmlTree = label;
return sem;
}
getFormulas(node, children, parse) {
const inf = children.length
? SemanticProcessor.getInstance().findNestedRow(children, 'inferenceRule')
: node;
const up = SemanticProcessor.getSemantics(inf)['inferenceRule'] === 'up';
const premRow = up ? inf.childNodes[1] : inf.childNodes[0];
const concRow = up ? inf.childNodes[0] : inf.childNodes[1];
const premTable = premRow.childNodes[0].childNodes[0];
const topRow = DomUtil.toArray(premTable.childNodes[0].childNodes);
const premNodes = [];
let i = 1;
for (const cell of topRow) {
if (i % 2) {
premNodes.push(cell.childNodes[0]);
}
i++;
}
const premises = parse(premNodes);
const conclusion = parse(DomUtil.toArray(concRow.childNodes[0].childNodes))[0];
const prem = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.PREMISES, premises, []);
prem.mathmlTree = premTable;
const conc = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.CONCLUSION, [conclusion], []);
conc.mathmlTree = concRow.childNodes[0].childNodes[0];
return { conclusion: conc, premises: prem };
}
findNestedRow(nodes, semantic, opt_value) {
return SemanticProcessor.getInstance().findNestedRow_(nodes, semantic, 0, opt_value);
}
cleanInference(nodes) {
return DomUtil.toArray(nodes).filter(function (x) {
return DomUtil.tagName(x) !== 'MSPACE';
});
}
operatorNode(node) {
if (node.type === semantic_meaning_js_1.SemanticType.UNKNOWN) {
node.type = semantic_meaning_js_1.SemanticType.OPERATOR;
}
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('multioperator', node);
}
constructor() {
this.funcAppls = {};
this.splitRoles = new Map([
[semantic_meaning_js_1.SemanticRole.SUBTRACTION, semantic_meaning_js_1.SemanticRole.NEGATIVE],
[semantic_meaning_js_1.SemanticRole.ADDITION, semantic_meaning_js_1.SemanticRole.POSITIVE]
]);
this.splitOps = ['', '-', '', '', '+'];
this.factory_ = new semantic_node_factory_js_1.SemanticNodeFactory();
semantic_heuristic_factory_js_1.SemanticHeuristics.updateFactory(this.factory_);
}
implicitNode_(nodes) {
const operators = SemanticProcessor.getInstance().factory_.makeMultipleContentNodes(nodes.length - 1, semantic_attr_js_1.NamedSymbol.invisibleTimes);
SemanticProcessor.matchSpaces_(nodes, operators);
const newNode = SemanticProcessor.getInstance().infixNode_(nodes, operators[0]);
newNode.role = semantic_meaning_js_1.SemanticRole.IMPLICIT;
operators.forEach(function (op) {
op.parent = newNode;
});
newNode.contentNodes = operators;
return newNode;
}
infixNode_(children, opNode) {
const node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFIXOP, children, [opNode], SemanticUtil.getEmbellishedInner(opNode).textContent);
node.role = opNode.role;
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateSimpleFunction', node);
}
explicitMixed_(nodes) {
const partition = SemanticUtil.partitionNodes(nodes, function (x) {
return x.textContent === semantic_attr_js_1.NamedSymbol.invisiblePlus;
});
if (!partition.rel.length) {
return nodes;
}
let result = [];
for (let i = 0, rel; (rel = partition.rel[i]); i++) {
const prev = partition.comp[i];
const next = partition.comp[i + 1];
const last = prev.length - 1;
if (prev[last] &&
next[0] &&
SemanticPred.isType(prev[last], semantic_meaning_js_1.SemanticType.NUMBER) &&
!SemanticPred.isRole(prev[last], semantic_meaning_js_1.SemanticRole.MIXED) &&
SemanticPred.isType(next[0], semantic_meaning_js_1.SemanticType.FRACTION)) {
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.NUMBER, [prev[last], next[0]], []);
newNode.role = semantic_meaning_js_1.SemanticRole.MIXED;
result = result.concat(prev.slice(0, last));
result.push(newNode);
next.shift();
}
else {
result = result.concat(prev);
result.push(rel);
}
}
return result.concat(partition.comp[partition.comp.length - 1]);
}
concatNode_(inner, nodeList, type) {
if (nodeList.length === 0) {
return inner;
}
const content = nodeList
.map(function (x) {
return SemanticUtil.getEmbellishedInner(x).textContent;
})
.join(' ');
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, [inner], nodeList, content);
if (nodeList.length > 1) {
newNode.role = semantic_meaning_js_1.SemanticRole.MULTIOP;
}
return newNode;
}
prefixNode_(node, prefixes) {
const newPrefixes = this.splitSingles(prefixes);
let newNode = node;
while (newPrefixes.length > 0) {
const op = newPrefixes.pop();
newNode = SemanticProcessor.getInstance().concatNode_(newNode, op, semantic_meaning_js_1.SemanticType.PREFIXOP);
if (op.length === 1 && this.splitOps.indexOf(op[0].textContent) !== -1) {
newNode.role = this.splitRoles.get(op[0].role);
}
}
return newNode;
}
splitSingles(prefixes) {
let lastOp = 0;
const result = [];
let i = 0;
while (i < prefixes.length) {
const op = prefixes[i];
if (this.splitRoles.has(op.role) &&
(!prefixes[i - 1] || prefixes[i - 1].role !== op.role) &&
(!prefixes[i + 1] || prefixes[i + 1].role !== op.role) &&
this.splitOps.indexOf(op.textContent) !== -1) {
result.push(prefixes.slice(lastOp, i));
result.push(prefixes.slice(i, i + 1));
lastOp = i + 1;
}
i++;
}
if (lastOp < i) {
result.push(prefixes.slice(lastOp, i));
}
return result;
}
postfixNode_(node, postfixes) {
if (!postfixes.length) {
return node;
}
return SemanticProcessor.getInstance().concatNode_(node, postfixes, semantic_meaning_js_1.SemanticType.POSTFIXOP);
}
combineUnits_(nodes) {
const partition = SemanticUtil.partitionNodes(nodes, function (x) {
return !SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.UNIT);
});
if (nodes.length === partition.rel.length) {
return partition.rel;
}
const result = [];
let rel;
let last;
do {
const comp = partition.comp.shift();
rel = partition.rel.shift();
let unitNode = null;
last = result.pop();
if (last) {
if (!comp.length || !SemanticPred.isUnitCounter(last)) {
result.push(last);
}
else {
comp.unshift(last);
}
}
if (comp.length === 1) {
unitNode = comp.pop();
}
if (comp.length > 1) {
unitNode = SemanticProcessor.getInstance().implicitNode_(comp);
unitNode.role = semantic_meaning_js_1.SemanticRole.UNIT;
}
if (unitNode) {
result.push(unitNode);
}
if (rel) {
result.push(rel);
}
} while (rel);
return result;
}
getMixedNumbers_(nodes) {
const partition = SemanticUtil.partitionNodes(nodes, function (x) {
return (SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.FRACTION) &&
SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.VULGAR));
});
if (!partition.rel.length) {
return nodes;
}
let result = [];
for (let i = 0, rel; (rel = partition.rel[i]); i++) {
const comp = partition.comp[i];
const last = comp.length - 1;
if (comp[last] &&
SemanticPred.isType(comp[last], semantic_meaning_js_1.SemanticType.NUMBER) &&
(SemanticPred.isRole(comp[last], semantic_meaning_js_1.SemanticRole.INTEGER) ||
SemanticPred.isRole(comp[last], semantic_meaning_js_1.SemanticRole.FLOAT))) {
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.NUMBER, [comp[last], rel], []);
newNode.role = semantic_meaning_js_1.SemanticRole.MIXED;
result = result.concat(comp.slice(0, last));
result.push(newNode);
}
else {
result = result.concat(comp);
result.push(rel);
}
}
return result.concat(partition.comp[partition.comp.length - 1]);
}
getTextInRow_(nodes) {
if (nodes.length === 0) {
return nodes;
}
if (nodes.length === 1) {
if (nodes[0].type === semantic_meaning_js_1.SemanticType.TEXT &&
nodes[0].role === semantic_meaning_js_1.SemanticRole.UNKNOWN) {
nodes[0].role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
}
return nodes;
}
const { rel: rel, comp: comp } = SemanticUtil.partitionNodes(nodes, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.TEXT));
if (rel.length === 0) {
return nodes;
}
const result = [];
let prevComp = comp.shift();
while (rel.length > 0) {
let currentRel = rel.shift();
let nextComp = comp.shift();
const text = [];
while (!nextComp.length &&
rel.length &&
currentRel.role !== semantic_meaning_js_1.SemanticRole.SPACE &&
rel[0].role !== semantic_meaning_js_1.SemanticRole.SPACE) {
text.push(currentRel);
currentRel = rel.shift();
nextComp = comp.shift();
}
if (text.length) {
if (prevComp.length) {
result.push(SemanticProcessor.getInstance().row(prevComp));
}
text.push(currentRel);
const dummy = SemanticProcessor.getInstance().dummyNode_(text);
result.push(dummy);
prevComp = nextComp;
continue;
}
if (currentRel.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
if (prevComp.length) {
result.push(SemanticProcessor.getInstance().row(prevComp));
}
result.push(currentRel);
prevComp = nextComp;
continue;
}
const meaning = semantic_attr_js_1.SemanticMap.Meaning.get(currentRel.textContent);
if (meaning.type === semantic_meaning_js_1.SemanticType.PUNCTUATION) {
currentRel.role = meaning.role;
currentRel.font = meaning.font;
if (prevComp.length) {
result.push(SemanticProcessor.getInstance().row(prevComp));
}
result.push(currentRel);
prevComp = nextComp;
continue;
}
if (meaning.type !== semantic_meaning_js_1.SemanticType.UNKNOWN) {
currentRel.type = meaning.type;
currentRel.role = meaning.role;
currentRel.font = meaning.font;
currentRel.addAnnotation('general', 'text');
prevComp.push(currentRel);
prevComp = prevComp.concat(nextComp);
continue;
}
SemanticProcessor.meaningFromContent(currentRel, (n, c, m) => {
if (n.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
return;
}
SemanticProcessor.numberRole_(n, c, m);
if (n.role !== semantic_meaning_js_1.SemanticRole.OTHERNUMBER) {
n.type = semantic_meaning_js_1.SemanticType.NUMBER;
return;
}
if (m.some((x) => x.type !== semantic_meaning_js_1.SemanticType.NUMBER &&
x.type !== semantic_meaning_js_1.SemanticType.IDENTIFIER)) {
n.type = semantic_meaning_js_1.SemanticType.TEXT;
n.role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
return;
}
n.role = semantic_meaning_js_1.SemanticRole.UNKNOWN;
});
if (currentRel.type === semantic_meaning_js_1.SemanticType.TEXT &&
currentRel.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
if (prevComp.length) {
result.push(SemanticProcessor.getInstance().row(prevComp));
}
result.push(currentRel);
prevComp = nextComp;
continue;
}
if (currentRel.role === semantic_meaning_js_1.SemanticRole.UNKNOWN) {
if (rel.length || nextComp.length) {
if (nextComp.length && nextComp[0].type === semantic_meaning_js_1.SemanticType.FENCED) {
currentRel.type = semantic_meaning_js_1.SemanticType.FUNCTION;
currentRel.role = semantic_meaning_js_1.SemanticRole.PREFIXFUNC;
}
else {
currentRel.role = semantic_meaning_js_1.SemanticRole.TEXT;
}
}
else {
currentRel.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
currentRel.role = semantic_meaning_js_1.SemanticRole.UNIT;
}
}
prevComp.push(currentRel);
prevComp = prevComp.concat(nextComp);
}
if (prevComp.length > 0) {
result.push(SemanticProcessor.getInstance().row(prevComp));
}
return result.length > 1
? [SemanticProcessor.getInstance().dummyNode_(result)]
: result;
}
relationsInRow_(nodes) {
const partition = SemanticUtil.partitionNodes(nodes, SemanticPred.isRelation);
const firstRel = partition.rel[0];
if (!firstRel) {
return SemanticProcessor.getInstance().operationsInRow_(nodes);
}
if (nodes.length === 1) {
return nodes[0];
}
const children = partition.comp.map(SemanticProcessor.getInstance().operationsInRow_);
let node;
if (partition.rel.some(function (x) {
return !x.equals(firstRel);
})) {
node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.MULTIREL, children, partition.rel);
if (partition.rel.every(function (x) {
return x.role === firstRel.role;
})) {
node.role = firstRel.role;
}
return node;
}
node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.RELSEQ, children, partition.rel, SemanticUtil.getEmbellishedInner(firstRel).textContent);
node.role = firstRel.role;
return node;
}
operationsInRow_(nodes) {
if (nodes.length === 0) {
return SemanticProcessor.getInstance().factory_.makeEmptyNode();
}
nodes = SemanticProcessor.getInstance().explicitMixed_(nodes);
if (nodes.length === 1) {
return nodes[0];
}
const prefix = [];
while (nodes.length > 0 && SemanticPred.isOperator(nodes[0])) {
prefix.push(nodes.shift());
}
if (nodes.length === 0) {
return SemanticProcessor.getInstance().prefixNode_(prefix.pop(), prefix);
}
if (nodes.length === 1) {
return SemanticProcessor.getInstance().prefixNode_(nodes[0], prefix);
}
nodes = semantic_heuristic_factory_js_1.SemanticHeuristics.run('convert_juxtaposition', nodes);
const split = SemanticUtil.sliceNodes(nodes, SemanticPred.isOperator);
const node = SemanticProcessor.getInstance().wrapFactor(prefix, split);
return SemanticProcessor.getInstance().addFactor(node, split);
}
wrapPostfix(split) {
var _a;
if (((_a = split.div) === null || _a === void 0 ? void 0 : _a.role) === semantic_meaning_js_1.SemanticRole.POSTFIXOP) {
if (!split.tail.length || split.tail[0].type === semantic_meaning_js_1.SemanticType.OPERATOR) {
split.head = [
SemanticProcessor.getInstance().postfixNode_(SemanticProcessor.getInstance().implicitNode(split.head), [split.div])
];
split.div = split.tail.shift();
SemanticProcessor.getInstance().wrapPostfix(split);
}
else {
split.div.role = semantic_meaning_js_1.SemanticRole.DIVISION;
}
}
}
wrapFactor(prefix, split) {
SemanticProcessor.getInstance().wrapPostfix(split);
return SemanticProcessor.getInstance().prefixNode_(SemanticProcessor.getInstance().implicitNode(split.head), prefix);
}
addFactor(node, split) {
if (!split.div) {
if (SemanticPred.isUnitProduct(node)) {
node.role = semantic_meaning_js_1.SemanticRole.UNIT;
}
return node;
}
return SemanticProcessor.getInstance().operationsTree_(split.tail, node, split.div);
}
operationsTree_(nodes, root, lastop, prefix = []) {
if (nodes.length === 0) {
prefix.unshift(lastop);
if (root.type === semantic_meaning_js_1.SemanticType.INFIXOP) {
const node = SemanticProcessor.getInstance().postfixNode_(root.childNodes.pop(), prefix);
root.appendChild(node);
return root;
}
return SemanticProcessor.getInstance().postfixNode_(root, prefix);
}
const split = SemanticUtil.sliceNodes(nodes, SemanticPred.isOperator);
if (split.head.length === 0) {
prefix.push(split.div);
return SemanticProcessor.getInstance().operationsTree_(split.tail, root, lastop, prefix);
}
const node = SemanticProcessor.getInstance().wrapFactor(prefix, split);
const newNode = SemanticProcessor.getInstance().appendOperand_(root, lastop, node);
return SemanticProcessor.getInstance().addFactor(newNode, split);
}
appendOperand_(root, op, node) {
if (root.type !== semantic_meaning_js_1.SemanticType.INFIXOP) {
return SemanticProcessor.getInstance().infixNode_([root, node], op);
}
const division = SemanticProcessor.getInstance().appendDivisionOp_(root, op, node);
if (division) {
return division;
}
if (SemanticProcessor.getInstance().appendExistingOperator_(root, op, node)) {
return root;
}
return op.role === semantic_meaning_js_1.SemanticRole.MULTIPLICATION
? SemanticProcessor.getInstance().appendMultiplicativeOp_(root, op, node)
: SemanticProcessor.getInstance().appendAdditiveOp_(root, op, node);
}
appendDivisionOp_(root, op, node) {
if (op.role === semantic_meaning_js_1.SemanticRole.DIVISION) {
if (SemanticPred.isImplicit(root)) {
return SemanticProcessor.getInstance().infixNode_([root, node], op);
}
return SemanticProcessor.getInstance().appendLastOperand_(root, op, node);
}
return root.role === semantic_meaning_js_1.SemanticRole.DIVISION
? SemanticProcessor.getInstance().infixNode_([root, node], op)
: null;
}
appendLastOperand_(root, op, node) {
let lastRoot = root;
let lastChild = root.childNodes[root.childNodes.length - 1];
while (lastChild &&
lastChild.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
!SemanticPred.isImplicit(lastChild)) {
lastRoot = lastChild;
lastChild = lastRoot.childNodes[root.childNodes.length - 1];
}
const newNode = SemanticProcessor.getInstance().infixNode_([lastRoot.childNodes.pop(), node], op);
lastRoot.appendChild(newNode);
return root;
}
appendMultiplicativeOp_(root, op, node) {
if (SemanticPred.isImplicit(root)) {
return SemanticProcessor.getInstance().infixNode_([root, node], op);
}
let lastRoot = root;
let lastChild = root.childNodes[root.childNodes.length - 1];
while (lastChild &&
lastChild.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
!SemanticPred.isImplicit(lastChild)) {
lastRoot = lastChild;
lastChild = lastRoot.childNodes[root.childNodes.length - 1];
}
const newNode = SemanticProcessor.getInstance().infixNode_([lastRoot.childNodes.pop(), node], op);
lastRoot.appendChild(newNode);
return root;
}
appendAdditiveOp_(root, op, node) {
return SemanticProcessor.getInstance().infixNode_([root, node], op);
}
appendExistingOperator_(root, op, node) {
if (!root ||
root.type !== semantic_meaning_js_1.SemanticType.INFIXOP ||
SemanticPred.isImplicit(root)) {
return false;
}
if (root.contentNodes[0].equals(op)) {
root.appendContentNode(op);
root.appendChild(node);
return true;
}
return SemanticProcessor.getInstance().appendExistingOperator_(root.childNodes[root.childNodes.length - 1], op, node);
}
getFencesInRow_(nodes) {
let partition = SemanticUtil.partitionNodes(nodes, SemanticPred.isFence);
partition = SemanticProcessor.purgeFences_(partition);
const felem = partition.comp.shift();
return SemanticProcessor.getInstance().fences_(partition.rel, partition.comp, [], [felem]);
}
fences_(fences, content, openStack, contentStack) {
if (fences.length === 0 && openStack.length === 0) {
return contentStack[0];
}
const interval = semantic_heuristic_factory_js_1.SemanticHeuristics.run('bracketed_interval', [fences[0], fences[1], ...(content[0] || [])], () => null);
if (interval) {
fences.shift();
fences.shift();
content.shift();
const stack = contentStack.pop() || [];
contentStack.push([...stack, interval, ...content.shift()]);
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
const openPred = (x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.OPEN);
if (fences.length === 0) {
const result = contentStack.shift();
while (openStack.length > 0) {
if (openPred(openStack[0])) {
const firstOpen = openStack.shift();
SemanticProcessor.fenceToPunct_(firstOpen);
result.push(firstOpen);
}
else {
const split = SemanticUtil.sliceNodes(openStack, openPred);
const cutLength = split.head.length - 1;
const innerNodes = SemanticProcessor.getInstance().neutralFences_(split.head, contentStack.slice(0, cutLength));
contentStack = contentStack.slice(cutLength);
result.push(...innerNodes);
if (split.div) {
split.tail.unshift(split.div);
}
openStack = split.tail;
}
result.push(...contentStack.shift());
}
return result;
}
const lastOpen = openStack[openStack.length - 1];
const firstRole = fences[0].role;
if (firstRole === semantic_meaning_js_1.SemanticRole.OPEN ||
(SemanticPred.isNeutralFence(fences[0]) &&
!(lastOpen && SemanticPred.compareNeutralFences(fences[0], lastOpen)))) {
openStack.push(fences.shift());
const cont = content.shift();
if (cont) {
contentStack.push(cont);
}
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
if (lastOpen &&
firstRole === semantic_meaning_js_1.SemanticRole.CLOSE &&
lastOpen.role === semantic_meaning_js_1.SemanticRole.OPEN) {
const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(openStack.pop(), fences.shift(), contentStack.pop());
contentStack.push(contentStack.pop().concat([fenced], content.shift()));
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
if (lastOpen &&
SemanticPred.compareNeutralFences(fences[0], lastOpen)) {
if (!SemanticPred.elligibleLeftNeutral(lastOpen) ||
!SemanticPred.elligibleRightNeutral(fences[0])) {
openStack.push(fences.shift());
const cont = content.shift();
if (cont) {
contentStack.push(cont);
}
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(openStack.pop(), fences.shift(), contentStack.pop());
contentStack.push(contentStack.pop().concat([fenced], content.shift()));
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
if (lastOpen &&
firstRole === semantic_meaning_js_1.SemanticRole.CLOSE &&
SemanticPred.isNeutralFence(lastOpen) &&
openStack.some(openPred)) {
const split = SemanticUtil.sliceNodes(openStack, openPred, true);
const rightContent = contentStack.pop();
const cutLength = contentStack.length - split.tail.length + 1;
const innerNodes = SemanticProcessor.getInstance().neutralFences_(split.tail, contentStack.slice(cutLength));
contentStack = contentStack.slice(0, cutLength);
const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(split.div, fences.shift(), contentStack.pop().concat(innerNodes, rightContent));
contentStack.push(contentStack.pop().concat([fenced], content.shift()));
return SemanticProcessor.getInstance().fences_(fences, content, split.head, contentStack);
}
const fenced = fences.shift();
SemanticProcessor.fenceToPunct_(fenced);
contentStack.push(contentStack.pop().concat([fenced], content.shift()));
return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
}
neutralFences_(fences, content) {
if (fences.length === 0) {
return fences;
}
if (fences.length === 1) {
SemanticProcessor.fenceToPunct_(fences[0]);
return fences;
}
const firstFence = fences.shift();
if (!SemanticPred.elligibleLeftNeutral(firstFence)) {
SemanticProcessor.fenceToPunct_(firstFence);
const restContent = content.shift();
restContent.unshift(firstFence);
return restContent.concat(SemanticProcessor.getInstance().neutralFences_(fences, content));
}
const split = SemanticUtil.sliceNodes(fences, function (x) {
return SemanticPred.compareNeutralFences(x, firstFence);
});
if (!split.div) {
SemanticProcessor.fenceToPunct_(firstFence);
const restContent = content.shift();
restContent.unshift(firstFence);
return restContent.concat(SemanticProcessor.getInstance().neutralFences_(fences, content));
}
if (!SemanticPred.elligibleRightNeutral(split.div)) {
SemanticProcessor.fenceToPunct_(split.div);
fences.unshift(firstFence);
return SemanticProcessor.getInstance().neutralFences_(fences, content);
}
const newContent = SemanticProcessor.getInstance().combineFencedContent_(firstFence, split.div, split.head, content);
if (split.tail.length > 0) {
const leftContent = newContent.shift();
const result = SemanticProcessor.getInstance().neutralFences_(split.tail, newContent);
return leftContent.concat(result);
}
return newContent[0];
}
combineFencedContent_(leftFence, rightFence, midFences, content) {
if (midFences.length === 0) {
const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(leftFence, rightFence, content.shift());
if (content.length > 0) {
content[0].unshift(fenced);
}
else {
content = [[fenced]];
}
return content;
}
const leftContent = content.shift();
const cutLength = midFences.length - 1;
const midContent = content.slice(0, cutLength);
content = content.slice(cutLength);
const rightContent = content.shift();
const innerNodes = SemanticProcessor.getInstance().neutralFences_(midFences, midContent);
leftContent.push(...innerNodes);
leftContent.push(...rightContent);
const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(leftFence, rightFence, leftContent);
if (content.length > 0) {
content[0].unshift(fenced);
}
else {
content = [[fenced]];
}
return content;
}
horizontalFencedNode_(ofence, cfence, content) {
const childNode = SemanticProcessor.getInstance().row(content);
let newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.FENCED, [childNode], [ofence, cfence]);
if (ofence.role === semantic_meaning_js_1.SemanticRole.OPEN) {
SemanticProcessor.getInstance().classifyHorizontalFence_(newNode);
newNode = semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateComposedFunction', newNode);
}
else {
newNode.role = ofence.role;
}
newNode = semantic_heuristic_factory_js_1.SemanticHeuristics.run('detect_cycle', newNode);
return SemanticProcessor.rewriteFencedNode_(newNode);
}
classifyHorizontalFence_(node) {
node.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
const children = node.childNodes;
if (!SemanticPred.isSetNode(node) || children.length > 1) {
return;
}
if (children.length === 0 || children[0].type === semantic_meaning_js_1.SemanticType.EMPTY) {
node.role = semantic_meaning_js_1.SemanticRole.SETEMPTY;
return;
}
const type = children[0].type;
if (children.length === 1 &&
SemanticPred.isSingletonSetContent(children[0])) {
node.role = semantic_meaning_js_1.SemanticRole.SETSINGLE;
return;
}
const role = children[0].role;
if (type !== semantic_meaning_js_1.SemanticType.PUNCTUATED || role !== semantic_meaning_js_1.SemanticRole.SEQUENCE) {
return;
}
if (children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.COMMA) {
node.role = semantic_meaning_js_1.SemanticRole.SETCOLLECT;
return;
}
if (children[0].contentNodes.length === 1 &&
(children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.VBAR ||
children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.COLON)) {
node.role = semantic_meaning_js_1.SemanticRole.SETEXT;
SemanticProcessor.getInstance().setExtension_(node);
return;
}
}
setExtension_(set) {
const extender = set.childNodes[0].childNodes[0];
if (extender &&
extender.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
extender.contentNodes.length === 1 &&
SemanticPred.isMembership(extender.contentNodes[0])) {
extender.addAnnotation('set', 'intensional');
extender.contentNodes[0].addAnnotation('set', 'intensional');
}
}
getPunctuationInRow_(nodes) {
if (nodes.length <= 1) {
return nodes;
}
const allowedType = (x) => {
const type = x.type;
return (type === 'punctuation' ||
type === 'text' ||
type === 'operator' ||
type === 'relation');
};
const partition = SemanticUtil.partitionNodes(nodes, function (x) {
if (!SemanticPred.isPunctuation(x)) {
return false;
}
if (SemanticPred.isPunctuation(x) &&
!SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.ELLIPSIS)) {
return true;
}
const index = nodes.indexOf(x);
if (index === 0) {
if (nodes[1] && allowedType(nodes[1])) {
return false;
}
return true;
}
const prev = nodes[index - 1];
if (index === nodes.length - 1) {
if (allowedType(prev)) {
return false;
}
return true;
}
const next = nodes[index + 1];
if (allowedType(prev) && allowedType(next)) {
return false;
}
return true;
});
if (partition.rel.length === 0) {
return nodes;
}
let newNodes = [];
let firstComp = partition.comp.shift();
if (firstComp.length > 0) {
newNodes.push(SemanticProcessor.getInstance().row(firstComp));
}
let relCounter = 0;
while (partition.comp.length > 0) {
let puncts = [];
const saveCount = relCounter;
do {
puncts.push(partition.rel[relCounter++]);
firstComp = partition.comp.shift();
} while (partition.rel[relCounter] &&
firstComp &&
firstComp.length === 0);
puncts = semantic_heuristic_factory_js_1.SemanticHeuristics.run('ellipses', puncts);
partition.rel.splice(saveCount, relCounter - saveCount, ...puncts);
relCounter = saveCount + puncts.length;
newNodes = newNodes.concat(puncts);
if (firstComp && firstComp.length > 0) {
newNodes.push(SemanticProcessor.getInstance().row(firstComp));
}
}
return newNodes.length === 1 && partition.rel.length === 1
? newNodes
: [
SemanticProcessor.getInstance().punctuatedNode_(newNodes, partition.rel)
];
}
punctuatedNode_(nodes, punctuations) {
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.PUNCTUATED, nodes, punctuations);
if (punctuations.length === nodes.length) {
const firstRole = punctuations[0].role;
if (firstRole !== semantic_meaning_js_1.SemanticRole.UNKNOWN &&
punctuations.every(function (punct) {
return punct.role === firstRole;
})) {
newNode.role = firstRole;
return newNode;
}
}
const fpunct = punctuations[0];
if (SemanticPred.singlePunctAtPosition(nodes, punctuations, 0)) {
newNode.role =
fpunct.childNodes.length && !fpunct.embellished
? fpunct.role
: semantic_meaning_js_1.SemanticRole.STARTPUNCT;
}
else if (SemanticPred.singlePunctAtPosition(nodes, punctuations, nodes.length - 1)) {
newNode.role =
fpunct.childNodes.length && !fpunct.embellished
? fpunct.role
: semantic_meaning_js_1.SemanticRole.ENDPUNCT;
}
else if (punctuations.every((x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.DUMMY))) {
newNode.role = semantic_meaning_js_1.SemanticRole.TEXT;
}
else if (punctuations.every((x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.SPACE))) {
newNode.role = semantic_meaning_js_1.SemanticRole.SPACE;
}
else {
newNode.role = semantic_meaning_js_1.SemanticRole.SEQUENCE;
}
return newNode;
}
dummyNode_(children) {
const commata = SemanticProcessor.getInstance().factory_.makeMultipleContentNodes(children.length - 1, semantic_attr_js_1.NamedSymbol.invisibleComma);
commata.forEach(function (comma) {
comma.role = semantic_meaning_js_1.SemanticRole.DUMMY;
});
return SemanticProcessor.getInstance().punctuatedNode_(children, commata);
}
accentRole_(node, type) {
if (!SemanticPred.isAccent(node)) {
return false;
}
const content = node.textContent;
const role = semantic_attr_js_1.SemanticMap.Secondary.get(content, semantic_meaning_js_1.SemanticSecondary.BAR) ||
semantic_attr_js_1.SemanticMap.Secondary.get(content, semantic_meaning_js_1.SemanticSecondary.TILDE) ||
node.role;
node.role =
type === semantic_meaning_js_1.SemanticType.UNDERSCORE
? semantic_meaning_js_1.SemanticRole.UNDERACCENT
: semantic_meaning_js_1.SemanticRole.OVERACCENT;
node.addAnnotation('accent', role);
return true;
}
accentNode_(center, children, type, length, accent) {
children = children.slice(0, length + 1);
const child1 = children[1];
const child2 = children[2];
let innerNode;
if (!accent && child2) {
innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.SUBSCRIPT, [center, child1], []);
innerNode.role = semantic_meaning_js_1.SemanticRole.SUBSUP;
children = [innerNode, child2];
type = semantic_meaning_js_1.SemanticType.SUPERSCRIPT;
}
if (accent) {
const underAccent = SemanticProcessor.getInstance().accentRole_(child1, type);
if (child2) {
const overAccent = SemanticProcessor.getInstance().accentRole_(child2, semantic_meaning_js_1.SemanticType.OVERSCORE);
if (overAccent && !underAccent) {
innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.OVERSCORE, [center, child2], []);
children = [innerNode, child1];
type = semantic_meaning_js_1.SemanticType.UNDERSCORE;
}
else {
innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.UNDERSCORE, [center, child1], []);
children = [innerNode, child2];
type = semantic_meaning_js_1.SemanticType.OVERSCORE;
}
innerNode.role = semantic_meaning_js_1.SemanticRole.UNDEROVER;
}
}
return SemanticProcessor.getInstance().makeLimitNode_(center, children, innerNode, type);
}
makeLimitNode_(center, children, innerNode, type) {
if (type === semantic_meaning_js_1.SemanticType.LIMUPPER &&
center.type === semantic_meaning_js_1.SemanticType.LIMLOWER) {
center.childNodes.push(children[1]);
children[1].parent = center;
center.type = semantic_meaning_js_1.SemanticType.LIMBOTH;
return center;
}
if (type === semantic_meaning_js_1.SemanticType.LIMLOWER &&
center.type === semantic_meaning_js_1.SemanticType.LIMUPPER) {
center.childNodes.splice(1, -1, children[1]);
children[1].parent = center;
center.type = semantic_meaning_js_1.SemanticType.LIMBOTH;
return center;
}
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, children, []);
const embellished = SemanticPred.isEmbellished(center);
if (innerNode) {
innerNode.embellished = embellished;
}
newNode.embellished = embellished;
newNode.role = center.role;
return newNode;
}
getFunctionsInRow_(restNodes, opt_result) {
const result = opt_result || [];
if (restNodes.length === 0) {
return result;
}
const firstNode = restNodes.shift();
const heuristic = SemanticProcessor.classifyFunction_(firstNode, restNodes);
if (!heuristic) {
result.push(firstNode);
return SemanticProcessor.getInstance().getFunctionsInRow_(restNodes, result);
}
const processedRest = SemanticProcessor.getInstance().getFunctionsInRow_(restNodes, []);
const newRest = SemanticProcessor.getInstance().getFunctionArgs_(firstNode, processedRest, heuristic);
return result.concat(newRest);
}
getFunctionArgs_(func, rest, heuristic) {
let partition, arg, funcNode;
switch (heuristic) {
case 'integral': {
const components = SemanticProcessor.getInstance().getIntegralArgs_(rest);
if (!components.intvar && !components.integrand.length) {
components.rest.unshift(func);
return components.rest;
}
const integrand = SemanticProcessor.getInstance().row(components.integrand);
funcNode = SemanticProcessor.getInstance().integralNode_(func, integrand, components.intvar);
semantic_heuristic_factory_js_1.SemanticHeuristics.run('intvar_from_fraction', funcNode);
components.rest.unshift(funcNode);
return components.rest;
}
case 'prefix': {
if (rest[0] && rest[0].type === semantic_meaning_js_1.SemanticType.FENCED) {
const arg = rest.shift();
if (!SemanticPred.isNeutralFence(arg)) {
arg.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
}
funcNode = SemanticProcessor.getInstance().functionNode_(func, arg);
rest.unshift(funcNode);
return rest;
}
partition = SemanticUtil.sliceNodes(rest, SemanticPred.isPrefixFunctionBoundary);
if (!partition.head.length) {
if (!partition.div ||
!SemanticPred.isType(partition.div, semantic_meaning_js_1.SemanticType.APPL)) {
rest.unshift(func);
return rest;
}
arg = partition.div;
}
else {
arg = SemanticProcessor.getInstance().row(partition.head);
if (partition.div) {
partition.tail.unshift(partition.div);
}
}
funcNode = SemanticProcessor.getInstance().functionNode_(func, arg);
partition.tail.unshift(funcNode);
return partition.tail;
}
case 'bigop': {
partition = SemanticUtil.sliceNodes(rest, SemanticPred.isBigOpBoundary);
if (!partition.head.length) {
rest.unshift(func);
return rest;
}
arg = SemanticProcessor.getInstance().row(partition.head);
funcNode = SemanticProcessor.getInstance().bigOpNode_(func, arg);
if (partition.div) {
partition.tail.unshift(partition.div);
}
partition.tail.unshift(funcNode);
return partition.tail;
}
case 'simple':
default: {
if (rest.length === 0) {
return [func];
}
const firstArg = rest[0];
if (firstArg.type === semantic_meaning_js_1.SemanticType.FENCED &&
!SemanticPred.isNeutralFence(firstArg) &&
SemanticPred.isSimpleFunctionScope(firstArg)) {
firstArg.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
SemanticProcessor.propagateFunctionRole_(func, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC);
funcNode = SemanticProcessor.getInstance().functionNode_(func, rest.shift());
rest.unshift(funcNode);
return rest;
}
rest.unshift(func);
return rest;
}
}
}
getIntegralArgs_(nodes, args = []) {
if (nodes.length === 0) {
const partition = SemanticUtil.sliceNodes(args, SemanticPred.isBigOpBoundary);
if (partition.div) {
partition.tail.unshift(partition.div);
}
return { integrand: partition.head, intvar: null, rest: partition.tail };
}
semantic_heuristic_factory_js_1.SemanticHeuristics.run('intvar_from_implicit', nodes);
const firstNode = nodes[0];
if (SemanticPred.isGeneralFunctionBoundary(firstNode)) {
const { integrand: args2, rest: rest2 } = SemanticProcessor.getInstance().getIntegralArgs_(args);
return { integrand: args2, intvar: null, rest: rest2.concat(nodes) };
}
if (SemanticPred.isIntegralDxBoundarySingle(firstNode)) {
firstNode.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
return { integrand: args, intvar: firstNode, rest: nodes.slice(1) };
}
if (nodes[1] && SemanticPred.isIntegralDxBoundary(firstNode, nodes[1])) {
const intvar = SemanticProcessor.getInstance().prefixNode_(nodes[1], [firstNode]);
intvar.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
return { integrand: args, intvar: intvar, rest: nodes.slice(2) };
}
args.push(nodes.shift());
return SemanticProcessor.getInstance().getIntegralArgs_(nodes, args);
}
functionNode_(func, arg) {
const applNode = SemanticProcessor.getInstance().factory_.makeContentNode(semantic_attr_js_1.NamedSymbol.functionApplication);
const appl = SemanticProcessor.getInstance().funcAppls[func.id];
if (appl) {
applNode.mathmlTree = appl.mathmlTree;
applNode.mathml = appl.mathml;
applNode.annotation = appl.annotation;
applNode.attributes = appl.attributes;
delete SemanticProcessor.getInstance().funcAppls[func.id];
}
applNode.type = semantic_meaning_js_1.SemanticType.PUNCTUATION;
applNode.role = semantic_meaning_js_1.SemanticRole.APPLICATION;
const funcop = SemanticProcessor.getFunctionOp_(func, function (node) {
return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.FUNCTION) ||
(SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.IDENTIFIER) &&
SemanticPred.isRole(node, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC)));
});
return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.APPL, [func, arg], funcop, [applNode]);
}
bigOpNode_(bigOp, arg) {
const largeop = SemanticProcessor.getFunctionOp_(bigOp, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.LARGEOP));
return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.BIGOP, [bigOp, arg], largeop, []);
}
integralNode_(integral, integrand, intvar) {
integrand =
integrand || SemanticProcessor.getInstance().factory_.makeEmptyNode();
intvar = intvar || SemanticProcessor.getInstance().factory_.makeEmptyNode();
const largeop = SemanticProcessor.getFunctionOp_(integral, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.LARGEOP));
return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.INTEGRAL, [integral, integrand, intvar], largeop, []);
}
functionalNode_(type, children, operator, content) {
const funcop = children[0];
let oldParent;
if (operator) {
oldParent = operator.parent;
content.push(operator);
}
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, children, content);
newNode.role = funcop.role;
if (oldParent) {
operator.parent = oldParent;
}
return newNode;
}
fractionNode_(denom, enume) {
const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.FRACTION, [denom, enume], []);
newNode.role = newNode.childNodes.every(function (x) {
return (SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.NUMBER) &&
SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.INTEGER));
})
? semantic_meaning_js_1.SemanticRole.VULGAR
: newNode.childNodes.every(SemanticPred.isPureUnit)
? semantic_meaning_js_1.SemanticRole.UNIT
: semantic_meaning_js_1.SemanticRole.DIVISION;
return semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateSimpleFunction', newNode);
}
scriptNode_(nodes, role, opt_noSingle) {
let newNode;
switch (nodes.length) {
case 0:
newNode = SemanticProcessor.getInstance().factory_.makeEmptyNode();
break;
case 1:
newNode = nodes[0];
if (opt_noSingle) {
return newNode;
}
break;
default:
newNode = SemanticProcessor.getInstance().dummyNode_(nodes);
}
newNode.role = role;
return newNode;
}
findNestedRow_(nodes, semantic, level, value) {
if (level > 3) {
return null;
}
for (let i = 0, node; (node = nodes[i]); i++) {
const tag = DomUtil.tagName(node);
if (tag !== semantic_util_js_1.MMLTAGS.MSPACE) {
if (tag === semantic_util_js_1.MMLTAGS.MROW) {
return SemanticProcessor.getInstance().findNestedRow_(DomUtil.toArray(node.childNodes), semantic, level + 1, value);
}
if (SemanticProcessor.findSemantics(node, semantic, value)) {
return node;
}
}
}
return null;
}
}
exports.SemanticProcessor = SemanticProcessor;
SemanticProcessor.FENCE_TO_PUNCT_ = {
[semantic_meaning_js_1.SemanticRole.METRIC]: semantic_meaning_js_1.SemanticRole.METRIC,
[semantic_meaning_js_1.SemanticRole.NEUTRAL]: semantic_meaning_js_1.SemanticRole.VBAR,
[semantic_meaning_js_1.SemanticRole.OPEN]: semantic_meaning_js_1.SemanticRole.OPENFENCE,
[semantic_meaning_js_1.SemanticRole.CLOSE]: semantic_meaning_js_1.SemanticRole.CLOSEFENCE
};
SemanticProcessor.MML_TO_LIMIT_ = {
[semantic_util_js_1.MMLTAGS.MSUB]: { type: semantic_meaning_js_1.SemanticType.LIMLOWER, length: 1 },
[semantic_util_js_1.MMLTAGS.MUNDER]: { type: semantic_meaning_js_1.SemanticType.LIMLOWER, length: 1 },
[semantic_util_js_1.MMLTAGS.MSUP]: { type: semantic_meaning_js_1.SemanticType.LIMUPPER, length: 1 },
[semantic_util_js_1.MMLTAGS.MOVER]: { type: semantic_meaning_js_1.SemanticType.LIMUPPER, length: 1 },
[semantic_util_js_1.MMLTAGS.MSUBSUP]: { type: semantic_meaning_js_1.SemanticType.LIMBOTH, length: 2 },
[semantic_util_js_1.MMLTAGS.MUNDEROVER]: { type: semantic_meaning_js_1.SemanticType.LIMBOTH, length: 2 }
};
SemanticProcessor.MML_TO_BOUNDS_ = {
[semantic_util_js_1.MMLTAGS.MSUB]: { type: semantic_meaning_js_1.SemanticType.SUBSCRIPT, length: 1, accent: false },
[semantic_util_js_1.MMLTAGS.MSUP]: {
type: semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
length: 1,
accent: false
},
[semantic_util_js_1.MMLTAGS.MSUBSUP]: {
type: semantic_meaning_js_1.SemanticType.SUBSCRIPT,
length: 2,
accent: false
},
[semantic_util_js_1.MMLTAGS.MUNDER]: {
type: semantic_meaning_js_1.SemanticType.UNDERSCORE,
length: 1,
accent: true
},
[semantic_util_js_1.MMLTAGS.MOVER]: { type: semantic_meaning_js_1.SemanticType.OVERSCORE, length: 1, accent: true },
[semantic_util_js_1.MMLTAGS.MUNDEROVER]: {
type: semantic_meaning_js_1.SemanticType.UNDERSCORE,
length: 2,
accent: true
}
};
SemanticProcessor.CLASSIFY_FUNCTION_ = {
[semantic_meaning_js_1.SemanticRole.INTEGRAL]: 'integral',
[semantic_meaning_js_1.SemanticRole.SUM]: 'bigop',
[semantic_meaning_js_1.SemanticRole.PREFIXFUNC]: 'prefix',
[semantic_meaning_js_1.SemanticRole.LIMFUNC]: 'prefix',
[semantic_meaning_js_1.SemanticRole.SIMPLEFUNC]: 'prefix',
[semantic_meaning_js_1.SemanticRole.COMPFUNC]: 'prefix'
};
SemanticProcessor.MATHJAX_FONTS = {
'-tex-caligraphic': semantic_meaning_js_1.SemanticFont.CALIGRAPHIC,
'-tex-caligraphic-bold': semantic_meaning_js_1.SemanticFont.CALIGRAPHICBOLD,
'-tex-calligraphic': semantic_meaning_js_1.SemanticFont.CALIGRAPHIC,
'-tex-calligraphic-bold': semantic_meaning_js_1.SemanticFont.CALIGRAPHICBOLD,
'-tex-oldstyle': semantic_meaning_js_1.SemanticFont.OLDSTYLE,
'-tex-oldstyle-bold': semantic_meaning_js_1.SemanticFont.OLDSTYLEBOLD,
'-tex-mathit': semantic_meaning_js_1.SemanticFont.ITALIC
};