collapse.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. "use strict";
  2. var __values = (this && this.__values) || function(o) {
  3. var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
  4. if (m) return m.call(o);
  5. if (o && typeof o.length === "number") return {
  6. next: function () {
  7. if (o && i >= o.length) o = void 0;
  8. return { value: o && o[i++], done: !o };
  9. }
  10. };
  11. throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. exports.Collapse = void 0;
  15. var Collapse = (function () {
  16. function Collapse(visitor) {
  17. var _this = this;
  18. this.cutoff = {
  19. identifier: 3,
  20. number: 3,
  21. text: 10,
  22. infixop: 15,
  23. relseq: 15,
  24. multirel: 15,
  25. fenced: 18,
  26. bigop: 20,
  27. integral: 20,
  28. fraction: 12,
  29. sqrt: 9,
  30. root: 12,
  31. vector: 15,
  32. matrix: 15,
  33. cases: 15,
  34. superscript: 9,
  35. subscript: 9,
  36. subsup: 9,
  37. punctuated: {
  38. endpunct: Collapse.NOCOLLAPSE,
  39. startpunct: Collapse.NOCOLLAPSE,
  40. value: 12
  41. }
  42. };
  43. this.marker = {
  44. identifier: 'x',
  45. number: '#',
  46. text: '...',
  47. appl: {
  48. 'limit function': 'lim',
  49. value: 'f()'
  50. },
  51. fraction: '/',
  52. sqrt: '\u221A',
  53. root: '\u221A',
  54. superscript: '\u25FD\u02D9',
  55. subscript: '\u25FD.',
  56. subsup: '\u25FD:',
  57. vector: {
  58. binomial: '(:)',
  59. determinant: '|:|',
  60. value: '\u27E8:\u27E9'
  61. },
  62. matrix: {
  63. squarematrix: '[::]',
  64. rowvector: '\u27E8\u22EF\u27E9',
  65. columnvector: '\u27E8\u22EE\u27E9',
  66. determinant: '|::|',
  67. value: '(::)'
  68. },
  69. cases: '{:',
  70. infixop: {
  71. addition: '+',
  72. subtraction: '\u2212',
  73. multiplication: '\u22C5',
  74. implicit: '\u22C5',
  75. value: '+'
  76. },
  77. punctuated: {
  78. text: '...',
  79. value: ','
  80. }
  81. };
  82. this.collapse = new Map([
  83. ['fenced', function (node, complexity) {
  84. complexity = _this.uncollapseChild(complexity, node, 1);
  85. if (complexity > _this.cutoff.fenced && node.attributes.get('data-semantic-role') === 'leftright') {
  86. complexity = _this.recordCollapse(node, complexity, _this.getText(node.childNodes[0]) +
  87. _this.getText(node.childNodes[node.childNodes.length - 1]));
  88. }
  89. return complexity;
  90. }],
  91. ['appl', function (node, complexity) {
  92. if (_this.canUncollapse(node, 2, 2)) {
  93. complexity = _this.complexity.visitNode(node, false);
  94. var marker = _this.marker.appl;
  95. var text = marker[node.attributes.get('data-semantic-role')] || marker.value;
  96. complexity = _this.recordCollapse(node, complexity, text);
  97. }
  98. return complexity;
  99. }],
  100. ['sqrt', function (node, complexity) {
  101. complexity = _this.uncollapseChild(complexity, node, 0);
  102. if (complexity > _this.cutoff.sqrt) {
  103. complexity = _this.recordCollapse(node, complexity, _this.marker.sqrt);
  104. }
  105. return complexity;
  106. }],
  107. ['root', function (node, complexity) {
  108. complexity = _this.uncollapseChild(complexity, node, 0, 2);
  109. if (complexity > _this.cutoff.sqrt) {
  110. complexity = _this.recordCollapse(node, complexity, _this.marker.sqrt);
  111. }
  112. return complexity;
  113. }],
  114. ['enclose', function (node, complexity) {
  115. if (_this.splitAttribute(node, 'children').length === 1) {
  116. var child = _this.canUncollapse(node, 1);
  117. if (child) {
  118. var marker = child.getProperty('collapse-marker');
  119. _this.unrecordCollapse(child);
  120. complexity = _this.recordCollapse(node, _this.complexity.visitNode(node, false), marker);
  121. }
  122. }
  123. return complexity;
  124. }],
  125. ['bigop', function (node, complexity) {
  126. if (complexity > _this.cutoff.bigop || !node.isKind('mo')) {
  127. var id = _this.splitAttribute(node, 'content').pop();
  128. var op = _this.findChildText(node, id);
  129. complexity = _this.recordCollapse(node, complexity, op);
  130. }
  131. return complexity;
  132. }],
  133. ['integral', function (node, complexity) {
  134. if (complexity > _this.cutoff.integral || !node.isKind('mo')) {
  135. var id = _this.splitAttribute(node, 'content').pop();
  136. var op = _this.findChildText(node, id);
  137. complexity = _this.recordCollapse(node, complexity, op);
  138. }
  139. return complexity;
  140. }],
  141. ['relseq', function (node, complexity) {
  142. if (complexity > _this.cutoff.relseq) {
  143. var id = _this.splitAttribute(node, 'content')[0];
  144. var text = _this.findChildText(node, id);
  145. complexity = _this.recordCollapse(node, complexity, text);
  146. }
  147. return complexity;
  148. }],
  149. ['multirel', function (node, complexity) {
  150. if (complexity > _this.cutoff.relseq) {
  151. var id = _this.splitAttribute(node, 'content')[0];
  152. var text = _this.findChildText(node, id) + '\u22EF';
  153. complexity = _this.recordCollapse(node, complexity, text);
  154. }
  155. return complexity;
  156. }],
  157. ['superscript', function (node, complexity) {
  158. complexity = _this.uncollapseChild(complexity, node, 0, 2);
  159. if (complexity > _this.cutoff.superscript) {
  160. complexity = _this.recordCollapse(node, complexity, _this.marker.superscript);
  161. }
  162. return complexity;
  163. }],
  164. ['subscript', function (node, complexity) {
  165. complexity = _this.uncollapseChild(complexity, node, 0, 2);
  166. if (complexity > _this.cutoff.subscript) {
  167. complexity = _this.recordCollapse(node, complexity, _this.marker.subscript);
  168. }
  169. return complexity;
  170. }],
  171. ['subsup', function (node, complexity) {
  172. complexity = _this.uncollapseChild(complexity, node, 0, 3);
  173. if (complexity > _this.cutoff.subsup) {
  174. complexity = _this.recordCollapse(node, complexity, _this.marker.subsup);
  175. }
  176. return complexity;
  177. }]
  178. ]);
  179. this.idCount = 0;
  180. this.complexity = visitor;
  181. }
  182. Collapse.prototype.check = function (node, complexity) {
  183. var type = node.attributes.get('data-semantic-type');
  184. if (this.collapse.has(type)) {
  185. return this.collapse.get(type).call(this, node, complexity);
  186. }
  187. if (this.cutoff.hasOwnProperty(type)) {
  188. return this.defaultCheck(node, complexity, type);
  189. }
  190. return complexity;
  191. };
  192. Collapse.prototype.defaultCheck = function (node, complexity, type) {
  193. var role = node.attributes.get('data-semantic-role');
  194. var check = this.cutoff[type];
  195. var cutoff = (typeof check === 'number' ? check : check[role] || check.value);
  196. if (complexity > cutoff) {
  197. var marker = this.marker[type] || '??';
  198. var text = (typeof marker === 'string' ? marker : marker[role] || marker.value);
  199. complexity = this.recordCollapse(node, complexity, text);
  200. }
  201. return complexity;
  202. };
  203. Collapse.prototype.recordCollapse = function (node, complexity, text) {
  204. text = '\u25C2' + text + '\u25B8';
  205. node.setProperty('collapse-marker', text);
  206. node.setProperty('collapse-complexity', complexity);
  207. return text.length * this.complexity.complexity.text;
  208. };
  209. Collapse.prototype.unrecordCollapse = function (node) {
  210. var complexity = node.getProperty('collapse-complexity');
  211. if (complexity != null) {
  212. node.attributes.set('data-semantic-complexity', complexity);
  213. node.removeProperty('collapse-complexity');
  214. node.removeProperty('collapse-marker');
  215. }
  216. };
  217. Collapse.prototype.canUncollapse = function (node, n, m) {
  218. if (m === void 0) { m = 1; }
  219. if (this.splitAttribute(node, 'children').length === m) {
  220. var mml = (node.childNodes.length === 1 &&
  221. node.childNodes[0].isInferred ? node.childNodes[0] : node);
  222. if (mml && mml.childNodes[n]) {
  223. var child = mml.childNodes[n];
  224. if (child.getProperty('collapse-marker')) {
  225. return child;
  226. }
  227. }
  228. }
  229. return null;
  230. };
  231. Collapse.prototype.uncollapseChild = function (complexity, node, n, m) {
  232. if (m === void 0) { m = 1; }
  233. var child = this.canUncollapse(node, n, m);
  234. if (child) {
  235. this.unrecordCollapse(child);
  236. if (child.parent !== node) {
  237. child.parent.attributes.set('data-semantic-complexity', undefined);
  238. }
  239. complexity = this.complexity.visitNode(node, false);
  240. }
  241. return complexity;
  242. };
  243. Collapse.prototype.splitAttribute = function (node, id) {
  244. return (node.attributes.get('data-semantic-' + id) || '').split(/,/);
  245. };
  246. Collapse.prototype.getText = function (node) {
  247. var _this = this;
  248. if (node.isToken)
  249. return node.getText();
  250. return node.childNodes.map(function (n) { return _this.getText(n); }).join('');
  251. };
  252. Collapse.prototype.findChildText = function (node, id) {
  253. var child = this.findChild(node, id);
  254. return this.getText(child.coreMO() || child);
  255. };
  256. Collapse.prototype.findChild = function (node, id) {
  257. var e_1, _a;
  258. if (!node || node.attributes.get('data-semantic-id') === id)
  259. return node;
  260. if (!node.isToken) {
  261. try {
  262. for (var _b = __values(node.childNodes), _c = _b.next(); !_c.done; _c = _b.next()) {
  263. var mml = _c.value;
  264. var child = this.findChild(mml, id);
  265. if (child)
  266. return child;
  267. }
  268. }
  269. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  270. finally {
  271. try {
  272. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  273. }
  274. finally { if (e_1) throw e_1.error; }
  275. }
  276. }
  277. return null;
  278. };
  279. Collapse.prototype.makeCollapse = function (node) {
  280. var nodes = [];
  281. node.walkTree(function (child) {
  282. if (child.getProperty('collapse-marker')) {
  283. nodes.push(child);
  284. }
  285. });
  286. this.makeActions(nodes);
  287. };
  288. Collapse.prototype.makeActions = function (nodes) {
  289. var e_2, _a;
  290. try {
  291. for (var nodes_1 = __values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) {
  292. var node = nodes_1_1.value;
  293. this.makeAction(node);
  294. }
  295. }
  296. catch (e_2_1) { e_2 = { error: e_2_1 }; }
  297. finally {
  298. try {
  299. if (nodes_1_1 && !nodes_1_1.done && (_a = nodes_1.return)) _a.call(nodes_1);
  300. }
  301. finally { if (e_2) throw e_2.error; }
  302. }
  303. };
  304. Collapse.prototype.makeId = function () {
  305. return 'mjx-collapse-' + this.idCount++;
  306. };
  307. Collapse.prototype.makeAction = function (node) {
  308. if (node.isKind('math')) {
  309. node = this.addMrow(node);
  310. }
  311. var factory = this.complexity.factory;
  312. var marker = node.getProperty('collapse-marker');
  313. var parent = node.parent;
  314. var maction = factory.create('maction', {
  315. actiontype: 'toggle',
  316. selection: 2,
  317. 'data-collapsible': true,
  318. id: this.makeId(),
  319. 'data-semantic-complexity': node.attributes.get('data-semantic-complexity')
  320. }, [
  321. factory.create('mtext', { mathcolor: 'blue' }, [
  322. factory.create('text').setText(marker)
  323. ])
  324. ]);
  325. maction.inheritAttributesFrom(node);
  326. node.attributes.set('data-semantic-complexity', node.getProperty('collapse-complexity'));
  327. node.removeProperty('collapse-marker');
  328. node.removeProperty('collapse-complexity');
  329. parent.replaceChild(maction, node);
  330. maction.appendChild(node);
  331. };
  332. Collapse.prototype.addMrow = function (node) {
  333. var e_3, _a;
  334. var mrow = this.complexity.factory.create('mrow', null, node.childNodes[0].childNodes);
  335. node.childNodes[0].setChildren([mrow]);
  336. var attributes = node.attributes.getAllAttributes();
  337. try {
  338. for (var _b = __values(Object.keys(attributes)), _c = _b.next(); !_c.done; _c = _b.next()) {
  339. var name_1 = _c.value;
  340. if (name_1.substr(0, 14) === 'data-semantic-') {
  341. mrow.attributes.set(name_1, attributes[name_1]);
  342. delete attributes[name_1];
  343. }
  344. }
  345. }
  346. catch (e_3_1) { e_3 = { error: e_3_1 }; }
  347. finally {
  348. try {
  349. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  350. }
  351. finally { if (e_3) throw e_3.error; }
  352. }
  353. mrow.setProperty('collapse-marker', node.getProperty('collapse-marker'));
  354. mrow.setProperty('collapse-complexity', node.getProperty('collapse-complexity'));
  355. node.removeProperty('collapse-marker');
  356. node.removeProperty('collapse-complexity');
  357. return mrow;
  358. };
  359. Collapse.NOCOLLAPSE = 10000000;
  360. return Collapse;
  361. }());
  362. exports.Collapse = Collapse;
  363. //# sourceMappingURL=collapse.js.map