1
0

add initial marp implementation with sample content and build configuration

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

View File

@@ -0,0 +1,10 @@
import { SemanticFont, SemanticRole, SemanticType } from './semantic_meaning.js';
import { SemanticTree } from './semantic_tree.js';
export type Font = SemanticFont;
export type Role = SemanticRole;
export type Type = SemanticType;
type Attr = Font | Role | Type;
export { Attr };
export declare function xmlTree(mml: Element): Element;
export declare function getTree(mml: Element): SemanticTree;
export declare function getTreeFromString(expr: string): SemanticTree;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.xmlTree = xmlTree;
exports.getTree = getTree;
exports.getTreeFromString = getTreeFromString;
const DomUtil = require("../common/dom_util.js");
const semantic_tree_js_1 = require("./semantic_tree.js");
function xmlTree(mml) {
return getTree(mml).xml();
}
function getTree(mml) {
return new semantic_tree_js_1.SemanticTree(mml);
}
function getTreeFromString(expr) {
const mml = DomUtil.parseInput(expr);
return getTree(mml);
}

View File

@@ -0,0 +1,8 @@
import { SemanticAnnotator, SemanticVisitor } from './semantic_annotator.js';
import { SemanticNode } from './semantic_node.js';
export declare const annotators: Map<string, SemanticAnnotator>;
export declare const visitors: Map<string, SemanticVisitor>;
export declare function register(annotator: SemanticAnnotator | SemanticVisitor): void;
export declare function activate(domain: string, name: string): void;
export declare function deactivate(domain: string, name: string): void;
export declare function annotate(node: SemanticNode): void;

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitors = exports.annotators = void 0;
exports.register = register;
exports.activate = activate;
exports.deactivate = deactivate;
exports.annotate = annotate;
const semantic_annotator_js_1 = require("./semantic_annotator.js");
exports.annotators = new Map();
exports.visitors = new Map();
function register(annotator) {
const name = annotator.domain + ':' + annotator.name;
annotator instanceof semantic_annotator_js_1.SemanticAnnotator
? exports.annotators.set(name, annotator)
: exports.visitors.set(name, annotator);
}
function activate(domain, name) {
const key = domain + ':' + name;
const annotator = exports.annotators.get(key) || exports.visitors.get(key);
if (annotator) {
annotator.active = true;
}
}
function deactivate(domain, name) {
const key = domain + ':' + name;
const annotator = exports.annotators.get(key) || exports.visitors.get(key);
if (annotator) {
annotator.active = false;
}
}
function annotate(node) {
for (const annotator of exports.annotators.values()) {
if (annotator.active) {
annotator.annotate(node);
}
}
for (const visitor of exports.visitors.values()) {
if (visitor.active) {
visitor.visit(node, Object.assign({}, visitor.def));
}
}
}

View File

@@ -0,0 +1,28 @@
import { SemanticNode } from './semantic_node.js';
export declare class SemanticAnnotator {
domain: string;
name: string;
func: (p1: SemanticNode) => any;
active: boolean;
constructor(domain: string, name: string, func: (p1: SemanticNode) => any);
annotate(node: SemanticNode): void;
}
export declare class SemanticVisitor {
domain: string;
name: string;
func: (p1: SemanticNode, p2: {
[key: string]: any;
}) => any;
def: {
[key: string]: any;
};
active: boolean;
constructor(domain: string, name: string, func: (p1: SemanticNode, p2: {
[key: string]: any;
}) => any, def?: {
[key: string]: any;
});
visit(node: SemanticNode, info: {
[key: string]: any;
}): any;
}

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticVisitor = exports.SemanticAnnotator = void 0;
class SemanticAnnotator {
constructor(domain, name, func) {
this.domain = domain;
this.name = name;
this.func = func;
this.active = false;
}
annotate(node) {
node.childNodes.forEach(this.annotate.bind(this));
node.contentNodes.forEach(this.annotate.bind(this));
node.addAnnotation(this.domain, this.func(node));
}
}
exports.SemanticAnnotator = SemanticAnnotator;
class SemanticVisitor {
constructor(domain, name, func, def = {}) {
this.domain = domain;
this.name = name;
this.func = func;
this.def = def;
this.active = false;
}
visit(node, info) {
let result = this.func(node, info);
node.addAnnotation(this.domain, result[0]);
for (let i = 0, child; (child = node.childNodes[i]); i++) {
result = this.visit(child, result[1]);
}
for (let i = 0, content; (content = node.contentNodes[i]); i++) {
result = this.visit(content, result[1]);
}
return result;
}
}
exports.SemanticVisitor = SemanticVisitor;

View File

@@ -0,0 +1,27 @@
import { SemanticMeaning, SemanticSecondary } from './semantic_meaning.js';
export declare const NamedSymbol: {
functionApplication: string;
invisibleTimes: string;
invisibleComma: string;
invisiblePlus: string;
};
declare class meaningMap extends Map<string, SemanticMeaning> {
get(symbol: string): SemanticMeaning;
}
declare class secondaryMap extends Map<string, string> {
set(char: string, kind: SemanticSecondary, annotation?: string): this;
has(char: string, kind?: SemanticSecondary): boolean;
get(char: string, kind?: SemanticSecondary): string;
private secKey;
}
export declare const SemanticMap: {
Meaning: meaningMap;
Secondary: secondaryMap;
FencesHoriz: Map<any, any>;
FencesVert: Map<any, any>;
LatexCommands: Map<any, any>;
};
export declare function addFunctionSemantic(base: string, names: string[]): void;
export declare function equal(meaning1: SemanticMeaning, meaning2: SemanticMeaning): boolean;
export declare function isMatchingFence(open: string, close: string): boolean;
export {};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
import { SemanticFont, SemanticMeaning } from './semantic_meaning.js';
import { SemanticNode } from './semantic_node.js';
export declare class SemanticDefault extends Map<string, SemanticMeaning> {
set(symbol: string, meaning: SemanticMeaning): this;
setNode(node: SemanticNode): void;
get(symbol: string, font?: SemanticFont): SemanticMeaning;
getNode(node: SemanticNode): SemanticMeaning;
}
declare abstract class SemanticCollator<T> extends Map<string, T[]> {
add(symbol: string, entry: T): void;
abstract addNode(node: SemanticNode): void;
get(symbol: string, font?: SemanticFont): T[];
getNode(node: SemanticNode): T[];
minimize(): void;
isMultiValued(): boolean;
}
export declare class SemanticNodeCollator extends SemanticCollator<SemanticNode> {
add(symbol: string, entry: SemanticNode): void;
addNode(node: SemanticNode): void;
toString(): string;
collateMeaning(): SemanticMeaningCollator;
}
export declare class SemanticMeaningCollator extends SemanticCollator<SemanticMeaning> {
add(symbol: string, entry: SemanticMeaning): void;
addNode(node: SemanticNode): void;
toString(): string;
reduce(): void;
default(): SemanticDefault;
newDefault(): SemanticDefault | null;
}
export {};

View File

@@ -0,0 +1,129 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticMeaningCollator = exports.SemanticNodeCollator = exports.SemanticDefault = void 0;
const SemanticAttr = require("./semantic_attr.js");
const semantic_ordering_js_1 = require("./semantic_ordering.js");
function key(symbol, font) {
return symbol.match(/^.+:.+$/) || !font ? symbol : symbol + ':' + font;
}
class SemanticDefault extends Map {
set(symbol, meaning) {
super.set(key(symbol, meaning.font), meaning);
return this;
}
setNode(node) {
this.set(node.textContent, node.meaning());
}
get(symbol, font = null) {
return super.get(key(symbol, font));
}
getNode(node) {
return this.get(node.textContent, node.font);
}
}
exports.SemanticDefault = SemanticDefault;
class SemanticCollator extends Map {
add(symbol, entry) {
const list = this.get(symbol);
if (list) {
list.push(entry);
}
else {
super.set(symbol, [entry]);
}
}
get(symbol, font = null) {
return super.get(key(symbol, font));
}
getNode(node) {
return this.get(node.textContent, node.font);
}
minimize() {
for (const [key, entry] of this) {
if (entry.length === 1) {
this.delete(key);
}
}
}
isMultiValued() {
for (const value of this.values()) {
if (value.length > 1) {
return true;
}
}
return false;
}
}
class SemanticNodeCollator extends SemanticCollator {
add(symbol, entry) {
super.add(key(symbol, entry.font), entry);
}
addNode(node) {
this.add(node.textContent, node);
}
toString() {
const outer = [];
for (const [key, nodes] of this) {
const length = Array(key.length + 3).join(' ');
const inner = nodes.map((node) => node.toString()).join('\n' + length);
outer.push(key + ': ' + inner);
}
return outer.join('\n');
}
collateMeaning() {
const collator = new SemanticMeaningCollator();
for (const [key, val] of this) {
collator.set(key, val.map((node) => node.meaning()));
}
return collator;
}
}
exports.SemanticNodeCollator = SemanticNodeCollator;
class SemanticMeaningCollator extends SemanticCollator {
add(symbol, entry) {
const list = this.get(symbol, entry.font);
if (!list ||
!list.find(function (x) {
return SemanticAttr.equal(x, entry);
})) {
super.add(key(symbol, entry.font), entry);
}
}
addNode(node) {
this.add(node.textContent, node.meaning());
}
toString() {
const outer = [];
for (const [key, nodes] of this) {
const length = Array(key.length + 3).join(' ');
const inner = nodes
.map((node) => `{type: ${node.type}, role: ${node.role}, font: ${node.font}}`)
.join('\n' + length);
outer.push(key + ': ' + inner);
}
return outer.join('\n');
}
reduce() {
for (const [key, val] of this) {
if (val.length !== 1) {
this.set(key, (0, semantic_ordering_js_1.reduce)(val));
}
}
}
default() {
const def = new SemanticDefault();
for (const [key, val] of this) {
if (val.length === 1) {
def.set(key, val[0]);
}
}
return def;
}
newDefault() {
const oldDefault = this.default();
this.reduce();
const newDefault = this.default();
return oldDefault.size !== newDefault.size ? newDefault : null;
}
}
exports.SemanticMeaningCollator = SemanticMeaningCollator;

View File

@@ -0,0 +1,20 @@
import { SemanticNode } from './semantic_node.js';
export declare type SemanticHeuristicTypes = Element | SemanticNode | SemanticNode[];
export interface SemanticHeuristic<T> {
name: string;
apply: (node: T) => void;
applicable: (node: T) => boolean;
}
declare abstract class SemanticAbstractHeuristic<T extends SemanticHeuristicTypes> implements SemanticHeuristic<T> {
name: string;
apply: (node: T) => void;
applicable: (_node: T) => boolean;
constructor(name: string, method: (node: T) => void, predicate?: (node: T) => boolean);
}
export declare class SemanticTreeHeuristic extends SemanticAbstractHeuristic<SemanticNode> {
}
export declare class SemanticMultiHeuristic extends SemanticAbstractHeuristic<SemanticNode[]> {
}
export declare class SemanticMmlHeuristic extends SemanticAbstractHeuristic<Element> {
}
export {};

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticMmlHeuristic = exports.SemanticMultiHeuristic = exports.SemanticTreeHeuristic = void 0;
class SemanticAbstractHeuristic {
constructor(name, method, predicate = (_x) => false) {
this.name = name;
this.apply = method;
this.applicable = predicate;
}
}
class SemanticTreeHeuristic extends SemanticAbstractHeuristic {
}
exports.SemanticTreeHeuristic = SemanticTreeHeuristic;
class SemanticMultiHeuristic extends SemanticAbstractHeuristic {
}
exports.SemanticMultiHeuristic = SemanticMultiHeuristic;
class SemanticMmlHeuristic extends SemanticAbstractHeuristic {
}
exports.SemanticMmlHeuristic = SemanticMmlHeuristic;

View File

