semantic_processor.js 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.SemanticProcessor = void 0;
  4. const DomUtil = require("../common/dom_util.js");
  5. const semantic_attr_js_1 = require("./semantic_attr.js");
  6. const semantic_meaning_js_1 = require("./semantic_meaning.js");
  7. const semantic_heuristic_factory_js_1 = require("./semantic_heuristic_factory.js");
  8. const semantic_node_factory_js_1 = require("./semantic_node_factory.js");
  9. const SemanticPred = require("./semantic_pred.js");
  10. const SemanticUtil = require("./semantic_util.js");
  11. const semantic_util_js_1 = require("../semantic_tree/semantic_util.js");
  12. class SemanticProcessor {
  13. static getInstance() {
  14. SemanticProcessor.instance =
  15. SemanticProcessor.instance || new SemanticProcessor();
  16. return SemanticProcessor.instance;
  17. }
  18. static tableToMultiline(table) {
  19. if (!SemanticPred.tableIsMultiline(table)) {
  20. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('rewrite_subcases', table, SemanticProcessor.classifyTable);
  21. }
  22. table.type = semantic_meaning_js_1.SemanticType.MULTILINE;
  23. for (let i = 0, row; (row = table.childNodes[i]); i++) {
  24. SemanticProcessor.rowToLine_(row, semantic_meaning_js_1.SemanticRole.MULTILINE);
  25. }
  26. if (table.childNodes.length === 1 &&
  27. !SemanticPred.lineIsLabelled(table.childNodes[0]) &&
  28. SemanticPred.isFencedElement(table.childNodes[0].childNodes[0])) {
  29. SemanticProcessor.tableToMatrixOrVector_(SemanticProcessor.rewriteFencedLine_(table));
  30. }
  31. SemanticProcessor.binomialForm_(table);
  32. SemanticProcessor.classifyMultiline(table);
  33. return table;
  34. }
  35. static number(node) {
  36. if (node.type === semantic_meaning_js_1.SemanticType.UNKNOWN ||
  37. node.type === semantic_meaning_js_1.SemanticType.IDENTIFIER) {
  38. node.type = semantic_meaning_js_1.SemanticType.NUMBER;
  39. }
  40. SemanticProcessor.meaningFromContent(node, SemanticProcessor.numberRole_);
  41. SemanticProcessor.exprFont_(node);
  42. }
  43. static classifyMultiline(multiline) {
  44. let index = 0;
  45. const length = multiline.childNodes.length;
  46. let line;
  47. while (index < length &&
  48. (!(line = multiline.childNodes[index]) || !line.childNodes.length)) {
  49. index++;
  50. }
  51. if (index >= length) {
  52. return;
  53. }
  54. const firstRole = line.childNodes[0].role;
  55. if (firstRole !== semantic_meaning_js_1.SemanticRole.UNKNOWN &&
  56. multiline.childNodes.every(function (x) {
  57. const cell = x.childNodes[0];
  58. return (!cell ||
  59. (cell.role === firstRole &&
  60. (SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.RELATION) ||
  61. SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.RELSEQ))));
  62. })) {
  63. multiline.role = firstRole;
  64. }
  65. }
  66. static classifyTable(table) {
  67. const columns = SemanticProcessor.computeColumns_(table);
  68. SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.EQUALITY) ||
  69. SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.INEQUALITY, [semantic_meaning_js_1.SemanticRole.EQUALITY]) ||
  70. SemanticProcessor.classifyByColumns_(table, columns, semantic_meaning_js_1.SemanticRole.ARROW) ||
  71. SemanticProcessor.detectCaleyTable(table);
  72. return table;
  73. }
  74. static detectCaleyTable(table) {
  75. if (!table.mathmlTree) {
  76. return false;
  77. }
  78. const tree = table.mathmlTree;
  79. const cl = tree.getAttribute('columnlines');
  80. const rl = tree.getAttribute('rowlines');
  81. if (!cl || !rl) {
  82. return false;
  83. }
  84. if (SemanticProcessor.cayleySpacing(cl) &&
  85. SemanticProcessor.cayleySpacing(rl)) {
  86. table.role = semantic_meaning_js_1.SemanticRole.CAYLEY;
  87. return true;
  88. }
  89. return false;
  90. }
  91. static cayleySpacing(lines) {
  92. const list = lines.split(' ');
  93. return ((list[0] === 'solid' || list[0] === 'dashed') &&
  94. list.slice(1).every((x) => x === 'none'));
  95. }
  96. static proof(node, semantics, parse) {
  97. const attrs = SemanticProcessor.separateSemantics(semantics);
  98. return SemanticProcessor.getInstance().proof(node, attrs, parse);
  99. }
  100. static findSemantics(node, attr, opt_value) {
  101. const value = opt_value == null ? null : opt_value;
  102. const semantics = SemanticProcessor.getSemantics(node);
  103. if (!semantics) {
  104. return false;
  105. }
  106. if (!semantics[attr]) {
  107. return false;
  108. }
  109. return value == null ? true : semantics[attr] === value;
  110. }
  111. static getSemantics(node) {
  112. const semantics = node.getAttribute('semantics');
  113. if (!semantics) {
  114. return null;
  115. }
  116. return SemanticProcessor.separateSemantics(semantics);
  117. }
  118. static removePrefix(name) {
  119. const [, ...rest] = name.split('_');
  120. return rest.join('_');
  121. }
  122. static separateSemantics(attr) {
  123. const result = {};
  124. attr.split(';').forEach(function (x) {
  125. const [name, value] = x.split(':');
  126. result[SemanticProcessor.removePrefix(name)] = value;
  127. });
  128. return result;
  129. }
  130. static matchSpaces_(nodes, ops) {
  131. for (let i = 0, op; (op = ops[i]); i++) {
  132. const node = nodes[i];
  133. const mt1 = node.mathmlTree;
  134. const mt2 = nodes[i + 1].mathmlTree;
  135. if (!mt1 || !mt2) {
  136. continue;
  137. }
  138. const sibling = mt1.nextSibling;
  139. if (!sibling || sibling === mt2) {
  140. continue;
  141. }
  142. const spacer = SemanticProcessor.getSpacer_(sibling);
  143. if (spacer) {
  144. op.mathml.push(spacer);
  145. op.mathmlTree = spacer;
  146. op.role = semantic_meaning_js_1.SemanticRole.SPACE;
  147. }
  148. }
  149. }
  150. static getSpacer_(node) {
  151. if (DomUtil.tagName(node) === semantic_util_js_1.MMLTAGS.MSPACE) {
  152. return node;
  153. }
  154. while (SemanticUtil.hasEmptyTag(node) && node.childNodes.length === 1) {
  155. node = node.childNodes[0];
  156. if (DomUtil.tagName(node) === semantic_util_js_1.MMLTAGS.MSPACE) {
  157. return node;
  158. }
  159. }
  160. return null;
  161. }
  162. static fenceToPunct_(fence) {
  163. const newRole = SemanticProcessor.FENCE_TO_PUNCT_[fence.role];
  164. if (!newRole) {
  165. return;
  166. }
  167. while (fence.embellished) {
  168. fence.embellished = semantic_meaning_js_1.SemanticType.PUNCTUATION;
  169. if (!(SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.SUBSUP) ||
  170. SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.UNDEROVER))) {
  171. fence.role = newRole;
  172. }
  173. fence = fence.childNodes[0];
  174. }
  175. fence.type = semantic_meaning_js_1.SemanticType.PUNCTUATION;
  176. fence.role = newRole;
  177. }
  178. static classifyFunction_(funcNode, restNodes) {
  179. if (funcNode.type === semantic_meaning_js_1.SemanticType.APPL ||
  180. funcNode.type === semantic_meaning_js_1.SemanticType.BIGOP ||
  181. funcNode.type === semantic_meaning_js_1.SemanticType.INTEGRAL) {
  182. return '';
  183. }
  184. if (restNodes[0] &&
  185. restNodes[0].textContent === semantic_attr_js_1.NamedSymbol.functionApplication) {
  186. SemanticProcessor.getInstance().funcAppls[funcNode.id] =
  187. restNodes.shift();
  188. let role = semantic_meaning_js_1.SemanticRole.SIMPLEFUNC;
  189. semantic_heuristic_factory_js_1.SemanticHeuristics.run('simple2prefix', funcNode);
  190. if (funcNode.role === semantic_meaning_js_1.SemanticRole.PREFIXFUNC ||
  191. funcNode.role === semantic_meaning_js_1.SemanticRole.LIMFUNC) {
  192. role = funcNode.role;
  193. }
  194. SemanticProcessor.propagateFunctionRole_(funcNode, role);
  195. return 'prefix';
  196. }
  197. const kind = SemanticProcessor.CLASSIFY_FUNCTION_[funcNode.role];
  198. return kind
  199. ? kind
  200. : SemanticPred.isSimpleFunctionHead(funcNode)
  201. ? 'simple'
  202. : '';
  203. }
  204. static propagateFunctionRole_(funcNode, tag) {
  205. if (funcNode) {
  206. if (funcNode.type === semantic_meaning_js_1.SemanticType.INFIXOP) {
  207. return;
  208. }
  209. if (!(SemanticPred.isRole(funcNode, semantic_meaning_js_1.SemanticRole.SUBSUP) ||
  210. SemanticPred.isRole(funcNode, semantic_meaning_js_1.SemanticRole.UNDEROVER))) {
  211. funcNode.role = tag;
  212. }
  213. SemanticProcessor.propagateFunctionRole_(funcNode.childNodes[0], tag);
  214. }
  215. }
  216. static getFunctionOp_(tree, pred) {
  217. if (pred(tree)) {
  218. return tree;
  219. }
  220. for (let i = 0, child; (child = tree.childNodes[i]); i++) {
  221. const op = SemanticProcessor.getFunctionOp_(child, pred);
  222. if (op) {
  223. return op;
  224. }
  225. }
  226. return null;
  227. }
  228. static tableToMatrixOrVector_(node) {
  229. const matrix = node.childNodes[0];
  230. SemanticPred.isType(matrix, semantic_meaning_js_1.SemanticType.MULTILINE)
  231. ? SemanticProcessor.tableToVector_(node)
  232. : SemanticProcessor.tableToMatrix_(node);
  233. node.contentNodes.forEach(matrix.appendContentNode.bind(matrix));
  234. for (let i = 0, row; (row = matrix.childNodes[i]); i++) {
  235. SemanticProcessor.assignRoleToRow_(row, SemanticProcessor.getComponentRoles_(matrix));
  236. }
  237. matrix.parent = null;
  238. return matrix;
  239. }
  240. static tableToVector_(node) {
  241. const vector = node.childNodes[0];
  242. vector.type = semantic_meaning_js_1.SemanticType.VECTOR;
  243. if (vector.childNodes.length === 1) {
  244. SemanticProcessor.tableToSquare_(node);
  245. return;
  246. }
  247. SemanticProcessor.binomialForm_(vector);
  248. }
  249. static binomialForm_(node) {
  250. if (!SemanticPred.isRole(node, semantic_meaning_js_1.SemanticRole.UNKNOWN)) {
  251. return;
  252. }
  253. if (SemanticPred.isBinomial(node)) {
  254. node.role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
  255. node.childNodes[0].role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
  256. node.childNodes[1].role = semantic_meaning_js_1.SemanticRole.BINOMIAL;
  257. }
  258. }
  259. static tableToMatrix_(node) {
  260. const matrix = node.childNodes[0];
  261. matrix.type = semantic_meaning_js_1.SemanticType.MATRIX;
  262. if (matrix.childNodes &&
  263. matrix.childNodes.length > 0 &&
  264. matrix.childNodes[0].childNodes &&
  265. matrix.childNodes.length === matrix.childNodes[0].childNodes.length) {
  266. SemanticProcessor.tableToSquare_(node);
  267. return;
  268. }
  269. if (matrix.childNodes && matrix.childNodes.length === 1) {
  270. matrix.role = semantic_meaning_js_1.SemanticRole.ROWVECTOR;
  271. }
  272. }
  273. static tableToSquare_(node) {
  274. const matrix = node.childNodes[0];
  275. if (!SemanticPred.isRole(matrix, semantic_meaning_js_1.SemanticRole.UNKNOWN)) {
  276. return;
  277. }
  278. if (SemanticPred.isNeutralFence(node)) {
  279. matrix.role = semantic_meaning_js_1.SemanticRole.DETERMINANT;
  280. return;
  281. }
  282. matrix.role = semantic_meaning_js_1.SemanticRole.SQUAREMATRIX;
  283. }
  284. static getComponentRoles_(node) {
  285. const role = node.role;
  286. if (role && role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  287. return role;
  288. }
  289. return node.type.toLowerCase() || semantic_meaning_js_1.SemanticRole.UNKNOWN;
  290. }
  291. static tableToCases_(table, openFence) {
  292. for (let i = 0, row; (row = table.childNodes[i]); i++) {
  293. SemanticProcessor.assignRoleToRow_(row, semantic_meaning_js_1.SemanticRole.CASES);
  294. }
  295. table.type = semantic_meaning_js_1.SemanticType.CASES;
  296. table.appendContentNode(openFence);
  297. if (SemanticPred.tableIsMultiline(table)) {
  298. SemanticProcessor.binomialForm_(table);
  299. }
  300. return table;
  301. }
  302. static rewriteFencedLine_(table) {
  303. const line = table.childNodes[0];
  304. const fenced = table.childNodes[0].childNodes[0];
  305. const element = table.childNodes[0].childNodes[0].childNodes[0];
  306. fenced.parent = table.parent;
  307. table.parent = fenced;
  308. element.parent = line;
  309. fenced.childNodes = [table];
  310. line.childNodes = [element];
  311. return fenced;
  312. }
  313. static rowToLine_(row, opt_role) {
  314. const role = opt_role || semantic_meaning_js_1.SemanticRole.UNKNOWN;
  315. if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.ROW)) {
  316. row.type = semantic_meaning_js_1.SemanticType.LINE;
  317. row.role = role;
  318. if (row.childNodes.length === 1 &&
  319. SemanticPred.isType(row.childNodes[0], semantic_meaning_js_1.SemanticType.CELL)) {
  320. row.childNodes = row.childNodes[0].childNodes;
  321. row.childNodes.forEach(function (x) {
  322. x.parent = row;
  323. });
  324. }
  325. }
  326. }
  327. static assignRoleToRow_(row, role) {
  328. if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.LINE)) {
  329. row.role = role;
  330. return;
  331. }
  332. if (SemanticPred.isType(row, semantic_meaning_js_1.SemanticType.ROW)) {
  333. row.role = role;
  334. row.childNodes.forEach(function (cell) {
  335. if (SemanticPred.isType(cell, semantic_meaning_js_1.SemanticType.CELL)) {
  336. cell.role = role;
  337. }
  338. });
  339. }
  340. }
  341. static nextSeparatorFunction_(separators) {
  342. let sepList;
  343. if (separators) {
  344. if (separators.match(/^\s+$/)) {
  345. return null;
  346. }
  347. else {
  348. sepList = separators
  349. .replace(/\s/g, '')
  350. .split('')
  351. .filter(function (x) {
  352. return x;
  353. });
  354. }
  355. }
  356. else {
  357. sepList = [','];
  358. }
  359. return function () {
  360. if (sepList.length > 1) {
  361. return sepList.shift();
  362. }
  363. return sepList[0];
  364. };
  365. }
  366. static meaningFromContent(node, func) {
  367. const content = [...node.textContent].filter((x) => x.match(/[^\s]/));
  368. const meaning = content.map((x) => semantic_attr_js_1.SemanticMap.Meaning.get(x));
  369. func(node, content, meaning);
  370. }
  371. static numberRole_(node, content, meaning) {
  372. if (node.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  373. return;
  374. }
  375. if (meaning.every(function (x) {
  376. return ((x.type === semantic_meaning_js_1.SemanticType.NUMBER && x.role === semantic_meaning_js_1.SemanticRole.INTEGER) ||
  377. (x.type === semantic_meaning_js_1.SemanticType.PUNCTUATION && x.role === semantic_meaning_js_1.SemanticRole.COMMA));
  378. })) {
  379. node.role = semantic_meaning_js_1.SemanticRole.INTEGER;
  380. if (content[0] === '0') {
  381. node.addAnnotation('general', 'basenumber');
  382. }
  383. return;
  384. }
  385. if (meaning.every(function (x) {
  386. return ((x.type === semantic_meaning_js_1.SemanticType.NUMBER && x.role === semantic_meaning_js_1.SemanticRole.INTEGER) ||
  387. x.type === semantic_meaning_js_1.SemanticType.PUNCTUATION);
  388. })) {
  389. node.role = semantic_meaning_js_1.SemanticRole.FLOAT;
  390. return;
  391. }
  392. node.role = semantic_meaning_js_1.SemanticRole.OTHERNUMBER;
  393. }
  394. static exprFont_(node) {
  395. if (node.font !== semantic_meaning_js_1.SemanticFont.UNKNOWN) {
  396. return;
  397. }
  398. SemanticProcessor.compSemantics(node, 'font', semantic_meaning_js_1.SemanticFont);
  399. }
  400. static compSemantics(node, field, sem) {
  401. const content = [...node.textContent];
  402. const meaning = content.map((x) => semantic_attr_js_1.SemanticMap.Meaning.get(x));
  403. const single = meaning.reduce(function (prev, curr) {
  404. if (!prev ||
  405. !curr[field] ||
  406. curr[field] === sem.UNKNOWN ||
  407. curr[field] === prev) {
  408. return prev;
  409. }
  410. if (prev === sem.UNKNOWN) {
  411. return curr[field];
  412. }
  413. return null;
  414. }, sem.UNKNOWN);
  415. if (single) {
  416. node[field] = single;
  417. }
  418. }
  419. static purgeFences_(partition) {
  420. const rel = partition.rel;
  421. const comp = partition.comp;
  422. const newRel = [];
  423. const newComp = [];
  424. while (rel.length > 0) {
  425. const currentRel = rel.shift();
  426. let currentComp = comp.shift();
  427. if (SemanticPred.isElligibleEmbellishedFence(currentRel)) {
  428. newRel.push(currentRel);
  429. newComp.push(currentComp);
  430. continue;
  431. }
  432. SemanticProcessor.fenceToPunct_(currentRel);
  433. currentComp.push(currentRel);
  434. currentComp = currentComp.concat(comp.shift());
  435. comp.unshift(currentComp);
  436. }
  437. newComp.push(comp.shift());
  438. return { rel: newRel, comp: newComp };
  439. }
  440. static rewriteFencedNode_(fenced) {
  441. const ofence = fenced.contentNodes[0];
  442. const cfence = fenced.contentNodes[1];
  443. let rewritten = SemanticProcessor.rewriteFence_(fenced, ofence);
  444. fenced.contentNodes[0] = rewritten.fence;
  445. rewritten = SemanticProcessor.rewriteFence_(rewritten.node, cfence);
  446. fenced.contentNodes[1] = rewritten.fence;
  447. fenced.contentNodes[0].parent = fenced;
  448. fenced.contentNodes[1].parent = fenced;
  449. rewritten.node.parent = null;
  450. return rewritten.node;
  451. }
  452. static rewriteFence_(node, fence) {
  453. if (!fence.embellished) {
  454. return { node: node, fence: fence };
  455. }
  456. const newFence = fence.childNodes[0];
  457. const rewritten = SemanticProcessor.rewriteFence_(node, newFence);
  458. if (SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.SUPERSCRIPT) ||
  459. SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.SUBSCRIPT) ||
  460. SemanticPred.isType(fence, semantic_meaning_js_1.SemanticType.TENSOR)) {
  461. if (!SemanticPred.isRole(fence, semantic_meaning_js_1.SemanticRole.SUBSUP)) {
  462. fence.role = node.role;
  463. }
  464. if (newFence !== rewritten.node) {
  465. fence.replaceChild(newFence, rewritten.node);
  466. newFence.parent = node;
  467. }
  468. SemanticProcessor.propagateFencePointer_(fence, newFence);
  469. return { node: fence, fence: rewritten.fence };
  470. }
  471. fence.replaceChild(newFence, rewritten.fence);
  472. if (fence.mathmlTree && fence.mathml.indexOf(fence.mathmlTree) === -1) {
  473. fence.mathml.push(fence.mathmlTree);
  474. }
  475. return { node: rewritten.node, fence: fence };
  476. }
  477. static propagateFencePointer_(oldNode, newNode) {
  478. oldNode.fencePointer = newNode.fencePointer || newNode.id.toString();
  479. oldNode.embellished = null;
  480. }
  481. static classifyByColumns_(table, columns, relation, alternatives = []) {
  482. const relations = [relation].concat(alternatives);
  483. const test1 = (x) => SemanticProcessor.isPureRelation_(x, relations);
  484. const test2 = (x) => SemanticProcessor.isEndRelation_(x, relations) ||
  485. SemanticProcessor.isPureRelation_(x, relations);
  486. const test3 = (x) => SemanticProcessor.isEndRelation_(x, relations, true) ||
  487. SemanticProcessor.isPureRelation_(x, relations);
  488. if ((columns.length === 3 &&
  489. SemanticProcessor.testColumns_(columns, 1, test1)) ||
  490. (columns.length === 2 &&
  491. (SemanticProcessor.testColumns_(columns, 1, test2) ||
  492. SemanticProcessor.testColumns_(columns, 0, test3)))) {
  493. table.role = relation;
  494. return true;
  495. }
  496. return false;
  497. }
  498. static isEndRelation_(node, relations, opt_right) {
  499. const position = opt_right ? node.childNodes.length - 1 : 0;
  500. return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.RELSEQ) &&
  501. relations.some((relation) => SemanticPred.isRole(node, relation)) &&
  502. SemanticPred.isType(node.childNodes[position], semantic_meaning_js_1.SemanticType.EMPTY));
  503. }
  504. static isPureRelation_(node, relations) {
  505. return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.RELATION) &&
  506. relations.some((relation) => SemanticPred.isRole(node, relation)));
  507. }
  508. static computeColumns_(table) {
  509. const columns = [];
  510. for (let i = 0, row; (row = table.childNodes[i]); i++) {
  511. for (let j = 0, cell; (cell = row.childNodes[j]); j++) {
  512. const column = columns[j];
  513. column ? columns[j].push(cell) : (columns[j] = [cell]);
  514. }
  515. }
  516. return columns;
  517. }
  518. static testColumns_(columns, index, pred) {
  519. const column = columns[index];
  520. return column
  521. ? column.some(function (cell) {
  522. return (cell.childNodes.length && pred(cell.childNodes[0]));
  523. }) &&
  524. column.every(function (cell) {
  525. return (!cell.childNodes.length ||
  526. pred(cell.childNodes[0]));
  527. })
  528. : false;
  529. }
  530. setNodeFactory(factory) {
  531. SemanticProcessor.getInstance().factory_ = factory;
  532. semantic_heuristic_factory_js_1.SemanticHeuristics.updateFactory(SemanticProcessor.getInstance().factory_);
  533. }
  534. getNodeFactory() {
  535. return SemanticProcessor.getInstance().factory_;
  536. }
  537. identifierNode(leaf, font, unit) {
  538. if (unit === 'MathML-Unit') {
  539. leaf.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
  540. leaf.role = semantic_meaning_js_1.SemanticRole.UNIT;
  541. }
  542. else if (!font &&
  543. leaf.textContent.length === 1 &&
  544. (leaf.role === semantic_meaning_js_1.SemanticRole.INTEGER ||
  545. leaf.role === semantic_meaning_js_1.SemanticRole.LATINLETTER ||
  546. leaf.role === semantic_meaning_js_1.SemanticRole.GREEKLETTER) &&
  547. leaf.font === semantic_meaning_js_1.SemanticFont.NORMAL) {
  548. leaf.font = semantic_meaning_js_1.SemanticFont.ITALIC;
  549. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('simpleNamedFunction', leaf);
  550. }
  551. if (leaf.type === semantic_meaning_js_1.SemanticType.UNKNOWN) {
  552. leaf.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
  553. }
  554. SemanticProcessor.exprFont_(leaf);
  555. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('simpleNamedFunction', leaf);
  556. }
  557. implicitNode(nodes) {
  558. nodes = SemanticProcessor.getInstance().getMixedNumbers_(nodes);
  559. nodes = SemanticProcessor.getInstance().combineUnits_(nodes);
  560. if (nodes.length === 1) {
  561. return nodes[0];
  562. }
  563. const node = SemanticProcessor.getInstance().implicitNode_(nodes);
  564. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('combine_juxtaposition', node);
  565. }
  566. text(leaf, type) {
  567. SemanticProcessor.exprFont_(leaf);
  568. leaf.type = semantic_meaning_js_1.SemanticType.TEXT;
  569. if (type === semantic_util_js_1.MMLTAGS.ANNOTATIONXML) {
  570. leaf.role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
  571. return leaf;
  572. }
  573. if (type === semantic_util_js_1.MMLTAGS.MS) {
  574. leaf.role = semantic_meaning_js_1.SemanticRole.STRING;
  575. return leaf;
  576. }
  577. if (type === semantic_util_js_1.MMLTAGS.MSPACE || leaf.textContent.match(/^\s*$/)) {
  578. leaf.role = semantic_meaning_js_1.SemanticRole.SPACE;
  579. return leaf;
  580. }
  581. if (/\s/.exec(leaf.textContent)) {
  582. leaf.role = semantic_meaning_js_1.SemanticRole.TEXT;
  583. return leaf;
  584. }
  585. leaf.role = semantic_meaning_js_1.SemanticRole.UNKNOWN;
  586. return leaf;
  587. }
  588. row(nodes) {
  589. nodes = nodes.filter(function (x) {
  590. return !SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.EMPTY);
  591. });
  592. if (nodes.length === 0) {
  593. return SemanticProcessor.getInstance().factory_.makeEmptyNode();
  594. }
  595. nodes = SemanticProcessor.getInstance().getFencesInRow_(nodes);
  596. nodes = SemanticProcessor.getInstance().tablesInRow(nodes);
  597. nodes = SemanticProcessor.getInstance().getPunctuationInRow_(nodes);
  598. nodes = SemanticProcessor.getInstance().getTextInRow_(nodes);
  599. nodes = SemanticProcessor.getInstance().getFunctionsInRow_(nodes);
  600. return SemanticProcessor.getInstance().relationsInRow_(nodes);
  601. }
  602. limitNode(mmlTag, children) {
  603. if (!children.length) {
  604. return SemanticProcessor.getInstance().factory_.makeEmptyNode();
  605. }
  606. let center = children[0];
  607. let type = semantic_meaning_js_1.SemanticType.UNKNOWN;
  608. if (!children[1]) {
  609. return center;
  610. }
  611. let result;
  612. semantic_heuristic_factory_js_1.SemanticHeuristics.run('op_with_limits', children);
  613. if (SemanticPred.isLimitBase(center)) {
  614. result = SemanticProcessor.MML_TO_LIMIT_[mmlTag];
  615. const length = result.length;
  616. type = result.type;
  617. children = children.slice(0, result.length + 1);
  618. if ((length === 1 && SemanticPred.isAccent(children[1])) ||
  619. (length === 2 &&
  620. SemanticPred.isAccent(children[1]) &&
  621. SemanticPred.isAccent(children[2]))) {
  622. result = SemanticProcessor.MML_TO_BOUNDS_[mmlTag];
  623. return SemanticProcessor.getInstance().accentNode_(center, children, result.type, result.length, result.accent);
  624. }
  625. if (length === 2) {
  626. if (SemanticPred.isAccent(children[1])) {
  627. center = SemanticProcessor.getInstance().accentNode_(center, [center, children[1]], {
  628. MSUBSUP: semantic_meaning_js_1.SemanticType.SUBSCRIPT,
  629. MUNDEROVER: semantic_meaning_js_1.SemanticType.UNDERSCORE
  630. }[mmlTag], 1, true);
  631. return !children[2]
  632. ? center
  633. : SemanticProcessor.getInstance().makeLimitNode_(center, [center, children[2]], null, semantic_meaning_js_1.SemanticType.LIMUPPER);
  634. }
  635. if (children[2] && SemanticPred.isAccent(children[2])) {
  636. center = SemanticProcessor.getInstance().accentNode_(center, [center, children[2]], {
  637. MSUBSUP: semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
  638. MUNDEROVER: semantic_meaning_js_1.SemanticType.OVERSCORE
  639. }[mmlTag], 1, true);
  640. return SemanticProcessor.getInstance().makeLimitNode_(center, [center, children[1]], null, semantic_meaning_js_1.SemanticType.LIMLOWER);
  641. }
  642. if (!children[length]) {
  643. type = semantic_meaning_js_1.SemanticType.LIMLOWER;
  644. }
  645. }
  646. return SemanticProcessor.getInstance().makeLimitNode_(center, children, null, type);
  647. }
  648. result = SemanticProcessor.MML_TO_BOUNDS_[mmlTag];
  649. return SemanticProcessor.getInstance().accentNode_(center, children, result.type, result.length, result.accent);
  650. }
  651. tablesInRow(nodes) {
  652. let partition = SemanticUtil.partitionNodes(nodes, SemanticPred.tableIsMatrixOrVector);
  653. let result = [];
  654. for (let i = 0, matrix; (matrix = partition.rel[i]); i++) {
  655. result = result.concat(partition.comp.shift());
  656. result.push(SemanticProcessor.tableToMatrixOrVector_(matrix));
  657. }
  658. result = result.concat(partition.comp.shift());
  659. partition = SemanticUtil.partitionNodes(result, SemanticPred.isTableOrMultiline);
  660. result = [];
  661. for (let i = 0, table; (table = partition.rel[i]); i++) {
  662. const prevNodes = partition.comp.shift();
  663. if (SemanticPred.tableIsCases(table, prevNodes)) {
  664. SemanticProcessor.tableToCases_(table, prevNodes.pop());
  665. }
  666. result = result.concat(prevNodes);
  667. result.push(table);
  668. }
  669. return result.concat(partition.comp.shift());
  670. }
  671. mfenced(open, close, sepValue, children) {
  672. if (sepValue && children.length > 0) {
  673. const separators = SemanticProcessor.nextSeparatorFunction_(sepValue);
  674. const newChildren = [children.shift()];
  675. children.forEach((child) => {
  676. newChildren.push(SemanticProcessor.getInstance().factory_.makeContentNode(separators()));
  677. newChildren.push(child);
  678. });
  679. children = newChildren;
  680. }
  681. if (open && close) {
  682. return SemanticProcessor.getInstance().horizontalFencedNode_(SemanticProcessor.getInstance().factory_.makeContentNode(open), SemanticProcessor.getInstance().factory_.makeContentNode(close), children);
  683. }
  684. if (open) {
  685. children.unshift(SemanticProcessor.getInstance().factory_.makeContentNode(open));
  686. }
  687. if (close) {
  688. children.push(SemanticProcessor.getInstance().factory_.makeContentNode(close));
  689. }
  690. return SemanticProcessor.getInstance().row(children);
  691. }
  692. fractionLikeNode(denom, enume, linethickness, bevelled) {
  693. let node;
  694. if (!bevelled && SemanticUtil.isZeroLength(linethickness)) {
  695. const child0 = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.LINE, [denom], []);
  696. const child1 = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.LINE, [enume], []);
  697. node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.MULTILINE, [child0, child1], []);
  698. SemanticProcessor.binomialForm_(node);
  699. SemanticProcessor.classifyMultiline(node);
  700. return node;
  701. }
  702. else {
  703. node = SemanticProcessor.getInstance().fractionNode_(denom, enume);
  704. if (bevelled) {
  705. node.addAnnotation('general', 'bevelled');
  706. }
  707. return node;
  708. }
  709. }
  710. tensor(base, lsub, lsup, rsub, rsup) {
  711. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.TENSOR, [
  712. base,
  713. SemanticProcessor.getInstance().scriptNode_(lsub, semantic_meaning_js_1.SemanticRole.LEFTSUB),
  714. SemanticProcessor.getInstance().scriptNode_(lsup, semantic_meaning_js_1.SemanticRole.LEFTSUPER),
  715. SemanticProcessor.getInstance().scriptNode_(rsub, semantic_meaning_js_1.SemanticRole.RIGHTSUB),
  716. SemanticProcessor.getInstance().scriptNode_(rsup, semantic_meaning_js_1.SemanticRole.RIGHTSUPER)
  717. ], []);
  718. newNode.role = base.role;
  719. newNode.embellished = SemanticPred.isEmbellished(base);
  720. return newNode;
  721. }
  722. pseudoTensor(base, sub, sup) {
  723. const isEmpty = (x) => !SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.EMPTY);
  724. const nonEmptySub = sub.filter(isEmpty).length;
  725. const nonEmptySup = sup.filter(isEmpty).length;
  726. if (!nonEmptySub && !nonEmptySup) {
  727. return base;
  728. }
  729. const mmlTag = nonEmptySub
  730. ? nonEmptySup
  731. ? semantic_util_js_1.MMLTAGS.MSUBSUP
  732. : semantic_util_js_1.MMLTAGS.MSUB
  733. : semantic_util_js_1.MMLTAGS.MSUP;
  734. const mmlchild = [base];
  735. if (nonEmptySub) {
  736. mmlchild.push(SemanticProcessor.getInstance().scriptNode_(sub, semantic_meaning_js_1.SemanticRole.RIGHTSUB, true));
  737. }
  738. if (nonEmptySup) {
  739. mmlchild.push(SemanticProcessor.getInstance().scriptNode_(sup, semantic_meaning_js_1.SemanticRole.RIGHTSUPER, true));
  740. }
  741. return SemanticProcessor.getInstance().limitNode(mmlTag, mmlchild);
  742. }
  743. font(font) {
  744. const mathjaxFont = SemanticProcessor.MATHJAX_FONTS[font];
  745. return mathjaxFont ? mathjaxFont : font;
  746. }
  747. proof(node, semantics, parse) {
  748. if (!semantics['inference'] && !semantics['axiom']) {
  749. console.log('Noise');
  750. }
  751. if (semantics['axiom']) {
  752. const cleaned = SemanticProcessor.getInstance().cleanInference(node.childNodes);
  753. const axiom = cleaned.length
  754. ? SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, parse(cleaned), [])
  755. : SemanticProcessor.getInstance().factory_.makeEmptyNode();
  756. axiom.role = semantic_meaning_js_1.SemanticRole.AXIOM;
  757. axiom.mathmlTree = node;
  758. return axiom;
  759. }
  760. const inference = SemanticProcessor.getInstance().inference(node, semantics, parse);
  761. if (semantics['proof']) {
  762. inference.role = semantic_meaning_js_1.SemanticRole.PROOF;
  763. inference.childNodes[0].role = semantic_meaning_js_1.SemanticRole.FINAL;
  764. }
  765. return inference;
  766. }
  767. inference(node, semantics, parse) {
  768. if (semantics['inferenceRule']) {
  769. const formulas = SemanticProcessor.getInstance().getFormulas(node, [], parse);
  770. const inference = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, [formulas.conclusion, formulas.premises], []);
  771. return inference;
  772. }
  773. const label = semantics['labelledRule'];
  774. const children = DomUtil.toArray(node.childNodes);
  775. const content = [];
  776. if (label === 'left' || label === 'both') {
  777. content.push(SemanticProcessor.getInstance().getLabel(node, children, parse, semantic_meaning_js_1.SemanticRole.LEFT));
  778. }
  779. if (label === 'right' || label === 'both') {
  780. content.push(SemanticProcessor.getInstance().getLabel(node, children, parse, semantic_meaning_js_1.SemanticRole.RIGHT));
  781. }
  782. const formulas = SemanticProcessor.getInstance().getFormulas(node, children, parse);
  783. const inference = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFERENCE, [formulas.conclusion, formulas.premises], content);
  784. inference.mathmlTree = node;
  785. return inference;
  786. }
  787. getLabel(_node, children, parse, side) {
  788. const label = SemanticProcessor.getInstance().findNestedRow(children, 'prooflabel', side);
  789. const sem = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.RULELABEL, parse(DomUtil.toArray(label.childNodes)), []);
  790. sem.role = side;
  791. sem.mathmlTree = label;
  792. return sem;
  793. }
  794. getFormulas(node, children, parse) {
  795. const inf = children.length
  796. ? SemanticProcessor.getInstance().findNestedRow(children, 'inferenceRule')
  797. : node;
  798. const up = SemanticProcessor.getSemantics(inf)['inferenceRule'] === 'up';
  799. const premRow = up ? inf.childNodes[1] : inf.childNodes[0];
  800. const concRow = up ? inf.childNodes[0] : inf.childNodes[1];
  801. const premTable = premRow.childNodes[0].childNodes[0];
  802. const topRow = DomUtil.toArray(premTable.childNodes[0].childNodes);
  803. const premNodes = [];
  804. let i = 1;
  805. for (const cell of topRow) {
  806. if (i % 2) {
  807. premNodes.push(cell.childNodes[0]);
  808. }
  809. i++;
  810. }
  811. const premises = parse(premNodes);
  812. const conclusion = parse(DomUtil.toArray(concRow.childNodes[0].childNodes))[0];
  813. const prem = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.PREMISES, premises, []);
  814. prem.mathmlTree = premTable;
  815. const conc = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.CONCLUSION, [conclusion], []);
  816. conc.mathmlTree = concRow.childNodes[0].childNodes[0];
  817. return { conclusion: conc, premises: prem };
  818. }
  819. findNestedRow(nodes, semantic, opt_value) {
  820. return SemanticProcessor.getInstance().findNestedRow_(nodes, semantic, 0, opt_value);
  821. }
  822. cleanInference(nodes) {
  823. return DomUtil.toArray(nodes).filter(function (x) {
  824. return DomUtil.tagName(x) !== 'MSPACE';
  825. });
  826. }
  827. operatorNode(node) {
  828. if (node.type === semantic_meaning_js_1.SemanticType.UNKNOWN) {
  829. node.type = semantic_meaning_js_1.SemanticType.OPERATOR;
  830. }
  831. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('multioperator', node);
  832. }
  833. constructor() {
  834. this.funcAppls = {};
  835. this.splitRoles = new Map([
  836. [semantic_meaning_js_1.SemanticRole.SUBTRACTION, semantic_meaning_js_1.SemanticRole.NEGATIVE],
  837. [semantic_meaning_js_1.SemanticRole.ADDITION, semantic_meaning_js_1.SemanticRole.POSITIVE]
  838. ]);
  839. this.splitOps = ['−', '-', '‐', '‑', '+'];
  840. this.factory_ = new semantic_node_factory_js_1.SemanticNodeFactory();
  841. semantic_heuristic_factory_js_1.SemanticHeuristics.updateFactory(this.factory_);
  842. }
  843. implicitNode_(nodes) {
  844. const operators = SemanticProcessor.getInstance().factory_.makeMultipleContentNodes(nodes.length - 1, semantic_attr_js_1.NamedSymbol.invisibleTimes);
  845. SemanticProcessor.matchSpaces_(nodes, operators);
  846. const newNode = SemanticProcessor.getInstance().infixNode_(nodes, operators[0]);
  847. newNode.role = semantic_meaning_js_1.SemanticRole.IMPLICIT;
  848. operators.forEach(function (op) {
  849. op.parent = newNode;
  850. });
  851. newNode.contentNodes = operators;
  852. return newNode;
  853. }
  854. infixNode_(children, opNode) {
  855. const node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.INFIXOP, children, [opNode], SemanticUtil.getEmbellishedInner(opNode).textContent);
  856. node.role = opNode.role;
  857. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateSimpleFunction', node);
  858. }
  859. explicitMixed_(nodes) {
  860. const partition = SemanticUtil.partitionNodes(nodes, function (x) {
  861. return x.textContent === semantic_attr_js_1.NamedSymbol.invisiblePlus;
  862. });
  863. if (!partition.rel.length) {
  864. return nodes;
  865. }
  866. let result = [];
  867. for (let i = 0, rel; (rel = partition.rel[i]); i++) {
  868. const prev = partition.comp[i];
  869. const next = partition.comp[i + 1];
  870. const last = prev.length - 1;
  871. if (prev[last] &&
  872. next[0] &&
  873. SemanticPred.isType(prev[last], semantic_meaning_js_1.SemanticType.NUMBER) &&
  874. !SemanticPred.isRole(prev[last], semantic_meaning_js_1.SemanticRole.MIXED) &&
  875. SemanticPred.isType(next[0], semantic_meaning_js_1.SemanticType.FRACTION)) {
  876. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.NUMBER, [prev[last], next[0]], []);
  877. newNode.role = semantic_meaning_js_1.SemanticRole.MIXED;
  878. result = result.concat(prev.slice(0, last));
  879. result.push(newNode);
  880. next.shift();
  881. }
  882. else {
  883. result = result.concat(prev);
  884. result.push(rel);
  885. }
  886. }
  887. return result.concat(partition.comp[partition.comp.length - 1]);
  888. }
  889. concatNode_(inner, nodeList, type) {
  890. if (nodeList.length === 0) {
  891. return inner;
  892. }
  893. const content = nodeList
  894. .map(function (x) {
  895. return SemanticUtil.getEmbellishedInner(x).textContent;
  896. })
  897. .join(' ');
  898. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, [inner], nodeList, content);
  899. if (nodeList.length > 1) {
  900. newNode.role = semantic_meaning_js_1.SemanticRole.MULTIOP;
  901. }
  902. return newNode;
  903. }
  904. prefixNode_(node, prefixes) {
  905. const newPrefixes = this.splitSingles(prefixes);
  906. let newNode = node;
  907. while (newPrefixes.length > 0) {
  908. const op = newPrefixes.pop();
  909. newNode = SemanticProcessor.getInstance().concatNode_(newNode, op, semantic_meaning_js_1.SemanticType.PREFIXOP);
  910. if (op.length === 1 && this.splitOps.indexOf(op[0].textContent) !== -1) {
  911. newNode.role = this.splitRoles.get(op[0].role);
  912. }
  913. }
  914. return newNode;
  915. }
  916. splitSingles(prefixes) {
  917. let lastOp = 0;
  918. const result = [];
  919. let i = 0;
  920. while (i < prefixes.length) {
  921. const op = prefixes[i];
  922. if (this.splitRoles.has(op.role) &&
  923. (!prefixes[i - 1] || prefixes[i - 1].role !== op.role) &&
  924. (!prefixes[i + 1] || prefixes[i + 1].role !== op.role) &&
  925. this.splitOps.indexOf(op.textContent) !== -1) {
  926. result.push(prefixes.slice(lastOp, i));
  927. result.push(prefixes.slice(i, i + 1));
  928. lastOp = i + 1;
  929. }
  930. i++;
  931. }
  932. if (lastOp < i) {
  933. result.push(prefixes.slice(lastOp, i));
  934. }
  935. return result;
  936. }
  937. postfixNode_(node, postfixes) {
  938. if (!postfixes.length) {
  939. return node;
  940. }
  941. return SemanticProcessor.getInstance().concatNode_(node, postfixes, semantic_meaning_js_1.SemanticType.POSTFIXOP);
  942. }
  943. combineUnits_(nodes) {
  944. const partition = SemanticUtil.partitionNodes(nodes, function (x) {
  945. return !SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.UNIT);
  946. });
  947. if (nodes.length === partition.rel.length) {
  948. return partition.rel;
  949. }
  950. const result = [];
  951. let rel;
  952. let last;
  953. do {
  954. const comp = partition.comp.shift();
  955. rel = partition.rel.shift();
  956. let unitNode = null;
  957. last = result.pop();
  958. if (last) {
  959. if (!comp.length || !SemanticPred.isUnitCounter(last)) {
  960. result.push(last);
  961. }
  962. else {
  963. comp.unshift(last);
  964. }
  965. }
  966. if (comp.length === 1) {
  967. unitNode = comp.pop();
  968. }
  969. if (comp.length > 1) {
  970. unitNode = SemanticProcessor.getInstance().implicitNode_(comp);
  971. unitNode.role = semantic_meaning_js_1.SemanticRole.UNIT;
  972. }
  973. if (unitNode) {
  974. result.push(unitNode);
  975. }
  976. if (rel) {
  977. result.push(rel);
  978. }
  979. } while (rel);
  980. return result;
  981. }
  982. getMixedNumbers_(nodes) {
  983. const partition = SemanticUtil.partitionNodes(nodes, function (x) {
  984. return (SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.FRACTION) &&
  985. SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.VULGAR));
  986. });
  987. if (!partition.rel.length) {
  988. return nodes;
  989. }
  990. let result = [];
  991. for (let i = 0, rel; (rel = partition.rel[i]); i++) {
  992. const comp = partition.comp[i];
  993. const last = comp.length - 1;
  994. if (comp[last] &&
  995. SemanticPred.isType(comp[last], semantic_meaning_js_1.SemanticType.NUMBER) &&
  996. (SemanticPred.isRole(comp[last], semantic_meaning_js_1.SemanticRole.INTEGER) ||
  997. SemanticPred.isRole(comp[last], semantic_meaning_js_1.SemanticRole.FLOAT))) {
  998. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.NUMBER, [comp[last], rel], []);
  999. newNode.role = semantic_meaning_js_1.SemanticRole.MIXED;
  1000. result = result.concat(comp.slice(0, last));
  1001. result.push(newNode);
  1002. }
  1003. else {
  1004. result = result.concat(comp);
  1005. result.push(rel);
  1006. }
  1007. }
  1008. return result.concat(partition.comp[partition.comp.length - 1]);
  1009. }
  1010. getTextInRow_(nodes) {
  1011. if (nodes.length === 0) {
  1012. return nodes;
  1013. }
  1014. if (nodes.length === 1) {
  1015. if (nodes[0].type === semantic_meaning_js_1.SemanticType.TEXT &&
  1016. nodes[0].role === semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  1017. nodes[0].role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
  1018. }
  1019. return nodes;
  1020. }
  1021. const { rel: rel, comp: comp } = SemanticUtil.partitionNodes(nodes, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.TEXT));
  1022. if (rel.length === 0) {
  1023. return nodes;
  1024. }
  1025. const result = [];
  1026. let prevComp = comp.shift();
  1027. while (rel.length > 0) {
  1028. let currentRel = rel.shift();
  1029. let nextComp = comp.shift();
  1030. const text = [];
  1031. while (!nextComp.length &&
  1032. rel.length &&
  1033. currentRel.role !== semantic_meaning_js_1.SemanticRole.SPACE &&
  1034. rel[0].role !== semantic_meaning_js_1.SemanticRole.SPACE) {
  1035. text.push(currentRel);
  1036. currentRel = rel.shift();
  1037. nextComp = comp.shift();
  1038. }
  1039. if (text.length) {
  1040. if (prevComp.length) {
  1041. result.push(SemanticProcessor.getInstance().row(prevComp));
  1042. }
  1043. text.push(currentRel);
  1044. const dummy = SemanticProcessor.getInstance().dummyNode_(text);
  1045. result.push(dummy);
  1046. prevComp = nextComp;
  1047. continue;
  1048. }
  1049. if (currentRel.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  1050. if (prevComp.length) {
  1051. result.push(SemanticProcessor.getInstance().row(prevComp));
  1052. }
  1053. result.push(currentRel);
  1054. prevComp = nextComp;
  1055. continue;
  1056. }
  1057. const meaning = semantic_attr_js_1.SemanticMap.Meaning.get(currentRel.textContent);
  1058. if (meaning.type === semantic_meaning_js_1.SemanticType.PUNCTUATION) {
  1059. currentRel.role = meaning.role;
  1060. currentRel.font = meaning.font;
  1061. if (prevComp.length) {
  1062. result.push(SemanticProcessor.getInstance().row(prevComp));
  1063. }
  1064. result.push(currentRel);
  1065. prevComp = nextComp;
  1066. continue;
  1067. }
  1068. if (meaning.type !== semantic_meaning_js_1.SemanticType.UNKNOWN) {
  1069. currentRel.type = meaning.type;
  1070. currentRel.role = meaning.role;
  1071. currentRel.font = meaning.font;
  1072. currentRel.addAnnotation('general', 'text');
  1073. prevComp.push(currentRel);
  1074. prevComp = prevComp.concat(nextComp);
  1075. continue;
  1076. }
  1077. SemanticProcessor.meaningFromContent(currentRel, (n, c, m) => {
  1078. if (n.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  1079. return;
  1080. }
  1081. SemanticProcessor.numberRole_(n, c, m);
  1082. if (n.role !== semantic_meaning_js_1.SemanticRole.OTHERNUMBER) {
  1083. n.type = semantic_meaning_js_1.SemanticType.NUMBER;
  1084. return;
  1085. }
  1086. if (m.some((x) => x.type !== semantic_meaning_js_1.SemanticType.NUMBER &&
  1087. x.type !== semantic_meaning_js_1.SemanticType.IDENTIFIER)) {
  1088. n.type = semantic_meaning_js_1.SemanticType.TEXT;
  1089. n.role = semantic_meaning_js_1.SemanticRole.ANNOTATION;
  1090. return;
  1091. }
  1092. n.role = semantic_meaning_js_1.SemanticRole.UNKNOWN;
  1093. });
  1094. if (currentRel.type === semantic_meaning_js_1.SemanticType.TEXT &&
  1095. currentRel.role !== semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  1096. if (prevComp.length) {
  1097. result.push(SemanticProcessor.getInstance().row(prevComp));
  1098. }
  1099. result.push(currentRel);
  1100. prevComp = nextComp;
  1101. continue;
  1102. }
  1103. if (currentRel.role === semantic_meaning_js_1.SemanticRole.UNKNOWN) {
  1104. if (rel.length || nextComp.length) {
  1105. if (nextComp.length && nextComp[0].type === semantic_meaning_js_1.SemanticType.FENCED) {
  1106. currentRel.type = semantic_meaning_js_1.SemanticType.FUNCTION;
  1107. currentRel.role = semantic_meaning_js_1.SemanticRole.PREFIXFUNC;
  1108. }
  1109. else {
  1110. currentRel.role = semantic_meaning_js_1.SemanticRole.TEXT;
  1111. }
  1112. }
  1113. else {
  1114. currentRel.type = semantic_meaning_js_1.SemanticType.IDENTIFIER;
  1115. currentRel.role = semantic_meaning_js_1.SemanticRole.UNIT;
  1116. }
  1117. }
  1118. prevComp.push(currentRel);
  1119. prevComp = prevComp.concat(nextComp);
  1120. }
  1121. if (prevComp.length > 0) {
  1122. result.push(SemanticProcessor.getInstance().row(prevComp));
  1123. }
  1124. return result.length > 1
  1125. ? [SemanticProcessor.getInstance().dummyNode_(result)]
  1126. : result;
  1127. }
  1128. relationsInRow_(nodes) {
  1129. const partition = SemanticUtil.partitionNodes(nodes, SemanticPred.isRelation);
  1130. const firstRel = partition.rel[0];
  1131. if (!firstRel) {
  1132. return SemanticProcessor.getInstance().operationsInRow_(nodes);
  1133. }
  1134. if (nodes.length === 1) {
  1135. return nodes[0];
  1136. }
  1137. const children = partition.comp.map(SemanticProcessor.getInstance().operationsInRow_);
  1138. let node;
  1139. if (partition.rel.some(function (x) {
  1140. return !x.equals(firstRel);
  1141. })) {
  1142. node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.MULTIREL, children, partition.rel);
  1143. if (partition.rel.every(function (x) {
  1144. return x.role === firstRel.role;
  1145. })) {
  1146. node.role = firstRel.role;
  1147. }
  1148. return node;
  1149. }
  1150. node = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.RELSEQ, children, partition.rel, SemanticUtil.getEmbellishedInner(firstRel).textContent);
  1151. node.role = firstRel.role;
  1152. return node;
  1153. }
  1154. operationsInRow_(nodes) {
  1155. if (nodes.length === 0) {
  1156. return SemanticProcessor.getInstance().factory_.makeEmptyNode();
  1157. }
  1158. nodes = SemanticProcessor.getInstance().explicitMixed_(nodes);
  1159. if (nodes.length === 1) {
  1160. return nodes[0];
  1161. }
  1162. const prefix = [];
  1163. while (nodes.length > 0 && SemanticPred.isOperator(nodes[0])) {
  1164. prefix.push(nodes.shift());
  1165. }
  1166. if (nodes.length === 0) {
  1167. return SemanticProcessor.getInstance().prefixNode_(prefix.pop(), prefix);
  1168. }
  1169. if (nodes.length === 1) {
  1170. return SemanticProcessor.getInstance().prefixNode_(nodes[0], prefix);
  1171. }
  1172. nodes = semantic_heuristic_factory_js_1.SemanticHeuristics.run('convert_juxtaposition', nodes);
  1173. const split = SemanticUtil.sliceNodes(nodes, SemanticPred.isOperator);
  1174. const node = SemanticProcessor.getInstance().wrapFactor(prefix, split);
  1175. return SemanticProcessor.getInstance().addFactor(node, split);
  1176. }
  1177. wrapPostfix(split) {
  1178. var _a;
  1179. if (((_a = split.div) === null || _a === void 0 ? void 0 : _a.role) === semantic_meaning_js_1.SemanticRole.POSTFIXOP) {
  1180. if (!split.tail.length || split.tail[0].type === semantic_meaning_js_1.SemanticType.OPERATOR) {
  1181. split.head = [
  1182. SemanticProcessor.getInstance().postfixNode_(SemanticProcessor.getInstance().implicitNode(split.head), [split.div])
  1183. ];
  1184. split.div = split.tail.shift();
  1185. SemanticProcessor.getInstance().wrapPostfix(split);
  1186. }
  1187. else {
  1188. split.div.role = semantic_meaning_js_1.SemanticRole.DIVISION;
  1189. }
  1190. }
  1191. }
  1192. wrapFactor(prefix, split) {
  1193. SemanticProcessor.getInstance().wrapPostfix(split);
  1194. return SemanticProcessor.getInstance().prefixNode_(SemanticProcessor.getInstance().implicitNode(split.head), prefix);
  1195. }
  1196. addFactor(node, split) {
  1197. if (!split.div) {
  1198. if (SemanticPred.isUnitProduct(node)) {
  1199. node.role = semantic_meaning_js_1.SemanticRole.UNIT;
  1200. }
  1201. return node;
  1202. }
  1203. return SemanticProcessor.getInstance().operationsTree_(split.tail, node, split.div);
  1204. }
  1205. operationsTree_(nodes, root, lastop, prefix = []) {
  1206. if (nodes.length === 0) {
  1207. prefix.unshift(lastop);
  1208. if (root.type === semantic_meaning_js_1.SemanticType.INFIXOP) {
  1209. const node = SemanticProcessor.getInstance().postfixNode_(root.childNodes.pop(), prefix);
  1210. root.appendChild(node);
  1211. return root;
  1212. }
  1213. return SemanticProcessor.getInstance().postfixNode_(root, prefix);
  1214. }
  1215. const split = SemanticUtil.sliceNodes(nodes, SemanticPred.isOperator);
  1216. if (split.head.length === 0) {
  1217. prefix.push(split.div);
  1218. return SemanticProcessor.getInstance().operationsTree_(split.tail, root, lastop, prefix);
  1219. }
  1220. const node = SemanticProcessor.getInstance().wrapFactor(prefix, split);
  1221. const newNode = SemanticProcessor.getInstance().appendOperand_(root, lastop, node);
  1222. return SemanticProcessor.getInstance().addFactor(newNode, split);
  1223. }
  1224. appendOperand_(root, op, node) {
  1225. if (root.type !== semantic_meaning_js_1.SemanticType.INFIXOP) {
  1226. return SemanticProcessor.getInstance().infixNode_([root, node], op);
  1227. }
  1228. const division = SemanticProcessor.getInstance().appendDivisionOp_(root, op, node);
  1229. if (division) {
  1230. return division;
  1231. }
  1232. if (SemanticProcessor.getInstance().appendExistingOperator_(root, op, node)) {
  1233. return root;
  1234. }
  1235. return op.role === semantic_meaning_js_1.SemanticRole.MULTIPLICATION
  1236. ? SemanticProcessor.getInstance().appendMultiplicativeOp_(root, op, node)
  1237. : SemanticProcessor.getInstance().appendAdditiveOp_(root, op, node);
  1238. }
  1239. appendDivisionOp_(root, op, node) {
  1240. if (op.role === semantic_meaning_js_1.SemanticRole.DIVISION) {
  1241. if (SemanticPred.isImplicit(root)) {
  1242. return SemanticProcessor.getInstance().infixNode_([root, node], op);
  1243. }
  1244. return SemanticProcessor.getInstance().appendLastOperand_(root, op, node);
  1245. }
  1246. return root.role === semantic_meaning_js_1.SemanticRole.DIVISION
  1247. ? SemanticProcessor.getInstance().infixNode_([root, node], op)
  1248. : null;
  1249. }
  1250. appendLastOperand_(root, op, node) {
  1251. let lastRoot = root;
  1252. let lastChild = root.childNodes[root.childNodes.length - 1];
  1253. while (lastChild &&
  1254. lastChild.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
  1255. !SemanticPred.isImplicit(lastChild)) {
  1256. lastRoot = lastChild;
  1257. lastChild = lastRoot.childNodes[root.childNodes.length - 1];
  1258. }
  1259. const newNode = SemanticProcessor.getInstance().infixNode_([lastRoot.childNodes.pop(), node], op);
  1260. lastRoot.appendChild(newNode);
  1261. return root;
  1262. }
  1263. appendMultiplicativeOp_(root, op, node) {
  1264. if (SemanticPred.isImplicit(root)) {
  1265. return SemanticProcessor.getInstance().infixNode_([root, node], op);
  1266. }
  1267. let lastRoot = root;
  1268. let lastChild = root.childNodes[root.childNodes.length - 1];
  1269. while (lastChild &&
  1270. lastChild.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
  1271. !SemanticPred.isImplicit(lastChild)) {
  1272. lastRoot = lastChild;
  1273. lastChild = lastRoot.childNodes[root.childNodes.length - 1];
  1274. }
  1275. const newNode = SemanticProcessor.getInstance().infixNode_([lastRoot.childNodes.pop(), node], op);
  1276. lastRoot.appendChild(newNode);
  1277. return root;
  1278. }
  1279. appendAdditiveOp_(root, op, node) {
  1280. return SemanticProcessor.getInstance().infixNode_([root, node], op);
  1281. }
  1282. appendExistingOperator_(root, op, node) {
  1283. if (!root ||
  1284. root.type !== semantic_meaning_js_1.SemanticType.INFIXOP ||
  1285. SemanticPred.isImplicit(root)) {
  1286. return false;
  1287. }
  1288. if (root.contentNodes[0].equals(op)) {
  1289. root.appendContentNode(op);
  1290. root.appendChild(node);
  1291. return true;
  1292. }
  1293. return SemanticProcessor.getInstance().appendExistingOperator_(root.childNodes[root.childNodes.length - 1], op, node);
  1294. }
  1295. getFencesInRow_(nodes) {
  1296. let partition = SemanticUtil.partitionNodes(nodes, SemanticPred.isFence);
  1297. partition = SemanticProcessor.purgeFences_(partition);
  1298. const felem = partition.comp.shift();
  1299. return SemanticProcessor.getInstance().fences_(partition.rel, partition.comp, [], [felem]);
  1300. }
  1301. fences_(fences, content, openStack, contentStack) {
  1302. if (fences.length === 0 && openStack.length === 0) {
  1303. return contentStack[0];
  1304. }
  1305. const interval = semantic_heuristic_factory_js_1.SemanticHeuristics.run('bracketed_interval', [fences[0], fences[1], ...(content[0] || [])], () => null);
  1306. if (interval) {
  1307. fences.shift();
  1308. fences.shift();
  1309. content.shift();
  1310. const stack = contentStack.pop() || [];
  1311. contentStack.push([...stack, interval, ...content.shift()]);
  1312. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1313. }
  1314. const openPred = (x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.OPEN);
  1315. if (fences.length === 0) {
  1316. const result = contentStack.shift();
  1317. while (openStack.length > 0) {
  1318. if (openPred(openStack[0])) {
  1319. const firstOpen = openStack.shift();
  1320. SemanticProcessor.fenceToPunct_(firstOpen);
  1321. result.push(firstOpen);
  1322. }
  1323. else {
  1324. const split = SemanticUtil.sliceNodes(openStack, openPred);
  1325. const cutLength = split.head.length - 1;
  1326. const innerNodes = SemanticProcessor.getInstance().neutralFences_(split.head, contentStack.slice(0, cutLength));
  1327. contentStack = contentStack.slice(cutLength);
  1328. result.push(...innerNodes);
  1329. if (split.div) {
  1330. split.tail.unshift(split.div);
  1331. }
  1332. openStack = split.tail;
  1333. }
  1334. result.push(...contentStack.shift());
  1335. }
  1336. return result;
  1337. }
  1338. const lastOpen = openStack[openStack.length - 1];
  1339. const firstRole = fences[0].role;
  1340. if (firstRole === semantic_meaning_js_1.SemanticRole.OPEN ||
  1341. (SemanticPred.isNeutralFence(fences[0]) &&
  1342. !(lastOpen && SemanticPred.compareNeutralFences(fences[0], lastOpen)))) {
  1343. openStack.push(fences.shift());
  1344. const cont = content.shift();
  1345. if (cont) {
  1346. contentStack.push(cont);
  1347. }
  1348. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1349. }
  1350. if (lastOpen &&
  1351. firstRole === semantic_meaning_js_1.SemanticRole.CLOSE &&
  1352. lastOpen.role === semantic_meaning_js_1.SemanticRole.OPEN) {
  1353. const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(openStack.pop(), fences.shift(), contentStack.pop());
  1354. contentStack.push(contentStack.pop().concat([fenced], content.shift()));
  1355. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1356. }
  1357. if (lastOpen &&
  1358. SemanticPred.compareNeutralFences(fences[0], lastOpen)) {
  1359. if (!SemanticPred.elligibleLeftNeutral(lastOpen) ||
  1360. !SemanticPred.elligibleRightNeutral(fences[0])) {
  1361. openStack.push(fences.shift());
  1362. const cont = content.shift();
  1363. if (cont) {
  1364. contentStack.push(cont);
  1365. }
  1366. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1367. }
  1368. const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(openStack.pop(), fences.shift(), contentStack.pop());
  1369. contentStack.push(contentStack.pop().concat([fenced], content.shift()));
  1370. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1371. }
  1372. if (lastOpen &&
  1373. firstRole === semantic_meaning_js_1.SemanticRole.CLOSE &&
  1374. SemanticPred.isNeutralFence(lastOpen) &&
  1375. openStack.some(openPred)) {
  1376. const split = SemanticUtil.sliceNodes(openStack, openPred, true);
  1377. const rightContent = contentStack.pop();
  1378. const cutLength = contentStack.length - split.tail.length + 1;
  1379. const innerNodes = SemanticProcessor.getInstance().neutralFences_(split.tail, contentStack.slice(cutLength));
  1380. contentStack = contentStack.slice(0, cutLength);
  1381. const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(split.div, fences.shift(), contentStack.pop().concat(innerNodes, rightContent));
  1382. contentStack.push(contentStack.pop().concat([fenced], content.shift()));
  1383. return SemanticProcessor.getInstance().fences_(fences, content, split.head, contentStack);
  1384. }
  1385. const fenced = fences.shift();
  1386. SemanticProcessor.fenceToPunct_(fenced);
  1387. contentStack.push(contentStack.pop().concat([fenced], content.shift()));
  1388. return SemanticProcessor.getInstance().fences_(fences, content, openStack, contentStack);
  1389. }
  1390. neutralFences_(fences, content) {
  1391. if (fences.length === 0) {
  1392. return fences;
  1393. }
  1394. if (fences.length === 1) {
  1395. SemanticProcessor.fenceToPunct_(fences[0]);
  1396. return fences;
  1397. }
  1398. const firstFence = fences.shift();
  1399. if (!SemanticPred.elligibleLeftNeutral(firstFence)) {
  1400. SemanticProcessor.fenceToPunct_(firstFence);
  1401. const restContent = content.shift();
  1402. restContent.unshift(firstFence);
  1403. return restContent.concat(SemanticProcessor.getInstance().neutralFences_(fences, content));
  1404. }
  1405. const split = SemanticUtil.sliceNodes(fences, function (x) {
  1406. return SemanticPred.compareNeutralFences(x, firstFence);
  1407. });
  1408. if (!split.div) {
  1409. SemanticProcessor.fenceToPunct_(firstFence);
  1410. const restContent = content.shift();
  1411. restContent.unshift(firstFence);
  1412. return restContent.concat(SemanticProcessor.getInstance().neutralFences_(fences, content));
  1413. }
  1414. if (!SemanticPred.elligibleRightNeutral(split.div)) {
  1415. SemanticProcessor.fenceToPunct_(split.div);
  1416. fences.unshift(firstFence);
  1417. return SemanticProcessor.getInstance().neutralFences_(fences, content);
  1418. }
  1419. const newContent = SemanticProcessor.getInstance().combineFencedContent_(firstFence, split.div, split.head, content);
  1420. if (split.tail.length > 0) {
  1421. const leftContent = newContent.shift();
  1422. const result = SemanticProcessor.getInstance().neutralFences_(split.tail, newContent);
  1423. return leftContent.concat(result);
  1424. }
  1425. return newContent[0];
  1426. }
  1427. combineFencedContent_(leftFence, rightFence, midFences, content) {
  1428. if (midFences.length === 0) {
  1429. const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(leftFence, rightFence, content.shift());
  1430. if (content.length > 0) {
  1431. content[0].unshift(fenced);
  1432. }
  1433. else {
  1434. content = [[fenced]];
  1435. }
  1436. return content;
  1437. }
  1438. const leftContent = content.shift();
  1439. const cutLength = midFences.length - 1;
  1440. const midContent = content.slice(0, cutLength);
  1441. content = content.slice(cutLength);
  1442. const rightContent = content.shift();
  1443. const innerNodes = SemanticProcessor.getInstance().neutralFences_(midFences, midContent);
  1444. leftContent.push(...innerNodes);
  1445. leftContent.push(...rightContent);
  1446. const fenced = SemanticProcessor.getInstance().horizontalFencedNode_(leftFence, rightFence, leftContent);
  1447. if (content.length > 0) {
  1448. content[0].unshift(fenced);
  1449. }
  1450. else {
  1451. content = [[fenced]];
  1452. }
  1453. return content;
  1454. }
  1455. horizontalFencedNode_(ofence, cfence, content) {
  1456. const childNode = SemanticProcessor.getInstance().row(content);
  1457. let newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.FENCED, [childNode], [ofence, cfence]);
  1458. if (ofence.role === semantic_meaning_js_1.SemanticRole.OPEN) {
  1459. SemanticProcessor.getInstance().classifyHorizontalFence_(newNode);
  1460. newNode = semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateComposedFunction', newNode);
  1461. }
  1462. else {
  1463. newNode.role = ofence.role;
  1464. }
  1465. newNode = semantic_heuristic_factory_js_1.SemanticHeuristics.run('detect_cycle', newNode);
  1466. return SemanticProcessor.rewriteFencedNode_(newNode);
  1467. }
  1468. classifyHorizontalFence_(node) {
  1469. node.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
  1470. const children = node.childNodes;
  1471. if (!SemanticPred.isSetNode(node) || children.length > 1) {
  1472. return;
  1473. }
  1474. if (children.length === 0 || children[0].type === semantic_meaning_js_1.SemanticType.EMPTY) {
  1475. node.role = semantic_meaning_js_1.SemanticRole.SETEMPTY;
  1476. return;
  1477. }
  1478. const type = children[0].type;
  1479. if (children.length === 1 &&
  1480. SemanticPred.isSingletonSetContent(children[0])) {
  1481. node.role = semantic_meaning_js_1.SemanticRole.SETSINGLE;
  1482. return;
  1483. }
  1484. const role = children[0].role;
  1485. if (type !== semantic_meaning_js_1.SemanticType.PUNCTUATED || role !== semantic_meaning_js_1.SemanticRole.SEQUENCE) {
  1486. return;
  1487. }
  1488. if (children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.COMMA) {
  1489. node.role = semantic_meaning_js_1.SemanticRole.SETCOLLECT;
  1490. return;
  1491. }
  1492. if (children[0].contentNodes.length === 1 &&
  1493. (children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.VBAR ||
  1494. children[0].contentNodes[0].role === semantic_meaning_js_1.SemanticRole.COLON)) {
  1495. node.role = semantic_meaning_js_1.SemanticRole.SETEXT;
  1496. SemanticProcessor.getInstance().setExtension_(node);
  1497. return;
  1498. }
  1499. }
  1500. setExtension_(set) {
  1501. const extender = set.childNodes[0].childNodes[0];
  1502. if (extender &&
  1503. extender.type === semantic_meaning_js_1.SemanticType.INFIXOP &&
  1504. extender.contentNodes.length === 1 &&
  1505. SemanticPred.isMembership(extender.contentNodes[0])) {
  1506. extender.addAnnotation('set', 'intensional');
  1507. extender.contentNodes[0].addAnnotation('set', 'intensional');
  1508. }
  1509. }
  1510. getPunctuationInRow_(nodes) {
  1511. if (nodes.length <= 1) {
  1512. return nodes;
  1513. }
  1514. const allowedType = (x) => {
  1515. const type = x.type;
  1516. return (type === 'punctuation' ||
  1517. type === 'text' ||
  1518. type === 'operator' ||
  1519. type === 'relation');
  1520. };
  1521. const partition = SemanticUtil.partitionNodes(nodes, function (x) {
  1522. if (!SemanticPred.isPunctuation(x)) {
  1523. return false;
  1524. }
  1525. if (SemanticPred.isPunctuation(x) &&
  1526. !SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.ELLIPSIS)) {
  1527. return true;
  1528. }
  1529. const index = nodes.indexOf(x);
  1530. if (index === 0) {
  1531. if (nodes[1] && allowedType(nodes[1])) {
  1532. return false;
  1533. }
  1534. return true;
  1535. }
  1536. const prev = nodes[index - 1];
  1537. if (index === nodes.length - 1) {
  1538. if (allowedType(prev)) {
  1539. return false;
  1540. }
  1541. return true;
  1542. }
  1543. const next = nodes[index + 1];
  1544. if (allowedType(prev) && allowedType(next)) {
  1545. return false;
  1546. }
  1547. return true;
  1548. });
  1549. if (partition.rel.length === 0) {
  1550. return nodes;
  1551. }
  1552. let newNodes = [];
  1553. let firstComp = partition.comp.shift();
  1554. if (firstComp.length > 0) {
  1555. newNodes.push(SemanticProcessor.getInstance().row(firstComp));
  1556. }
  1557. let relCounter = 0;
  1558. while (partition.comp.length > 0) {
  1559. let puncts = [];
  1560. const saveCount = relCounter;
  1561. do {
  1562. puncts.push(partition.rel[relCounter++]);
  1563. firstComp = partition.comp.shift();
  1564. } while (partition.rel[relCounter] &&
  1565. firstComp &&
  1566. firstComp.length === 0);
  1567. puncts = semantic_heuristic_factory_js_1.SemanticHeuristics.run('ellipses', puncts);
  1568. partition.rel.splice(saveCount, relCounter - saveCount, ...puncts);
  1569. relCounter = saveCount + puncts.length;
  1570. newNodes = newNodes.concat(puncts);
  1571. if (firstComp && firstComp.length > 0) {
  1572. newNodes.push(SemanticProcessor.getInstance().row(firstComp));
  1573. }
  1574. }
  1575. return newNodes.length === 1 && partition.rel.length === 1
  1576. ? newNodes
  1577. : [
  1578. SemanticProcessor.getInstance().punctuatedNode_(newNodes, partition.rel)
  1579. ];
  1580. }
  1581. punctuatedNode_(nodes, punctuations) {
  1582. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.PUNCTUATED, nodes, punctuations);
  1583. if (punctuations.length === nodes.length) {
  1584. const firstRole = punctuations[0].role;
  1585. if (firstRole !== semantic_meaning_js_1.SemanticRole.UNKNOWN &&
  1586. punctuations.every(function (punct) {
  1587. return punct.role === firstRole;
  1588. })) {
  1589. newNode.role = firstRole;
  1590. return newNode;
  1591. }
  1592. }
  1593. const fpunct = punctuations[0];
  1594. if (SemanticPred.singlePunctAtPosition(nodes, punctuations, 0)) {
  1595. newNode.role =
  1596. fpunct.childNodes.length && !fpunct.embellished
  1597. ? fpunct.role
  1598. : semantic_meaning_js_1.SemanticRole.STARTPUNCT;
  1599. }
  1600. else if (SemanticPred.singlePunctAtPosition(nodes, punctuations, nodes.length - 1)) {
  1601. newNode.role =
  1602. fpunct.childNodes.length && !fpunct.embellished
  1603. ? fpunct.role
  1604. : semantic_meaning_js_1.SemanticRole.ENDPUNCT;
  1605. }
  1606. else if (punctuations.every((x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.DUMMY))) {
  1607. newNode.role = semantic_meaning_js_1.SemanticRole.TEXT;
  1608. }
  1609. else if (punctuations.every((x) => SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.SPACE))) {
  1610. newNode.role = semantic_meaning_js_1.SemanticRole.SPACE;
  1611. }
  1612. else {
  1613. newNode.role = semantic_meaning_js_1.SemanticRole.SEQUENCE;
  1614. }
  1615. return newNode;
  1616. }
  1617. dummyNode_(children) {
  1618. const commata = SemanticProcessor.getInstance().factory_.makeMultipleContentNodes(children.length - 1, semantic_attr_js_1.NamedSymbol.invisibleComma);
  1619. commata.forEach(function (comma) {
  1620. comma.role = semantic_meaning_js_1.SemanticRole.DUMMY;
  1621. });
  1622. return SemanticProcessor.getInstance().punctuatedNode_(children, commata);
  1623. }
  1624. accentRole_(node, type) {
  1625. if (!SemanticPred.isAccent(node)) {
  1626. return false;
  1627. }
  1628. const content = node.textContent;
  1629. const role = semantic_attr_js_1.SemanticMap.Secondary.get(content, semantic_meaning_js_1.SemanticSecondary.BAR) ||
  1630. semantic_attr_js_1.SemanticMap.Secondary.get(content, semantic_meaning_js_1.SemanticSecondary.TILDE) ||
  1631. node.role;
  1632. node.role =
  1633. type === semantic_meaning_js_1.SemanticType.UNDERSCORE
  1634. ? semantic_meaning_js_1.SemanticRole.UNDERACCENT
  1635. : semantic_meaning_js_1.SemanticRole.OVERACCENT;
  1636. node.addAnnotation('accent', role);
  1637. return true;
  1638. }
  1639. accentNode_(center, children, type, length, accent) {
  1640. children = children.slice(0, length + 1);
  1641. const child1 = children[1];
  1642. const child2 = children[2];
  1643. let innerNode;
  1644. if (!accent && child2) {
  1645. innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.SUBSCRIPT, [center, child1], []);
  1646. innerNode.role = semantic_meaning_js_1.SemanticRole.SUBSUP;
  1647. children = [innerNode, child2];
  1648. type = semantic_meaning_js_1.SemanticType.SUPERSCRIPT;
  1649. }
  1650. if (accent) {
  1651. const underAccent = SemanticProcessor.getInstance().accentRole_(child1, type);
  1652. if (child2) {
  1653. const overAccent = SemanticProcessor.getInstance().accentRole_(child2, semantic_meaning_js_1.SemanticType.OVERSCORE);
  1654. if (overAccent && !underAccent) {
  1655. innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.OVERSCORE, [center, child2], []);
  1656. children = [innerNode, child1];
  1657. type = semantic_meaning_js_1.SemanticType.UNDERSCORE;
  1658. }
  1659. else {
  1660. innerNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.UNDERSCORE, [center, child1], []);
  1661. children = [innerNode, child2];
  1662. type = semantic_meaning_js_1.SemanticType.OVERSCORE;
  1663. }
  1664. innerNode.role = semantic_meaning_js_1.SemanticRole.UNDEROVER;
  1665. }
  1666. }
  1667. return SemanticProcessor.getInstance().makeLimitNode_(center, children, innerNode, type);
  1668. }
  1669. makeLimitNode_(center, children, innerNode, type) {
  1670. if (type === semantic_meaning_js_1.SemanticType.LIMUPPER &&
  1671. center.type === semantic_meaning_js_1.SemanticType.LIMLOWER) {
  1672. center.childNodes.push(children[1]);
  1673. children[1].parent = center;
  1674. center.type = semantic_meaning_js_1.SemanticType.LIMBOTH;
  1675. return center;
  1676. }
  1677. if (type === semantic_meaning_js_1.SemanticType.LIMLOWER &&
  1678. center.type === semantic_meaning_js_1.SemanticType.LIMUPPER) {
  1679. center.childNodes.splice(1, -1, children[1]);
  1680. children[1].parent = center;
  1681. center.type = semantic_meaning_js_1.SemanticType.LIMBOTH;
  1682. return center;
  1683. }
  1684. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, children, []);
  1685. const embellished = SemanticPred.isEmbellished(center);
  1686. if (innerNode) {
  1687. innerNode.embellished = embellished;
  1688. }
  1689. newNode.embellished = embellished;
  1690. newNode.role = center.role;
  1691. return newNode;
  1692. }
  1693. getFunctionsInRow_(restNodes, opt_result) {
  1694. const result = opt_result || [];
  1695. if (restNodes.length === 0) {
  1696. return result;
  1697. }
  1698. const firstNode = restNodes.shift();
  1699. const heuristic = SemanticProcessor.classifyFunction_(firstNode, restNodes);
  1700. if (!heuristic) {
  1701. result.push(firstNode);
  1702. return SemanticProcessor.getInstance().getFunctionsInRow_(restNodes, result);
  1703. }
  1704. const processedRest = SemanticProcessor.getInstance().getFunctionsInRow_(restNodes, []);
  1705. const newRest = SemanticProcessor.getInstance().getFunctionArgs_(firstNode, processedRest, heuristic);
  1706. return result.concat(newRest);
  1707. }
  1708. getFunctionArgs_(func, rest, heuristic) {
  1709. let partition, arg, funcNode;
  1710. switch (heuristic) {
  1711. case 'integral': {
  1712. const components = SemanticProcessor.getInstance().getIntegralArgs_(rest);
  1713. if (!components.intvar && !components.integrand.length) {
  1714. components.rest.unshift(func);
  1715. return components.rest;
  1716. }
  1717. const integrand = SemanticProcessor.getInstance().row(components.integrand);
  1718. funcNode = SemanticProcessor.getInstance().integralNode_(func, integrand, components.intvar);
  1719. semantic_heuristic_factory_js_1.SemanticHeuristics.run('intvar_from_fraction', funcNode);
  1720. components.rest.unshift(funcNode);
  1721. return components.rest;
  1722. }
  1723. case 'prefix': {
  1724. if (rest[0] && rest[0].type === semantic_meaning_js_1.SemanticType.FENCED) {
  1725. const arg = rest.shift();
  1726. if (!SemanticPred.isNeutralFence(arg)) {
  1727. arg.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
  1728. }
  1729. funcNode = SemanticProcessor.getInstance().functionNode_(func, arg);
  1730. rest.unshift(funcNode);
  1731. return rest;
  1732. }
  1733. partition = SemanticUtil.sliceNodes(rest, SemanticPred.isPrefixFunctionBoundary);
  1734. if (!partition.head.length) {
  1735. if (!partition.div ||
  1736. !SemanticPred.isType(partition.div, semantic_meaning_js_1.SemanticType.APPL)) {
  1737. rest.unshift(func);
  1738. return rest;
  1739. }
  1740. arg = partition.div;
  1741. }
  1742. else {
  1743. arg = SemanticProcessor.getInstance().row(partition.head);
  1744. if (partition.div) {
  1745. partition.tail.unshift(partition.div);
  1746. }
  1747. }
  1748. funcNode = SemanticProcessor.getInstance().functionNode_(func, arg);
  1749. partition.tail.unshift(funcNode);
  1750. return partition.tail;
  1751. }
  1752. case 'bigop': {
  1753. partition = SemanticUtil.sliceNodes(rest, SemanticPred.isBigOpBoundary);
  1754. if (!partition.head.length) {
  1755. rest.unshift(func);
  1756. return rest;
  1757. }
  1758. arg = SemanticProcessor.getInstance().row(partition.head);
  1759. funcNode = SemanticProcessor.getInstance().bigOpNode_(func, arg);
  1760. if (partition.div) {
  1761. partition.tail.unshift(partition.div);
  1762. }
  1763. partition.tail.unshift(funcNode);
  1764. return partition.tail;
  1765. }
  1766. case 'simple':
  1767. default: {
  1768. if (rest.length === 0) {
  1769. return [func];
  1770. }
  1771. const firstArg = rest[0];
  1772. if (firstArg.type === semantic_meaning_js_1.SemanticType.FENCED &&
  1773. !SemanticPred.isNeutralFence(firstArg) &&
  1774. SemanticPred.isSimpleFunctionScope(firstArg)) {
  1775. firstArg.role = semantic_meaning_js_1.SemanticRole.LEFTRIGHT;
  1776. SemanticProcessor.propagateFunctionRole_(func, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC);
  1777. funcNode = SemanticProcessor.getInstance().functionNode_(func, rest.shift());
  1778. rest.unshift(funcNode);
  1779. return rest;
  1780. }
  1781. rest.unshift(func);
  1782. return rest;
  1783. }
  1784. }
  1785. }
  1786. getIntegralArgs_(nodes, args = []) {
  1787. if (nodes.length === 0) {
  1788. const partition = SemanticUtil.sliceNodes(args, SemanticPred.isBigOpBoundary);
  1789. if (partition.div) {
  1790. partition.tail.unshift(partition.div);
  1791. }
  1792. return { integrand: partition.head, intvar: null, rest: partition.tail };
  1793. }
  1794. semantic_heuristic_factory_js_1.SemanticHeuristics.run('intvar_from_implicit', nodes);
  1795. const firstNode = nodes[0];
  1796. if (SemanticPred.isGeneralFunctionBoundary(firstNode)) {
  1797. const { integrand: args2, rest: rest2 } = SemanticProcessor.getInstance().getIntegralArgs_(args);
  1798. return { integrand: args2, intvar: null, rest: rest2.concat(nodes) };
  1799. }
  1800. if (SemanticPred.isIntegralDxBoundarySingle(firstNode)) {
  1801. firstNode.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
  1802. return { integrand: args, intvar: firstNode, rest: nodes.slice(1) };
  1803. }
  1804. if (nodes[1] && SemanticPred.isIntegralDxBoundary(firstNode, nodes[1])) {
  1805. const intvar = SemanticProcessor.getInstance().prefixNode_(nodes[1], [firstNode]);
  1806. intvar.role = semantic_meaning_js_1.SemanticRole.INTEGRAL;
  1807. return { integrand: args, intvar: intvar, rest: nodes.slice(2) };
  1808. }
  1809. args.push(nodes.shift());
  1810. return SemanticProcessor.getInstance().getIntegralArgs_(nodes, args);
  1811. }
  1812. functionNode_(func, arg) {
  1813. const applNode = SemanticProcessor.getInstance().factory_.makeContentNode(semantic_attr_js_1.NamedSymbol.functionApplication);
  1814. const appl = SemanticProcessor.getInstance().funcAppls[func.id];
  1815. if (appl) {
  1816. applNode.mathmlTree = appl.mathmlTree;
  1817. applNode.mathml = appl.mathml;
  1818. applNode.annotation = appl.annotation;
  1819. applNode.attributes = appl.attributes;
  1820. delete SemanticProcessor.getInstance().funcAppls[func.id];
  1821. }
  1822. applNode.type = semantic_meaning_js_1.SemanticType.PUNCTUATION;
  1823. applNode.role = semantic_meaning_js_1.SemanticRole.APPLICATION;
  1824. const funcop = SemanticProcessor.getFunctionOp_(func, function (node) {
  1825. return (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.FUNCTION) ||
  1826. (SemanticPred.isType(node, semantic_meaning_js_1.SemanticType.IDENTIFIER) &&
  1827. SemanticPred.isRole(node, semantic_meaning_js_1.SemanticRole.SIMPLEFUNC)));
  1828. });
  1829. return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.APPL, [func, arg], funcop, [applNode]);
  1830. }
  1831. bigOpNode_(bigOp, arg) {
  1832. const largeop = SemanticProcessor.getFunctionOp_(bigOp, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.LARGEOP));
  1833. return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.BIGOP, [bigOp, arg], largeop, []);
  1834. }
  1835. integralNode_(integral, integrand, intvar) {
  1836. integrand =
  1837. integrand || SemanticProcessor.getInstance().factory_.makeEmptyNode();
  1838. intvar = intvar || SemanticProcessor.getInstance().factory_.makeEmptyNode();
  1839. const largeop = SemanticProcessor.getFunctionOp_(integral, (x) => SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.LARGEOP));
  1840. return SemanticProcessor.getInstance().functionalNode_(semantic_meaning_js_1.SemanticType.INTEGRAL, [integral, integrand, intvar], largeop, []);
  1841. }
  1842. functionalNode_(type, children, operator, content) {
  1843. const funcop = children[0];
  1844. let oldParent;
  1845. if (operator) {
  1846. oldParent = operator.parent;
  1847. content.push(operator);
  1848. }
  1849. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(type, children, content);
  1850. newNode.role = funcop.role;
  1851. if (oldParent) {
  1852. operator.parent = oldParent;
  1853. }
  1854. return newNode;
  1855. }
  1856. fractionNode_(denom, enume) {
  1857. const newNode = SemanticProcessor.getInstance().factory_.makeBranchNode(semantic_meaning_js_1.SemanticType.FRACTION, [denom, enume], []);
  1858. newNode.role = newNode.childNodes.every(function (x) {
  1859. return (SemanticPred.isType(x, semantic_meaning_js_1.SemanticType.NUMBER) &&
  1860. SemanticPred.isRole(x, semantic_meaning_js_1.SemanticRole.INTEGER));
  1861. })
  1862. ? semantic_meaning_js_1.SemanticRole.VULGAR
  1863. : newNode.childNodes.every(SemanticPred.isPureUnit)
  1864. ? semantic_meaning_js_1.SemanticRole.UNIT
  1865. : semantic_meaning_js_1.SemanticRole.DIVISION;
  1866. return semantic_heuristic_factory_js_1.SemanticHeuristics.run('propagateSimpleFunction', newNode);
  1867. }
  1868. scriptNode_(nodes, role, opt_noSingle) {
  1869. let newNode;
  1870. switch (nodes.length) {
  1871. case 0:
  1872. newNode = SemanticProcessor.getInstance().factory_.makeEmptyNode();
  1873. break;
  1874. case 1:
  1875. newNode = nodes[0];
  1876. if (opt_noSingle) {
  1877. return newNode;
  1878. }
  1879. break;
  1880. default:
  1881. newNode = SemanticProcessor.getInstance().dummyNode_(nodes);
  1882. }
  1883. newNode.role = role;
  1884. return newNode;
  1885. }
  1886. findNestedRow_(nodes, semantic, level, value) {
  1887. if (level > 3) {
  1888. return null;
  1889. }
  1890. for (let i = 0, node; (node = nodes[i]); i++) {
  1891. const tag = DomUtil.tagName(node);
  1892. if (tag !== semantic_util_js_1.MMLTAGS.MSPACE) {
  1893. if (tag === semantic_util_js_1.MMLTAGS.MROW) {
  1894. return SemanticProcessor.getInstance().findNestedRow_(DomUtil.toArray(node.childNodes), semantic, level + 1, value);
  1895. }
  1896. if (SemanticProcessor.findSemantics(node, semantic, value)) {
  1897. return node;
  1898. }
  1899. }
  1900. }
  1901. return null;
  1902. }
  1903. }
  1904. exports.SemanticProcessor = SemanticProcessor;
  1905. SemanticProcessor.FENCE_TO_PUNCT_ = {
  1906. [semantic_meaning_js_1.SemanticRole.METRIC]: semantic_meaning_js_1.SemanticRole.METRIC,
  1907. [semantic_meaning_js_1.SemanticRole.NEUTRAL]: semantic_meaning_js_1.SemanticRole.VBAR,
  1908. [semantic_meaning_js_1.SemanticRole.OPEN]: semantic_meaning_js_1.SemanticRole.OPENFENCE,
  1909. [semantic_meaning_js_1.SemanticRole.CLOSE]: semantic_meaning_js_1.SemanticRole.CLOSEFENCE
  1910. };
  1911. SemanticProcessor.MML_TO_LIMIT_ = {
  1912. [semantic_util_js_1.MMLTAGS.MSUB]: { type: semantic_meaning_js_1.SemanticType.LIMLOWER, length: 1 },
  1913. [semantic_util_js_1.MMLTAGS.MUNDER]: { type: semantic_meaning_js_1.SemanticType.LIMLOWER, length: 1 },
  1914. [semantic_util_js_1.MMLTAGS.MSUP]: { type: semantic_meaning_js_1.SemanticType.LIMUPPER, length: 1 },
  1915. [semantic_util_js_1.MMLTAGS.MOVER]: { type: semantic_meaning_js_1.SemanticType.LIMUPPER, length: 1 },
  1916. [semantic_util_js_1.MMLTAGS.MSUBSUP]: { type: semantic_meaning_js_1.SemanticType.LIMBOTH, length: 2 },
  1917. [semantic_util_js_1.MMLTAGS.MUNDEROVER]: { type: semantic_meaning_js_1.SemanticType.LIMBOTH, length: 2 }
  1918. };
  1919. SemanticProcessor.MML_TO_BOUNDS_ = {
  1920. [semantic_util_js_1.MMLTAGS.MSUB]: { type: semantic_meaning_js_1.SemanticType.SUBSCRIPT, length: 1, accent: false },
  1921. [semantic_util_js_1.MMLTAGS.MSUP]: {
  1922. type: semantic_meaning_js_1.SemanticType.SUPERSCRIPT,
  1923. length: 1,
  1924. accent: false
  1925. },
  1926. [semantic_util_js_1.MMLTAGS.MSUBSUP]: {
  1927. type: semantic_meaning_js_1.SemanticType.SUBSCRIPT,
  1928. length: 2,
  1929. accent: false
  1930. },
  1931. [semantic_util_js_1.MMLTAGS.MUNDER]: {
  1932. type: semantic_meaning_js_1.SemanticType.UNDERSCORE,
  1933. length: 1,
  1934. accent: true
  1935. },
  1936. [semantic_util_js_1.MMLTAGS.MOVER]: { type: semantic_meaning_js_1.SemanticType.OVERSCORE, length: 1, accent: true },
  1937. [semantic_util_js_1.MMLTAGS.MUNDEROVER]: {
  1938. type: semantic_meaning_js_1.SemanticType.UNDERSCORE,
  1939. length: 2,
  1940. accent: true
  1941. }
  1942. };
  1943. SemanticProcessor.CLASSIFY_FUNCTION_ = {
  1944. [semantic_meaning_js_1.SemanticRole.INTEGRAL]: 'integral',
  1945. [semantic_meaning_js_1.SemanticRole.SUM]: 'bigop',
  1946. [semantic_meaning_js_1.SemanticRole.PREFIXFUNC]: 'prefix',
  1947. [semantic_meaning_js_1.SemanticRole.LIMFUNC]: 'prefix',
  1948. [semantic_meaning_js_1.SemanticRole.SIMPLEFUNC]: 'prefix',
  1949. [semantic_meaning_js_1.SemanticRole.COMPFUNC]: 'prefix'
  1950. };
  1951. SemanticProcessor.MATHJAX_FONTS = {
  1952. '-tex-caligraphic': semantic_meaning_js_1.SemanticFont.CALIGRAPHIC,
  1953. '-tex-caligraphic-bold': semantic_meaning_js_1.SemanticFont.CALIGRAPHICBOLD,
  1954. '-tex-calligraphic': semantic_meaning_js_1.SemanticFont.CALIGRAPHIC,
  1955. '-tex-calligraphic-bold': semantic_meaning_js_1.SemanticFont.CALIGRAPHICBOLD,
  1956. '-tex-oldstyle': semantic_meaning_js_1.SemanticFont.OLDSTYLE,
  1957. '-tex-oldstyle-bold': semantic_meaning_js_1.SemanticFont.OLDSTYLEBOLD,
  1958. '-tex-mathit': semantic_meaning_js_1.SemanticFont.ITALIC
  1959. };