math-core 0.7.0 → 0.8.1

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/README.md CHANGED
@@ -12,6 +12,7 @@ A Node.js library for converting LaTeX math expressions to MathML Core.
12
12
  - Support for both inline and display (block) math
13
13
  - Define custom LaTeX macros for extended functionality
14
14
  - Global and local counter for numbered equations
15
+ - Batch conversion which resolves forward references between snippets
15
16
  - Pretty-printing option for readable MathML output
16
17
  - Comprehensive error handling with descriptive error messages
17
18
 
@@ -120,6 +121,28 @@ const doc2 = converter.convert_with_local_state(
120
121
  ); // Also contains (1) and (2)
121
122
  ```
122
123
 
124
+ ### Converting a Whole Document at Once
125
+
126
+ `convert_all` converts a collection of snippets in one go, which is the only way to get
127
+ *forward references* right: a snippet may refer to an equation which is only defined in a later
128
+ snippet.
129
+
130
+ ```javascript
131
+ const converter = new LatexToMathML({});
132
+
133
+ const [reference, equation] = converter.convert_all([
134
+ { latex: "\\eqref{eq:euler}", displayStyle: false },
135
+ {
136
+ latex: "\\begin{align}e^{i\\pi} + 1 = 0\\label{eq:euler}\\end{align}",
137
+ displayStyle: true,
138
+ },
139
+ ]);
140
+ // `reference` refers to equation (1), even though it comes first.
141
+ ```
142
+
143
+ Equation numbering restarts with every call to `convert_all`; the state of
144
+ `convert_with_global_state` is neither used nor modified.
145
+
123
146
  ### Error Handling
124
147
 
125
148
  By default, conversion errors throw a `LatexError` with detailed diagnostics:
@@ -168,11 +191,15 @@ new LatexToMathML(options: MathCoreOptions)
168
191
  | `throwOnError` | `boolean` | `true` | Throw `LatexError` on conversion errors. If `false`, returns an HTML error snippet instead. |
169
192
  | `ignoreUnknownCommands` | `boolean` | `false` | Render unknown commands as red text instead of erroring. |
170
193
  | `annotation` | `boolean` | `false` | Include the original LaTeX as an annotation in the MathML output. |
194
+ | `globalGroup` | `boolean` | `false` | Run the conversion in the global group, so that commands defined with `\newcommand` stay defined for subsequent calls to `convert_with_global_state`. If `false`, such definitions are local to the snippet which contains them. |
195
+ | `maxExpansions` | `number` | `1000` | How many custom commands may be expanded in one snippet before the conversion gives up. The limit exists because a macro may expand to itself, directly or indirectly. |
196
+ | `idPrefix` | `string` | `""` | Added to the beginning of every `id` and anchor reference. Use this to avoid conflicts when embedding the output. |
171
197
 
172
198
  **Methods:**
173
199
 
174
200
  - `convert_with_global_state(latex: string, displaystyle: boolean): string` — Convert LaTeX to MathML using global state.
175
201
  - `convert_with_local_state(latex: string, displaystyle: boolean): string` — Convert LaTeX to MathML using local state.
202
+ - `convert_all(snippets: MathSnippet[]): string[]` — Convert all snippets of a document at once, resolving forward references between them. A `MathSnippet` is `{ latex: string, displayStyle: boolean }`. Uses a fresh state for the batch, independent of the global state.
176
203
  - `reset_global_state(): void` — Reset the global state (e.g., set the equation counter to zero).
177
204
 
178
205
  ### `LatexError`
@@ -188,6 +215,7 @@ Error thrown when LaTeX parsing or conversion fails.
188
215
  | `context` | `string \| undefined` | The relevant LaTeX source. |
189
216
  | `start` | `number` | Start offset of the error in the source. |
190
217
  | `end` | `number` | End offset of the error in the source. |
218
+ | `index` | `number \| undefined` | Index of the failing snippet; only set by `convert_all`. |
191
219
 
192
220
  ## Why MathML Core?
193
221
 
@@ -9,7 +9,15 @@ interface MathCoreOptions {
9
9
  ignoreUnknownCommands?: boolean;
10
10
  annotation?: boolean;
11
11
  allowUnreliableRendering?: boolean;
12
+ globalGroup?: boolean;
12
13
  unicodeSubstitution?: "never" | "conventional";
14
+ maxExpansions?: number;
15
+ idPrefix?: string;
16
+ }
17
+
18
+ interface MathSnippet {
19
+ latex: string;
20
+ displayStyle: boolean;
13
21
  }
14
22
 
15
23
 
@@ -26,6 +34,14 @@ export class LatexError {
26
34
  free(): void;
27
35
  [Symbol.dispose](): void;
28
36
  end: number;
37
+ /**
38
+ * The index of the snippet that caused the error; only set by `convert_all`.
39
+ */
40
+ get index(): number | undefined;
41
+ /**
42
+ * The index of the snippet that caused the error; only set by `convert_all`.
43
+ */
44
+ set index(value: number | null | undefined);
29
45
  start: number;
30
46
  readonly context: string | undefined;
31
47
  readonly label: string;
@@ -36,6 +52,16 @@ export class LatexError {
36
52
  export class LatexToMathML {
37
53
  free(): void;
38
54
  [Symbol.dispose](): void;
55
+ /**
56
+ * Convert a collection of LaTeX snippets to MathML.
57
+ *
58
+ * In contrast to the other conversion methods, this one resolves *forward references*
59
+ * correctly, meaning that a snippet can refer to an equation which is only defined in a
60
+ * later snippet. This is why all snippets of a document have to be passed in at once.
61
+ *
62
+ * The conversion does not touch the global state; it uses a fresh state for the whole batch.
63
+ */
64
+ convert_all(snippets: MathSnippet[]): string[];
39
65
  convert_with_global_state(content: string, displaystyle: boolean): string;
40
66
  convert_with_local_state(content: string, displaystyle: boolean): string;
41
67
  constructor(js_config: MathCoreOptions);
package/dist/math_core.js CHANGED
@@ -53,6 +53,14 @@ export class LatexError {
53
53
  const ret = wasm.__wbg_get_latexerror_end(this.__wbg_ptr);
54
54
  return ret >>> 0;
55
55
  }
56
+ /**
57
+ * The index of the snippet that caused the error; only set by `convert_all`.
58
+ * @returns {number | undefined}
59
+ */
60
+ get index() {
61
+ const ret = wasm.__wbg_get_latexerror_index(this.__wbg_ptr);
62
+ return ret === Number.MAX_SAFE_INTEGER ? undefined : ret;
63
+ }
56
64
  /**
57
65
  * @returns {number}
58
66
  */
@@ -94,6 +102,13 @@ export class LatexError {
94
102
  set end(arg0) {
95
103
  wasm.__wbg_set_latexerror_end(this.__wbg_ptr, arg0);
96
104
  }
105
+ /**
106
+ * The index of the snippet that caused the error; only set by `convert_all`.
107
+ * @param {number | null} [arg0]
108
+ */
109
+ set index(arg0) {
110
+ wasm.__wbg_set_latexerror_index(this.__wbg_ptr, isLikeNone(arg0) ? Number.MAX_SAFE_INTEGER : (arg0) >>> 0);
111
+ }
97
112
  /**
98
113
  * @param {number} arg0
99
114
  */
@@ -114,6 +129,26 @@ export class LatexToMathML {
114
129
  const ptr = this.__destroy_into_raw();
115
130
  wasm.__wbg_latextomathml_free(ptr, 0);
116
131
  }
132
+ /**
133
+ * Convert a collection of LaTeX snippets to MathML.
134
+ *
135
+ * In contrast to the other conversion methods, this one resolves *forward references*
136
+ * correctly, meaning that a snippet can refer to an equation which is only defined in a
137
+ * later snippet. This is why all snippets of a document have to be passed in at once.
138
+ *
139
+ * The conversion does not touch the global state; it uses a fresh state for the whole batch.
140
+ * @param {MathSnippet[]} snippets
141
+ * @returns {string[]}
142
+ */
143
+ convert_all(snippets) {
144
+ const ptr0 = passArrayJsValueToWasm0(snippets, wasm.__wbindgen_malloc);
145
+ const len0 = WASM_VECTOR_LEN;
146
+ const ret = wasm.latextomathml_convert_all(this.__wbg_ptr, ptr0, len0);
147
+ if (ret[2]) {
148
+ throw takeFromExternrefTable0(ret[1]);
149
+ }
150
+ return takeFromExternrefTable0(ret[0]);
151
+ }
117
152
  /**
118
153
  * @param {string} content
119
154
  * @param {boolean} displaystyle
@@ -162,7 +197,7 @@ if (Symbol.dispose) LatexToMathML.prototype[Symbol.dispose] = LatexToMathML.prot
162
197
  function __wbg_get_imports() {
163
198
  const import0 = {
164
199
  __proto__: null,
165
- __wbg___wbindgen_string_get_b0ca35b86a603356: function(arg0, arg1) {
200
+ __wbg___wbindgen_string_get_d154f1e671052120: function(arg0, arg1) {
166
201
  const obj = arg1;
167
202
  const ret = typeof(obj) === 'string' ? obj : undefined;
168
203
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -170,14 +205,14 @@ function __wbg_get_imports() {
170
205
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
171
206
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
172
207
  },
173
- __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
208
+ __wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
174
209
  throw new Error(getStringFromWasm0(arg0, arg1));
175
210
  },
176
- __wbg_allowUnreliableRendering_09ef135275eede85: function(arg0) {
211
+ __wbg_allowUnreliableRendering_f0c78f4923af73fc: function(arg0) {
177
212
  const ret = arg0.allowUnreliableRendering;
178
213
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
179
214
  },
180
- __wbg_annotation_363d3c8394162f0f: function(arg0) {
215
+ __wbg_annotation_219e13c187863cec: function(arg0) {
181
216
  const ret = arg0.annotation;
182
217
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
183
218
  },
@@ -185,65 +220,91 @@ function __wbg_get_imports() {
185
220
  const ret = ConfigParseError.__wrap(arg0);
186
221
  return ret;
187
222
  },
188
- __wbg_done_89b2b13e91a60321: function(arg0) {
223
+ __wbg_displayStyle_ef5256c58c97a5f4: function(arg0) {
224
+ const ret = arg0.displayStyle;
225
+ return ret;
226
+ },
227
+ __wbg_done_669171204c3dcae2: function(arg0) {
189
228
  const ret = arg0.done;
190
229
  return ret;
191
230
  },
192
- __wbg_entries_00d7283394649868: function(arg0) {
231
+ __wbg_entries_71601bcb707d5078: function(arg0) {
193
232
  const ret = arg0.entries();
194
233
  return ret;
195
234
  },
196
- __wbg_get_507a50627bffa49b: function(arg0, arg1) {
235
+ __wbg_get_c0c8f8d7da0c03dd: function(arg0, arg1) {
197
236
  const ret = arg0[arg1 >>> 0];
198
237
  return ret;
199
238
  },
200
- __wbg_ignoreUnknownCommands_fbafb7b34d6e9764: function(arg0) {
239
+ __wbg_globalGroup_417d1d431020809d: function(arg0) {
240
+ const ret = arg0.globalGroup;
241
+ return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
242
+ },
243
+ __wbg_idPrefix_07be803c89cf3933: function(arg0, arg1) {
244
+ const ret = arg1.idPrefix;
245
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
246
+ var len1 = WASM_VECTOR_LEN;
247
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
248
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
249
+ },
250
+ __wbg_ignoreUnknownCommands_da90e0b44c9174eb: function(arg0) {
201
251
  const ret = arg0.ignoreUnknownCommands;
202
252
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
203
253
  },
204
- __wbg_isArray_0677c962b281d01a: function(arg0) {
254
+ __wbg_isArray_6339f732981044bf: function(arg0) {
205
255
  const ret = Array.isArray(arg0);
206
256
  return ret;
207
257
  },
258
+ __wbg_latex_1391c6fb0158a049: function(arg0, arg1) {
259
+ const ret = arg1.latex;
260
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
261
+ const len1 = WASM_VECTOR_LEN;
262
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
263
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
264
+ },
208
265
  __wbg_latexerror_new: function(arg0) {
209
266
  const ret = LatexError.__wrap(arg0);
210
267
  return ret;
211
268
  },
212
- __wbg_macros_03715a0e353a948d: function(arg0) {
269
+ __wbg_macros_8b80b019c07a1eea: function(arg0) {
213
270
  const ret = arg0.macros;
214
271
  return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
215
272
  },
216
- __wbg_next_71f2aa1cb3d1e37e: function() { return handleError(function (arg0) {
273
+ __wbg_maxExpansions_16e5fe2a6d81c63d: function(arg0) {
274
+ const ret = arg0.maxExpansions;
275
+ return isLikeNone(ret) ? Number.MAX_SAFE_INTEGER : (ret) >>> 0;
276
+ },
277
+ __wbg_next_42cf16ee0dafc9e2: function() { return handleError(function (arg0) {
217
278
  const ret = arg0.next();
218
279
  return ret;
219
280
  }, arguments); },
220
- __wbg_prettyPrint_53b1abd5bf18c3d9: function(arg0, arg1) {
281
+ __wbg_prettyPrint_5d11563071318855: function(arg0, arg1) {
221
282
  const ret = arg1.prettyPrint;
222
283
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
223
284
  var len1 = WASM_VECTOR_LEN;
224
285
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
225
286
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
226
287
  },
227
- __wbg_size_56cb46b36f9b2664: function(arg0) {
288
+ __wbg_size_7c5f5d6c17503441: function(arg0) {
228
289
  const ret = arg0.size;
229
290
  return ret;
230
291
  },
231
- __wbg_throwOnError_b6c73f7b5c7ff297: function(arg0) {
292
+ __wbg_throwOnError_1c2db037b7b92155: function(arg0) {
232
293
  const ret = arg0.throwOnError;
233
294
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
234
295
  },
235
- __wbg_unicodeSubstitution_0308f153a7409367: function(arg0, arg1) {
296
+ __wbg_unicodeSubstitution_ef25a02b6746022e: function(arg0, arg1) {
236
297
  const ret = arg1.unicodeSubstitution;
237
298
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
238
299
  var len1 = WASM_VECTOR_LEN;
239
300
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
240
301
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
241
302
  },
242
- __wbg_value_a5d5488a9589444a: function(arg0) {
303
+ __wbg_value_1e2369fab29b420e: function(arg0) {
243
304
  const ret = arg0.value;
244
305
  return ret;
245
306
  },
246
- __wbg_xmlNamespace_28171b05853d5a2e: function(arg0) {
307
+ __wbg_xmlNamespace_58e49416ebc58362: function(arg0) {
247
308
  const ret = arg0.xmlNamespace;
248
309
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
249
310
  },
@@ -252,6 +313,13 @@ function __wbg_get_imports() {
252
313
  const ret = getStringFromWasm0(arg0, arg1);
253
314
  return ret;
254
315
  },
316
+ __wbindgen_cast_0000000000000002: function(arg0, arg1) {
317
+ var v0 = getArrayJsValueFromWasm0(arg0, arg1);
318
+ wasm.__wbindgen_free(arg0, arg1 * 4, 4);
319
+ // Cast intrinsic for `Vector(Externref) -> Externref`.
320
+ const ret = v0;
321
+ return ret;
322
+ },
255
323
  __wbindgen_init_externref_table: function() {
256
324
  const table = wasm.__wbindgen_externrefs;
257
325
  const offset = table.grow(4);
@@ -284,6 +352,17 @@ function addToExternrefTable0(obj) {
284
352
  return idx;
285
353
  }
286
354
 
355
+ function getArrayJsValueFromWasm0(ptr, len) {
356
+ ptr = ptr >>> 0;
357
+ const mem = getDataViewMemory0();
358
+ const result = [];
359
+ for (let i = ptr; i < ptr + 4 * len; i += 4) {
360
+ result.push(wasm.__wbindgen_externrefs.get(mem.getUint32(i, true)));
361
+ }
362
+ wasm.__externref_drop_slice(ptr, len);
363
+ return result;
364
+ }
365
+
287
366
  let cachedDataViewMemory0 = null;
288
367
  function getDataViewMemory0() {
289
368
  if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
@@ -317,6 +396,16 @@ function isLikeNone(x) {
317
396
  return x === undefined || x === null;
318
397
  }
319
398
 
399
+ function passArrayJsValueToWasm0(array, malloc) {
400
+ const ptr = malloc(array.length * 4, 4) >>> 0;
401
+ for (let i = 0; i < array.length; i++) {
402
+ const add = addToExternrefTable0(array[i]);
403
+ getDataViewMemory0().setUint32(ptr + 4 * i, add, true);
404
+ }
405
+ WASM_VECTOR_LEN = array.length;
406
+ return ptr;
407
+ }
408
+
320
409
  function passStringToWasm0(arg, malloc, realloc) {
321
410
  if (realloc === undefined) {
322
411
  const buf = cachedTextEncoder.encode(arg);
Binary file
@@ -3,16 +3,19 @@
3
3
  export const memory: WebAssembly.Memory;
4
4
  export const __wbg_configparseerror_free: (a: number, b: number) => void;
5
5
  export const __wbg_get_latexerror_end: (a: number) => number;
6
+ export const __wbg_get_latexerror_index: (a: number) => number;
6
7
  export const __wbg_get_latexerror_start: (a: number) => number;
7
8
  export const __wbg_latexerror_free: (a: number, b: number) => void;
8
9
  export const __wbg_latextomathml_free: (a: number, b: number) => void;
9
10
  export const __wbg_set_latexerror_end: (a: number, b: number) => void;
11
+ export const __wbg_set_latexerror_index: (a: number, b: number) => void;
10
12
  export const __wbg_set_latexerror_start: (a: number, b: number) => void;
11
13
  export const configparseerror_message: (a: number) => any;
12
14
  export const latexerror_context: (a: number) => any;
13
15
  export const latexerror_label: (a: number) => any;
14
16
  export const latexerror_message: (a: number) => any;
15
17
  export const latexerror_report: (a: number) => any;
18
+ export const latextomathml_convert_all: (a: number, b: number, c: number) => [number, number, number];
16
19
  export const latextomathml_convert_with_global_state: (a: number, b: number, c: number, d: number) => [number, number, number];
17
20
  export const latextomathml_convert_with_local_state: (a: number, b: number, c: number, d: number) => [number, number, number];
18
21
  export const latextomathml_new: (a: any) => [number, number, number];
@@ -22,5 +25,7 @@ export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) =>
22
25
  export const __externref_table_alloc: () => number;
23
26
  export const __wbindgen_externrefs: WebAssembly.Table;
24
27
  export const __wbindgen_exn_store: (a: number) => void;
28
+ export const __externref_drop_slice: (a: number, b: number) => void;
29
+ export const __wbindgen_free: (a: number, b: number, c: number) => void;
25
30
  export const __externref_table_dealloc: (a: number) => void;
26
31
  export const __wbindgen_start: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "math-core",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Convert LaTeX to MathML Core",
5
5
  "homepage": "https://github.com/tmke8/math-core#readme",
6
6
  "bugs": {