@@ -0,0 +1,15 @@
import { SemanticHeuristic, SemanticHeuristicTypes } from './semantic_heuristic.js';
import { SemanticNodeFactory } from './semantic_node_factory.js';
export declare const SemanticHeuristics: {
factory: SemanticNodeFactory;
updateFactory: (nodeFactory: SemanticNodeFactory) => void;
heuristics: Map<string, SemanticHeuristic<SemanticHeuristicTypes>>;
flags: {
[key: string]: boolean;
};
blacklist: {
[key: string]: boolean;
};
add: (heuristic: SemanticHeuristic<SemanticHeuristicTypes>) => void;
run: (name: string, root: SemanticHeuristicTypes, opt_alternative?: (p1: SemanticHeuristicTypes) => SemanticHeuristicTypes) => SemanticHeuristicTypes | void;
};

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticHeuristics = void 0;
exports.SemanticHeuristics = {
factory: null,
updateFactory: function (nodeFactory) {
exports.SemanticHeuristics.factory = nodeFactory;
},
heuristics: new Map(),
flags: {
combine_juxtaposition: true,
convert_juxtaposition: true,
multioperator: true
},
blacklist: {},
add: function (heuristic) {
const name = heuristic.name;
exports.SemanticHeuristics.heuristics.set(name, heuristic);
if (!exports.SemanticHeuristics.flags[name]) {
exports.SemanticHeuristics.flags[name] = false;
}
},
run: function (name, root, opt_alternative) {
const heuristic = exports.SemanticHeuristics.heuristics.get(name);
return heuristic &&
!exports.SemanticHeuristics.blacklist[name] &&
(exports.SemanticHeuristics.flags[name] || heuristic.applicable(root))
? heuristic.apply(root)
: opt_alternative
? opt_alternative(root)
: root;
}
};

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,511 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const debugger_js_1 = require("../common/debugger.js");
const engine_js_1 = require("../common/engine.js");
const semantic_attr_js_1 = require("./semantic_attr.js");
const semantic_heuristic_factory_js_1 = require("./semantic_heuristic_factory.js");
const semantic_heuristic_js_1 = require("./semantic_heuristic.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const SemanticPred = require("./semantic_pred.js");
const semantic_processor_js_1 = require("./semantic_processor.js");
const SemanticUtil = require("./semantic_util.js");
const semantic_skeleton_js_1 = require("./semantic_skeleton.js");
const semantic_util_js_1 = require("../semantic_tree/semantic_util.js");
const DomUtil = require("../common/dom_util.js");
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('combine_juxtaposition', combineJuxtaposition));
function combineJuxtaposition(root) {
for (let i = root.childNodes.length - 1, child; (child = root.childNodes[i]); i--) {
if (!SemanticPred.isImplicitOp(child) || child.nobreaking) {
continue;
}
root.childNodes.splice(i, 1, ...child.childNodes);
root.contentNodes.splice(i, 0, ...child.contentNodes);
child.childNodes.concat(child.contentNodes).forEach(function (x) {
x.parent = root;
});
root.addMathmlNodes(child.mathml);
}
return root;
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('propagateSimpleFunction', (node) => {
if ((node.type === semantic_meaning_js_1.SemanticType.INFIXOP ||
node.type === semantic_meaning_js_1.SemanticType.FRACTION) &&
node.childNodes.every(SemanticPred.isSimpleFunction)) {
node.role = semantic_meaning_js_1.SemanticRole.COMPFUNC;
}
return node;
}, (_node) => engine_js_1.Engine.getInstance().domain === 'clearspeak'));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('simpleNamedFunction', (node) => {
const specialFunctions = ['f', 'g', 'h', 'F', 'G', 'H'];
if (node.role !== semantic_meaning_js_1.SemanticRole.UNIT &&
specialFunctions.indexOf(node.textContent) !== -1) {
node.role = semantic_meaning_js_1.SemanticRole.SIMPLEFUNC;
}
return node;
}, (_node) => engine_js_1.Engine.getInstance().domain === 'clearspeak'));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('propagateComposedFunction', (node) => {
if (node.type === semantic_meaning_js_1.SemanticType.FENCED &&
node.childNodes[0].role === semantic_meaning_js_1.SemanticRole.COMPFUNC) {
node.role = semantic_meaning_js_1.SemanticRole.COMPFUNC;
}
return node;
}, (_node) => engine_js_1.Engine.getInstance().domain === 'clearspeak'));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('multioperator', (node) => {
if (node.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN || node.textContent.length <= 1) {
return;
}
semantic_processor_js_1.SemanticProcessor.compSemantics(node, 'role', semantic_meaning_js_1.SemanticRole);
semantic_processor_js_1.SemanticProcessor.compSemantics(node, 'type', semantic_meaning_js_1.SemanticType);
}));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMultiHeuristic('convert_juxtaposition', (nodes) => {
let partition = SemanticUtil.partitionNodes(nodes, function (x) {
return (x.textContent === semantic_attr_js_1.NamedSymbol.invisibleTimes &&
x.type === semantic_meaning_js_1.SemanticType.OPERATOR);
});
partition = partition.rel.length
? juxtapositionPrePost(partition)
: partition;
nodes = partition.comp[0];
for (let i = 1, c, r; (c = partition.comp[i]), (r = partition.rel[i - 1]); i++) {
nodes.push(r);
nodes = nodes.concat(c);
}
partition = SemanticUtil.partitionNodes(nodes, function (x) {
return (x.textContent === semantic_attr_js_1.NamedSymbol.invisibleTimes &&
(x.type === semantic_meaning_js_1.SemanticType.OPERATOR || x.type === semantic_meaning_js_1.SemanticType.INFIXOP));
});
if (!partition.rel.length) {
return nodes;
}
return recurseJuxtaposition(partition.comp.shift(), partition.rel, partition.comp);
}));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('simple2prefix', (node) => {
if (node.textContent.length > 1 &&
!node.textContent[0].match(/[A-Z]/)) {
node.role = semantic_meaning_js_1.SemanticRole.PREFIXFUNC;
}
return node;
}, (node) => engine_js_1.Engine.getInstance().modality === 'braille' &&
node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('detect_cycle', (node) => {
node.type = semantic_meaning_js_1.SemanticType.MATRIX;
node.role = semantic_meaning_js_1.SemanticRole.CYCLE;
const row = node.childNodes[0];
row.type = semantic_meaning_js_1.SemanticType.ROW;
row.role = semantic_meaning_js_1.SemanticRole.CYCLE;
row.textContent = '';
row.contentNodes = [];
return node;
}, (node) => node.type === semantic_meaning_js_1.SemanticType.FENCED &&
node.childNodes[0].type === semantic_meaning_js_1.SemanticType.INFIXOP &&
node.childNodes[0].role === semantic_meaning_js_1.SemanticRole.IMPLICIT &&
node.childNodes[0].childNodes.every(function (x) {
return x.type === semantic_meaning_js_1.SemanticType.NUMBER;
}) &&
node.childNodes[0].contentNodes.every(function (x) {
return x.role === semantic_meaning_js_1.SemanticRole.SPACE;
})));
function juxtapositionPrePost(partition) {
const rels = [];
const comps = [];
let next = partition.comp.shift();
let rel = null;
let collect = [];
while (partition.comp.length) {
collect = [];
if (next.length) {
if (rel) {
rels.push(rel);
}
comps.push(next);
rel = partition.rel.shift();
next = partition.comp.shift();
continue;
}
if (rel) {
collect.push(rel);
}
while (!next.length && partition.comp.length) {
next = partition.comp.shift();
collect.push(partition.rel.shift());
}
rel = convertPrePost(collect, next, comps);
}
if (!collect.length && !next.length) {
collect.push(rel);
convertPrePost(collect, next, comps);
}
else {
rels.push(rel);
comps.push(next);
}
return { rel: rels, comp: comps };
}
function convertPrePost(collect, next, comps) {
let rel = null;
if (!collect.length) {
return rel;
}
const prev = comps[comps.length - 1];
const prevExists = prev && prev.length;
const nextExists = next && next.length;
const processor = semantic_processor_js_1.SemanticProcessor.getInstance();
if (prevExists && nextExists) {
if (next[0].type === semantic_meaning_js_1.SemanticType.INFIXOP &&
next[0].role === semantic_meaning_js_1.SemanticRole.IMPLICIT) {
rel = collect.pop();
prev.push(processor['postfixNode_'](prev.pop(), collect));
return rel;
}
rel = collect.shift();
const result = processor['prefixNode_'](next.shift(), collect);
next.unshift(result);
return rel;
}
if (prevExists) {
prev.push(processor['postfixNode_'](prev.pop(), collect));
return rel;
}
if (nextExists) {
next.unshift(processor['prefixNode_'](next.shift(), collect));
}
return rel;
}
function recurseJuxtaposition(acc, ops, elements) {
if (!ops.length) {
return acc;
}
const left = acc.pop();
const op = ops.shift();
const first = elements.shift();
if (op.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
(op.role === semantic_meaning_js_1.SemanticRole.IMPLICIT || op.role === semantic_meaning_js_1.SemanticRole.UNIT)) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 2');
const right = (left ? [left, op] : [op]).concat(first);
return recurseJuxtaposition(acc.concat(right), ops, elements);
}
if (!left) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 3');
return recurseJuxtaposition([op].concat(first), ops, elements);
}
const right = first.shift();
if (!right) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 9');
const newOp = semantic_heuristic_factory_js_1.SemanticHeuristics.factory.makeBranchNode(semantic_meaning_js_1.SemanticType.INFIXOP, [left, ops.shift()], [op], op.textContent);
newOp.role = semantic_meaning_js_1.SemanticRole.IMPLICIT;
semantic_heuristic_factory_js_1.SemanticHeuristics.run('combine_juxtaposition', newOp);
ops.unshift(newOp);
return recurseJuxtaposition(acc, ops, elements);
}
if (SemanticPred.isOperator(left) || SemanticPred.isOperator(right)) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 4');
return recurseJuxtaposition(acc.concat([left, op, right]).concat(first), ops, elements);
}
let result = null;
if (SemanticPred.isImplicitOp(left) && SemanticPred.isImplicitOp(right)) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 5');
left.contentNodes.push(op);
left.contentNodes = left.contentNodes.concat(right.contentNodes);
left.childNodes.push(right);
left.childNodes = left.childNodes.concat(right.childNodes);
right.childNodes.forEach((x) => (x.parent = left));
op.parent = left;
left.addMathmlNodes(op.mathml);
left.addMathmlNodes(right.mathml);
result = left;
}
else if (SemanticPred.isImplicitOp(left)) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 6');
left.contentNodes.push(op);
left.childNodes.push(right);
right.parent = left;
op.parent = left;
left.addMathmlNodes(op.mathml);
left.addMathmlNodes(right.mathml);
result = left;
}
else if (SemanticPred.isImplicitOp(right)) {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 7');
right.contentNodes.unshift(op);
right.childNodes.unshift(left);
left.parent = right;
op.parent = right;
right.addMathmlNodes(op.mathml);
right.addMathmlNodes(left.mathml);
result = right;
}
else {
debugger_js_1.Debugger.getInstance().output('Juxta Heuristic Case 8');
result = semantic_heuristic_factory_js_1.SemanticHeuristics.factory.makeBranchNode(semantic_meaning_js_1.SemanticType.INFIXOP, [left, right], [op], op.textContent);
result.role = semantic_meaning_js_1.SemanticRole.IMPLICIT;
}
acc.push(result);
return recurseJuxtaposition(acc.concat(first), ops, elements);
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMultiHeuristic('intvar_from_implicit', implicitUnpack, (nodes) => nodes[0] && SemanticPred.isImplicit(nodes[0])));
function implicitUnpack(nodes) {
const children = nodes[0].childNodes;
nodes.splice(0, 1, ...children);
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('intvar_from_fraction', integralFractionArg, (node) => {
if (node.type !== semantic_meaning_js_1.SemanticType.INTEGRAL)
return false;
const [, integrand, intvar] = node.childNodes;
return (intvar.type === semantic_meaning_js_1.SemanticType.EMPTY &&
integrand.type === semantic_meaning_js_1.SemanticType.FRACTION);
}));
function integralFractionArg(node) {
const integrand = node.childNodes[1];
const enumerator = integrand.childNodes[0];
if (SemanticPred.isIntegralDxBoundarySingle(enumerator)) {
enumerator.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
return;
}
if (!SemanticPred.isImplicit(enumerator))
return;
const length = enumerator.childNodes.length;
const first = enumerator.childNodes[length - 2];
const second = enumerator.childNodes[length - 1];
if (SemanticPred.isIntegralDxBoundarySingle(second)) {
second.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
return;
}
if (SemanticPred.isIntegralDxBoundary(first, second)) {
const prefix = semantic_processor_js_1.SemanticProcessor.getInstance()['prefixNode_'](second, [
first
]);
prefix.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
if (length === 2) {
integrand.childNodes[0] = prefix;
}
else {
enumerator.childNodes.pop();
enumerator.contentNodes.pop();
enumerator.childNodes[length - 2] = prefix;
prefix.parent = enumerator;
}
}
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticTreeHeuristic('rewrite_subcases', rewriteSubcasesTable, (table) => {
let left = true;
let right = true;
const topLeft = table.childNodes[0].childNodes[0];
if (!eligibleNode(topLeft.mathmlTree)) {
left = false;
}
else {
for (let i = 1, row; (row = table.childNodes[i]); i++) {
if (row.childNodes[0].childNodes.length) {
left = false;
break;
}
}
}
if (left) {
table.addAnnotation('Emph', 'left');
}
const topRight = table.childNodes[0].childNodes[table.childNodes[0].childNodes.length - 1];
if (!eligibleNode(topRight.mathmlTree)) {
right = false;
}
else {
const firstRow = table.childNodes[0].childNodes.length;
for (let i = 1, row; (row = table.childNodes[i]); i++) {
if (row.childNodes.length >= firstRow) {
right = false;
break;
}
}
}
if (right) {
table.addAnnotation('Emph', 'right');
}
return left || right;
}));
function eligibleNode(node) {
return (node.childNodes[0] &&
node.childNodes[0].childNodes[0] &&
DomUtil.tagName(node.childNodes[0]) === semantic_util_js_1.MMLTAGS.MPADDED &&
DomUtil.tagName(node.childNodes[0].childNodes[0]) ===
semantic_util_js_1.MMLTAGS.MPADDED &&
DomUtil.tagName(node.childNodes[0].childNodes[node.childNodes[0].childNodes.length - 1]) === semantic_util_js_1.MMLTAGS.MPHANTOM);
}
const rewritable = [
semantic_meaning_js_1.SemanticType.PUNCTUATED,
semantic_meaning_js_1.SemanticType.RELSEQ,
semantic_meaning_js_1.SemanticType.MULTIREL,
semantic_meaning_js_1.SemanticType.INFIXOP,
semantic_meaning_js_1.SemanticType.PREFIXOP,
semantic_meaning_js_1.SemanticType.POSTFIXOP
];
function rewriteSubcasesTable(table) {
table.addAnnotation('Emph', 'top');
let row = [];
if (table.hasAnnotation('Emph', 'left')) {
const topLeft = table.childNodes[0].childNodes[0].childNodes[0];
const cells = rewriteCell(topLeft, true);
cells.forEach((x) => x.addAnnotation('Emph', 'left'));
row = row.concat(cells);
for (let i = 0, line; (line = table.childNodes[i]); i++) {
line.childNodes.shift();
}
}
row.push(table);
if (table.hasAnnotation('Emph', 'right')) {
const topRight = table.childNodes[0].childNodes[table.childNodes[0].childNodes.length - 1]
.childNodes[0];
const cells = rewriteCell(topRight);
cells.forEach((x) => x.addAnnotation('Emph', 'left'));
row = row.concat(cells);
table.childNodes[0].childNodes.pop();
}
semantic_processor_js_1.SemanticProcessor.tableToMultiline(table);
const newNode = semantic_processor_js_1.SemanticProcessor.getInstance().row(row);
const annotation = table.annotation['Emph'];
table.annotation['Emph'] = ['table'];
annotation.forEach((x) => newNode.addAnnotation('Emph', x));
return newNode;
}
function rewriteCell(cell, left) {
if (!cell.childNodes.length) {
rewriteFence(cell);
return [cell];
}
let fence = null;
if (cell.type === semantic_meaning_js_1.SemanticType.PUNCTUATED &&
(left
? cell.role === semantic_meaning_js_1.SemanticRole.ENDPUNCT
: cell.role === semantic_meaning_js_1.SemanticRole.STARTPUNCT)) {
const children = cell.childNodes;
if (rewriteFence(children[left ? children.length - 1 : 0])) {
cell = children[left ? 0 : children.length - 1];
fence = children[left ? children.length - 1 : 0];
}
}
if (rewritable.indexOf(cell.type) !== -1) {
const children = cell.childNodes;
rewriteFence(children[left ? children.length - 1 : 0]);
const newNodes = semantic_skeleton_js_1.SemanticSkeleton.combineContentChildren(cell.type, cell.role, cell.contentNodes, cell.childNodes);
if (fence) {
if (left) {
newNodes.push(fence);
}
else {
newNodes.unshift(fence);
}
}
return newNodes;
}
return fence ? (left ? [cell, fence] : [fence, cell]) : [cell];
}
const PUNCT_TO_FENCE_ = {
[semantic_meaning_js_1.SemanticRole.METRIC]: semantic_meaning_js_1.SemanticRole.METRIC,
[semantic_meaning_js_1.SemanticRole.VBAR]: semantic_meaning_js_1.SemanticRole.NEUTRAL,
[semantic_meaning_js_1.SemanticRole.OPENFENCE]: semantic_meaning_js_1.SemanticRole.OPEN,
[semantic_meaning_js_1.SemanticRole.CLOSEFENCE]: semantic_meaning_js_1.SemanticRole.CLOSE
};
function rewriteFence(fence) {
if (fence.type !== semantic_meaning_js_1.SemanticType.PUNCTUATION) {
return false;
}
const role = PUNCT_TO_FENCE_[fence.role];
if (!role) {
return false;
}
fence.role = role;
fence.type = semantic_meaning_js_1.SemanticType.FENCE;
fence.addAnnotation('Emph', 'fence');
return true;
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMultiHeuristic('ellipses', (nodes) => {
const newNodes = [];
let current = nodes.shift();
while (current) {
[current, nodes] = combineNodes(current, nodes, semantic_meaning_js_1.SemanticRole.FULLSTOP, semantic_meaning_js_1.SemanticRole.ELLIPSIS);
[current, nodes] = combineNodes(current, nodes, semantic_meaning_js_1.SemanticRole.DASH);
newNodes.push(current);
current = nodes.shift();
}
return newNodes;
}, (nodes) => nodes.length > 1));
function combineNodes(current, nodes, src, target = src) {
const collect = [];
while (current && current.role === src) {
collect.push(current);
current = nodes.shift();
}
if (!collect.length) {
return [current, nodes];
}
if (current) {
nodes.unshift(current);
}
return [
collect.length === 1 ? collect[0] : combinedNodes(collect, target),
nodes
];
}
function combinedNodes(nodes, role) {
const node = semantic_heuristic_factory_js_1.SemanticHeuristics.factory.makeBranchNode(semantic_meaning_js_1.SemanticType.PUNCTUATION, nodes, []);
node.role = role;
return node;
}
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMultiHeuristic('op_with_limits', (nodes) => {
const center = nodes[0];
center.type = semantic_meaning_js_1.SemanticType.LARGEOP;
center.role = semantic_meaning_js_1.SemanticRole.SUM;
return nodes;
}, (nodes) => {
return (nodes[0].type === semantic_meaning_js_1.SemanticType.OPERATOR &&
nodes
.slice(1)
.some((node) => node.type === semantic_meaning_js_1.SemanticType.RELSEQ ||
node.type === semantic_meaning_js_1.SemanticType.MULTIREL ||
(node.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
node.role === semantic_meaning_js_1.SemanticRole.ELEMENT) ||
(node.type === semantic_meaning_js_1.SemanticType.PUNCTUATED &&
node.role === semantic_meaning_js_1.SemanticRole.SEQUENCE)));
}));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMultiHeuristic('bracketed_interval', (nodes) => {
const leftFence = nodes[0];
const rightFence = nodes[1];
const content = nodes.slice(2);
const childNode = semantic_processor_js_1.SemanticProcessor.getInstance().row(content);
const fenced = semantic_heuristic_factory_js_1.SemanticHeuristics.factory.makeBranchNode(semantic_meaning_js_1.SemanticType.FENCED, [childNode], [leftFence, rightFence]);
fenced.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
return fenced;
}, (nodes) => {
const leftFence = nodes[0];
const rightFence = nodes[1];
const content = nodes.slice(2);
if (!(leftFence &&
(leftFence.textContent === ']' || leftFence.textContent === '[') &&
rightFence &&
(rightFence.textContent === ']' || rightFence.textContent === '['))) {
return false;
}
const partition = SemanticUtil.partitionNodes(content, SemanticPred.isPunctuation);
return !!(partition.rel.length === 1 &&
partition.comp[0].length &&
partition.comp[1].length);
}));
semantic_heuristic_factory_js_1.SemanticHeuristics.add(new semantic_heuristic_js_1.SemanticMmlHeuristic('function_from_identifiers', (node) => {
const expr = DomUtil.toArray(node.childNodes)
.map((x) => x.textContent.trim())
.join('');
const meaning = semantic_attr_js_1.SemanticMap.Meaning.get(expr);
if (meaning.type === semantic_meaning_js_1.SemanticType.UNKNOWN) {
return node;
}
const snode = semantic_heuristic_factory_js_1.SemanticHeuristics.factory.makeLeafNode(expr, semantic_processor_js_1.SemanticProcessor.getInstance().font(node.getAttribute('mathvariant')));
snode.mathmlTree = node;
return snode;
}, (node) => {
const children = DomUtil.toArray(node.childNodes);
if (children.length < 2) {
return false;
}
return children.every((child) => DomUtil.tagName(child) === semantic_util_js_1.MMLTAGS.MI &&
semantic_attr_js_1.SemanticMap.Meaning.get(child.textContent.trim()).role ===
semantic_meaning_js_1.SemanticRole.LATINLETTER);
}));

View File

