Skip to content

Commit 3849c87

Browse files
committed
Merge pull request mathjax#126 from mathjax/develop
Merge develop into master
2 parents e69475e + 183c9a2 commit 3849c87

File tree

8 files changed

+215
-38
lines changed

8 files changed

+215
-38
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- 'iojs'
4+
sudo: false
5+
script:
6+
- npm install
7+
- npm test

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# MathJax-node
1+
# MathJax-node [![Build Status](https://travis-ci.org/mathjax/MathJax-node.svg?branch=develop)](https://travis-ci.org/mathjax/MathJax-node)
22

33
This repository contains files that provide APIs to call MathJax from
44
node.js programs. There is an API for converting individual math
@@ -23,3 +23,55 @@ These API's can produce PNG images, but that requires the
2323
should be installed in the `batik` directory. See the README file in that
2424
directory for more details.
2525

26+
# Getting started
27+
28+
MahJax-node provides two libraries, `lib/mj-single.js` and `lib/mj-page.js`. Below are two very minimal examples -- be sure to check out the examples in `./bin/` for more advanced configurations.
29+
30+
* `lib/mj-single.js` is optimized for processing single equations.
31+
32+
33+
```javascript
34+
// a simple TeX-input example
35+
var mjAPI = require("./lib/mj-single.js");
36+
mjAPI.config({
37+
MathJax: {
38+
// traditional MathJax configuration
39+
}
40+
});
41+
mjAPI.start();
42+
43+
var yourMath = 'E = mc^2';
44+
45+
mjAPI.typeset({
46+
math: yourMath,
47+
format: "TeX", // "inline-TeX", "MathML"
48+
mml:true, // svg:true,
49+
}, function (data) {
50+
if (!data.errors) {console.log(data.mml)}
51+
});
52+
```
53+
54+
55+
* `lib/mj-page.js` is optimized for handling full HTML pages.
56+
57+
58+
```javascript
59+
var mjAPI = require("./lib/mj-page.js");
60+
var jsdom = require("jsdom").jsdom;
61+
62+
var document = jsdom("<!DOCTYPE html><html lang='en'><head><title>Test</title></head><body><h1>Let's test mj-page</h1> <p> \\[f: X \\to Y\\], where \\( X = 2^{\mathbb{N}}\\) </p></body></html>");
63+
64+
mjAPI.start();
65+
66+
mjAPI.typeset({
67+
html: document.body.innerHTML,
68+
renderer: "NativeMML",
69+
inputs: ["TeX"],
70+
xmlns: "mml"
71+
}, function(result) {
72+
"use strict";
73+
document.body.innerHTML = result.html;
74+
var HTML = "<!DOCTYPE html>\n" + document.documentElement.outerHTML.replace(/^(\n|\s)*/, "");
75+
console.log(HTML);
76+
});
77+
```

lib/mj-page.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ var MathJax; // filled in once MathJax is loaded
8787
var serverState = STATE.STOPPED; // nothing loaded yet
8888
var timer; // used to reset MathJax if it runs too long
8989

90-
var tmpfile = os.tmpdir() + "/mj-single-svg"; // file name prefix to use for temp files
90+
var tmpfile = os.tmpdir() + "/mj-single-svg" + process.pid; // file name prefix to use for temp files
9191

9292
var document, window, content, html; // the DOM elements
9393

@@ -116,7 +116,7 @@ var STYLES; // filled in when SVG is loaded
116116
function GetWindow() {
117117
document = jsdom();
118118
html = document.firstChild;
119-
window = document.parentWindow;
119+
window = document.defaultView;
120120
window.console = console;
121121
window.onerror = function (err,url,line) {AddError("Error: "+err)}
122122
content = document.body.appendChild(document.createElement("div"));
@@ -148,7 +148,7 @@ function ConfigureMathJax() {
148148
tex2jax: {inlineMath: [['$','$'],['\\(','\\)']], preview:"none"},
149149
mml2jax: {preview:"none"},
150150
asciimath2jax: {preview:"none"},
151-
SVG: {useFontCache: true, useGlobalCache: false},
151+
SVG: {useFontCache: true, useGlobalCache: false, EqnChunk: 1000000, EqnDelay: 0},
152152

153153
//
154154
// This gets run before MathJax queues any actions
@@ -210,6 +210,13 @@ function ConfigureMathJax() {
210210
AddError("TeX parse error",message[1]);
211211
});
212212

213+
//
214+
// Set the delays to 0 (we don't need to update the screen)
215+
//
216+
MathJax.Hub.processSectionDelay = 0;
217+
MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
218+
MathJax.Hub.processUpdateDelay = 0;
219+
213220
//
214221
// Adjust the SVG output jax
215222
//
@@ -283,7 +290,7 @@ function ConfigureMathJax() {
283290
jax.SVG.ex = ex = (data||defaults).ex;
284291
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
285292
jax.SVG.cwidth = width / em * 1000;
286-
jax.SVG.lineWidth = (linebreak ? width / em *1000 : 1000000);
293+
jax.SVG.lineWidth = (linebreak ? width / em *1000 : SVG.BIGDIMEN);
287294
}
288295
//
289296
// Set state variables used for displaying equations in chunks
@@ -361,7 +368,25 @@ function ConfigureMathJax() {
361368
window.MathJax.extensions.push(matches[1] + '.js');
362369
}
363370
}
364-
if (MathJaxConfig) {Insert(window.MathJax,MathJaxConfig)}
371+
372+
//
373+
// Turn arrays into jsdom window arrays
374+
// (so "instanceof Array" will identify them properly)
375+
//
376+
var adjustArrays = function (obj) {
377+
for (var id in obj) {if (obj.hasOwnProperty(id)) {
378+
if (obj[id] instanceof Array) {
379+
var A = window.Array();
380+
obj[id] = A.concat.apply(A,obj[id]);
381+
} else if (typeof obj[id] === "object") {
382+
adjustArrays(obj[id]);
383+
}
384+
}}
385+
}
386+
if (MathJaxConfig) {
387+
adjustArrays(MathJaxConfig);
388+
Insert(window.MathJax,MathJaxConfig);
389+
}
365390
}
366391

