mathjax-svg 0.1.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/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 karei
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# mathjax-svg
|
|
2
|
+
|
|
3
|
+
A small Node.js library that renders TeX to a raw SVG string with MathJax 4.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install mathjax-svg
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> Node.js 16.14.2 or later is required.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { renderToSvg, warmup } from 'mathjax-svg';
|
|
18
|
+
|
|
19
|
+
await warmup(); // optional
|
|
20
|
+
|
|
21
|
+
const inlineSvg = await renderToSvg(String.raw`E=mc^2`);
|
|
22
|
+
const displaySvg = await renderToSvg(String.raw`\frac{1}{2}`, { display: true });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API
|
|
26
|
+
|
|
27
|
+
**`warmup(): Promise<void>`**
|
|
28
|
+
|
|
29
|
+
Loads and initializes MathJax without rendering a formula. Calling it is optional; the first render initializes MathJax automatically.
|
|
30
|
+
|
|
31
|
+
**`renderToSvg(tex, options?): Promise<string>`**
|
|
32
|
+
|
|
33
|
+
Renders `tex`. `options.display` defaults to `false`.
|
|
34
|
+
|
|
35
|
+
Initialization failures throw `MathJaxInitializationError`, whose `phase` is `module-import` or `mathjax-init`. Rendering failures throw `MathJaxRenderError`, whose `phase` is `tex2svg`, `serialize`, or `svg-validation`. Both error classes retain the original failure in `original`.
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface RenderToSvgOptions {
|
|
2
|
+
display?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export type MathJaxInitializationPhase = 'module-import' | 'mathjax-init';
|
|
5
|
+
export type MathJaxRenderPhase = 'tex2svg' | 'serialize' | 'svg-validation';
|
|
6
|
+
export declare class MathJaxInitializationError extends Error {
|
|
7
|
+
readonly phase: MathJaxInitializationPhase;
|
|
8
|
+
readonly original: unknown;
|
|
9
|
+
constructor(phase: MathJaxInitializationPhase, original: unknown);
|
|
10
|
+
}
|
|
11
|
+
export declare class MathJaxRenderError extends Error {
|
|
12
|
+
readonly phase: MathJaxRenderPhase;
|
|
13
|
+
readonly original: unknown;
|
|
14
|
+
constructor(phase: MathJaxRenderPhase, original: unknown);
|
|
15
|
+
}
|
|
16
|
+
export declare function warmup(): Promise<void>;
|
|
17
|
+
export declare function renderToSvg(tex: string, options?: RenderToSvgOptions): Promise<string>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MathJaxRenderError = exports.MathJaxInitializationError = void 0;
|
|
4
|
+
exports.warmup = warmup;
|
|
5
|
+
exports.renderToSvg = renderToSvg;
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const node_url_1 = require("node:url");
|
|
8
|
+
class MathJaxInitializationError extends Error {
|
|
9
|
+
phase;
|
|
10
|
+
original;
|
|
11
|
+
constructor(phase, original) {
|
|
12
|
+
super(`MathJax initialization failed during ${phase}: ${errorText(original)}`);
|
|
13
|
+
this.phase = phase;
|
|
14
|
+
this.original = original;
|
|
15
|
+
this.name = 'MathJaxInitializationError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.MathJaxInitializationError = MathJaxInitializationError;
|
|
19
|
+
class MathJaxRenderError extends Error {
|
|
20
|
+
phase;
|
|
21
|
+
original;
|
|
22
|
+
constructor(phase, original) {
|
|
23
|
+
super(`Math rendering failed during ${phase}: ${errorText(original)}`);
|
|
24
|
+
this.phase = phase;
|
|
25
|
+
this.original = original;
|
|
26
|
+
this.name = 'MathJaxRenderError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.MathJaxRenderError = MathJaxRenderError;
|
|
30
|
+
let mathJaxPromise;
|
|
31
|
+
async function warmup() {
|
|
32
|
+
await mathJax();
|
|
33
|
+
}
|
|
34
|
+
async function renderToSvg(tex, options = {}) {
|
|
35
|
+
const mathJaxApi = await mathJax();
|
|
36
|
+
let node;
|
|
37
|
+
try {
|
|
38
|
+
node = await mathJaxApi.tex2svgPromise(tex, { display: options.display ?? false });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new MathJaxRenderError('tex2svg', error);
|
|
42
|
+
}
|
|
43
|
+
let serialized;
|
|
44
|
+
try {
|
|
45
|
+
serialized = mathJaxApi.startup.adaptor.serializeXML(node);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw new MathJaxRenderError('serialize', error);
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
if (serialized.includes('data-mml-node="merror"'))
|
|
52
|
+
throw new Error('MathJax returned an merror node.');
|
|
53
|
+
const matches = serialized.match(/<svg\b[\s\S]*?<\/svg>/g);
|
|
54
|
+
if (matches?.length !== 1)
|
|
55
|
+
throw new Error('MathJax did not produce exactly one SVG image.');
|
|
56
|
+
return matches[0];
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new MathJaxRenderError('svg-validation', error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function mathJax() {
|
|
63
|
+
if (mathJaxPromise)
|
|
64
|
+
return mathJaxPromise;
|
|
65
|
+
let promise;
|
|
66
|
+
promise = initializeMathJax().catch((error) => {
|
|
67
|
+
if (mathJaxPromise === promise)
|
|
68
|
+
mathJaxPromise = undefined;
|
|
69
|
+
if (error instanceof MathJaxInitializationError)
|
|
70
|
+
throw error;
|
|
71
|
+
throw new MathJaxInitializationError('mathjax-init', error);
|
|
72
|
+
});
|
|
73
|
+
mathJaxPromise = promise;
|
|
74
|
+
return promise;
|
|
75
|
+
}
|
|
76
|
+
async function initializeMathJax() {
|
|
77
|
+
let module;
|
|
78
|
+
try {
|
|
79
|
+
module = await import('mathjax');
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throw new MathJaxInitializationError('module-import', error);
|
|
83
|
+
}
|
|
84
|
+
const mathJaxApi = module.default;
|
|
85
|
+
try {
|
|
86
|
+
await mathJaxApi.init({
|
|
87
|
+
loader: {
|
|
88
|
+
paths: { 'mathjax-tex': '@mathjax/mathjax-tex-font' },
|
|
89
|
+
load: ['input/tex', 'output/svg'],
|
|
90
|
+
require: (file) => import(process.platform === 'win32' && node_path_1.win32.isAbsolute(file) ? (0, node_url_1.pathToFileURL)(file).href : file),
|
|
91
|
+
},
|
|
92
|
+
output: { font: 'mathjax-tex', displayOverflow: 'overflow', linebreaks: { inline: false } },
|
|
93
|
+
tex: { packages: ['base', 'ams', 'newcommand'] },
|
|
94
|
+
});
|
|
95
|
+
if (typeof mathJaxApi.tex2svgPromise !== 'function')
|
|
96
|
+
throw new TypeError('MathJax initialized without a tex2svgPromise API.');
|
|
97
|
+
return mathJaxApi;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw new MathJaxInitializationError('mathjax-init', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function errorText(error) {
|
|
104
|
+
return error instanceof Error ? error.message : String(error);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA+BA,wBAEC;AACD,kCAsBC;AAxDD,yCAAkC;AAClC,uCAAyC;AASzC,MAAa,0BAA2B,SAAQ,KAAK;IAExC;IACA;IAFX,YACW,KAAiC,EACjC,QAAiB;QAE1B,KAAK,CAAC,wCAAwC,KAAK,KAAK,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAHtE,UAAK,GAAL,KAAK,CAA4B;QACjC,aAAQ,GAAR,QAAQ,CAAS;QAG1B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AARD,gEAQC;AACD,MAAa,kBAAmB,SAAQ,KAAK;IAEhC;IACA;IAFX,YACW,KAAyB,EACzB,QAAiB;QAE1B,KAAK,CAAC,gCAAgC,KAAK,KAAK,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAH9D,UAAK,GAAL,KAAK,CAAoB;QACzB,aAAQ,GAAR,QAAQ,CAAS;QAG1B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AARD,gDAQC;AAED,IAAI,cAA+C,CAAC;AAE7C,KAAK,UAAU,MAAM;IAC1B,MAAM,OAAO,EAAE,CAAC;AAClB,CAAC;AACM,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,UAA8B,EAAE;IAC7E,MAAM,UAAU,GAAG,MAAM,OAAO,EAAE,CAAC;IACnC,IAAI,IAAuD,CAAC;IAC5D,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,UAAU,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;IACrF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kBAAkB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACvG,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,OAAO,EAAE,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC7F,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kBAAkB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAS,OAAO;IACd,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC1C,IAAI,OAA6B,CAAC;IAClC,OAAO,GAAG,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5C,IAAI,cAAc,KAAK,OAAO;YAAE,cAAc,GAAG,SAAS,CAAC;QAC3D,IAAI,KAAK,YAAY,0BAA0B;YAAE,MAAM,KAAK,CAAC;QAC7D,MAAM,IAAI,0BAA0B,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IACH,cAAc,GAAG,OAAO,CAAC;IACzB,OAAO,OAAO,CAAC;AACjB,CAAC;AACD,KAAK,UAAU,iBAAiB;IAC9B,IAAI,MAAgC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,0BAA0B,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAgC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,IAAI,CAAC;YACpB,MAAM,EAAE;gBACN,KAAK,EAAE,EAAE,aAAa,EAAE,2BAA2B,EAAE;gBACrD,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;gBACjC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CACxB,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,iBAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,wBAAa,EAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;aACnG;YACD,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3F,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE;SACjD,CAAC,CAAC;QACH,IAAI,OAAO,UAAU,CAAC,cAAc,KAAK,UAAU;YACjD,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,0BAA0B,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AACD,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mathjax-svg",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Render TeX to a raw SVG string with MathJax in Node.js.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mathjax",
|
|
7
|
+
"svg",
|
|
8
|
+
"tex",
|
|
9
|
+
"latex"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "karei"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/abcdvvvv/mathjax-svg.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/abcdvvvv/mathjax-svg/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/abcdvvvv/mathjax-svg#readme",
|
|
23
|
+
"type": "commonjs",
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"require": "./dist/index.js",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"sideEffects": false,
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=16.14.2"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
46
|
+
"build": "tsc -p tsconfig.json",
|
|
47
|
+
"test": "npm run clean && npm run build && node test/index.test.cjs",
|
|
48
|
+
"benchmark": "npm run build && node benchmark/render.mjs",
|
|
49
|
+
"prepack": "npm run clean && npm run build",
|
|
50
|
+
"prepublishOnly": "npm test"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@mathjax/mathjax-tex-font": "4.1.3",
|
|
54
|
+
"mathjax": "4.1.3"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^18.19.0",
|
|
58
|
+
"typescript": "^5.9.3"
|
|
59
|
+
}
|
|
60
|
+
}
|