@@ -0,0 +1,29 @@
import { SemanticAbstractParser } from './semantic_parser.js';
export declare class SemanticMathml extends SemanticAbstractParser<Element> {
private parseMap_;
private static getAttribute_;
constructor();
parse(mml: Element): any;
private semantics_;
private rows_;
private fraction_;
private limits_;
private root_;
private sqrt_;
private table_;
private tableRow_;
private tableLabeledRow_;
private tableCell_;
private space_;
private text_;
private identifier_;
private number_;
private operator_;
private fenced_;
private enclosed_;
private multiscripts_;
private empty_;
private action_;
private dummy_;
private leaf_;
}

View File

@@ -0,0 +1,328 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticMathml = void 0;
const DomUtil = require("../common/dom_util.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const semantic_attr_js_1 = require("./semantic_attr.js");
const semantic_parser_js_1 = require("./semantic_parser.js");
const SemanticPred = require("./semantic_pred.js");
const semantic_processor_js_1 = require("./semantic_processor.js");
const SemanticUtil = require("./semantic_util.js");
const semantic_util_js_1 = require("../semantic_tree/semantic_util.js");
const semantic_heuristic_factory_js_1 = require("./semantic_heuristic_factory.js");
class SemanticMathml extends semantic_parser_js_1.SemanticAbstractParser {
static getAttribute_(node, attr, def) {
if (!node.hasAttribute(attr)) {
return def;
}
const value = node.getAttribute(attr);
if (value.match(/^\s*$/)) {
return null;
}
return value;
}
constructor() {
super('MathML');
this.parseMap_ = new Map([
[semantic_util_js_1.MMLTAGS.SEMANTICS, this.semantics_.bind(this)],
[semantic_util_js_1.MMLTAGS.MATH, this.rows_.bind(this)],
[semantic_util_js_1.MMLTAGS.MROW, this.rows_.bind(this)],
[semantic_util_js_1.MMLTAGS.MPADDED, this.rows_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSTYLE, this.rows_.bind(this)],
[semantic_util_js_1.MMLTAGS.MFRAC, this.fraction_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSUB, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSUP, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSUBSUP, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MOVER, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MUNDER, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MUNDEROVER, this.limits_.bind(this)],
[semantic_util_js_1.MMLTAGS.MROOT, this.root_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSQRT, this.sqrt_.bind(this)],
[semantic_util_js_1.MMLTAGS.MTABLE, this.table_.bind(this)],
[semantic_util_js_1.MMLTAGS.MLABELEDTR, this.tableLabeledRow_.bind(this)],
[semantic_util_js_1.MMLTAGS.MTR, this.tableRow_.bind(this)],
[semantic_util_js_1.MMLTAGS.MTD, this.tableCell_.bind(this)],
[semantic_util_js_1.MMLTAGS.MS, this.text_.bind(this)],
[semantic_util_js_1.MMLTAGS.MTEXT, this.text_.bind(this)],
[semantic_util_js_1.MMLTAGS.MSPACE, this.space_.bind(this)],
[semantic_util_js_1.MMLTAGS.ANNOTATIONXML, this.text_.bind(this)],
[semantic_util_js_1.MMLTAGS.MI, this.identifier_.bind(this)],
[semantic_util_js_1.MMLTAGS.MN, this.number_.bind(this)],
[semantic_util_js_1.MMLTAGS.MO, this.operator_.bind(this)],
[semantic_util_js_1.MMLTAGS.MFENCED, this.fenced_.bind(this)],
[semantic_util_js_1.MMLTAGS.MENCLOSE, this.enclosed_.bind(this)],
[semantic_util_js_1.MMLTAGS.MMULTISCRIPTS, this.multiscripts_.bind(this)],
[semantic_util_js_1.MMLTAGS.ANNOTATION, this.empty_.bind(this)],
[semantic_util_js_1.MMLTAGS.NONE, this.empty_.bind(this)],
[semantic_util_js_1.MMLTAGS.MACTION, this.action_.bind(this)]
]);
const meaning = {
type: semantic_meaning_js_1.SemanticType.IDENTIFIER,
role: semantic_meaning_js_1.SemanticRole.NUMBERSET,
font: semantic_meaning_js_1.SemanticFont.DOUBLESTRUCK
};
[
'C',
'H',
'N',
'P',
'Q',
'R',
'Z',
'',
'',
'',
'',
'',
'',
''
].forEach(((x) => this.getFactory().defaultMap.set(x, meaning)).bind(this));
}
parse(mml) {
semantic_processor_js_1.SemanticProcessor.getInstance().setNodeFactory(this.getFactory());
const children = DomUtil.toArray(mml.childNodes);
const tag = DomUtil.tagName(mml);
const func = this.parseMap_.get(tag);
const newNode = (func ? func : this.dummy_.bind(this))(mml, children);
SemanticUtil.addAttributes(newNode, mml);
if ([
semantic_util_js_1.MMLTAGS.MATH,
semantic_util_js_1.MMLTAGS.MROW,
semantic_util_js_1.MMLTAGS.MPADDED,
semantic_util_js_1.MMLTAGS.MSTYLE,
semantic_util_js_1.MMLTAGS.SEMANTICS,
semantic_util_js_1.MMLTAGS.MACTION
].indexOf(tag) !== -1) {
return newNode;
}
newNode.mathml.unshift(mml);
newNode.mathmlTree = mml;
return newNode;
}
semantics_(_node, children) {
return children.length
? this.parse(children[0])
: this.getFactory().makeEmptyNode();
}
rows_(node, children) {
const semantics = node.getAttribute('semantics');
if (semantics && semantics.match('bspr_')) {
return semantic_processor_js_1.SemanticProcessor.proof(node, semantics, this.parseList.bind(this));
}
children = SemanticUtil.purgeNodes(children);
let newNode;
if (children.length === 1) {
newNode = this.parse(children[0]);
if (newNode.type === semantic_meaning_js_1.SemanticType.EMPTY && !newNode.mathmlTree) {
newNode.mathmlTree = node;
}
}
else {
const snode = semantic_heuristic_factory_js_1.SemanticHeuristics.run('function_from_identifiers', node);
newNode =
snode && snode !== node
? snode
: semantic_processor_js_1.SemanticProcessor.getInstance().row(this.parseList(children));
}
newNode.mathml.unshift(node);
return newNode;
}
fraction_(node, children) {
if (!children.length) {
return this.getFactory().makeEmptyNode();
}
const upper = this.parse(children[0]);
const lower = children[1]
? this.parse(children[1])
: this.getFactory().makeEmptyNode();
const sem = semantic_processor_js_1.SemanticProcessor.getInstance().fractionLikeNode(upper, lower, node.getAttribute('linethickness'), node.getAttribute('bevelled') === 'true');
return sem;
}
limits_(node, children) {
return semantic_processor_js_1.SemanticProcessor.getInstance().limitNode(DomUtil.tagName(node), this.parseList(children));
}
root_(node, children) {
if (!children[1]) {
return this.sqrt_(node, children);
}
return this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.ROOT, [this.parse(children[1]), this.parse(children[0])], []);
}
sqrt_(_node, children) {
const semNodes = this.parseList(SemanticUtil.purgeNodes(children));
return this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.SQRT, [semantic_processor_js_1.SemanticProcessor.getInstance().row(semNodes)], []);
}
table_(node, children) {
const semantics = node.getAttribute('semantics');
if (semantics && semantics.match('bspr_')) {
return semantic_processor_js_1.SemanticProcessor.proof(node, semantics, this.parseList.bind(this));
}
const newNode = this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.TABLE, this.parseList(children), []);
newNode.mathmlTree = node;
return semantic_processor_js_1.SemanticProcessor.tableToMultiline(newNode);
}
tableRow_(_node, children) {
const newNode = this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.ROW, this.parseList(children), []);
newNode.role = semantic_meaning_js_1.SemanticRole.TABLE;
return newNode;
}
tableLabeledRow_(node, children) {
var _a;
if (!children.length) {
return this.tableRow_(node, children);
}
const label = this.parse(children[0]);
label.role = semantic_meaning_js_1.SemanticRole.LABEL;
if (((_a = label.childNodes[0]) === null || _a === void 0 ? void 0 : _a.type) === semantic_meaning_js_1.SemanticType.TEXT) {
label.childNodes[0].role = semantic_meaning_js_1.SemanticRole.LABEL;
}
const newNode = this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.ROW, this.parseList(children.slice(1)), [label]);
newNode.role = semantic_meaning_js_1.SemanticRole.TABLE;
return newNode;
}
tableCell_(_node, children) {
const semNodes = this.parseList(SemanticUtil.purgeNodes(children));
let childNodes;
if (!semNodes.length) {
childNodes = [];
}
else if (semNodes.length === 1 &&
SemanticPred.isType(semNodes[0], semantic_meaning_js_1.SemanticType.EMPTY)) {
childNodes = semNodes;
}
else {
childNodes = [semantic_processor_js_1.SemanticProcessor.getInstance().row(semNodes)];
}
const newNode = this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.CELL, childNodes, []);
newNode.role = semantic_meaning_js_1.SemanticRole.TABLE;
return newNode;
}
space_(node, children) {
const width = node.getAttribute('width');
const match = width && width.match(/[a-z]*$/);
if (!match) {
return this.empty_(node, children);
}
const sizes = {
cm: 0.4,
pc: 0.5,
em: 0.5,
ex: 1,
in: 0.15,
pt: 5,
mm: 5
};
const unit = match[0];
const measure = parseFloat(width.slice(0, match.index));
const size = sizes[unit];
if (!size || isNaN(measure) || measure < size) {
return this.empty_(node, children);
}
const newNode = this.getFactory().makeUnprocessed(node);
return semantic_processor_js_1.SemanticProcessor.getInstance().text(newNode, DomUtil.tagName(node));
}
text_(node, children) {
const newNode = this.leaf_(node, children);
if (!node.textContent) {
return newNode;
}
newNode.updateContent(node.textContent, true);
return semantic_processor_js_1.SemanticProcessor.getInstance().text(newNode, DomUtil.tagName(node));
}
identifier_(node, children) {
const newNode = this.leaf_(node, children);
return semantic_processor_js_1.SemanticProcessor.getInstance().identifierNode(newNode, semantic_processor_js_1.SemanticProcessor.getInstance().font(node.getAttribute('mathvariant')), node.getAttribute('class'));
}
number_(node, children) {
const newNode = this.leaf_(node, children);
semantic_processor_js_1.SemanticProcessor.number(newNode);
return newNode;
}
operator_(node, children) {
const newNode = this.leaf_(node, children);
semantic_processor_js_1.SemanticProcessor.getInstance().operatorNode(newNode);
return newNode;
}
fenced_(node, children) {
const semNodes = this.parseList(SemanticUtil.purgeNodes(children));
const sepValue = SemanticMathml.getAttribute_(node, 'separators', ',');
const open = SemanticMathml.getAttribute_(node, 'open', '(');
const close = SemanticMathml.getAttribute_(node, 'close', ')');
const newNode = semantic_processor_js_1.SemanticProcessor.getInstance().mfenced(open, close, sepValue, semNodes);
const nodes = semantic_processor_js_1.SemanticProcessor.getInstance().tablesInRow([newNode]);
return nodes[0];
}
enclosed_(node, children) {
const semNodes = this.parseList(SemanticUtil.purgeNodes(children));
const newNode = this.getFactory().makeBranchNode(semantic_meaning_js_1.SemanticType.ENCLOSE, [semantic_processor_js_1.SemanticProcessor.getInstance().row(semNodes)], []);
newNode.role =
node.getAttribute('notation') || semantic_meaning_js_1.SemanticRole.UNKNOWN;
return newNode;
}
multiscripts_(_node, children) {
if (!children.length) {
return this.getFactory().makeEmptyNode();
}
const base = this.parse(children.shift());
if (!children.length) {
return base;
}
const lsup = [];
const lsub = [];
const rsup = [];
const rsub = [];
let prescripts = false;
let scriptcount = 0;
for (let i = 0, child; (child = children[i]); i++) {
if (DomUtil.tagName(child) === semantic_util_js_1.MMLTAGS.MPRESCRIPTS) {
prescripts = true;
scriptcount = 0;
continue;
}
prescripts
? scriptcount & 1
? lsup.push(child)
: lsub.push(child)
: scriptcount & 1
? rsup.push(child)
: rsub.push(child);
scriptcount++;
}
if (!SemanticUtil.purgeNodes(lsup).length &&
!SemanticUtil.purgeNodes(lsub).length) {
return semantic_processor_js_1.SemanticProcessor.getInstance().pseudoTensor(base, this.parseList(rsub), this.parseList(rsup));
}
return semantic_processor_js_1.SemanticProcessor.getInstance().tensor(base, this.parseList(lsub), this.parseList(lsup), this.parseList(rsub), this.parseList(rsup));
}
empty_(_node, _children) {
return this.getFactory().makeEmptyNode();
}
action_(node, children) {
const selection = children[node.hasAttribute('selection')
? parseInt(node.getAttribute('selection'), 10) - 1
: 0];
const stree = this.parse(selection);
stree.mathmlTree = selection;
return stree;
}
dummy_(node, _children) {
const unknown = this.getFactory().makeUnprocessed(node);
unknown.role = node.tagName;
unknown.textContent = node.textContent;
return unknown;
}
leaf_(mml, children) {
if (children.length === 1 &&
children[0].nodeType !== DomUtil.NodeType.TEXT_NODE) {
const node = this.getFactory().makeUnprocessed(mml);
node.role = children[0].tagName;
SemanticUtil.addAttributes(node, children[0]);
return node;
}
const node = this.getFactory().makeLeafNode(mml.textContent, semantic_processor_js_1.SemanticProcessor.getInstance().font(mml.getAttribute('mathvariant')));
if (mml.hasAttribute('data-latex')) {
semantic_attr_js_1.SemanticMap.LatexCommands.set(mml.getAttribute('data-latex'), mml.textContent);
}
return node;
}
}
exports.SemanticMathml = SemanticMathml;

View File

