OutputJax.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. if (typeof b !== "function" && b !== null)
  11. throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  12. extendStatics(d, b);
  13. function __() { this.constructor = d; }
  14. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15. };
  16. })();
  17. var __assign = (this && this.__assign) || function () {
  18. __assign = Object.assign || function(t) {
  19. for (var s, i = 1, n = arguments.length; i < n; i++) {
  20. s = arguments[i];
  21. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  22. t[p] = s[p];
  23. }
  24. return t;
  25. };
  26. return __assign.apply(this, arguments);
  27. };
  28. var __read = (this && this.__read) || function (o, n) {
  29. var m = typeof Symbol === "function" && o[Symbol.iterator];
  30. if (!m) return o;
  31. var i = m.call(o), r, ar = [], e;
  32. try {
  33. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  34. }
  35. catch (error) { e = { error: error }; }
  36. finally {
  37. try {
  38. if (r && !r.done && (m = i["return"])) m.call(i);
  39. }
  40. finally { if (e) throw e.error; }
  41. }
  42. return ar;
  43. };
  44. var __values = (this && this.__values) || function(o) {
  45. var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
  46. if (m) return m.call(o);
  47. if (o && typeof o.length === "number") return {
  48. next: function () {
  49. if (o && i >= o.length) o = void 0;
  50. return { value: o && o[i++], done: !o };
  51. }
  52. };
  53. throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
  54. };
  55. Object.defineProperty(exports, "__esModule", { value: true });
  56. exports.CommonOutputJax = void 0;
  57. var OutputJax_js_1 = require("../../core/OutputJax.js");
  58. var MathItem_js_1 = require("../../core/MathItem.js");
  59. var Options_js_1 = require("../../util/Options.js");
  60. var lengths_js_1 = require("../../util/lengths.js");
  61. var Styles_js_1 = require("../../util/Styles.js");
  62. var StyleList_js_1 = require("../../util/StyleList.js");
  63. var CommonOutputJax = (function (_super) {
  64. __extends(CommonOutputJax, _super);
  65. function CommonOutputJax(options, defaultFactory, defaultFont) {
  66. if (options === void 0) { options = null; }
  67. if (defaultFactory === void 0) { defaultFactory = null; }
  68. if (defaultFont === void 0) { defaultFont = null; }
  69. var _this = this;
  70. var _a = __read((0, Options_js_1.separateOptions)(options, defaultFont.OPTIONS), 2), jaxOptions = _a[0], fontOptions = _a[1];
  71. _this = _super.call(this, jaxOptions) || this;
  72. _this.factory = _this.options.wrapperFactory ||
  73. new defaultFactory();
  74. _this.factory.jax = _this;
  75. _this.cssStyles = _this.options.cssStyles || new StyleList_js_1.CssStyles();
  76. _this.font = _this.options.font || new defaultFont(fontOptions);
  77. _this.unknownCache = new Map();
  78. return _this;
  79. }
  80. CommonOutputJax.prototype.typeset = function (math, html) {
  81. this.setDocument(html);
  82. var node = this.createNode();
  83. this.toDOM(math, node, html);
  84. return node;
  85. };
  86. CommonOutputJax.prototype.createNode = function () {
  87. var jax = this.constructor.NAME;
  88. return this.html('mjx-container', { 'class': 'MathJax', jax: jax });
  89. };
  90. CommonOutputJax.prototype.setScale = function (node) {
  91. var scale = this.math.metrics.scale * this.options.scale;
  92. if (scale !== 1) {
  93. this.adaptor.setStyle(node, 'fontSize', (0, lengths_js_1.percent)(scale));
  94. }
  95. };
  96. CommonOutputJax.prototype.toDOM = function (math, node, html) {
  97. if (html === void 0) { html = null; }
  98. this.setDocument(html);
  99. this.math = math;
  100. this.pxPerEm = math.metrics.ex / this.font.params.x_height;
  101. math.root.setTeXclass(null);
  102. this.setScale(node);
  103. this.nodeMap = new Map();
  104. this.container = node;
  105. this.processMath(math.root, node);
  106. this.nodeMap = null;
  107. this.executeFilters(this.postFilters, math, html, node);
  108. };
  109. CommonOutputJax.prototype.getBBox = function (math, html) {
  110. this.setDocument(html);
  111. this.math = math;
  112. math.root.setTeXclass(null);
  113. this.nodeMap = new Map();
  114. var bbox = this.factory.wrap(math.root).getOuterBBox();
  115. this.nodeMap = null;
  116. return bbox;
  117. };
  118. CommonOutputJax.prototype.getMetrics = function (html) {
  119. var e_1, _a;
  120. this.setDocument(html);
  121. var adaptor = this.adaptor;
  122. var maps = this.getMetricMaps(html);
  123. try {
  124. for (var _b = __values(html.math), _c = _b.next(); !_c.done; _c = _b.next()) {
  125. var math = _c.value;
  126. var parent_1 = adaptor.parent(math.start.node);
  127. if (math.state() < MathItem_js_1.STATE.METRICS && parent_1) {
  128. var map = maps[math.display ? 1 : 0];
  129. var _d = map.get(parent_1), em = _d.em, ex = _d.ex, containerWidth = _d.containerWidth, lineWidth = _d.lineWidth, scale = _d.scale, family = _d.family;
  130. math.setMetrics(em, ex, containerWidth, lineWidth, scale);
  131. if (this.options.mtextInheritFont) {
  132. math.outputData.mtextFamily = family;
  133. }
  134. if (this.options.merrorInheritFont) {
  135. math.outputData.merrorFamily = family;
  136. }
  137. math.state(MathItem_js_1.STATE.METRICS);
  138. }
  139. }
  140. }
  141. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  142. finally {
  143. try {
  144. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  145. }
  146. finally { if (e_1) throw e_1.error; }
  147. }
  148. };
  149. CommonOutputJax.prototype.getMetricsFor = function (node, display) {
  150. var getFamily = (this.options.mtextInheritFont || this.options.merrorInheritFont);
  151. var test = this.getTestElement(node, display);
  152. var metrics = this.measureMetrics(test, getFamily);
  153. this.adaptor.remove(test);
  154. return metrics;
  155. };
  156. CommonOutputJax.prototype.getMetricMaps = function (html) {
  157. var e_2, _a, e_3, _b, e_4, _c, e_5, _d, e_6, _e;
  158. var adaptor = this.adaptor;
  159. var domMaps = [new Map(), new Map()];
  160. try {
  161. for (var _f = __values(html.math), _g = _f.next(); !_g.done; _g = _f.next()) {
  162. var math = _g.value;
  163. var node = adaptor.parent(math.start.node);
  164. if (node && math.state() < MathItem_js_1.STATE.METRICS) {
  165. var map = domMaps[math.display ? 1 : 0];
  166. if (!map.has(node)) {
  167. map.set(node, this.getTestElement(node, math.display));
  168. }
  169. }
  170. }
  171. }
  172. catch (e_2_1) { e_2 = { error: e_2_1 }; }
  173. finally {
  174. try {
  175. if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
  176. }
  177. finally { if (e_2) throw e_2.error; }
  178. }
  179. var getFamily = this.options.mtextInheritFont || this.options.merrorInheritFont;
  180. var maps = [new Map(), new Map()];
  181. try {
  182. for (var _h = __values(maps.keys()), _j = _h.next(); !_j.done; _j = _h.next()) {
  183. var i = _j.value;
  184. try {
  185. for (var _k = (e_4 = void 0, __values(domMaps[i].keys())), _l = _k.next(); !_l.done; _l = _k.next()) {
  186. var node = _l.value;
  187. maps[i].set(node, this.measureMetrics(domMaps[i].get(node), getFamily));
  188. }
  189. }
  190. catch (e_4_1) { e_4 = { error: e_4_1 }; }
  191. finally {
  192. try {
  193. if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
  194. }
  195. finally { if (e_4) throw e_4.error; }
  196. }
  197. }
  198. }
  199. catch (e_3_1) { e_3 = { error: e_3_1 }; }
  200. finally {
  201. try {
  202. if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
  203. }
  204. finally { if (e_3) throw e_3.error; }
  205. }
  206. try {
  207. for (var _m = __values(maps.keys()), _o = _m.next(); !_o.done; _o = _m.next()) {
  208. var i = _o.value;
  209. try {
  210. for (var _p = (e_6 = void 0, __values(domMaps[i].values())), _q = _p.next(); !_q.done; _q = _p.next()) {
  211. var node = _q.value;
  212. adaptor.remove(node);
  213. }
  214. }
  215. catch (e_6_1) { e_6 = { error: e_6_1 }; }
  216. finally {
  217. try {
  218. if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
  219. }
  220. finally { if (e_6) throw e_6.error; }
  221. }
  222. }
  223. }
  224. catch (e_5_1) { e_5 = { error: e_5_1 }; }
  225. finally {
  226. try {
  227. if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
  228. }
  229. finally { if (e_5) throw e_5.error; }
  230. }
  231. return maps;
  232. };
  233. CommonOutputJax.prototype.getTestElement = function (node, display) {
  234. var adaptor = this.adaptor;
  235. if (!this.testInline) {
  236. this.testInline = this.html('mjx-test', { style: {
  237. display: 'inline-block',
  238. width: '100%',
  239. 'font-style': 'normal',
  240. 'font-weight': 'normal',
  241. 'font-size': '100%',
  242. 'font-size-adjust': 'none',
  243. 'text-indent': 0,
  244. 'text-transform': 'none',
  245. 'letter-spacing': 'normal',
  246. 'word-spacing': 'normal',
  247. overflow: 'hidden',
  248. height: '1px',
  249. 'margin-right': '-1px'
  250. } }, [
  251. this.html('mjx-left-box', { style: {
  252. display: 'inline-block',
  253. width: 0,
  254. 'float': 'left'
  255. } }),
  256. this.html('mjx-ex-box', { style: {
  257. position: 'absolute',
  258. overflow: 'hidden',
  259. width: '1px', height: '60ex'
  260. } }),
  261. this.html('mjx-right-box', { style: {
  262. display: 'inline-block',
  263. width: 0,
  264. 'float': 'right'
  265. } })
  266. ]);
  267. this.testDisplay = adaptor.clone(this.testInline);
  268. adaptor.setStyle(this.testDisplay, 'display', 'table');
  269. adaptor.setStyle(this.testDisplay, 'margin-right', '');
  270. adaptor.setStyle(adaptor.firstChild(this.testDisplay), 'display', 'none');
  271. var right = adaptor.lastChild(this.testDisplay);
  272. adaptor.setStyle(right, 'display', 'table-cell');
  273. adaptor.setStyle(right, 'width', '10000em');
  274. adaptor.setStyle(right, 'float', '');
  275. }
  276. return adaptor.append(node, adaptor.clone(display ? this.testDisplay : this.testInline));
  277. };
  278. CommonOutputJax.prototype.measureMetrics = function (node, getFamily) {
  279. var adaptor = this.adaptor;
  280. var family = (getFamily ? adaptor.fontFamily(node) : '');
  281. var em = adaptor.fontSize(node);
  282. var _a = __read(adaptor.nodeSize(adaptor.childNode(node, 1)), 2), w = _a[0], h = _a[1];
  283. var ex = (w ? h / 60 : em * this.options.exFactor);
  284. var containerWidth = (!w ? 1000000 : adaptor.getStyle(node, 'display') === 'table' ?
  285. adaptor.nodeSize(adaptor.lastChild(node))[0] - 1 :
  286. adaptor.nodeBBox(adaptor.lastChild(node)).left -
  287. adaptor.nodeBBox(adaptor.firstChild(node)).left - 2);
  288. var scale = Math.max(this.options.minScale, this.options.matchFontHeight ? ex / this.font.params.x_height / em : 1);
  289. var lineWidth = 1000000;
  290. return { em: em, ex: ex, containerWidth: containerWidth, lineWidth: lineWidth, scale: scale, family: family };
  291. };
  292. CommonOutputJax.prototype.styleSheet = function (html) {
  293. var e_7, _a;
  294. this.setDocument(html);
  295. this.cssStyles.clear();
  296. this.cssStyles.addStyles(this.constructor.commonStyles);
  297. if ('getStyles' in html) {
  298. try {
  299. for (var _b = __values(html.getStyles()), _c = _b.next(); !_c.done; _c = _b.next()) {
  300. var styles = _c.value;
  301. this.cssStyles.addStyles(styles);
  302. }
  303. }
  304. catch (e_7_1) { e_7 = { error: e_7_1 }; }
  305. finally {
  306. try {
  307. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  308. }
  309. finally { if (e_7) throw e_7.error; }
  310. }
  311. }
  312. this.addWrapperStyles(this.cssStyles);
  313. this.addFontStyles(this.cssStyles);
  314. var sheet = this.html('style', { id: 'MJX-styles' }, [this.text('\n' + this.cssStyles.cssText + '\n')]);
  315. return sheet;
  316. };
  317. CommonOutputJax.prototype.addFontStyles = function (styles) {
  318. styles.addStyles(this.font.styles);
  319. };
  320. CommonOutputJax.prototype.addWrapperStyles = function (styles) {
  321. var e_8, _a;
  322. try {
  323. for (var _b = __values(this.factory.getKinds()), _c = _b.next(); !_c.done; _c = _b.next()) {
  324. var kind = _c.value;
  325. this.addClassStyles(this.factory.getNodeClass(kind), styles);
  326. }
  327. }
  328. catch (e_8_1) { e_8 = { error: e_8_1 }; }
  329. finally {
  330. try {
  331. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  332. }
  333. finally { if (e_8) throw e_8.error; }
  334. }
  335. };
  336. CommonOutputJax.prototype.addClassStyles = function (CLASS, styles) {
  337. styles.addStyles(CLASS.styles);
  338. };
  339. CommonOutputJax.prototype.setDocument = function (html) {
  340. if (html) {
  341. this.document = html;
  342. this.adaptor.document = html.document;
  343. }
  344. };
  345. CommonOutputJax.prototype.html = function (type, def, content, ns) {
  346. if (def === void 0) { def = {}; }
  347. if (content === void 0) { content = []; }
  348. return this.adaptor.node(type, def, content, ns);
  349. };
  350. CommonOutputJax.prototype.text = function (text) {
  351. return this.adaptor.text(text);
  352. };
  353. CommonOutputJax.prototype.fixed = function (m, n) {
  354. if (n === void 0) { n = 3; }
  355. if (Math.abs(m) < .0006) {
  356. return '0';
  357. }
  358. return m.toFixed(n).replace(/\.?0+$/, '');
  359. };
  360. CommonOutputJax.prototype.measureText = function (text, variant, font) {
  361. if (font === void 0) { font = ['', false, false]; }
  362. var node = this.unknownText(text, variant);
  363. if (variant === '-explicitFont') {
  364. var styles = this.cssFontStyles(font);
  365. this.adaptor.setAttributes(node, { style: styles });
  366. }
  367. return this.measureTextNodeWithCache(node, text, variant, font);
  368. };
  369. CommonOutputJax.prototype.measureTextNodeWithCache = function (text, chars, variant, font) {
  370. if (font === void 0) { font = ['', false, false]; }
  371. if (variant === '-explicitFont') {
  372. variant = [font[0], font[1] ? 'T' : 'F', font[2] ? 'T' : 'F', ''].join('-');
  373. }
  374. if (!this.unknownCache.has(variant)) {
  375. this.unknownCache.set(variant, new Map());
  376. }
  377. var map = this.unknownCache.get(variant);
  378. var cached = map.get(chars);
  379. if (cached)
  380. return cached;
  381. var bbox = this.measureTextNode(text);
  382. map.set(chars, bbox);
  383. return bbox;
  384. };
  385. CommonOutputJax.prototype.measureXMLnode = function (xml) {
  386. var adaptor = this.adaptor;
  387. var content = this.html('mjx-xml-block', { style: { display: 'inline-block' } }, [adaptor.clone(xml)]);
  388. var base = this.html('mjx-baseline', { style: { display: 'inline-block', width: 0, height: 0 } });
  389. var style = {
  390. position: 'absolute',
  391. display: 'inline-block',
  392. 'font-family': 'initial',
  393. 'line-height': 'normal'
  394. };
  395. var node = this.html('mjx-measure-xml', { style: style }, [base, content]);
  396. adaptor.append(adaptor.parent(this.math.start.node), this.container);
  397. adaptor.append(this.container, node);
  398. var em = this.math.metrics.em * this.math.metrics.scale;
  399. var _a = adaptor.nodeBBox(content), left = _a.left, right = _a.right, bottom = _a.bottom, top = _a.top;
  400. var w = (right - left) / em;
  401. var h = (adaptor.nodeBBox(base).top - top) / em;
  402. var d = (bottom - top) / em - h;
  403. adaptor.remove(this.container);
  404. adaptor.remove(node);
  405. return { w: w, h: h, d: d };
  406. };
  407. CommonOutputJax.prototype.cssFontStyles = function (font, styles) {
  408. if (styles === void 0) { styles = {}; }
  409. var _a = __read(font, 3), family = _a[0], italic = _a[1], bold = _a[2];
  410. styles['font-family'] = this.font.getFamily(family);
  411. if (italic)
  412. styles['font-style'] = 'italic';
  413. if (bold)
  414. styles['font-weight'] = 'bold';
  415. return styles;
  416. };
  417. CommonOutputJax.prototype.getFontData = function (styles) {
  418. if (!styles) {
  419. styles = new Styles_js_1.Styles();
  420. }
  421. return [this.font.getFamily(styles.get('font-family')),
  422. styles.get('font-style') === 'italic',
  423. styles.get('font-weight') === 'bold'];
  424. };
  425. CommonOutputJax.NAME = 'Common';
  426. CommonOutputJax.OPTIONS = __assign(__assign({}, OutputJax_js_1.AbstractOutputJax.OPTIONS), { scale: 1, minScale: .5, mtextInheritFont: false, merrorInheritFont: false, mtextFont: '', merrorFont: 'serif', mathmlSpacing: false, skipAttributes: {}, exFactor: .5, displayAlign: 'center', displayIndent: '0', wrapperFactory: null, font: null, cssStyles: null });
  427. CommonOutputJax.commonStyles = {};
  428. return CommonOutputJax;
  429. }(OutputJax_js_1.AbstractOutputJax));
  430. exports.CommonOutputJax = CommonOutputJax;
  431. //# sourceMappingURL=OutputJax.js.map