367392
//
@@ -501,7 +526,7 @@ function ConfigureTypeset() {
501526
// Configure SVG and TeX
502527
//
503528
SVG.defaultEx = data.ex;
504-
SVG.defaultWidth = data.width;
529+
SVG.defaultWidth = data.width * data.ex;
505530
SVG.config.linebreaks.automatic = data.linebreaks;
506531
SVG.config.linebreaks.width = data.width * data.ex;
507532
SVG.config.useFontCache = data.useFontCache;

lib/mj-single.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ var MathJaxConfig; // configuration for when starting MathJax
8585
var MathJax; // filled in once MathJax is loaded
8686
var serverState = STATE.STOPPED; // nothing loaded yet
8787
var timer; // used to reset MathJax if it runs too long
88-
var tmpfile = os.tmpdir() + "/mj-single-svg"; // file name prefix to use for temp files
88+
var tmpfile = os.tmpdir() + "/mj-single-svg" + process.pid; // file name prefix to use for temp files
8989

9090
var document, window, content, html; // the DOM elements
9191

@@ -117,7 +117,7 @@ var delimiters = {
117117
function GetWindow() {
118118
document = jsdom();
119119
html = document.firstChild;
120-
window = document.parentWindow;
120+
window = document.defaultView;
121121
window.console = console;
122122
window.onerror = function (err,url,line) {AddError("Error: "+err)}
123123
content = document.body.appendChild(document.createElement("div"));
@@ -149,7 +149,7 @@ function ConfigureMathJax() {
149149
tex2jax: {inlineMath: [['$','$'],['\\(','\\)']], preview:"none"},
150150
mml2jax: {preview:"none"},
151151
asciimath2jax: {preview:"none"},
152-
SVG: {useFontCache: true, useGlobalCache: false},
152+
SVG: {useFontCache: true, useGlobalCache: false, EqnChunk: 1000000, EqnDelay: 0},
153153

154154
//
155155
// This gets run before MathJax queues any actions
@@ -211,6 +211,13 @@ function ConfigureMathJax() {
211211
AddError("TeX parse error: "+message[1]);
212212
});
213213

214+
//
215+
// Set the delays to 0 (we don't need to update the screen)
216+
//
217+
MathJax.Hub.processSectionDelay = 0;
218+
MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
219+
MathJax.Hub.processUpdateDelay = 0;
220+
214221
//
215222
// Adjust the SVG output jax
216223
//
@@ -278,7 +285,7 @@ function ConfigureMathJax() {
278285
jax.SVG.ex = ex = (data||defaults).ex;
279286
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
280287
jax.SVG.cwidth = width / em * 1000;
281-
jax.SVG.lineWidth = (linebreak ? width / em * 1000 : 1000000);
288+
jax.SVG.lineWidth = (linebreak ? width / em * 1000 : SVG.BIGDIMEN);
282289
}
283290
//
284291
// Set state variables used for displaying equations in chunks
@@ -335,7 +342,25 @@ function ConfigureMathJax() {
335342
window.MathJax.extensions.push(matches[1] + '.js');
336343
}
337344
}
338-
if (MathJaxConfig) {Insert(window.MathJax,MathJaxConfig)}
345+
346+
//
347+
// Turn arrays into jsdom window arrays
348+
// (so "instanceof Array" will identify them properly)
349+
//
350+
var adjustArrays = function (obj) {
351+
for (var id in obj) {if (obj.hasOwnProperty(id)) {
352+
if (obj[id] instanceof Array) {
353+
var A = window.Array();
354+
obj[id] = A.concat.apply(A,obj[id]);
355+
} else if (typeof obj[id] === "object") {
356+
adjustArrays(obj[id]);
357+
}
358+
}}
359+
}
360+
if (MathJaxConfig) {
361+
adjustArrays(MathJaxConfig);
362+
Insert(window.MathJax,MathJaxConfig);
363+
}
339364
}
340365

341366
//
@@ -530,7 +555,7 @@ function StartQueue() {
530555
HUB = MathJax.Hub;
531556

532557
SVG.defaultEx = data.ex;
533-
SVG.defaultWidth = data.width;
558+
SVG.defaultWidth = data.width * data.ex;
534559
SVG.config.linebreaks.automatic = data.linebreaks;
535560
SVG.config.linebreaks.width = data.width * data.ex;
536561
SVG.config.useFontCache = data.useFontCache;

package.json

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,37 @@
11
{
2-
"name": "MathJax-node",
3-
"version": "0.3.0",
4-
"description": "API's for calling MathJax from node.js",
5-
"keywords": ["MathJax","math","svg","MathML","TeX","AsciiMath"],
6-
"maintainers": [
7-
"MathJax Consortium <[email protected]> (http://www.mathjax.org)"
8-
],
9-
"bugs": {
10-
"url": "http://github.com/mathjax/MathJax-node/issues"
11-
},
12-
"license": {
13-
"type": "Apache",
14-
"url": "http://github.com/mathjax/MathJax-node/blob/master/LICENSE"
15-
},
16-
"repository": {
17-
"type": "git",
18-
"url": "git://github.com/mathjax/MathJax-node.git"
19-
},
20-
"dependencies": {
21-
"jsdom": "3.1.1",
22-
"speech-rule-engine": "*",
23-
"yargs": "*",
24-
"MathJax": "https://github.com/mathjax/MathJax/tarball/mathjax-node-2.5.1"
25-
},
26-
"main": "./lib/mj-page.js"
2+
"name": "mathjax-node",
3+
"version": "0.4.0",
4+
"description": "API's for calling MathJax from node.js",
5+
"keywords": [
6+
"MathJax",
7+
"math",
8+
"svg",
9+
"MathML",
10+
"TeX",
11+
"AsciiMath"
12+
],
13+
"maintainers": [
14+
"MathJax Consortium <[email protected]> (http://www.mathjax.org)"
15+
],
16+
"bugs": {
17+
"url": "http://github.com/mathjax/MathJax-node/issues"
18+
},
19+
"license": "Apache-2.0",
20+
"repository": {
21+
"type": "git",
22+
"url": "git://github.com/mathjax/MathJax-node.git"
23+
},
24+
"dependencies": {
25+
"jsdom": "^6.0.0",
26+
"speech-rule-engine": "*",
27+
"yargs": "^3.0.0",
28+
"MathJax": "https://github.com/mathjax/MathJax/tarball/mathjax-node-2.5.1"
29+
},
30+
"scripts": {
31+
"test": "tape test/*.js"
32+
},
33+
"main": "./lib/mj-page.js",
34+
"devDependencies": {
35+
"tape": "^4.0.3"
36+
}
2737
}

test/base-mathjax.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var tape = require('tape');
2+
var mjAPI = require("..//lib/mj-single.js");
3+
4+
tape('basic test: check MathJax core', function(t) {
5+
t.plan(1);
6+
7+
var tex = '';
8+
mjAPI.start();
9+
10+
mjAPI.typeset({
11+
math: tex,
12+
format: "TeX",
13+
mml: true
14+
}, function(data) {
15+
t.ok(data.mml, 'MathJax core seems ok');
16+
});
17+
});

test/base-speechruleengine.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var tape = require('tape');
2+
var mjAPI = require("..//lib/mj-single.js");
3+
4+
tape('basic test: check speechruleengine', function(t) {
5+
t.plan(1);
6+
7+
var tex = 'MathJax';
8+
mjAPI.start();
9+
10+
mjAPI.typeset({
11+
math: tex,
12+
format: "TeX",
13+
mml: true,
14+
speakText: true
15+
}, function(data) {
16+
t.ok(data.speakText, 'speechruleengine seems ok');
17+
});
18+
});

test/issue104.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var tape = require('tape');
2+
var mjAPI = require("..//lib/mj-single.js");
3+
var jsdom = require('jsdom').jsdom;
4+
5+
tape('the SVG width should match the default', function(t) {
6+
t.plan(1);
7+
8+
mjAPI.start();
9+
var tex = 'a \\\\ b';
10+
var expected = '100ex';
11+
12+
mjAPI.typeset({
13+
math: tex,
14+
format: "TeX",
15+
svg: true
16+
}, function(data) {
17+
var document = jsdom(data.svg);
18+
var window = document.defaultView;
19+
var element = window.document.getElementsByTagName("svg")[0];
20+
var width = element.getAttribute('width');
21+
t.equal(width, expected);
22+
});
23+
});

0 commit comments

Comments
 (0)