@@ -0,0 +1,390 @@
import * as Alphabet from '../speech_rules/alphabet.js';
export interface SemanticMeaning {
type: SemanticType;
role: SemanticRole;
font: SemanticFont;
}
declare enum Types {
PUNCTUATION = "punctuation",
FENCE = "fence",
NUMBER = "number",
IDENTIFIER = "identifier",
TEXT = "text",
OPERATOR = "operator",
RELATION = "relation",
LARGEOP = "largeop",
FUNCTION = "function",
ACCENT = "accent",
FENCED = "fenced",
FRACTION = "fraction",
PUNCTUATED = "punctuated",
RELSEQ = "relseq",
MULTIREL = "multirel",
INFIXOP = "infixop",
PREFIXOP = "prefixop",
POSTFIXOP = "postfixop",
APPL = "appl",
INTEGRAL = "integral",
BIGOP = "bigop",
SQRT = "sqrt",
ROOT = "root",
LIMUPPER = "limupper",
LIMLOWER = "limlower",
LIMBOTH = "limboth",
SUBSCRIPT = "subscript",
SUPERSCRIPT = "superscript",
UNDERSCORE = "underscore",
OVERSCORE = "overscore",
TENSOR = "tensor",
TABLE = "table",
MULTILINE = "multiline",
MATRIX = "matrix",
VECTOR = "vector",
CASES = "cases",
ROW = "row",
LINE = "line",
CELL = "cell",
ENCLOSE = "enclose",
INFERENCE = "inference",
RULELABEL = "rulelabel",
CONCLUSION = "conclusion",
PREMISES = "premises",
UNKNOWN = "unknown",
EMPTY = "empty"
}
export type SemanticType = Types;
export declare const SemanticType: {
PUNCTUATION: Types.PUNCTUATION;
FENCE: Types.FENCE;
NUMBER: Types.NUMBER;
IDENTIFIER: Types.IDENTIFIER;
TEXT: Types.TEXT;
OPERATOR: Types.OPERATOR;
RELATION: Types.RELATION;
LARGEOP: Types.LARGEOP;
FUNCTION: Types.FUNCTION;
ACCENT: Types.ACCENT;
FENCED: Types.FENCED;
FRACTION: Types.FRACTION;
PUNCTUATED: Types.PUNCTUATED;
RELSEQ: Types.RELSEQ;
MULTIREL: Types.MULTIREL;
INFIXOP: Types.INFIXOP;
PREFIXOP: Types.PREFIXOP;
POSTFIXOP: Types.POSTFIXOP;
APPL: Types.APPL;
INTEGRAL: Types.INTEGRAL;
BIGOP: Types.BIGOP;
SQRT: Types.SQRT;
ROOT: Types.ROOT;
LIMUPPER: Types.LIMUPPER;
LIMLOWER: Types.LIMLOWER;
LIMBOTH: Types.LIMBOTH;
SUBSCRIPT: Types.SUBSCRIPT;
SUPERSCRIPT: Types.SUPERSCRIPT;
UNDERSCORE: Types.UNDERSCORE;
OVERSCORE: Types.OVERSCORE;
TENSOR: Types.TENSOR;
TABLE: Types.TABLE;
MULTILINE: Types.MULTILINE;
MATRIX: Types.MATRIX;
VECTOR: Types.VECTOR;
CASES: Types.CASES;
ROW: Types.ROW;
LINE: Types.LINE;
CELL: Types.CELL;
ENCLOSE: Types.ENCLOSE;
INFERENCE: Types.INFERENCE;
RULELABEL: Types.RULELABEL;
CONCLUSION: Types.CONCLUSION;
PREMISES: Types.PREMISES;
UNKNOWN: Types.UNKNOWN;
EMPTY: Types.EMPTY;
};
declare enum Roles {
COMMA = "comma",
SEMICOLON = "semicolon",
ELLIPSIS = "ellipsis",
FULLSTOP = "fullstop",
QUESTION = "question",
EXCLAMATION = "exclamation",
QUOTES = "quotes",
DASH = "dash",
TILDE = "tilde",
PRIME = "prime",
DEGREE = "degree",
VBAR = "vbar",
COLON = "colon",
OPENFENCE = "openfence",
CLOSEFENCE = "closefence",
APPLICATION = "application",
DUMMY = "dummy",
UNIT = "unit",
LABEL = "label",
OPEN = "open",
CLOSE = "close",
TOP = "top",
BOTTOM = "bottom",
NEUTRAL = "neutral",
METRIC = "metric",
LATINLETTER = "latinletter",
GREEKLETTER = "greekletter",
OTHERLETTER = "otherletter",
NUMBERSET = "numbersetletter",
INTEGER = "integer",
FLOAT = "float",
OTHERNUMBER = "othernumber",
INFTY = "infty",
MIXED = "mixed",
MULTIACCENT = "multiaccent",
OVERACCENT = "overaccent",
UNDERACCENT = "underaccent",
UNDEROVER = "underover",
SUBSUP = "subsup",
LEFTSUB = "leftsub",
LEFTSUPER = "leftsuper",
RIGHTSUB = "rightsub",
RIGHTSUPER = "rightsuper",
LEFTRIGHT = "leftright",
ABOVEBELOW = "abovebelow",
SETEMPTY = "set empty",
SETEXT = "set extended",
SETSINGLE = "set singleton",
SETCOLLECT = "set collection",
STRING = "string",
SPACE = "space",
ANNOTATION = "annotation",
TEXT = "text",
SEQUENCE = "sequence",
ENDPUNCT = "endpunct",
STARTPUNCT = "startpunct",
NEGATIVE = "negative",
POSITIVE = "positive",
NEGATION = "negation",
MULTIOP = "multiop",
PREFIXOP = "prefix operator",
POSTFIXOP = "postfix operator",
LIMFUNC = "limit function",
INFIXFUNC = "infix function",
PREFIXFUNC = "prefix function",
POSTFIXFUNC = "postfix function",
SIMPLEFUNC = "simple function",
COMPFUNC = "composed function",
SUM = "sum",
INTEGRAL = "integral",
GEOMETRY = "geometry",
BOX = "box",
BLOCK = "block",
ADDITION = "addition",
MULTIPLICATION = "multiplication",
SUBTRACTION = "subtraction",
IMPLICIT = "implicit",
DIVISION = "division",
VULGAR = "vulgar",
EQUALITY = "equality",
INEQUALITY = "inequality",
ARROW = "arrow",
ELEMENT = "element",
NONELEMENT = "nonelement",
REELEMENT = "reelement",
RENONELEMENT = "renonelement",
SET = "set",
DETERMINANT = "determinant",
ROWVECTOR = "rowvector",
BINOMIAL = "binomial",
SQUAREMATRIX = "squarematrix",
CYCLE = "cycle",
MULTILINE = "multiline",
MATRIX = "matrix",
VECTOR = "vector",
CASES = "cases",
TABLE = "table",
CAYLEY = "cayley",
PROOF = "proof",
LEFT = "left",
RIGHT = "right",
UP = "up",
DOWN = "down",
FINAL = "final",
SINGLE = "single",
HYP = "hyp",
AXIOM = "axiom",
LOGIC = "logic",
UNKNOWN = "unknown",
MGLYPH = "mglyph"
}
export type SemanticRole = Roles;
export declare const SemanticRole: {
COMMA: Roles.COMMA;
SEMICOLON: Roles.SEMICOLON;
ELLIPSIS: Roles.ELLIPSIS;
FULLSTOP: Roles.FULLSTOP;
QUESTION: Roles.QUESTION;
EXCLAMATION: Roles.EXCLAMATION;
QUOTES: Roles.QUOTES;
DASH: Roles.DASH;
TILDE: Roles.TILDE;
PRIME: Roles.PRIME;
DEGREE: Roles.DEGREE;
VBAR: Roles.VBAR;
COLON: Roles.COLON;
OPENFENCE: Roles.OPENFENCE;
CLOSEFENCE: Roles.CLOSEFENCE;
APPLICATION: Roles.APPLICATION;
DUMMY: Roles.DUMMY;
UNIT: Roles.UNIT;
LABEL: Roles.LABEL;
OPEN: Roles.OPEN;
CLOSE: Roles.CLOSE;
TOP: Roles.TOP;
BOTTOM: Roles.BOTTOM;
NEUTRAL: Roles.NEUTRAL;
METRIC: Roles.METRIC;
LATINLETTER: Roles.LATINLETTER;
GREEKLETTER: Roles.GREEKLETTER;
OTHERLETTER: Roles.OTHERLETTER;
NUMBERSET: Roles.NUMBERSET;
INTEGER: Roles.INTEGER;
FLOAT: Roles.FLOAT;
OTHERNUMBER: Roles.OTHERNUMBER;
INFTY: Roles.INFTY;
MIXED: Roles.MIXED;
MULTIACCENT: Roles.MULTIACCENT;
OVERACCENT: Roles.OVERACCENT;
UNDERACCENT: Roles.UNDERACCENT;
UNDEROVER: Roles.UNDEROVER;
SUBSUP: Roles.SUBSUP;
LEFTSUB: Roles.LEFTSUB;
LEFTSUPER: Roles.LEFTSUPER;
RIGHTSUB: Roles.RIGHTSUB;
RIGHTSUPER: Roles.RIGHTSUPER;
LEFTRIGHT: Roles.LEFTRIGHT;
ABOVEBELOW: Roles.ABOVEBELOW;
SETEMPTY: Roles.SETEMPTY;
SETEXT: Roles.SETEXT;
SETSINGLE: Roles.SETSINGLE;
SETCOLLECT: Roles.SETCOLLECT;
STRING: Roles.STRING;
SPACE: Roles.SPACE;
ANNOTATION: Roles.ANNOTATION;
TEXT: Roles.TEXT;
SEQUENCE: Roles.SEQUENCE;
ENDPUNCT: Roles.ENDPUNCT;
STARTPUNCT: Roles.STARTPUNCT;
NEGATIVE: Roles.NEGATIVE;
POSITIVE: Roles.POSITIVE;
NEGATION: Roles.NEGATION;
MULTIOP: Roles.MULTIOP;
PREFIXOP: Roles.PREFIXOP;
POSTFIXOP: Roles.POSTFIXOP;
LIMFUNC: Roles.LIMFUNC;
INFIXFUNC: Roles.INFIXFUNC;
PREFIXFUNC: Roles.PREFIXFUNC;
POSTFIXFUNC: Roles.POSTFIXFUNC;
SIMPLEFUNC: Roles.SIMPLEFUNC;
COMPFUNC: Roles.COMPFUNC;
SUM: Roles.SUM;
INTEGRAL: Roles.INTEGRAL;
GEOMETRY: Roles.GEOMETRY;
BOX: Roles.BOX;
BLOCK: Roles.BLOCK;
ADDITION: Roles.ADDITION;
MULTIPLICATION: Roles.MULTIPLICATION;
SUBTRACTION: Roles.SUBTRACTION;
IMPLICIT: Roles.IMPLICIT;
DIVISION: Roles.DIVISION;
VULGAR: Roles.VULGAR;
EQUALITY: Roles.EQUALITY;
INEQUALITY: Roles.INEQUALITY;
ARROW: Roles.ARROW;
ELEMENT: Roles.ELEMENT;
NONELEMENT: Roles.NONELEMENT;
REELEMENT: Roles.REELEMENT;
RENONELEMENT: Roles.RENONELEMENT;
SET: Roles.SET;
DETERMINANT: Roles.DETERMINANT;
ROWVECTOR: Roles.ROWVECTOR;
BINOMIAL: Roles.BINOMIAL;
SQUAREMATRIX: Roles.SQUAREMATRIX;
CYCLE: Roles.CYCLE;
MULTILINE: Roles.MULTILINE;
MATRIX: Roles.MATRIX;
VECTOR: Roles.VECTOR;
CASES: Roles.CASES;
TABLE: Roles.TABLE;
CAYLEY: Roles.CAYLEY;
PROOF: Roles.PROOF;
LEFT: Roles.LEFT;
RIGHT: Roles.RIGHT;
UP: Roles.UP;
DOWN: Roles.DOWN;
FINAL: Roles.FINAL;
SINGLE: Roles.SINGLE;
HYP: Roles.HYP;
AXIOM: Roles.AXIOM;
LOGIC: Roles.LOGIC;
UNKNOWN: Roles.UNKNOWN;
MGLYPH: Roles.MGLYPH;
};
declare enum ExtraFont {
CALIGRAPHIC = "caligraphic",
CALIGRAPHICBOLD = "caligraphic-bold",
OLDSTYLE = "oldstyle",
OLDSTYLEBOLD = "oldstyle-bold",
UNKNOWN = "unknown"
}
export type SemanticFont = Alphabet.Font | ExtraFont | Alphabet.Embellish;
export declare const SemanticFont: {
SUPER: Alphabet.Embellish.SUPER;
SUB: Alphabet.Embellish.SUB;
CIRCLED: Alphabet.Embellish.CIRCLED;
PARENTHESIZED: Alphabet.Embellish.PARENTHESIZED;
PERIOD: Alphabet.Embellish.PERIOD;
NEGATIVECIRCLED: Alphabet.Embellish.NEGATIVECIRCLED;
DOUBLECIRCLED: Alphabet.Embellish.DOUBLECIRCLED;
CIRCLEDSANSSERIF: Alphabet.Embellish.CIRCLEDSANSSERIF;
NEGATIVECIRCLEDSANSSERIF: Alphabet.Embellish.NEGATIVECIRCLEDSANSSERIF;
COMMA: Alphabet.Embellish.COMMA;
SQUARED: Alphabet.Embellish.SQUARED;
NEGATIVESQUARED: Alphabet.Embellish.NEGATIVESQUARED;
CALIGRAPHIC: ExtraFont.CALIGRAPHIC;
CALIGRAPHICBOLD: ExtraFont.CALIGRAPHICBOLD;
OLDSTYLE: ExtraFont.OLDSTYLE;
OLDSTYLEBOLD: ExtraFont.OLDSTYLEBOLD;
UNKNOWN: ExtraFont.UNKNOWN;
BOLD: Alphabet.Font.BOLD;
BOLDFRAKTUR: Alphabet.Font.BOLDFRAKTUR;
BOLDITALIC: Alphabet.Font.BOLDITALIC;
BOLDSCRIPT: Alphabet.Font.BOLDSCRIPT;
DOUBLESTRUCK: Alphabet.Font.DOUBLESTRUCK;
DOUBLESTRUCKITALIC: Alphabet.Font.DOUBLESTRUCKITALIC;
FULLWIDTH: Alphabet.Font.FULLWIDTH;
FRAKTUR: Alphabet.Font.FRAKTUR;
ITALIC: Alphabet.Font.ITALIC;
MONOSPACE: Alphabet.Font.MONOSPACE;
NORMAL: Alphabet.Font.NORMAL;
SCRIPT: Alphabet.Font.SCRIPT;
SANSSERIF: Alphabet.Font.SANSSERIF;
SANSSERIFITALIC: Alphabet.Font.SANSSERIFITALIC;
SANSSERIFBOLD: Alphabet.Font.SANSSERIFBOLD;
SANSSERIFBOLDITALIC: Alphabet.Font.SANSSERIFBOLDITALIC;
};
declare enum SecondaryEnum {
ALLLETTERS = "allLetters",
D = "d",
BAR = "bar",
TILDE = "tilde"
}
export type SemanticSecondary = Alphabet.Base | SecondaryEnum;
export declare const SemanticSecondary: {
ALLLETTERS: SecondaryEnum.ALLLETTERS;
D: SecondaryEnum.D;
BAR: SecondaryEnum.BAR;
TILDE: SecondaryEnum.TILDE;
LATINCAP: Alphabet.Base.LATINCAP;
LATINSMALL: Alphabet.Base.LATINSMALL;
GREEKCAP: Alphabet.Base.GREEKCAP;
GREEKSMALL: Alphabet.Base.GREEKSMALL;
DIGIT: Alphabet.Base.DIGIT;
};
export {};

View File

@@ -0,0 +1,185 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticSecondary = exports.SemanticFont = exports.SemanticRole = exports.SemanticType = void 0;
const Alphabet = require("../speech_rules/alphabet.js");
var Types;
(function (Types) {
Types["PUNCTUATION"] = "punctuation";
Types["FENCE"] = "fence";
Types["NUMBER"] = "number";
Types["IDENTIFIER"] = "identifier";
Types["TEXT"] = "text";
Types["OPERATOR"] = "operator";
Types["RELATION"] = "relation";
Types["LARGEOP"] = "largeop";
Types["FUNCTION"] = "function";
Types["ACCENT"] = "accent";
Types["FENCED"] = "fenced";
Types["FRACTION"] = "fraction";
Types["PUNCTUATED"] = "punctuated";
Types["RELSEQ"] = "relseq";
Types["MULTIREL"] = "multirel";
Types["INFIXOP"] = "infixop";
Types["PREFIXOP"] = "prefixop";
Types["POSTFIXOP"] = "postfixop";
Types["APPL"] = "appl";
Types["INTEGRAL"] = "integral";
Types["BIGOP"] = "bigop";
Types["SQRT"] = "sqrt";
Types["ROOT"] = "root";
Types["LIMUPPER"] = "limupper";
Types["LIMLOWER"] = "limlower";
Types["LIMBOTH"] = "limboth";
Types["SUBSCRIPT"] = "subscript";
Types["SUPERSCRIPT"] = "superscript";
Types["UNDERSCORE"] = "underscore";
Types["OVERSCORE"] = "overscore";
Types["TENSOR"] = "tensor";
Types["TABLE"] = "table";
Types["MULTILINE"] = "multiline";
Types["MATRIX"] = "matrix";
Types["VECTOR"] = "vector";
Types["CASES"] = "cases";
Types["ROW"] = "row";
Types["LINE"] = "line";
Types["CELL"] = "cell";
Types["ENCLOSE"] = "enclose";
Types["INFERENCE"] = "inference";
Types["RULELABEL"] = "rulelabel";
Types["CONCLUSION"] = "conclusion";
Types["PREMISES"] = "premises";
Types["UNKNOWN"] = "unknown";
Types["EMPTY"] = "empty";
})(Types || (Types = {}));
exports.SemanticType = Object.assign({}, Types);
var Roles;
(function (Roles) {
Roles["COMMA"] = "comma";
Roles["SEMICOLON"] = "semicolon";
Roles["ELLIPSIS"] = "ellipsis";
Roles["FULLSTOP"] = "fullstop";
Roles["QUESTION"] = "question";
Roles["EXCLAMATION"] = "exclamation";
Roles["QUOTES"] = "quotes";
Roles["DASH"] = "dash";
Roles["TILDE"] = "tilde";
Roles["PRIME"] = "prime";
Roles["DEGREE"] = "degree";
Roles["VBAR"] = "vbar";
Roles["COLON"] = "colon";
Roles["OPENFENCE"] = "openfence";
Roles["CLOSEFENCE"] = "closefence";
Roles["APPLICATION"] = "application";
Roles["DUMMY"] = "dummy";
Roles["UNIT"] = "unit";
Roles["LABEL"] = "label";
Roles["OPEN"] = "open";
Roles["CLOSE"] = "close";
Roles["TOP"] = "top";
Roles["BOTTOM"] = "bottom";
Roles["NEUTRAL"] = "neutral";
Roles["METRIC"] = "metric";
Roles["LATINLETTER"] = "latinletter";
Roles["GREEKLETTER"] = "greekletter";
Roles["OTHERLETTER"] = "otherletter";
Roles["NUMBERSET"] = "numbersetletter";
Roles["INTEGER"] = "integer";
Roles["FLOAT"] = "float";
Roles["OTHERNUMBER"] = "othernumber";
Roles["INFTY"] = "infty";
Roles["MIXED"] = "mixed";
Roles["MULTIACCENT"] = "multiaccent";
Roles["OVERACCENT"] = "overaccent";
Roles["UNDERACCENT"] = "underaccent";
Roles["UNDEROVER"] = "underover";
Roles["SUBSUP"] = "subsup";
Roles["LEFTSUB"] = "leftsub";
Roles["LEFTSUPER"] = "leftsuper";
Roles["RIGHTSUB"] = "rightsub";
Roles["RIGHTSUPER"] = "rightsuper";
Roles["LEFTRIGHT"] = "leftright";
Roles["ABOVEBELOW"] = "abovebelow";
Roles["SETEMPTY"] = "set empty";
Roles["SETEXT"] = "set extended";
Roles["SETSINGLE"] = "set singleton";
Roles["SETCOLLECT"] = "set collection";
Roles["STRING"] = "string";
Roles["SPACE"] = "space";
Roles["ANNOTATION"] = "annotation";
Roles["TEXT"] = "text";
Roles["SEQUENCE"] = "sequence";
Roles["ENDPUNCT"] = "endpunct";
Roles["STARTPUNCT"] = "startpunct";
Roles["NEGATIVE"] = "negative";
Roles["POSITIVE"] = "positive";
Roles["NEGATION"] = "negation";
Roles["MULTIOP"] = "multiop";
Roles["PREFIXOP"] = "prefix operator";
Roles["POSTFIXOP"] = "postfix operator";
Roles["LIMFUNC"] = "limit function";
Roles["INFIXFUNC"] = "infix function";
Roles["PREFIXFUNC"] = "prefix function";
Roles["POSTFIXFUNC"] = "postfix function";
Roles["SIMPLEFUNC"] = "simple function";
Roles["COMPFUNC"] = "composed function";
Roles["SUM"] = "sum";
Roles["INTEGRAL"] = "integral";
Roles["GEOMETRY"] = "geometry";
Roles["BOX"] = "box";
Roles["BLOCK"] = "block";
Roles["ADDITION"] = "addition";
Roles["MULTIPLICATION"] = "multiplication";
Roles["SUBTRACTION"] = "subtraction";
Roles["IMPLICIT"] = "implicit";
Roles["DIVISION"] = "division";
Roles["VULGAR"] = "vulgar";
Roles["EQUALITY"] = "equality";
Roles["INEQUALITY"] = "inequality";
Roles["ARROW"] = "arrow";
Roles["ELEMENT"] = "element";
Roles["NONELEMENT"] = "nonelement";
Roles["REELEMENT"] = "reelement";
Roles["RENONELEMENT"] = "renonelement";
Roles["SET"] = "set";
Roles["DETERMINANT"] = "determinant";
Roles["ROWVECTOR"] = "rowvector";
Roles["BINOMIAL"] = "binomial";
Roles["SQUAREMATRIX"] = "squarematrix";
Roles["CYCLE"] = "cycle";
Roles["MULTILINE"] = "multiline";
Roles["MATRIX"] = "matrix";
Roles["VECTOR"] = "vector";
Roles["CASES"] = "cases";
Roles["TABLE"] = "table";
Roles["CAYLEY"] = "cayley";
Roles["PROOF"] = "proof";
Roles["LEFT"] = "left";
Roles["RIGHT"] = "right";
Roles["UP"] = "up";
Roles["DOWN"] = "down";
Roles["FINAL"] = "final";
Roles["SINGLE"] = "single";
Roles["HYP"] = "hyp";
Roles["AXIOM"] = "axiom";
Roles["LOGIC"] = "logic";
Roles["UNKNOWN"] = "unknown";
Roles["MGLYPH"] = "mglyph";
})(Roles || (Roles = {}));
exports.SemanticRole = Object.assign({}, Roles);
var ExtraFont;
(function (ExtraFont) {
ExtraFont["CALIGRAPHIC"] = "caligraphic";
ExtraFont["CALIGRAPHICBOLD"] = "caligraphic-bold";
ExtraFont["OLDSTYLE"] = "oldstyle";
ExtraFont["OLDSTYLEBOLD"] = "oldstyle-bold";
ExtraFont["UNKNOWN"] = "unknown";
})(ExtraFont || (ExtraFont = {}));
exports.SemanticFont = Object.assign(Object.assign(Object.assign({}, Alphabet.Font), ExtraFont), Alphabet.Embellish);
var SecondaryEnum;
(function (SecondaryEnum) {
SecondaryEnum["ALLLETTERS"] = "allLetters";
SecondaryEnum["D"] = "d";
SecondaryEnum["BAR"] = "bar";
SecondaryEnum["TILDE"] = "tilde";
})(SecondaryEnum || (SecondaryEnum = {}));
exports.SemanticSecondary = Object.assign(Object.assign({}, Alphabet.Base), SecondaryEnum);

