Last active
May 27, 2016 12:00
-
-
Save pkra/d633ca37c0eb644db83efc7af840273f to your computer and use it in GitHub Desktop.
Quick MathJax-node wrapper for xhtml files containig MathML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var mjAPI = require('mathjax-node/lib/mj-single'); | |
var typeset = mjAPI.typeset; | |
var fs = require('fs'); | |
var libxmljs = require('libxmljs'); | |
var argv = require('yargs') | |
.strict() | |
.usage('Usage: jats -i input.html -o output.html -f HTML', { | |
i: { | |
describe: 'specify input file', | |
alias: ('i', 'input') | |
}, | |
o: { | |
describe: 'specify output file', | |
alias: ('o', 'output') | |
}, | |
f: { | |
default: 'HTML', | |
describe: 'output format to generate -- HTML or SVG' | |
}, | |
}) | |
.demand(['i']) | |
.argv; | |
var inputFile = fs.readFileSync(argv.i); | |
var outputFile = argv.o | |
var xmlDocument = libxmljs.parseXmlString(inputFile); | |
mjAPI.config({ | |
MathJax: { | |
menuSettings: { | |
semantics: true, | |
}, | |
'displayAlign': 'left', | |
TeX: { | |
TagSide: 'left', | |
Macros: { | |
bigsqcap: '\\mmlToken{mo}{\u2a05}', | |
lefteqn: ['\\rlap{\\displaystyle{#1}}', 1] | |
// btran 8 | |
} | |
} | |
} | |
}); | |
mjAPI.start(); | |
var mathNodes = xmlDocument.find('//*[name() = "math"]'); // cf. http://stackoverflow.com/a/10990253 | |
// For TeX or ascii input, this might be | |
// var texMathNodes = xmlDocument.find('.//*[name()="span"][@class="math"]'); | |
// For TeX, you'd need some delimiter handling | |
// e.g., use class="math block" without delimiters or use delimiters and check innerHTML for them. | |
var state = {}; // shared state among typeset requests (SVG <defs> for global sprite are stored here); cf useGlobalCache | |
for (var i = 0; i < mathNodes.length; i++) { | |
let index = i; | |
let element = mathNodes[index]; | |
mjAPI.typeset({ | |
math: element.toString(), | |
format: 'MathML', | |
svg: (argv.f === 'SVG'), | |
useGlobalCache: true, | |
state: state, | |
html: (argv.f === 'HTML'), | |
speakText: true | |
// TODO: handle state | |
}, function(data) { | |
if (data.errors) { | |
throw data.errors; | |
} | |
if (data.svg) { | |
console.log("Hello" + index); | |
var svgNode = libxmljs.parseXmlString(data.svg); | |
element.replace(svgNode.root()); | |
} | |
if (data.html) { | |
var htmlNode = libxmljs.parseHtmlString(data.html); | |
element.replace(htmlNode.root()); | |
} | |
// wrap up at end of loop | |
// (typesetting is async but guaranteed to be in series.) | |
if ((index + 1) === mathNodes.length) { | |
if (data.svg) { | |
var body = xmlDocument.find('//*[name() = "body"]')[0]; | |
var globalSVG = libxmljs.parseXmlString("<svg style='display:none'>" + state.defs.outerHTML + "</svg>"); // the SVG sprite | |
body.addChild(globalSVG.root()); | |
} | |
fs.writeFile(outputFile, xmlDocument, function(err) { | |
if (err) { | |
throw err; | |
} else { | |
console.log("It\'s saved!"); | |
} | |
}); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment