temml 0.10.34 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/temml.mjs CHANGED
@@ -2008,7 +2008,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
2008
2008
  }
2009
2009
  block.push(node);
2010
2010
  if (node.type && node.type === "mo" && node.children.length === 1 &&
2011
- !Object.hasOwn(node.attributes, "movablelimits")) {
2011
+ !Object.prototype.hasOwnProperty.call(node.attributes, "movablelimits")) {
2012
2012
  const ch = node.children[0].text;
2013
2013
  if (openDelims.indexOf(ch) > -1) {
2014
2014
  level += 1;
@@ -13675,7 +13675,7 @@ class Style {
13675
13675
  * https://mit-license.org/
13676
13676
  */
13677
13677
 
13678
- const version = "0.10.34";
13678
+ const version = "0.11.00";
13679
13679
 
13680
13680
  function postProcess(block) {
13681
13681
  const labelMap = {};
@@ -13740,6 +13740,267 @@ function postProcess(block) {
13740
13740
  });
13741
13741
  }
13742
13742
 
13743
+ const findEndOfMath = function(delimiter, text, startIndex) {
13744
+ // Adapted from
13745
+ // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
13746
+ let index = startIndex;
13747
+ let braceLevel = 0;
13748
+
13749
+ const delimLength = delimiter.length;
13750
+
13751
+ while (index < text.length) {
13752
+ const character = text[index];
13753
+
13754
+ if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
13755
+ return index;
13756
+ } else if (character === "\\") {
13757
+ index++;
13758
+ } else if (character === "{") {
13759
+ braceLevel++;
13760
+ } else if (character === "}") {
13761
+ braceLevel--;
13762
+ }
13763
+
13764
+ index++;
13765
+ }
13766
+
13767
+ return -1;
13768
+ };
13769
+
13770
+ const escapeRegex = function(string) {
13771
+ return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
13772
+ };
13773
+
13774
+ const amsRegex = /^\\(?:begin|(?:eq)?ref){/;
13775
+
13776
+ const splitAtDelimiters = function(text, delimiters) {
13777
+ let index;
13778
+ const data = [];
13779
+
13780
+ const regexLeft = new RegExp(
13781
+ "(" + delimiters.map((x) => escapeRegex(x.left)).join("|") + ")"
13782
+ );
13783
+
13784
+ while (true) {
13785
+ index = text.search(regexLeft);
13786
+ if (index === -1) {
13787
+ break;
13788
+ }
13789
+ if (index > 0) {
13790
+ data.push({
13791
+ type: "text",
13792
+ data: text.slice(0, index)
13793
+ });
13794
+ text = text.slice(index); // now text starts with delimiter
13795
+ }
13796
+ // ... so this always succeeds:
13797
+ const i = delimiters.findIndex((delim) => text.startsWith(delim.left));
13798
+ index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
13799
+ if (index === -1) {
13800
+ break;
13801
+ }
13802
+ const rawData = text.slice(0, index + delimiters[i].right.length);
13803
+ const math = amsRegex.test(rawData)
13804
+ ? rawData
13805
+ : text.slice(delimiters[i].left.length, index);
13806
+ data.push({
13807
+ type: "math",
13808
+ data: math,
13809
+ rawData,
13810
+ display: delimiters[i].display
13811
+ });
13812
+ text = text.slice(index + delimiters[i].right.length);
13813
+ }
13814
+
13815
+ if (text !== "") {
13816
+ data.push({
13817
+ type: "text",
13818
+ data: text
13819
+ });
13820
+ }
13821
+
13822
+ return data;
13823
+ };
13824
+
13825
+ const defaultDelimiters = [
13826
+ { left: "$$", right: "$$", display: true },
13827
+ { left: "\\(", right: "\\)", display: false },
13828
+ // LaTeX uses $…$, but it ruins the display of normal `$` in text:
13829
+ // {left: "$", right: "$", display: false},
13830
+ // $ must come after $$
13831
+
13832
+ // Render AMS environments even if outside $$…$$ delimiters.
13833
+ { left: "\\begin{equation}", right: "\\end{equation}", display: true },
13834
+ { left: "\\begin{equation*}", right: "\\end{equation*}", display: true },
13835
+ { left: "\\begin{align}", right: "\\end{align}", display: true },
13836
+ { left: "\\begin{align*}", right: "\\end{align*}", display: true },
13837
+ { left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
13838
+ { left: "\\begin{alignat*}", right: "\\end{alignat*}", display: true },
13839
+ { left: "\\begin{gather}", right: "\\end{gather}", display: true },
13840
+ { left: "\\begin{gather*}", right: "\\end{gather*}", display: true },
13841
+ { left: "\\begin{CD}", right: "\\end{CD}", display: true },
13842
+ // Ditto \ref & \eqref
13843
+ { left: "\\ref{", right: "}", display: false },
13844
+ { left: "\\eqref{", right: "}", display: false },
13845
+
13846
+ { left: "\\[", right: "\\]", display: true }
13847
+ ];
13848
+
13849
+ const firstDraftDelimiters = {
13850
+ "$": [
13851
+ { left: "$$", right: "$$", display: true },
13852
+ { left: "$`", right: "`$", display: false },
13853
+ { left: "$", right: "$", display: false }
13854
+ ],
13855
+ "(": [
13856
+ { left: "\\[", right: "\\]", display: true },
13857
+ { left: "\\(", right: "\\)", display: false }
13858
+ ]
13859
+ };
13860
+
13861
+ const amsDelimiters = [
13862
+ { left: "\\begin{equation}", right: "\\end{equation}", display: true },
13863
+ { left: "\\begin{equation*}", right: "\\end{equation*}", display: true },
13864
+ { left: "\\begin{align}", right: "\\end{align}", display: true },
13865
+ { left: "\\begin{align*}", right: "\\end{align*}", display: true },
13866
+ { left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
13867
+ { left: "\\begin{alignat*}", right: "\\end{alignat*}", display: true },
13868
+ { left: "\\begin{gather}", right: "\\end{gather}", display: true },
13869
+ { left: "\\begin{gather*}", right: "\\end{gather*}", display: true },
13870
+ { left: "\\begin{CD}", right: "\\end{CD}", display: true },
13871
+ { left: "\\ref{", right: "}", display: false },
13872
+ { left: "\\eqref{", right: "}", display: false }
13873
+ ];
13874
+
13875
+ const delimitersFromKey = key => {
13876
+ if (key === "$" || key === "(") {
13877
+ return firstDraftDelimiters[key];
13878
+ } else if (key === "$+" || key === "(+") {
13879
+ const firstDraft = firstDraftDelimiters[key.slice(0, 1)];
13880
+ return firstDraft.concat(amsDelimiters)
13881
+ } else if (key === "ams") {
13882
+ return amsDelimiters
13883
+ } else if (key === "all") {
13884
+ return (firstDraftDelimiters["("]).concat(firstDraftDelimiters["$"]).concat(amsDelimiters)
13885
+ } else {
13886
+ return defaultDelimiters
13887
+ }
13888
+ };
13889
+
13890
+ /* Note: optionsCopy is mutated by this method. If it is ever exposed in the
13891
+ * API, we should copy it before mutating.
13892
+ */
13893
+ const renderMathInText = function(text, optionsCopy) {
13894
+ const data = splitAtDelimiters(text, optionsCopy.delimiters);
13895
+ if (data.length === 1 && data[0].type === "text") {
13896
+ // There is no formula in the text.
13897
+ // Let's return null which means there is no need to replace
13898
+ // the current text node with a new one.
13899
+ return null;
13900
+ }
13901
+
13902
+ const fragment = document.createDocumentFragment();
13903
+
13904
+ for (let i = 0; i < data.length; i++) {
13905
+ if (data[i].type === "text") {
13906
+ fragment.appendChild(document.createTextNode(data[i].data));
13907
+ } else {
13908
+ const span = document.createElement("span");
13909
+ let math = data[i].data;
13910
+ // Override any display mode defined in the settings with that
13911
+ // defined by the text itself
13912
+ optionsCopy.displayMode = data[i].display;
13913
+ try {
13914
+ if (optionsCopy.preProcess) {
13915
+ math = optionsCopy.preProcess(math);
13916
+ }
13917
+ // Importing render() from temml.js would be a circular dependency.
13918
+ // So call the global version.
13919
+ // eslint-disable-next-line no-undef
13920
+ temml.render(math, span, optionsCopy);
13921
+ } catch (e) {
13922
+ if (!(e instanceof ParseError)) {
13923
+ throw e;
13924
+ }
13925
+ optionsCopy.errorCallback(
13926
+ "Temml auto-render: Failed to parse `" + data[i].data + "` with ",
13927
+ e
13928
+ );
13929
+ fragment.appendChild(document.createTextNode(data[i].rawData));
13930
+ continue;
13931
+ }
13932
+ fragment.appendChild(span);
13933
+ }
13934
+ }
13935
+
13936
+ return fragment;
13937
+ };
13938
+
13939
+ const renderElem = function(elem, optionsCopy) {
13940
+ for (let i = 0; i < elem.childNodes.length; i++) {
13941
+ const childNode = elem.childNodes[i];
13942
+ if (childNode.nodeType === 3) {
13943
+ // Text node
13944
+ const frag = renderMathInText(childNode.textContent, optionsCopy);
13945
+ if (frag) {
13946
+ i += frag.childNodes.length - 1;
13947
+ elem.replaceChild(frag, childNode);
13948
+ }
13949
+ } else if (childNode.nodeType === 1) {
13950
+ // Element node
13951
+ const className = " " + childNode.className + " ";
13952
+ const shouldRender =
13953
+ optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 &&
13954
+ optionsCopy.ignoredClasses.every((x) => className.indexOf(" " + x + " ") === -1);
13955
+
13956
+ if (shouldRender) {
13957
+ renderElem(childNode, optionsCopy);
13958
+ }
13959
+ }
13960
+ // Otherwise, it's something else, and ignore it.
13961
+ }
13962
+ };
13963
+
13964
+ const renderMathInElement = function(elem, options) {
13965
+ if (!elem) {
13966
+ throw new Error("No element provided to render");
13967
+ }
13968
+
13969
+ const optionsCopy = {};
13970
+
13971
+ // Object.assign(optionsCopy, option)
13972
+ for (const option in options) {
13973
+ if (Object.prototype.hasOwnProperty.call(options, option)) {
13974
+ optionsCopy[option] = options[option];
13975
+ }
13976
+ }
13977
+
13978
+ if (optionsCopy.fences) {
13979
+ optionsCopy.delimiters = delimitersFromKey(optionsCopy.fences);
13980
+ } else {
13981
+ optionsCopy.delimiters = optionsCopy.delimiters || defaultDelimiters;
13982
+ }
13983
+ optionsCopy.ignoredTags = optionsCopy.ignoredTags || [
13984
+ "script",
13985
+ "noscript",
13986
+ "style",
13987
+ "textarea",
13988
+ "pre",
13989
+ "code",
13990
+ "option"
13991
+ ];
13992
+ optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
13993
+ // eslint-disable-next-line no-console
13994
+ optionsCopy.errorCallback = optionsCopy.errorCallback || console.error;
13995
+
13996
+ // Enable sharing of global macros defined via `\gdef` between different
13997
+ // math elements within a single call to `renderMathInElement`.
13998
+ optionsCopy.macros = optionsCopy.macros || {};
13999
+
14000
+ renderElem(elem, optionsCopy);
14001
+ postProcess(elem);
14002
+ };
14003
+
13743
14004
  /* eslint no-console:0 */
13744
14005
  /**
13745
14006
  * This is the main entry point for Temml. Here, we expose functions for
@@ -13859,7 +14120,7 @@ const renderToMathMLTree = function(expression, options) {
13859
14120
  };
13860
14121
 
13861
14122
  /** @type {import('./temml').default} */
13862
- var temml = {
14123
+ var temml$1 = {
13863
14124
  /**
13864
14125
  * Current Temml version
13865
14126
  */
@@ -13874,6 +14135,11 @@ var temml = {
13874
14135
  * for sending to the client.
13875
14136
  */
13876
14137
  renderToString,
14138
+ /**
14139
+ * Finds all the math delimiters in a given element of a running HTML document
14140
+ * and converts the contents of each instance into a <math> element.
14141
+ */
14142
+ renderMathInElement,
13877
14143
  /**
13878
14144
  * Post-process an entire HTML block.
13879
14145
  * Writes AMS auto-numbers and implements \ref{}.
@@ -13916,4 +14182,4 @@ var temml = {
13916
14182
  __defineMacro: defineMacro
13917
14183
  };
13918
14184
 
13919
- export { temml as default };
14185
+ export { temml$1 as default };
@@ -11,7 +11,7 @@
11
11
  * https://mit-license.org/
12
12
  */
13
13
 
14
- const version = "0.10.34";
14
+ const version = "0.11.00";
15
15
 
16
16
  function postProcess(block) {
17
17
  const labelMap = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temml",
3
- "version": "0.10.34",
3
+ "version": "0.11.00",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "engines": {
@@ -44,6 +44,6 @@
44
44
  "minify": "terser test/temml.js -o site/assets/temml.min.js -c -m && terser contrib/mhchem/mhchem.js -o site/assets/mhchem.min.js -c -m",
45
45
  "build": "rollup --config ./utils/rollupConfig.mjs && yarn minify && node utils/insertPlugins.js",
46
46
  "docs": "node utils/buildDocs.js",
47
- "dist": "yarn build && node ./utils/copyfiles.js && terser contrib/auto-render/test/auto-render.js -o contrib/auto-render/dist/auto-render.min.js -c -m"
47
+ "dist": "yarn build && node ./utils/copyfiles.js"
48
48
  }
49
49
  }
@@ -0,0 +1,263 @@
1
+ import ParseError from "./ParseError.js"
2
+ import { postProcess } from "./postProcess.js";
3
+
4
+ const findEndOfMath = function(delimiter, text, startIndex) {
5
+ // Adapted from
6
+ // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
7
+ let index = startIndex;
8
+ let braceLevel = 0;
9
+
10
+ const delimLength = delimiter.length;
11
+
12
+ while (index < text.length) {
13
+ const character = text[index];
14
+
15
+ if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
16
+ return index;
17
+ } else if (character === "\\") {
18
+ index++;
19
+ } else if (character === "{") {
20
+ braceLevel++;
21
+ } else if (character === "}") {
22
+ braceLevel--;
23
+ }
24
+
25
+ index++;
26
+ }
27
+
28
+ return -1;
29
+ };
30
+
31
+ const escapeRegex = function(string) {
32
+ return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
33
+ };
34
+
35
+ const amsRegex = /^\\(?:begin|(?:eq)?ref){/
36
+
37
+ const splitAtDelimiters = function(text, delimiters) {
38
+ let index;
39
+ const data = [];
40
+
41
+ const regexLeft = new RegExp(
42
+ "(" + delimiters.map((x) => escapeRegex(x.left)).join("|") + ")"
43
+ )
44
+
45
+ while (true) {
46
+ index = text.search(regexLeft);
47
+ if (index === -1) {
48
+ break;
49
+ }
50
+ if (index > 0) {
51
+ data.push({
52
+ type: "text",
53
+ data: text.slice(0, index)
54
+ });
55
+ text = text.slice(index); // now text starts with delimiter
56
+ }
57
+ // ... so this always succeeds:
58
+ const i = delimiters.findIndex((delim) => text.startsWith(delim.left));
59
+ index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
60
+ if (index === -1) {
61
+ break;
62
+ }
63
+ const rawData = text.slice(0, index + delimiters[i].right.length);
64
+ const math = amsRegex.test(rawData)
65
+ ? rawData
66
+ : text.slice(delimiters[i].left.length, index);
67
+ data.push({
68
+ type: "math",
69
+ data: math,
70
+ rawData,
71
+ display: delimiters[i].display
72
+ });
73
+ text = text.slice(index + delimiters[i].right.length);
74
+ }
75
+
76
+ if (text !== "") {
77
+ data.push({
78
+ type: "text",
79
+ data: text
80
+ });
81
+ }
82
+
83
+ return data;
84
+ };
85
+
86
+ const defaultDelimiters = [
87
+ { left: "$$", right: "$$", display: true },
88
+ { left: "\\(", right: "\\)", display: false },
89
+ // LaTeX uses $…$, but it ruins the display of normal `$` in text:
90
+ // {left: "$", right: "$", display: false},
91
+ // $ must come after $$
92
+
93
+ // Render AMS environments even if outside $$…$$ delimiters.
94
+ { left: "\\begin{equation}", right: "\\end{equation}", display: true },
95
+ { left: "\\begin{equation*}", right: "\\end{equation*}", display: true },
96
+ { left: "\\begin{align}", right: "\\end{align}", display: true },
97
+ { left: "\\begin{align*}", right: "\\end{align*}", display: true },
98
+ { left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
99
+ { left: "\\begin{alignat*}", right: "\\end{alignat*}", display: true },
100
+ { left: "\\begin{gather}", right: "\\end{gather}", display: true },
101
+ { left: "\\begin{gather*}", right: "\\end{gather*}", display: true },
102
+ { left: "\\begin{CD}", right: "\\end{CD}", display: true },
103
+ // Ditto \ref & \eqref
104
+ { left: "\\ref{", right: "}", display: false },
105
+ { left: "\\eqref{", right: "}", display: false },
106
+
107
+ { left: "\\[", right: "\\]", display: true }
108
+ ];
109
+
110
+ const firstDraftDelimiters = {
111
+ "$": [
112
+ { left: "$$", right: "$$", display: true },
113
+ { left: "$`", right: "`$", display: false },
114
+ { left: "$", right: "$", display: false }
115
+ ],
116
+ "(": [
117
+ { left: "\\[", right: "\\]", display: true },
118
+ { left: "\\(", right: "\\)", display: false }
119
+ ]
120
+ }
121
+
122
+ const amsDelimiters = [
123
+ { left: "\\begin{equation}", right: "\\end{equation}", display: true },
124
+ { left: "\\begin{equation*}", right: "\\end{equation*}", display: true },
125
+ { left: "\\begin{align}", right: "\\end{align}", display: true },
126
+ { left: "\\begin{align*}", right: "\\end{align*}", display: true },
127
+ { left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
128
+ { left: "\\begin{alignat*}", right: "\\end{alignat*}", display: true },
129
+ { left: "\\begin{gather}", right: "\\end{gather}", display: true },
130
+ { left: "\\begin{gather*}", right: "\\end{gather*}", display: true },
131
+ { left: "\\begin{CD}", right: "\\end{CD}", display: true },
132
+ { left: "\\ref{", right: "}", display: false },
133
+ { left: "\\eqref{", right: "}", display: false }
134
+ ];
135
+
136
+ const delimitersFromKey = key => {
137
+ if (key === "$" || key === "(") {
138
+ return firstDraftDelimiters[key];
139
+ } else if (key === "$+" || key === "(+") {
140
+ const firstDraft = firstDraftDelimiters[key.slice(0, 1)];
141
+ return firstDraft.concat(amsDelimiters)
142
+ } else if (key === "ams") {
143
+ return amsDelimiters
144
+ } else if (key === "all") {
145
+ return (firstDraftDelimiters["("]).concat(firstDraftDelimiters["$"]).concat(amsDelimiters)
146
+ } else {
147
+ return defaultDelimiters
148
+ }
149
+ }
150
+
151
+ /* Note: optionsCopy is mutated by this method. If it is ever exposed in the
152
+ * API, we should copy it before mutating.
153
+ */
154
+ const renderMathInText = function(text, optionsCopy) {
155
+ const data = splitAtDelimiters(text, optionsCopy.delimiters);
156
+ if (data.length === 1 && data[0].type === "text") {
157
+ // There is no formula in the text.
158
+ // Let's return null which means there is no need to replace
159
+ // the current text node with a new one.
160
+ return null;
161
+ }
162
+
163
+ const fragment = document.createDocumentFragment();
164
+
165
+ for (let i = 0; i < data.length; i++) {
166
+ if (data[i].type === "text") {
167
+ fragment.appendChild(document.createTextNode(data[i].data));
168
+ } else {
169
+ const span = document.createElement("span");
170
+ let math = data[i].data;
171
+ // Override any display mode defined in the settings with that
172
+ // defined by the text itself
173
+ optionsCopy.displayMode = data[i].display;
174
+ try {
175
+ if (optionsCopy.preProcess) {
176
+ math = optionsCopy.preProcess(math);
177
+ }
178
+ // Importing render() from temml.js would be a circular dependency.
179
+ // So call the global version.
180
+ // eslint-disable-next-line no-undef
181
+ temml.render(math, span, optionsCopy);
182
+ } catch (e) {
183
+ if (!(e instanceof ParseError)) {
184
+ throw e;
185
+ }
186
+ optionsCopy.errorCallback(
187
+ "Temml auto-render: Failed to parse `" + data[i].data + "` with ",
188
+ e
189
+ );
190
+ fragment.appendChild(document.createTextNode(data[i].rawData));
191
+ continue;
192
+ }
193
+ fragment.appendChild(span);
194
+ }
195
+ }
196
+
197
+ return fragment;
198
+ };
199
+
200
+ const renderElem = function(elem, optionsCopy) {
201
+ for (let i = 0; i < elem.childNodes.length; i++) {
202
+ const childNode = elem.childNodes[i];
203
+ if (childNode.nodeType === 3) {
204
+ // Text node
205
+ const frag = renderMathInText(childNode.textContent, optionsCopy);
206
+ if (frag) {
207
+ i += frag.childNodes.length - 1;
208
+ elem.replaceChild(frag, childNode);
209
+ }
210
+ } else if (childNode.nodeType === 1) {
211
+ // Element node
212
+ const className = " " + childNode.className + " ";
213
+ const shouldRender =
214
+ optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 &&
215
+ optionsCopy.ignoredClasses.every((x) => className.indexOf(" " + x + " ") === -1);
216
+
217
+ if (shouldRender) {
218
+ renderElem(childNode, optionsCopy);
219
+ }
220
+ }
221
+ // Otherwise, it's something else, and ignore it.
222
+ }
223
+ };
224
+
225
+ export const renderMathInElement = function(elem, options) {
226
+ if (!elem) {
227
+ throw new Error("No element provided to render");
228
+ }
229
+
230
+ const optionsCopy = {};
231
+
232
+ // Object.assign(optionsCopy, option)
233
+ for (const option in options) {
234
+ if (Object.prototype.hasOwnProperty.call(options, option)) {
235
+ optionsCopy[option] = options[option];
236
+ }
237
+ }
238
+
239
+ if (optionsCopy.fences) {
240
+ optionsCopy.delimiters = delimitersFromKey(optionsCopy.fences);
241
+ } else {
242
+ optionsCopy.delimiters = optionsCopy.delimiters || defaultDelimiters
243
+ }
244
+ optionsCopy.ignoredTags = optionsCopy.ignoredTags || [
245
+ "script",
246
+ "noscript",
247
+ "style",
248
+ "textarea",
249
+ "pre",
250
+ "code",
251
+ "option"
252
+ ];
253
+ optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
254
+ // eslint-disable-next-line no-console
255
+ optionsCopy.errorCallback = optionsCopy.errorCallback || console.error;
256
+
257
+ // Enable sharing of global macros defined via `\gdef` between different
258
+ // math elements within a single call to `renderMathInElement`.
259
+ optionsCopy.macros = optionsCopy.macros || {};
260
+
261
+ renderElem(elem, optionsCopy);
262
+ postProcess(elem);
263
+ };
@@ -58,7 +58,7 @@ export default function setLineBreaks(expression, wrapMode, isDisplayMode) {
58
58
  }
59
59
  block.push(node);
60
60
  if (node.type && node.type === "mo" && node.children.length === 1 &&
61
- !Object.hasOwn(node.attributes, "movablelimits")) {
61
+ !Object.prototype.hasOwnProperty.call(node.attributes, "movablelimits")) {
62
62
  const ch = node.children[0].text
63
63
  if (openDelims.indexOf(ch) > -1) {
64
64
  level += 1
@@ -5,7 +5,7 @@
5
5
  * https://mit-license.org/
6
6
  */
7
7
 
8
- export const version = "0.10.34";
8
+ export const version = "0.11.00";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}
package/temml.js CHANGED
@@ -19,6 +19,7 @@ import { Span, TextNode } from "./src/domTree";
19
19
  import { defineSymbol } from "./src/symbols";
20
20
  import defineMacro from "./src/defineMacro";
21
21
  import { postProcess, version } from "./src/postProcess";
22
+ import { renderMathInElement } from "./src/auto-render"
22
23
 
23
24
  /**
24
25
  * @type {import('./temml').render}
@@ -144,6 +145,11 @@ export default {
144
145
  * for sending to the client.
145
146
  */
146
147
  renderToString,
148
+ /**
149
+ * Finds all the math delimiters in a given element of a running HTML document
150
+ * and converts the contents of each instance into a <math> element.
151
+ */
152
+ renderMathInElement,
147
153
  /**
148
154
  * Post-process an entire HTML block.
149
155
  * Writes AMS auto-numbers and implements \ref{}.