View File

@@ -0,0 +1,67 @@
import { SemanticMeaning, SemanticFont, SemanticRole, SemanticType } from './semantic_meaning.js';
declare const enum Attribute {
EMBELLISHED = "embellished",
FENCEPOINTER = "fencepointer",
FONT = "font",
ID = "id",
ANNOTATION = "annotation",
ROLE = "role",
TYPE = "type",
CHILDREN = "children",
CONTENT = "content",
TEXT = "$t"
}
export declare class SemanticNode {
id: number;
mathml: Element[];
parent: SemanticNode;
type: SemanticType;
role: SemanticRole;
font: SemanticFont;
embellished: SemanticType;
fencePointer: string;
childNodes: SemanticNode[];
textContent: string;
mathmlTree: Element;
contentNodes: SemanticNode[];
annotation: {
[key: string]: string[];
};
attributes: {
[key: string]: string;
};
nobreaking: boolean;
static fromXml(xml: Element): SemanticNode;
private static setAttribute;
private static processChildren;
constructor(id: number);
querySelectorAll(pred: (p1: SemanticNode) => boolean): SemanticNode[];
xml(xml: Document, brief?: boolean): Element;
toString(brief?: boolean): string;
allAttributes(): [Attribute, string][];
private annotationXml;
attributesXml(): string;
toJson(): any;
updateContent(content: string, text?: boolean): void;
addMathmlNodes(mmlNodes: Element[]): void;
appendChild(child: SemanticNode): void;
replaceChild(oldNode: SemanticNode, newNode: SemanticNode): void;
appendContentNode(node: SemanticNode): void;
removeContentNode(node: SemanticNode): void;
equals(node: SemanticNode): boolean;
displayTree(): void;
addAnnotation(domain: string, annotation: string): void;
getAnnotation(domain: string): string[];
hasAnnotation(domain: string, annotation: string): boolean;
parseAnnotation(stateStr: string): void;
meaning(): SemanticMeaning;
private xmlAttributes;
private addExternalAttributes;
private static escapeValue;
parseAttributes(stateStr: string): void;
private removeMathmlNodes;
private displayTree_;
private mathmlTreeString;
private addAnnotation_;
}
export {};

View File

@@ -0,0 +1,343 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticNode = 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 SemanticUtil = require("./semantic_util.js");
class SemanticNode {
static fromXml(xml) {
const id = parseInt(xml.getAttribute('id'), 10);
const node = new SemanticNode(id);
node.type = xml.tagName;
SemanticNode.setAttribute(node, xml, 'role');
SemanticNode.setAttribute(node, xml, 'font');
SemanticNode.setAttribute(node, xml, 'embellished');
SemanticNode.setAttribute(node, xml, 'fencepointer', 'fencePointer');
if (xml.getAttribute('annotation')) {
node.parseAnnotation(xml.getAttribute('annotation'));
}
SemanticUtil.addAttributes(node, xml);
SemanticNode.processChildren(node, xml);
return node;
}
static setAttribute(node, xml, attribute, opt_name) {
opt_name = opt_name || attribute;
const value = xml.getAttribute(attribute);
if (value) {
node[opt_name] = value;
}
}
static processChildren(node, xml) {
for (const child of DomUtil.toArray(xml.childNodes)) {
if (child.nodeType === DomUtil.NodeType.TEXT_NODE) {
node.textContent = child.textContent;
continue;
}
const children = DomUtil.toArray(child.childNodes).map(SemanticNode.fromXml);
children.forEach((x) => (x.parent = node));
if (DomUtil.tagName(child) === 'CONTENT') {
node.contentNodes = children;
}
else {
node.childNodes = children;
}
}
}
constructor(id) {
this.id = id;
this.mathml = [];
this.parent = null;
this.type = semantic_meaning_js_1.SemanticType.UNKNOWN;
this.role = semantic_meaning_js_1.SemanticRole.UNKNOWN;
this.font = semantic_meaning_js_1.SemanticFont.UNKNOWN;
this.embellished = null;
this.fencePointer = '';
this.childNodes = [];
this.textContent = '';
this.mathmlTree = null;
this.contentNodes = [];
this.annotation = {};
this.attributes = {};
this.nobreaking = false;
}
querySelectorAll(pred) {
let result = [];
for (let i = 0, child; (child = this.childNodes[i]); i++) {
result = result.concat(child.querySelectorAll(pred));
}
for (let i = 0, content; (content = this.contentNodes[i]); i++) {
result = result.concat(content.querySelectorAll(pred));
}
if (pred(this)) {
result.unshift(this);
}
return result;
}
xml(xml, brief) {
const xmlNodeList = function (tag, nodes) {
const xmlNodes = nodes.map(function (x) {
return x.xml(xml, brief);
});
const tagNode = xml.createElementNS('', tag);
for (let i = 0, child; (child = xmlNodes[i]); i++) {
tagNode.appendChild(child);
}
return tagNode;
};
const node = xml.createElementNS('', this.type);
if (!brief) {
this.xmlAttributes(node);
}
node.textContent = this.textContent;
if (this.contentNodes.length > 0) {
node.appendChild(xmlNodeList("content", this.contentNodes));
}
if (this.childNodes.length > 0) {
node.appendChild(xmlNodeList("children", this.childNodes));
}
return node;
}
toString(brief = false) {
const xml = DomUtil.parseInput('<snode/>');
return DomUtil.serializeXml(this.xml(xml.ownerDocument, brief));
}
allAttributes() {
const attributes = [];
attributes.push(["role", this.role]);
if (this.font !== semantic_meaning_js_1.SemanticFont.UNKNOWN) {
attributes.push(["font", this.font]);
}
if (Object.keys(this.annotation).length) {
attributes.push(["annotation", this.annotationXml()]);
}
if (this.embellished) {
attributes.push(["embellished", this.embellished]);
}
if (this.fencePointer) {
attributes.push(["fencepointer", this.fencePointer]);
}
attributes.push(["id", this.id.toString()]);
return attributes;
}
annotationXml() {
const result = [];
for (const [key, val] of Object.entries(this.annotation)) {
val.forEach((mean) => result.push(key + ':' + mean));
}
return result.join(';');
}
attributesXml() {
const result = [];
for (const [key, value] of Object.entries(this.attributes)) {
result.push(key + ':' + SemanticNode.escapeValue(value));
}
return result.join(';');
}
toJson() {
const json = {};
json["type"] = this.type;
const attributes = this.allAttributes();
for (let i = 0, attr; (attr = attributes[i]); i++) {
json[attr[0]] = attr[1].toString();
}
if (this.textContent) {
json["$t"] = this.textContent;
}
if (this.childNodes.length) {
json["children"] = this.childNodes.map(function (child) {
return child.toJson();
});
}
if (this.contentNodes.length) {
json["content"] = this.contentNodes.map(function (child) {
return child.toJson();
});
}
return json;
}
updateContent(content, text) {
const newContent = text
? content
.replace(/^[ \f\n\r\t\v\u200b]*/, '')
.replace(/[ \f\n\r\t\v\u200b]*$/, '')
: content.trim();
content = content && !newContent ? content : newContent;
if (this.textContent === content) {
return;
}
const meaning = semantic_attr_js_1.SemanticMap.Meaning.get(content.replace(/\s/g, ' '));
this.textContent = content;
this.role = meaning.role;
this.type = meaning.type;
this.font = meaning.font;
}
addMathmlNodes(mmlNodes) {
for (let i = 0, mml; (mml = mmlNodes[i]); i++) {
if (this.mathml.indexOf(mml) === -1) {
this.mathml.push(mml);
}
}
}
appendChild(child) {
this.childNodes.push(child);
this.addMathmlNodes(child.mathml);
child.parent = this;
}
replaceChild(oldNode, newNode) {
const index = this.childNodes.indexOf(oldNode);
if (index === -1) {
return;
}
oldNode.parent = null;
newNode.parent = this;
this.childNodes[index] = newNode;
const removeMathml = oldNode.mathml.filter(function (x) {
return newNode.mathml.indexOf(x) === -1;
});
const addMathml = newNode.mathml.filter(function (x) {
return oldNode.mathml.indexOf(x) === -1;
});
this.removeMathmlNodes(removeMathml);
this.addMathmlNodes(addMathml);
}
appendContentNode(node) {
if (node) {
this.contentNodes.push(node);
this.addMathmlNodes(node.mathml);
node.parent = this;
}
}
removeContentNode(node) {
if (node) {
const index = this.contentNodes.indexOf(node);
if (index !== -1) {
this.contentNodes.slice(index, 1);
}
}
}
equals(node) {
if (!node) {
return false;
}
if (this.type !== node.type ||
this.role !== node.role ||
this.textContent !== node.textContent ||
this.childNodes.length !== node.childNodes.length ||
this.contentNodes.length !== node.contentNodes.length) {
return false;
}
for (let i = 0, node1, node2; (node1 = this.childNodes[i]), (node2 = node.childNodes[i]); i++) {
if (!node1.equals(node2)) {
return false;
}
}
for (let i = 0, node1, node2; (node1 = this.contentNodes[i]), (node2 = node.contentNodes[i]); i++) {
if (!node1.equals(node2)) {
return false;
}
}
return true;
}
displayTree() {
console.info(this.displayTree_(0));
}
addAnnotation(domain, annotation) {
if (annotation) {
this.addAnnotation_(domain, annotation);
}
}
getAnnotation(domain) {
const content = this.annotation[domain];
return content ? content : [];
}
hasAnnotation(domain, annotation) {
const content = this.annotation[domain];
if (!content) {
return false;
}
return content.indexOf(annotation) !== -1;
}
parseAnnotation(stateStr) {
const annotations = stateStr.split(';');
for (let i = 0, l = annotations.length; i < l; i++) {
const annotation = annotations[i].split(':');
this.addAnnotation(annotation[0], annotation[1]);
}
}
meaning() {
return { type: this.type, role: this.role, font: this.font };
}
xmlAttributes(node) {
const attributes = this.allAttributes();
for (let i = 0, attr; (attr = attributes[i]); i++) {
node.setAttribute(attr[0], attr[1]);
}
this.addExternalAttributes(node);
}
addExternalAttributes(node) {
for (const [attr, val] of Object.entries(this.attributes)) {
node.setAttribute(attr, val);
}
}
static escapeValue(value) {
return value.replace(/;/g, '\\0003B');
}
parseAttributes(stateStr) {
if (!stateStr)
return;
const attributes = stateStr.split(';');
for (let i = 0, l = attributes.length; i < l; i++) {
const [key, ...values] = attributes[i].split(':');
if (key) {
this.attributes[key] = values.join('').replace(/\\0003B/g, ';');
}
}
}
removeMathmlNodes(mmlNodes) {
const mmlList = this.mathml;
for (let i = 0, mml; (mml = mmlNodes[i]); i++) {
const index = mmlList.indexOf(mml);
if (index !== -1) {
mmlList.splice(index, 1);
}
}
this.mathml = mmlList;
}
displayTree_(depth) {
depth++;
const depthString = Array(depth).join(' ');
let result = '';
result += '\n' + depthString + this.toString();
result += '\n' + depthString + 'MathmlTree:';
result += '\n' + depthString + this.mathmlTreeString();
result += '\n' + depthString + 'MathML:';
for (let i = 0, mml; (mml = this.mathml[i]); i++) {
result += '\n' + depthString + mml.toString();
}
result += '\n' + depthString + 'Begin Content';
this.contentNodes.forEach(function (x) {
result += x.displayTree_(depth);
});
result += '\n' + depthString + 'End Content';
result += '\n' + depthString + 'Begin Children';
this.childNodes.forEach(function (x) {
result += x.displayTree_(depth);
});
result += '\n' + depthString + 'End Children';
return result;
}
mathmlTreeString() {
return this.mathmlTree ? this.mathmlTree.toString() : 'EMPTY';
}
addAnnotation_(domain, annotation) {
const content = this.annotation[domain];
if (content && !content.includes(annotation)) {
content.push(annotation);
}
else {
this.annotation[domain] = [annotation];
}
}
}
exports.SemanticNode = SemanticNode;

View File

@@ -0,0 +1,17 @@
import { SemanticFont, SemanticType } from './semantic_meaning.js';
import { SemanticDefault } from './semantic_default.js';
import { SemanticNodeCollator } from './semantic_default.js';
import { SemanticNode } from './semantic_node.js';
export declare class SemanticNodeFactory {
leafMap: SemanticNodeCollator;
defaultMap: SemanticDefault;
private idCounter_;
makeNode(id: number): SemanticNode;
makeUnprocessed(mml: Element): SemanticNode;
makeEmptyNode(): SemanticNode;
makeContentNode(content: string): SemanticNode;
makeMultipleContentNodes(num: number, content: string): SemanticNode[];
makeLeafNode(content: string, font: SemanticFont): SemanticNode;
makeBranchNode(type: SemanticType, children: SemanticNode[], contentNodes: SemanticNode[], opt_content?: string): SemanticNode;
private createNode_;
}

View File

