Skip to content

Commit

Permalink
Merge pull request #126 from mathjax/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
pkra committed Oct 28, 2015
2 parents e69475e + 183c9a2 commit 3849c87
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 38 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: node_js
node_js:
- 'iojs'
sudo: false
script:
- npm install
- npm test
54 changes: 53 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MathJax-node
# MathJax-node [![Build Status](https://travis-ci.org/mathjax/MathJax-node.svg?branch=develop)](https://travis-ci.org/mathjax/MathJax-node)

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

# Getting started

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.

* `lib/mj-single.js` is optimized for processing single equations.


```javascript
// a simple TeX-input example
var mjAPI = require("./lib/mj-single.js");
mjAPI.config({
MathJax: {
// traditional MathJax configuration
}
});
mjAPI.start();

var yourMath = 'E = mc^2';

mjAPI.typeset({
math: yourMath,
format: "TeX", // "inline-TeX", "MathML"
mml:true, // svg:true,
}, function (data) {
if (!data.errors) {console.log(data.mml)}
});
```


* `lib/mj-page.js` is optimized for handling full HTML pages.


```javascript
var mjAPI = require("./lib/mj-page.js");
var jsdom = require("jsdom").jsdom;

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>");

mjAPI.start();

mjAPI.typeset({
html: document.body.innerHTML,
renderer: "NativeMML",
inputs: ["TeX"],
xmlns: "mml"
}, function(result) {
"use strict";
document.body.innerHTML = result.html;
var HTML = "<!DOCTYPE html>\n" + document.documentElement.outerHTML.replace(/^(\n|\s)*/, "");
console.log(HTML);
});
```
37 changes: 31 additions & 6 deletions lib/mj-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ var MathJax; // filled in once MathJax is loaded
var serverState = STATE.STOPPED; // nothing loaded yet
var timer; // used to reset MathJax if it runs too long

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

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

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

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

//
// Set the delays to 0 (we don't need to update the screen)
//
MathJax.Hub.processSectionDelay = 0;
MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
MathJax.Hub.processUpdateDelay = 0;

//
// Adjust the SVG output jax
//
Expand Down Expand Up @@ -283,7 +290,7 @@ function ConfigureMathJax() {
jax.SVG.ex = ex = (data||defaults).ex;
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
jax.SVG.cwidth = width / em * 1000;
jax.SVG.lineWidth = (linebreak ? width / em *1000 : 1000000);
jax.SVG.lineWidth = (linebreak ? width / em *1000 : SVG.BIGDIMEN);
}
//
// Set state variables used for displaying equations in chunks
Expand Down Expand Up @@ -361,7 +368,25 @@ function ConfigureMathJax() {
window.MathJax.extensions.push(matches[1] + '.js');
}
}
if (MathJaxConfig) {Insert(window.MathJax,MathJaxConfig)}

//
// Turn arrays into jsdom window arrays
// (so "instanceof Array" will identify them properly)
//
var adjustArrays = function (obj) {
for (var id in obj) {if (obj.hasOwnProperty(id)) {
if (obj[id] instanceof Array) {
var A = window.Array();
obj[id] = A.concat.apply(A,obj[id]);
} else if (typeof obj[id] === "object") {
adjustArrays(obj[id]);
}
}}
}
if (MathJaxConfig) {
adjustArrays(MathJaxConfig);
Insert(window.MathJax,MathJaxConfig);
}
}

//
Expand Down Expand Up @@ -501,7 +526,7 @@ function ConfigureTypeset() {
// Configure SVG and TeX
//
SVG.defaultEx = data.ex;
SVG.defaultWidth = data.width;
SVG.defaultWidth = data.width * data.ex;
SVG.config.linebreaks.automatic = data.linebreaks;
SVG.config.linebreaks.width = data.width * data.ex;
SVG.config.useFontCache = data.useFontCache;
Expand Down
37 changes: 31 additions & 6 deletions lib/mj-single.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ var MathJaxConfig; // configuration for when starting MathJax
var MathJax; // filled in once MathJax is loaded
var serverState = STATE.STOPPED; // nothing loaded yet
var timer; // used to reset MathJax if it runs too long
var tmpfile = os.tmpdir() + "/mj-single-svg"; // file name prefix to use for temp files
var tmpfile = os.tmpdir() + "/mj-single-svg" + process.pid; // file name prefix to use for temp files

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

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

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

//
// Set the delays to 0 (we don't need to update the screen)
//
MathJax.Hub.processSectionDelay = 0;
MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
MathJax.Hub.processUpdateDelay = 0;

//
// Adjust the SVG output jax
//
Expand Down Expand Up @@ -278,7 +285,7 @@ function ConfigureMathJax() {
jax.SVG.ex = ex = (data||defaults).ex;
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
jax.SVG.cwidth = width / em * 1000;
jax.SVG.lineWidth = (linebreak ? width / em * 1000 : 1000000);
jax.SVG.lineWidth = (linebreak ? width / em * 1000 : SVG.BIGDIMEN);
}
//
// Set state variables used for displaying equations in chunks
Expand Down Expand Up @@ -335,7 +342,25 @@ function ConfigureMathJax() {
window.MathJax.extensions.push(matches[1] + '.js');
}
}
if (MathJaxConfig) {Insert(window.MathJax,MathJaxConfig)}