@@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticNodeFactory = void 0;
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const semantic_default_js_1 = require("./semantic_default.js");
const semantic_default_js_2 = require("./semantic_default.js");
const semantic_node_js_1 = require("./semantic_node.js");
class SemanticNodeFactory {
constructor() {
this.leafMap = new semantic_default_js_2.SemanticNodeCollator();
this.defaultMap = new semantic_default_js_1.SemanticDefault();
this.idCounter_ = -1;
}
makeNode(id) {
return this.createNode_(id);
}
makeUnprocessed(mml) {
const node = this.createNode_();
node.mathml = [mml];
node.mathmlTree = mml;
return node;
}
makeEmptyNode() {
const node = this.createNode_();
node.type = semantic_meaning_js_1.SemanticType.EMPTY;
return node;
}
makeContentNode(content) {
const node = this.createNode_();
node.updateContent(content);
return node;
}
makeMultipleContentNodes(num, content) {
const nodes = [];
for (let i = 0; i < num; i++) {
nodes.push(this.makeContentNode(content));
}
return nodes;
}
makeLeafNode(content, font) {
if (!content) {
return this.makeEmptyNode();
}
const node = this.makeContentNode(content);
node.font = font || node.font;
const meaning = this.defaultMap.getNode(node);
if (meaning) {
node.type = meaning.type;
node.role = meaning.role;
node.font = meaning.font;
}
this.leafMap.addNode(node);
return node;
}
makeBranchNode(type, children, contentNodes, opt_content) {
const node = this.createNode_();
if (opt_content) {
node.updateContent(opt_content);
}
node.type = type;
node.childNodes = children;
node.contentNodes = contentNodes;
children.concat(contentNodes).forEach(function (x) {
x.parent = node;
node.addMathmlNodes(x.mathml);
});
return node;
}
createNode_(id) {
if (typeof id !== 'undefined') {
this.idCounter_ = Math.max(this.idCounter_, id);
}
else {
id = ++this.idCounter_;
}
return new semantic_node_js_1.SemanticNode(id);
}
}
exports.SemanticNodeFactory = SemanticNodeFactory;

View File

@@ -0,0 +1,2 @@
import { SemanticMeaning } from './semantic_meaning.js';
export declare function reduce(meanings: SemanticMeaning[]): SemanticMeaning[];

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduce = reduce;
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const comparators = [];
function add(comparator) {
comparators.push(comparator);
}
function apply(meaning1, meaning2) {
for (let i = 0, comparator; (comparator = comparators[i]); i++) {
const result = comparator.compare(meaning1, meaning2);
if (result !== 0) {
return result;
}
}
return 0;
}
function sort(meanings) {
meanings.sort(apply);
}
function reduce(meanings) {
if (meanings.length <= 1) {
return meanings;
}
const copy = meanings.slice();
sort(copy);
const result = [];
let last;
do {
last = copy.pop();
result.push(last);
} while (last && copy.length && apply(copy[copy.length - 1], last) === 0);
return result;
}
class SemanticComparator {
constructor(comparator, type = null) {
this.comparator = comparator;
this.type = type;
add(this);
}
compare(meaning1, meaning2) {
return this.type &&
this.type === meaning1.type &&
this.type === meaning2.type
? this.comparator(meaning1, meaning2)
: 0;
}
}
function simpleFunction(meaning1, meaning2) {
if (meaning1.role === semantic_meaning_js_1.SemanticRole.SIMPLEFUNC) {
return 1;
}
if (meaning2.role === semantic_meaning_js_1.SemanticRole.SIMPLEFUNC) {
return -1;
}
return 0;
}
new SemanticComparator(simpleFunction, semantic_meaning_js_1.SemanticType.IDENTIFIER);

View File

@@ -0,0 +1,19 @@
import { SemanticNode } from './semantic_node.js';
import { SemanticNodeFactory } from './semantic_node_factory.js';
export interface SemanticParser<T> {
parse(representation: T): SemanticNode;
parseList(list: T[]): SemanticNode[];
getFactory(): SemanticNodeFactory;
setFactory(factory: SemanticNodeFactory): void;
getType(): string;
}
export declare abstract class SemanticAbstractParser<T> implements SemanticParser<T> {
private type;
private factory_;
constructor(type: string);
abstract parse(representation: T): SemanticNode;
getFactory(): SemanticNodeFactory;
setFactory(factory: SemanticNodeFactory): void;
getType(): string;
parseList(list: T[]): SemanticNode[];
}

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticAbstractParser = void 0;
const semantic_node_factory_js_1 = require("./semantic_node_factory.js");
class SemanticAbstractParser {
constructor(type) {
this.type = type;
this.factory_ = new semantic_node_factory_js_1.SemanticNodeFactory();
}
getFactory() {
return this.factory_;
}
setFactory(factory) {
this.factory_ = factory;
}
getType() {
return this.type;
}
parseList(list) {
const result = [];
for (let i = 0, element; (element = list[i]); i++) {
result.push(this.parse(element));
}
return result;
}
}
exports.SemanticAbstractParser = SemanticAbstractParser;

View File

@@ -0,0 +1,40 @@
import { SemanticRole, SemanticType } from './semantic_meaning.js';
import { SemanticNode } from './semantic_node.js';
export declare function isType(node: SemanticNode, attr: SemanticType): boolean;
export declare function isRole(node: SemanticNode, attr: SemanticRole): boolean;
export declare function isAccent(node: SemanticNode): boolean;
export declare function isSimpleFunctionScope(node: SemanticNode): boolean;
export declare function isPrefixFunctionBoundary(node: SemanticNode): boolean;
export declare function isBigOpBoundary(node: SemanticNode): boolean;
export declare function isIntegralDxBoundary(firstNode: SemanticNode, secondNode: SemanticNode): boolean;
export declare function isIntegralDxBoundarySingle(node: SemanticNode): boolean;
export declare function isGeneralFunctionBoundary(node: SemanticNode): boolean;
export declare function isEmbellished(node: SemanticNode): SemanticType | null;
export declare function isOperator(node: SemanticNode): boolean;
export declare function isRelation(node: SemanticNode): boolean;
export declare function isPunctuation(node: SemanticNode): boolean;
export declare function isFence(node: SemanticNode): boolean;
export declare function isElligibleEmbellishedFence(node: SemanticNode): boolean;
export declare function isTableOrMultiline(node: SemanticNode): boolean;
export declare function tableIsMatrixOrVector(node: SemanticNode): boolean;
export declare function isFencedElement(node: SemanticNode): boolean;
export declare function tableIsCases(_table: SemanticNode, prevNodes: SemanticNode[]): boolean;
export declare function tableIsMultiline(table: SemanticNode): boolean;
export declare function lineIsLabelled(line: SemanticNode): boolean;
export declare function isBinomial(table: SemanticNode): boolean;
export declare function isLimitBase(node: SemanticNode): boolean;
export declare function isSimpleFunctionHead(node: SemanticNode): boolean;
export declare function singlePunctAtPosition(nodes: SemanticNode[], puncts: SemanticNode[], position: number): boolean;
export declare function isSimpleFunction(node: SemanticNode): boolean;
export declare function isSetNode(node: SemanticNode): boolean;
export declare function isSingletonSetContent(node: SemanticNode): boolean;
export declare function isUnitCounter(node: SemanticNode): boolean;
export declare function isPureUnit(node: SemanticNode): boolean;
export declare function isUnitProduct(node: SemanticNode): boolean;
export declare function isImplicit(node: SemanticNode): boolean;
export declare function isImplicitOp(node: SemanticNode): boolean;
export declare function isNeutralFence(fence: SemanticNode): boolean;
export declare function compareNeutralFences(fence1: SemanticNode, fence2: SemanticNode): boolean;
export declare function elligibleLeftNeutral(fence: SemanticNode): boolean;
export declare function elligibleRightNeutral(fence: SemanticNode): boolean;
export declare function isMembership(element: SemanticNode): boolean;

View File

@@ -0,0 +1,353 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isType = isType;
exports.isRole = isRole;
exports.isAccent = isAccent;
exports.isSimpleFunctionScope = isSimpleFunctionScope;
exports.isPrefixFunctionBoundary = isPrefixFunctionBoundary;
exports.isBigOpBoundary = isBigOpBoundary;
exports.isIntegralDxBoundary = isIntegralDxBoundary;
exports.isIntegralDxBoundarySingle = isIntegralDxBoundarySingle;
exports.isGeneralFunctionBoundary = isGeneralFunctionBoundary;
exports.isEmbellished = isEmbellished;
exports.isOperator = isOperator;
exports.isRelation = isRelation;
exports.isPunctuation = isPunctuation;
exports.isFence = isFence;
exports.isElligibleEmbellishedFence = isElligibleEmbellishedFence;
exports.isTableOrMultiline = isTableOrMultiline;
exports.tableIsMatrixOrVector = tableIsMatrixOrVector;
exports.isFencedElement = isFencedElement;
exports.tableIsCases = tableIsCases;
exports.tableIsMultiline = tableIsMultiline;
exports.lineIsLabelled = lineIsLabelled;
exports.isBinomial = isBinomial;
exports.isLimitBase = isLimitBase;
exports.isSimpleFunctionHead = isSimpleFunctionHead;
exports.singlePunctAtPosition = singlePunctAtPosition;
exports.isSimpleFunction = isSimpleFunction;
exports.isSetNode = isSetNode;
exports.isSingletonSetContent = isSingletonSetContent;
exports.isUnitCounter = isUnitCounter;
exports.isPureUnit = isPureUnit;
exports.isUnitProduct = isUnitProduct;
exports.isImplicit = isImplicit;
exports.isImplicitOp = isImplicitOp;
exports.isNeutralFence = isNeutralFence;
exports.compareNeutralFences = compareNeutralFences;
exports.elligibleLeftNeutral = elligibleLeftNeutral;
exports.elligibleRightNeutral = elligibleRightNeutral;
exports.isMembership = isMembership;
const semantic_attr_js_1 = require("./semantic_attr.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const semantic_util_js_1 = require("./semantic_util.js");
function isType(node, attr) {
return node.type === attr;
}
function embellishedType(node, attr) {
return node.embellished === attr;
}
function isRole(node, attr) {
return node.role === attr;
}
function isAccent(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.FENCE) ||
isType(node, semantic_meaning_js_1.SemanticType.PUNCTUATION) ||
isType(node, semantic_meaning_js_1.SemanticType.OPERATOR) ||
isType(node, semantic_meaning_js_1.SemanticType.RELATION));
}
function isSimpleFunctionScope(node) {
const children = node.childNodes;
if (children.length === 0) {
return true;
}
if (children.length > 1) {
return false;
}
const child = children[0];
if (child.type === semantic_meaning_js_1.SemanticType.INFIXOP) {
if (child.role !== semantic_meaning_js_1.SemanticRole.IMPLICIT) {
return false;
}
if (child.childNodes.some((x) => isType(x, semantic_meaning_js_1.SemanticType.INFIXOP))) {
return false;
}
}
return true;
}
function isPrefixFunctionBoundary(node) {
return ((isOperator(node) && !isRole(node, semantic_meaning_js_1.SemanticRole.DIVISION)) ||
isType(node, semantic_meaning_js_1.SemanticType.APPL) ||
isGeneralFunctionBoundary(node));
}
function isBigOpBoundary(node) {
return isOperator(node) || isGeneralFunctionBoundary(node);
}
function isIntegralDxBoundary(firstNode, secondNode) {
return (!!secondNode &&
isType(secondNode, semantic_meaning_js_1.SemanticType.IDENTIFIER) &&
semantic_attr_js_1.SemanticMap.Secondary.has(firstNode.textContent, semantic_meaning_js_1.SemanticSecondary.D));
}
function isIntegralDxBoundarySingle(node) {
if (isType(node, semantic_meaning_js_1.SemanticType.IDENTIFIER)) {
const firstChar = node.textContent[0];
return (firstChar &&
node.textContent[1] &&
semantic_attr_js_1.SemanticMap.Secondary.has(firstChar, semantic_meaning_js_1.SemanticSecondary.D));
}
return false;
}
function isGeneralFunctionBoundary(node) {
return isRelation(node) || isPunctuation(node);
}
function isEmbellished(node) {
if (node.embellished) {
return node.embellished;
}
if (isEmbellishedType(node.type)) {
return node.type;
}
return null;
}
function isEmbellishedType(type) {
return (type === semantic_meaning_js_1.SemanticType.OPERATOR ||
type === semantic_meaning_js_1.SemanticType.RELATION ||
type === semantic_meaning_js_1.SemanticType.FENCE ||
type === semantic_meaning_js_1.SemanticType.PUNCTUATION);
}
function isOperator(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.OPERATOR) ||
embellishedType(node, semantic_meaning_js_1.SemanticType.OPERATOR));
}
function isRelation(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.RELATION) ||
embellishedType(node, semantic_meaning_js_1.SemanticType.RELATION));
}
function isPunctuation(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.PUNCTUATION) ||
embellishedType(node, semantic_meaning_js_1.SemanticType.PUNCTUATION));
}
function isFence(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.FENCE) ||
embellishedType(node, semantic_meaning_js_1.SemanticType.FENCE));
}
function isElligibleEmbellishedFence(node) {
if (!node || !isFence(node)) {
return false;
}
if (!node.embellished) {
return true;
}
return recurseBaseNode(node);
}
function bothSide(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.TENSOR) &&
(!isType(node.childNodes[1], semantic_meaning_js_1.SemanticType.EMPTY) ||
!isType(node.childNodes[2], semantic_meaning_js_1.SemanticType.EMPTY)) &&
(!isType(node.childNodes[3], semantic_meaning_js_1.SemanticType.EMPTY) ||
!isType(node.childNodes[4], semantic_meaning_js_1.SemanticType.EMPTY)));
}
function recurseBaseNode(node) {
if (!node.embellished) {
return true;
}
if (bothSide(node)) {
return false;
}
if (isRole(node, semantic_meaning_js_1.SemanticRole.CLOSE) && isType(node, semantic_meaning_js_1.SemanticType.TENSOR)) {
return false;
}
if (isRole(node, semantic_meaning_js_1.SemanticRole.OPEN) &&
(isType(node, semantic_meaning_js_1.SemanticType.SUBSCRIPT) ||
isType(node, semantic_meaning_js_1.SemanticType.SUPERSCRIPT))) {
return false;
}
return recurseBaseNode(node.childNodes[0]);
}
function isTableOrMultiline(node) {
return (!!node &&
(isType(node, semantic_meaning_js_1.SemanticType.TABLE) || isType(node, semantic_meaning_js_1.SemanticType.MULTILINE)));
}
function tableIsMatrixOrVector(node) {
return (!!node && isFencedElement(node) && isTableOrMultiline(node.childNodes[0]));
}
function isFencedElement(node) {
return (!!node &&
isType(node, semantic_meaning_js_1.SemanticType.FENCED) &&
(isRole(node, semantic_meaning_js_1.SemanticRole.LEFTRIGHT) || isNeutralFence(node)) &&
node.childNodes.length === 1);
}
function tableIsCases(_table, prevNodes) {
return (prevNodes.length > 0 &&
isRole(prevNodes[prevNodes.length - 1], semantic_meaning_js_1.SemanticRole.OPENFENCE));
}
function tableIsMultiline(table) {
return table.childNodes.every(function (row) {
const length = row.childNodes.length;
return length <= 1;
});
}
function lineIsLabelled(line) {
return (isType(line, semantic_meaning_js_1.SemanticType.LINE) &&
line.contentNodes.length &&
isRole(line.contentNodes[0], semantic_meaning_js_1.SemanticRole.LABEL));
}
function isBinomial(table) {
return table.childNodes.length === 2;
}
function isLimitBase(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.LARGEOP) ||
isType(node, semantic_meaning_js_1.SemanticType.LIMBOTH) ||
isType(node, semantic_meaning_js_1.SemanticType.LIMLOWER) ||
isType(node, semantic_meaning_js_1.SemanticType.LIMUPPER) ||
(isType(node, semantic_meaning_js_1.SemanticType.FUNCTION) &&
isRole(node, semantic_meaning_js_1.SemanticRole.LIMFUNC)) ||
((isType(node, semantic_meaning_js_1.SemanticType.OVERSCORE) ||
isType(node, semantic_meaning_js_1.SemanticType.UNDERSCORE)) &&
isLimitBase(node.childNodes[0])));
}
function isSimpleFunctionHead(node) {
return (node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER ||
node.role === semantic_meaning_js_1.SemanticRole.LATINLETTER ||
node.role === semantic_meaning_js_1.SemanticRole.GREEKLETTER ||
node.role === semantic_meaning_js_1.SemanticRole.OTHERLETTER);
}
function singlePunctAtPosition(nodes, puncts, position) {
return (puncts.length === 1 &&
(nodes[position].type === semantic_meaning_js_1.SemanticType.PUNCTUATION ||
nodes[position].embellished === semantic_meaning_js_1.SemanticType.PUNCTUATION) &&
nodes[position] === puncts[0]);
}
function isSimpleFunction(node) {
return (isType(node, semantic_meaning_js_1.SemanticType.IDENTIFIER) &&
isRole(node, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC));
}
function isLeftBrace(node) {
const leftBrace = ['{', '﹛', ''];
return !!node && leftBrace.indexOf(node.textContent) !== -1;
}
function isRightBrace(node) {
const rightBrace = ['}', '﹜', ''];
return !!node && rightBrace.indexOf(node.textContent) !== -1;
}
function isSetNode(node) {
return (isLeftBrace(node.contentNodes[0]) && isRightBrace(node.contentNodes[1]));
}
const illegalSingleton = [
semantic_meaning_js_1.SemanticType.PUNCTUATION,
semantic_meaning_js_1.SemanticType.PUNCTUATED,
semantic_meaning_js_1.SemanticType.RELSEQ,
semantic_meaning_js_1.SemanticType.MULTIREL,
semantic_meaning_js_1.SemanticType.TABLE,
semantic_meaning_js_1.SemanticType.MULTILINE,
semantic_meaning_js_1.SemanticType.CASES,
semantic_meaning_js_1.SemanticType.INFERENCE
];
const scriptedElement = [
semantic_meaning_js_1.SemanticType.LIMUPPER,
semantic_meaning_js_1.SemanticType.LIMLOWER,
semantic_meaning_js_1.SemanticType.LIMBOTH,
semantic_meaning_js_1.SemanticType.SUBSCRIPT,
semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
semantic_meaning_js_1.SemanticType.UNDERSCORE,
semantic_meaning_js_1.SemanticType.OVERSCORE,
semantic_meaning_js_1.SemanticType.TENSOR
];
function isSingletonSetContent(node) {
const type = node.type;
if (illegalSingleton.indexOf(type) !== -1 ||
(type === semantic_meaning_js_1.SemanticType.INFIXOP && node.role !== semantic_meaning_js_1.SemanticRole.IMPLICIT)) {
return false;
}
if (type === semantic_meaning_js_1.SemanticType.FENCED) {
return node.role === semantic_meaning_js_1.SemanticRole.LEFTRIGHT
? isSingletonSetContent(node.childNodes[0])
: true;
}
if (scriptedElement.indexOf(type) !== -1) {
return isSingletonSetContent(node.childNodes[0]);
}
return true;
}
function isNumber(node) {
return (node.type === semantic_meaning_js_1.SemanticType.NUMBER &&
(node.role === semantic_meaning_js_1.SemanticRole.INTEGER || node.role === semantic_meaning_js_1.SemanticRole.FLOAT));
}
function isUnitCounter(node) {
return (isNumber(node) ||
node.role === semantic_meaning_js_1.SemanticRole.VULGAR ||
node.role === semantic_meaning_js_1.SemanticRole.MIXED);
}
function isPureUnit(node) {
const children = node.childNodes;
return (node.role === semantic_meaning_js_1.SemanticRole.UNIT &&
(!children.length || children[0].role === semantic_meaning_js_1.SemanticRole.UNIT));
}
function isUnitProduct(node) {
const children = node.childNodes;
return (node.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
(node.role === semantic_meaning_js_1.SemanticRole.MULTIPLICATION ||
node.role === semantic_meaning_js_1.SemanticRole.IMPLICIT) &&
children.length &&
(isPureUnit(children[0]) || isUnitCounter(children[0])) &&
node.childNodes.slice(1).every(isPureUnit));
}
function isImplicit(node) {
return (node.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
(node.role === semantic_meaning_js_1.SemanticRole.IMPLICIT ||
(node.role === semantic_meaning_js_1.SemanticRole.UNIT &&
!!node.contentNodes.length &&
node.contentNodes[0].textContent === semantic_attr_js_1.NamedSymbol.invisibleTimes)));
}
function isImplicitOp(node) {
return (node.type === semantic_meaning_js_1.SemanticType.INFIXOP && node.role === semantic_meaning_js_1.SemanticRole.IMPLICIT);
}
function isNeutralFence(fence) {
return (fence.role === semantic_meaning_js_1.SemanticRole.NEUTRAL || fence.role === semantic_meaning_js_1.SemanticRole.METRIC);
}
function compareNeutralFences(fence1, fence2) {
return (isNeutralFence(fence1) &&
isNeutralFence(fence2) &&
(0, semantic_util_js_1.getEmbellishedInner)(fence1).textContent ===
(0, semantic_util_js_1.getEmbellishedInner)(fence2).textContent);
}
function elligibleLeftNeutral(fence) {
if (!isNeutralFence(fence)) {
return false;
}
if (!fence.embellished) {
return true;
}
if (fence.type === semantic_meaning_js_1.SemanticType.SUPERSCRIPT ||
fence.type === semantic_meaning_js_1.SemanticType.SUBSCRIPT) {
return false;
}
if (fence.type === semantic_meaning_js_1.SemanticType.TENSOR &&
(fence.childNodes[3].type !== semantic_meaning_js_1.SemanticType.EMPTY ||
fence.childNodes[4].type !== semantic_meaning_js_1.SemanticType.EMPTY)) {
return false;
}
return true;
}
function elligibleRightNeutral(fence) {
if (!isNeutralFence(fence)) {
return false;
}
if (!fence.embellished) {
return true;
}
if (fence.type === semantic_meaning_js_1.SemanticType.TENSOR &&
(fence.childNodes[1].type !== semantic_meaning_js_1.SemanticType.EMPTY ||
fence.childNodes[2].type !== semantic_meaning_js_1.SemanticType.EMPTY)) {
return false;
}
return true;
}
function isMembership(element) {
return [
semantic_meaning_js_1.SemanticRole.ELEMENT,
semantic_meaning_js_1.SemanticRole.NONELEMENT,
semantic_meaning_js_1.SemanticRole.REELEMENT,
semantic_meaning_js_1.SemanticRole.RENONELEMENT
].includes(element.role);
}