//
// Turn arrays into jsdom window arrays
// (so "instanceof Array" will identify them properly)
//
var adjustArrays = function (obj) {
for (var id in obj) {if (obj.hasOwnProperty(id)) {
if (obj[id] instanceof Array) {
var A = window.Array();
obj[id] = A.concat.apply(A,obj[id]);
} else if (typeof obj[id] === "object") {
adjustArrays(obj[id]);
}
}}
}
if (MathJaxConfig) {
adjustArrays(MathJaxConfig);
Insert(window.MathJax,MathJaxConfig);
}
}

//
Expand Down Expand Up @@ -530,7 +555,7 @@ function StartQueue() {
HUB = MathJax.Hub;

SVG.defaultEx = data.ex;
SVG.defaultWidth = data.width;
SVG.defaultWidth = data.width * data.ex;
SVG.config.linebreaks.automatic = data.linebreaks;
SVG.config.linebreaks.width = data.width * data.ex;
SVG.config.useFontCache = data.useFontCache;
Expand Down
60 changes: 35 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
{
"name": "MathJax-node",
"version": "0.3.0",
"description": "API's for calling MathJax from node.js",
"keywords": ["MathJax","math","svg","MathML","TeX","AsciiMath"],
"maintainers": [
"MathJax Consortium <[email protected]> (http://www.mathjax.org)"
],
"bugs": {
"url": "http://github.com/mathjax/MathJax-node/issues"
},
"license": {
"type": "Apache",
"url": "http://github.com/mathjax/MathJax-node/blob/master/LICENSE"
},
"repository": {
"type": "git",
"url": "git://github.com/mathjax/MathJax-node.git"
},
"dependencies": {
"jsdom": "3.1.1",
"speech-rule-engine": "*",
"yargs": "*",
"MathJax": "https://github.com/mathjax/MathJax/tarball/mathjax-node-2.5.1"
},
"main": "./lib/mj-page.js"
"name": "mathjax-node",
"version": "0.4.0",
"description": "API's for calling MathJax from node.js",
"keywords": [
"MathJax",
"math",
"svg",
"MathML",
"TeX",
"AsciiMath"
],
"maintainers": [
"MathJax Consortium <[email protected]> (http://www.mathjax.org)"
],
"bugs": {
"url": "http://github.com/mathjax/MathJax-node/issues"
},
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git://github.com/mathjax/MathJax-node.git"
},
"dependencies": {
"jsdom": "^6.0.0",
"speech-rule-engine": "*",
"yargs": "^3.0.0",
"MathJax": "https://github.com/mathjax/MathJax/tarball/mathjax-node-2.5.1"
},
"scripts": {
"test": "tape test/*.js"
},
"main": "./lib/mj-page.js",
"devDependencies": {
"tape": "^4.0.3"
}
}
17 changes: 17 additions & 0 deletions test/base-mathjax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var tape = require('tape');
var mjAPI = require("..//lib/mj-single.js");

tape('basic test: check MathJax core', function(t) {
t.plan(1);

var tex = '';
mjAPI.start();

mjAPI.typeset({
math: tex,
format: "TeX",
mml: true
}, function(data) {
t.ok(data.mml, 'MathJax core seems ok');
});
});
18 changes: 18 additions & 0 deletions test/base-speechruleengine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var tape = require('tape');
var mjAPI = require("..//lib/mj-single.js");

tape('basic test: check speechruleengine', function(t) {
t.plan(1);

var tex = 'MathJax';
mjAPI.start();

mjAPI.typeset({
math: tex,
format: "TeX",
mml: true,
speakText: true
}, function(data) {
t.ok(data.speakText, 'speechruleengine seems ok');
});
});
23 changes: 23 additions & 0 deletions test/issue104.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var tape = require('tape');
var mjAPI = require("..//lib/mj-single.js");
var jsdom = require('jsdom').jsdom;

tape('the SVG width should match the default', function(t) {
t.plan(1);

mjAPI.start();
var tex = 'a \\\\ b';
var expected = '100ex';

mjAPI.typeset({
math: tex,
format: "TeX",
svg: true
}, function(data) {
var document = jsdom(data.svg);
var window = document.defaultView;
var element = window.document.getElementsByTagName("svg")[0];
var width = element.getAttribute('width');
t.equal(width, expected);
});
});

0 comments on commit 3849c87

Please sign in to comment.