View File

@@ -0,0 +1,136 @@
import { SemanticFont } from './semantic_meaning.js';
import { SemanticNode } from './semantic_node.js';
import { SemanticNodeFactory } from './semantic_node_factory.js';
export declare class SemanticProcessor {
private static readonly FENCE_TO_PUNCT_;
private static readonly MML_TO_LIMIT_;
private static readonly MML_TO_BOUNDS_;
private static readonly CLASSIFY_FUNCTION_;
private static readonly MATHJAX_FONTS;
private static instance;
funcAppls: {
[key: string]: SemanticNode;
};
private factory_;
static getInstance(): SemanticProcessor;
static tableToMultiline(table: SemanticNode): SemanticNode;
static number(node: SemanticNode): void;
static classifyMultiline(multiline: SemanticNode): void;
static classifyTable(table: SemanticNode): SemanticNode;
private static detectCaleyTable;
private static cayleySpacing;
static proof(node: Element, semantics: string, parse: (p1: Element[]) => SemanticNode[]): SemanticNode;
static findSemantics(node: Element, attr: string, opt_value?: string): boolean;
static getSemantics(node: Element): {
[key: string]: string;
};
static removePrefix(name: string): string;
static separateSemantics(attr: string): {
[key: string]: string;
};
private static matchSpaces_;
private static getSpacer_;
private static fenceToPunct_;
private static classifyFunction_;
private static propagateFunctionRole_;
private static getFunctionOp_;
private static tableToMatrixOrVector_;
private static tableToVector_;
private static binomialForm_;
private static tableToMatrix_;
private static tableToSquare_;
private static getComponentRoles_;
private static tableToCases_;
private static rewriteFencedLine_;
private static rowToLine_;
private static assignRoleToRow_;
private static nextSeparatorFunction_;
private static meaningFromContent;
private static numberRole_;
private static exprFont_;
static compSemantics(node: SemanticNode, field: string, sem: any): void;
private static purgeFences_;
private static rewriteFencedNode_;
private static rewriteFence_;
private static propagateFencePointer_;
private static classifyByColumns_;
private static isEndRelation_;
private static isPureRelation_;
private static computeColumns_;
private static testColumns_;
setNodeFactory(factory: SemanticNodeFactory): void;
getNodeFactory(): SemanticNodeFactory;
identifierNode(leaf: SemanticNode, font: SemanticFont, unit: string): SemanticNode;
implicitNode(nodes: SemanticNode[]): SemanticNode;
text(leaf: SemanticNode, type: string): SemanticNode;
row(nodes: SemanticNode[]): SemanticNode;
limitNode(mmlTag: string, children: SemanticNode[]): SemanticNode;
tablesInRow(nodes: SemanticNode[]): SemanticNode[];
mfenced(open: string | null, close: string | null, sepValue: string | null, children: SemanticNode[]): SemanticNode;
fractionLikeNode(denom: SemanticNode, enume: SemanticNode, linethickness: string, bevelled: boolean): SemanticNode;
tensor(base: SemanticNode, lsub: SemanticNode[], lsup: SemanticNode[], rsub: SemanticNode[], rsup: SemanticNode[]): SemanticNode;
pseudoTensor(base: SemanticNode, sub: SemanticNode[], sup: SemanticNode[]): SemanticNode;
font(font: string): SemanticFont;
proof(node: Element, semantics: {
[key: string]: string;
}, parse: (p1: Element[]) => SemanticNode[]): SemanticNode;
inference(node: Element, semantics: {
[key: string]: string;
}, parse: (p1: Element[]) => SemanticNode[]): SemanticNode;
getLabel(_node: Element, children: Element[], parse: (p1: Element[]) => SemanticNode[], side: string): SemanticNode;
getFormulas(node: Element, children: Element[], parse: (p1: Element[]) => SemanticNode[]): {
conclusion: SemanticNode;
premises: SemanticNode;
};
findNestedRow(nodes: Element[], semantic: string, opt_value?: string): Element;
cleanInference(nodes: NodeList): Element[];
operatorNode(node: SemanticNode): SemanticNode;
private constructor();
private implicitNode_;
private infixNode_;
private explicitMixed_;
private concatNode_;
private prefixNode_;
private splitRoles;
private splitOps;
private splitSingles;
private postfixNode_;
private combineUnits_;
private getMixedNumbers_;
private getTextInRow_;
private relationsInRow_;
private operationsInRow_;
private wrapPostfix;
private wrapFactor;
private addFactor;
private operationsTree_;
private appendOperand_;
private appendDivisionOp_;
private appendLastOperand_;
private appendMultiplicativeOp_;
private appendAdditiveOp_;
private appendExistingOperator_;
private getFencesInRow_;
private fences_;
private neutralFences_;
private combineFencedContent_;
private horizontalFencedNode_;
private classifyHorizontalFence_;
private setExtension_;
private getPunctuationInRow_;
private punctuatedNode_;
private dummyNode_;
private accentRole_;
private accentNode_;
private makeLimitNode_;
private getFunctionsInRow_;
private getFunctionArgs_;
private getIntegralArgs_;
private functionNode_;
private bigOpNode_;
private integralNode_;
private functionalNode_;
private fractionNode_;
private scriptNode_;
private findNestedRow_;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
import { SemanticType, SemanticRole } from './semantic_meaning.js';
import { SemanticNode } from './semantic_node.js';
import { SemanticTree } from './semantic_tree.js';
export type Sexp = number | Sexp[];
export declare class SemanticSkeleton {
array: Sexp;
parents: {
[key: number]: number[];
};
levelsMap: {
[key: number]: Sexp[];
};
static fromTree(tree: SemanticTree): SemanticSkeleton;
static fromNode(node: SemanticNode): SemanticSkeleton;
static fromString(skel: string): SemanticSkeleton;
static simpleCollapseStructure(strct: Sexp): boolean;
static contentCollapseStructure(strct: Sexp): boolean;
static interleaveIds(first: Sexp, second: Sexp): Sexp;
static collapsedLeafs(...args: Sexp[]): number[];
static fromStructure(mml: Element, tree: SemanticTree): SemanticSkeleton;
static combineContentChildren<T>(type: SemanticType, _role: SemanticRole, content: T[], children: T[]): T[];
private static makeSexp_;
private static fromString_;
private static fromNode_;
private static tree_;
private static addAria;
private static addOwns_;
private static realLeafs_;
constructor(skeleton: Sexp);
populate(): void;
toString(): string;
private populate_;
isRoot(id: number): boolean;
directChildren(id: number): number[];
subtreeNodes(id: number): number[];
}

View File

@@ -0,0 +1,254 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticSkeleton = void 0;
const BaseUtil = require("../common/base_util.js");
const engine_js_1 = require("../common/engine.js");
const XpathUtil = require("../common/xpath_util.js");
const enrich_attr_js_1 = require("../enrich_mathml/enrich_attr.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const Options = {
tree: false
};
class SemanticSkeleton {
static fromTree(tree) {
return SemanticSkeleton.fromNode(tree.root);
}
static fromNode(node) {
return new SemanticSkeleton(SemanticSkeleton.fromNode_(node));
}
static fromString(skel) {
return new SemanticSkeleton(SemanticSkeleton.fromString_(skel));
}
static simpleCollapseStructure(strct) {
return typeof strct === 'number';
}
static contentCollapseStructure(strct) {
return (!!strct &&
!SemanticSkeleton.simpleCollapseStructure(strct) &&
strct[0] === 'c');
}
static interleaveIds(first, second) {
return BaseUtil.interleaveLists(SemanticSkeleton.collapsedLeafs(first), SemanticSkeleton.collapsedLeafs(second));
}
static collapsedLeafs(...args) {
const collapseStructure = (coll) => {
if (SemanticSkeleton.simpleCollapseStructure(coll)) {
return [coll];
}
coll = coll;
return SemanticSkeleton.contentCollapseStructure(coll[1])
? coll.slice(2)
: coll.slice(1);
};
return args.reduce((x, y) => x.concat(collapseStructure(y)), []);
}
static fromStructure(mml, tree) {
return new SemanticSkeleton(SemanticSkeleton.tree_(mml, tree.root));
}
static combineContentChildren(type, _role, content, children) {
switch (type) {
case semantic_meaning_js_1.SemanticType.RELSEQ:
case semantic_meaning_js_1.SemanticType.INFIXOP:
case semantic_meaning_js_1.SemanticType.MULTIREL:
return BaseUtil.interleaveLists(children, content);
case semantic_meaning_js_1.SemanticType.PREFIXOP:
return content.concat(children);
case semantic_meaning_js_1.SemanticType.POSTFIXOP:
return children.concat(content);
case semantic_meaning_js_1.SemanticType.MATRIX:
case semantic_meaning_js_1.SemanticType.VECTOR:
case semantic_meaning_js_1.SemanticType.FENCED:
children.unshift(content[0]);
children.push(content[1]);
return children;
case semantic_meaning_js_1.SemanticType.CASES:
children.unshift(content[0]);
return children;
case semantic_meaning_js_1.SemanticType.APPL:
return [children[0], content[0], children[1]];
case semantic_meaning_js_1.SemanticType.ROOT:
return [children[0], children[1]];
case semantic_meaning_js_1.SemanticType.ROW:
case semantic_meaning_js_1.SemanticType.LINE:
if (content.length) {
children.unshift(content[0]);
}
return children;
default:
return children;
}
}
static makeSexp_(struct) {
if (SemanticSkeleton.simpleCollapseStructure(struct)) {
return struct.toString();
}
if (SemanticSkeleton.contentCollapseStructure(struct)) {
return ('(' +
'c ' +
struct.slice(1).map(SemanticSkeleton.makeSexp_).join(' ') +
')');
}
return ('(' + struct.map(SemanticSkeleton.makeSexp_).join(' ') + ')');
}
static fromString_(skeleton) {
let str = skeleton.replace(/\(/g, '[');
str = str.replace(/\)/g, ']');
str = str.replace(/ /g, ',');
str = str.replace(/c/g, '"c"');
return JSON.parse(str);
}
static fromNode_(node) {
if (!node) {
return [];
}
const content = node.contentNodes;
let contentStructure;
if (content.length) {
contentStructure = content.map(SemanticSkeleton.fromNode_);
contentStructure.unshift('c');
}
const children = node.childNodes;
if (!children.length) {
return content.length ? [node.id, contentStructure] : node.id;
}
const structure = children.map(SemanticSkeleton.fromNode_);
if (content.length) {
structure.unshift(contentStructure);
}
structure.unshift(node.id);
return structure;
}
static tree_(mml, node, level = 0, posinset = 1, setsize = 1) {
if (!node) {
return [];
}
const id = node.id;
const skeleton = [id];
XpathUtil.updateEvaluator(mml);
const mmlChild = XpathUtil.evalXPath(`.//self::*[@${enrich_attr_js_1.Attribute.ID}=${id}]`, mml)[0];
if (!node.childNodes.length) {
SemanticSkeleton.addAria(mmlChild, level, posinset, setsize);
return node.id;
}
const children = SemanticSkeleton.combineContentChildren(node.type, node.role, node.contentNodes.map(function (x) {
return x;
}), node.childNodes.map(function (x) {
return x;
}));
if (mmlChild) {
SemanticSkeleton.addOwns_(mmlChild, children);
}
for (let i = 0, l = children.length, child; (child = children[i]); i++) {
skeleton.push(SemanticSkeleton.tree_(mml, child, level + 1, i + 1, l));
}
SemanticSkeleton.addAria(mmlChild, level, posinset, setsize, !Options.tree ? 'treeitem' : level ? 'group' : 'tree');
return skeleton;
}
static addAria(node, level, posinset, setsize, role = !Options.tree ? 'treeitem' : level ? 'treeitem' : 'tree') {
if (!engine_js_1.Engine.getInstance().aria || !node) {
return;
}
node.setAttribute('aria-level', level.toString());
node.setAttribute('aria-posinset', posinset.toString());
node.setAttribute('aria-setsize', setsize.toString());
node.setAttribute('role', role);
if (node.hasAttribute(enrich_attr_js_1.Attribute.OWNS)) {
node.setAttribute('aria-owns', node.getAttribute(enrich_attr_js_1.Attribute.OWNS));
}
}
static addOwns_(node, children) {
const collapsed = node.getAttribute(enrich_attr_js_1.Attribute.COLLAPSED);
const leafs = collapsed
? SemanticSkeleton.realLeafs_(SemanticSkeleton.fromString(collapsed).array)
: children.map((x) => x.id);
node.setAttribute(enrich_attr_js_1.Attribute.OWNS, leafs.join(' '));
}
static realLeafs_(sexp) {
if (SemanticSkeleton.simpleCollapseStructure(sexp)) {
return [sexp];
}
if (SemanticSkeleton.contentCollapseStructure(sexp)) {
return [];
}
sexp = sexp;
let result = [];
for (let i = 1; i < sexp.length; i++) {
result = result.concat(SemanticSkeleton.realLeafs_(sexp[i]));
}
return result;
}
constructor(skeleton) {
this.parents = null;
this.levelsMap = null;
skeleton = skeleton === 0 ? skeleton : skeleton || [];
this.array = skeleton;
}
populate() {
if (this.parents && this.levelsMap) {
return;
}
this.parents = {};
this.levelsMap = {};
this.populate_(this.array, this.array, []);
}
toString() {
return SemanticSkeleton.makeSexp_(this.array);
}
populate_(element, layer, parents) {
if (SemanticSkeleton.simpleCollapseStructure(element)) {
element = element;
this.levelsMap[element] = layer;
this.parents[element] =
element === parents[0] ? parents.slice(1) : parents;
return;
}
const newElement = SemanticSkeleton.contentCollapseStructure(element)
? element.slice(1)
: element;
const newParents = [newElement[0]].concat(parents);
for (let i = 0, l = newElement.length; i < l; i++) {
const current = newElement[i];
this.populate_(current, element, newParents);
}
}
isRoot(id) {
const level = this.levelsMap[id];
return id === level[0];
}
directChildren(id) {
if (!this.isRoot(id)) {
return [];
}
const level = this.levelsMap[id];
return level.slice(1).map((child) => {
if (SemanticSkeleton.simpleCollapseStructure(child)) {
return child;
}
if (SemanticSkeleton.contentCollapseStructure(child)) {
return child[1];
}
return child[0];
});
}
subtreeNodes(id) {
if (!this.isRoot(id)) {
return [];
}
const subtreeNodes_ = (tree, nodes) => {
if (SemanticSkeleton.simpleCollapseStructure(tree)) {
nodes.push(tree);
return;
}
tree = tree;
if (SemanticSkeleton.contentCollapseStructure(tree)) {
tree = tree.slice(1);
}
tree.forEach((x) => subtreeNodes_(x, nodes));
};
const level = this.levelsMap[id];
const subtree = [];
subtreeNodes_(level.slice(1), subtree);
return subtree;
}
}
exports.SemanticSkeleton = SemanticSkeleton;

View File

@@ -0,0 +1,21 @@
import { SemanticMeaningCollator } from './semantic_default.js';
import { SemanticNode } from './semantic_node.js';
import { SemanticParser } from './semantic_parser.js';
import './semantic_heuristics.js';
export declare class SemanticTree {
mathml: Element;
parser: SemanticParser<Element>;
root: SemanticNode;
collator: SemanticMeaningCollator;
static empty(): SemanticTree;
static fromNode(semantic: SemanticNode, opt_mathml?: Element): SemanticTree;
static fromRoot(semantic: SemanticNode, opt_mathml?: Element): SemanticTree;
static fromXml(xml: Element): SemanticTree;
constructor(mathml: Element);
xml(opt_brief?: boolean): Element;
toString(opt_brief?: boolean): string;
formatXml(opt_brief?: boolean): string;
displayTree(): void;
replaceNode(oldNode: SemanticNode, newNode: SemanticNode): void;
toJson(): any;
}

View File

@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticTree = void 0;
const DomUtil = require("../common/dom_util.js");
const semantic_annotations_js_1 = require("./semantic_annotations.js");
const semantic_annotator_js_1 = require("./semantic_annotator.js");
const semantic_meaning_js_1 = require("./semantic_meaning.js");
const semantic_mathml_js_1 = require("./semantic_mathml.js");
const semantic_node_js_1 = require("./semantic_node.js");
const SemanticPred = require("./semantic_pred.js");
require("./semantic_heuristics.js");
class SemanticTree {
static empty() {
const empty = DomUtil.parseInput('<math/>');
const stree = new SemanticTree(empty);
stree.mathml = empty;
return stree;
}
static fromNode(semantic, opt_mathml) {
const stree = SemanticTree.empty();
stree.root = semantic;
if (opt_mathml) {
stree.mathml = opt_mathml;
}
return stree;
}
static fromRoot(semantic, opt_mathml) {
let root = semantic;
while (root.parent) {
root = root.parent;
}
const stree = SemanticTree.fromNode(root);
if (opt_mathml) {
stree.mathml = opt_mathml;
}
return stree;
}
static fromXml(xml) {
const stree = SemanticTree.empty();
if (xml.childNodes[0]) {
stree.root = semantic_node_js_1.SemanticNode.fromXml(xml.childNodes[0]);
}
return stree;
}
constructor(mathml) {
this.mathml = mathml;
this.parser = new semantic_mathml_js_1.SemanticMathml();
this.root = this.parser.parse(mathml);
this.collator = this.parser.getFactory().leafMap.collateMeaning();
const newDefault = this.collator.newDefault();
if (newDefault) {
this.parser = new semantic_mathml_js_1.SemanticMathml();
this.parser.getFactory().defaultMap = newDefault;
this.root = this.parser.parse(mathml);
}
unitVisitor.visit(this.root, {});
(0, semantic_annotations_js_1.annotate)(this.root);
}
xml(opt_brief) {
const xml = DomUtil.parseInput('<stree></stree>');
const xmlRoot = this.root.xml(xml.ownerDocument, opt_brief);
xml.appendChild(xmlRoot);
return xml;
}
toString(opt_brief) {
return DomUtil.serializeXml(this.xml(opt_brief));
}
formatXml(opt_brief) {
const xml = this.toString(opt_brief);
return DomUtil.formatXml(xml);
}
displayTree() {
this.root.displayTree();
}
replaceNode(oldNode, newNode) {
const parent = oldNode.parent;
if (!parent) {
this.root = newNode;
return;
}
parent.replaceChild(oldNode, newNode);
}
toJson() {
const json = {};
json['stree'] = this.root.toJson();
return json;
}
}
exports.SemanticTree = SemanticTree;
const unitVisitor = new semantic_annotator_js_1.SemanticVisitor('general', 'unit', (node, _info) => {
if (SemanticPred.isUnitProduct(node)) {
node.role = semantic_meaning_js_1.SemanticRole.UNIT;
}
return false;
});

View File

@@ -0,0 +1,60 @@
import { SemanticNode } from './semantic_node.js';
export declare enum MMLTAGS {
ANNOTATION = "ANNOTATION",
ANNOTATIONXML = "ANNOTATION-XML",
MACTION = "MACTION",
MALIGNGROUP = "MALIGNGROUP",
MALIGNMARK = "MALIGNMARK",
MATH = "MATH",
MENCLOSE = "MENCLOSE",
MERROR = "MERROR",
MFENCED = "MFENCED",
MFRAC = "MFRAC",
MGLYPH = "MGLYPH",
MI = "MI",
MLABELEDTR = "MLABELEDTR",
MMULTISCRIPTS = "MMULTISCRIPTS",
MN = "MN",
MO = "MO",
MOVER = "MOVER",
MPADDED = "MPADDED",
MPHANTOM = "MPHANTOM",
MPRESCRIPTS = "MPRESCRIPTS",
MROOT = "MROOT",
MROW = "MROW",
MS = "MS",
MSPACE = "MSPACE",
MSQRT = "MSQRT",
MSTYLE = "MSTYLE",
MSUB = "MSUB",
MSUBSUP = "MSUBSUP",
MSUP = "MSUP",
MTABLE = "MTABLE",
MTD = "MTD",
MTEXT = "MTEXT",
MTR = "MTR",
MUNDER = "MUNDER",
MUNDEROVER = "MUNDEROVER",
NONE = "NONE",
SEMANTICS = "SEMANTICS"
}
export declare function hasMathTag(node: Element): boolean;
export declare function hasIgnoreTag(node: Element): boolean;
export declare function hasEmptyTag(node: Element): boolean;
export declare function hasDisplayTag(node: Element): boolean;
export declare function isOrphanedGlyph(node: Element): boolean;
export declare function purgeNodes(nodes: Element[]): Element[];
export declare function isZeroLength(length: string): boolean;
export declare function addAttributes(to: SemanticNode, from: Element): void;
export declare function getEmbellishedInner(node: SemanticNode): SemanticNode;
export interface Slice {
head: SemanticNode[];
div: SemanticNode;
tail: SemanticNode[];
}
export declare function sliceNodes(nodes: SemanticNode[], pred: (p1: SemanticNode) => boolean, opt_reverse?: boolean): Slice;
export interface Partition {
rel: SemanticNode[];
comp: SemanticNode[][];
}
export declare function partitionNodes(nodes: SemanticNode[], pred: (p1: SemanticNode) => boolean): Partition;

View File

@@ -0,0 +1,214 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MMLTAGS = void 0;
exports.hasMathTag = hasMathTag;
exports.hasIgnoreTag = hasIgnoreTag;
exports.hasEmptyTag = hasEmptyTag;
exports.hasDisplayTag = hasDisplayTag;
exports.isOrphanedGlyph = isOrphanedGlyph;
exports.purgeNodes = purgeNodes;
exports.isZeroLength = isZeroLength;
exports.addAttributes = addAttributes;
exports.getEmbellishedInner = getEmbellishedInner;
exports.sliceNodes = sliceNodes;
exports.partitionNodes = partitionNodes;
const DomUtil = require("../common/dom_util.js");
var MMLTAGS;
(function (MMLTAGS) {
MMLTAGS["ANNOTATION"] = "ANNOTATION";
MMLTAGS["ANNOTATIONXML"] = "ANNOTATION-XML";
MMLTAGS["MACTION"] = "MACTION";
MMLTAGS["MALIGNGROUP"] = "MALIGNGROUP";
MMLTAGS["MALIGNMARK"] = "MALIGNMARK";
MMLTAGS["MATH"] = "MATH";
MMLTAGS["MENCLOSE"] = "MENCLOSE";
MMLTAGS["MERROR"] = "MERROR";
MMLTAGS["MFENCED"] = "MFENCED";
MMLTAGS["MFRAC"] = "MFRAC";
MMLTAGS["MGLYPH"] = "MGLYPH";
MMLTAGS["MI"] = "MI";
MMLTAGS["MLABELEDTR"] = "MLABELEDTR";
MMLTAGS["MMULTISCRIPTS"] = "MMULTISCRIPTS";
MMLTAGS["MN"] = "MN";
MMLTAGS["MO"] = "MO";
MMLTAGS["MOVER"] = "MOVER";
MMLTAGS["MPADDED"] = "MPADDED";
MMLTAGS["MPHANTOM"] = "MPHANTOM";
MMLTAGS["MPRESCRIPTS"] = "MPRESCRIPTS";
MMLTAGS["MROOT"] = "MROOT";
MMLTAGS["MROW"] = "MROW";
MMLTAGS["MS"] = "MS";
MMLTAGS["MSPACE"] = "MSPACE";
MMLTAGS["MSQRT"] = "MSQRT";
MMLTAGS["MSTYLE"] = "MSTYLE";
MMLTAGS["MSUB"] = "MSUB";
MMLTAGS["MSUBSUP"] = "MSUBSUP";
MMLTAGS["MSUP"] = "MSUP";
MMLTAGS["MTABLE"] = "MTABLE";
MMLTAGS["MTD"] = "MTD";
MMLTAGS["MTEXT"] = "MTEXT";
MMLTAGS["MTR"] = "MTR";
MMLTAGS["MUNDER"] = "MUNDER";
MMLTAGS["MUNDEROVER"] = "MUNDEROVER";
MMLTAGS["NONE"] = "NONE";
MMLTAGS["SEMANTICS"] = "SEMANTICS";
})(MMLTAGS || (exports.MMLTAGS = MMLTAGS = {}));
const ALLTAGS = Object.values(MMLTAGS);
const LEAFTAGS = [
MMLTAGS.MO,
MMLTAGS.MI,
MMLTAGS.MN,
MMLTAGS.MTEXT,
MMLTAGS.MS,
MMLTAGS.MSPACE
];
const IGNORETAGS = [
MMLTAGS.MERROR,
MMLTAGS.MPHANTOM,
MMLTAGS.MALIGNGROUP,
MMLTAGS.MALIGNMARK,
MMLTAGS.MPRESCRIPTS,
MMLTAGS.ANNOTATION,
MMLTAGS.ANNOTATIONXML
];
const EMPTYTAGS = [
MMLTAGS.MATH,
MMLTAGS.MROW,
MMLTAGS.MPADDED,
MMLTAGS.MACTION,
MMLTAGS.NONE,
MMLTAGS.MSTYLE,
MMLTAGS.SEMANTICS
];
const DISPLAYTAGS = [MMLTAGS.MROOT, MMLTAGS.MSQRT];
const directSpeechKeys = ['aria-label', 'exact-speech', 'alt'];
function hasMathTag(node) {
return !!node && DomUtil.tagName(node) === MMLTAGS.MATH;
}
function hasLeafTag(node) {
return !!node && LEAFTAGS.includes(DomUtil.tagName(node));
}
function hasIgnoreTag(node) {
return (!!node &&
(IGNORETAGS.includes(DomUtil.tagName(node)) ||
!ALLTAGS.includes(DomUtil.tagName(node))));
}
function hasEmptyTag(node) {
return !!node && EMPTYTAGS.includes(DomUtil.tagName(node));
}
function hasDisplayTag(node) {
return !!node && DISPLAYTAGS.includes(DomUtil.tagName(node));
}
function isOrphanedGlyph(node) {
return (!!node &&
DomUtil.tagName(node) === MMLTAGS.MGLYPH &&
!hasLeafTag(node.parentNode));
}
function purgeNodes(nodes) {
const nodeArray = [];
for (let i = 0, node; (node = nodes[i]); i++) {
if (node.nodeType !== DomUtil.NodeType.ELEMENT_NODE) {
continue;
}
const tagName = DomUtil.tagName(node);
if (IGNORETAGS.includes(tagName)) {
continue;
}
if (EMPTYTAGS.includes(tagName) && node.childNodes.length === 0) {
continue;
}
nodeArray.push(node);
}
return nodeArray;
}
function isZeroLength(length) {
if (!length) {
return false;
}
const negativeNamedSpaces = [
'negativeveryverythinmathspace',
'negativeverythinmathspace',
'negativethinmathspace',
'negativemediummathspace',
'negativethickmathspace',
'negativeverythickmathspace',
'negativeveryverythickmathspace'
];
if (negativeNamedSpaces.includes(length)) {
return true;
}
const value = length.match(/[0-9.]+/);
if (!value) {
return false;
}
return parseFloat(value[0]) === 0;
}
function addAttributes(to, from) {
if (from.hasAttributes()) {
const attrs = from.attributes;
for (let i = attrs.length - 1; i >= 0; i--) {
const key = attrs[i].name;
if (key.match(/^ext/)) {
to.attributes[key] = attrs[i].value;
to.nobreaking = true;
}
if (directSpeechKeys.includes(key)) {
to.attributes['ext-speech'] = attrs[i].value;
to.nobreaking = true;
}
if (key.match(/texclass$/)) {
to.attributes['texclass'] = attrs[i].value;
}
if (key.toLowerCase() === 'data-latex') {
to.attributes['latex'] = attrs[i].value;
}
if (key === 'href') {
to.attributes['href'] = attrs[i].value;
to.nobreaking = true;
}
}
}
}
function getEmbellishedInner(node) {
if (node && node.embellished && node.childNodes.length > 0) {
return getEmbellishedInner(node.childNodes[0]);
}
return node;
}
function sliceNodes(nodes, pred, opt_reverse) {
if (opt_reverse) {
nodes.reverse();
}
const head = [];
for (let i = 0, node; (node = nodes[i]); i++) {
if (pred(node)) {
if (opt_reverse) {
return {
head: nodes.slice(i + 1).reverse(),
div: node,
tail: head.reverse()
};
}
return { head: head, div: node, tail: nodes.slice(i + 1) };
}
head.push(node);
}
if (opt_reverse) {
return { head: [], div: null, tail: head.reverse() };
}
return { head: head, div: null, tail: [] };
}
function partitionNodes(nodes, pred) {
let restNodes = nodes;
const rel = [];
const comp = [];
let result = null;
do {
result = sliceNodes(restNodes, pred);
comp.push(result.head);
rel.push(result.div);
restNodes = result.tail;
} while (result.div);
rel.pop();
return { rel: rel, comp: comp };
}