mathjax / MathJax-demos-node

A repository with examples using mathjax-v3 in NodeJS
Apache License 2.0
98 stars 42 forks source link

example using jsdom adaptor #1

Open pkra opened 6 years ago

pkra commented 6 years ago

I ran into a bug in the lite adaptor and can't figure out how to quickly switch out the jsdom one.

A code snippet would be great.

dpvc commented 6 years ago

Install jsdom using

npm install jsdom

and try

#! /usr/bin/env node

/*************************************************************************
 *
 *  mj3-tex2html
 *
 *  Uses MathJax v3 to convert a TeX string to an HTML string.
 *
 * ----------------------------------------------------------------------
 *
 *  Copyright (c) 2018 The MathJax Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

//
//  Get the command-line arguments
//
var argv = require('yargs')
  .demand(0).strict()
  .usage('$0 [options] "math" > file.html')
  .options({
    inline: {
      boolean: true,
      describe: "process as display math"
    },
    em: {
      default: 16,
      describe: 'em-size in pixels'
    },
    ex: {
      default: 8,
      describe: 'ex-size in pixels'
    },
    width: {
      default: 80 * 16,
      describe: 'width of container in pixels'
    },
    packages: {
      default: 'base, ams, noundefined, newcommand, boldsymbol',
      describe: 'the packages to use, e.g. "base, ams"'
    },
    css: {
      boolean: true,
      describe: 'output the required CSS rather than the HTML itself'
    },
    fontURL: {
      default: 'https://cdn.rawgit.com/mathjax/mathjax-v3/3.0.0-beta.1/mathjax2/css',
      describe: 'the URL to use for web fonts'
    }
  })
  .argv;

//
//  Load the packages needed for MathJax
//
const TeX = require('mathjax3/mathjax3/input/tex.js').TeX;
const CHTML = require('mathjax3/mathjax3/output/chtml.js').CHTML;
const HTMLMathItem = require('mathjax3/mathjax3/handlers/html/HTMLMathItem.js').HTMLMathItem;
const HTMLDocument = require('mathjax3/mathjax3/handlers/html/HTMLDocument.js').HTMLDocument;
const jsdomAdaptor = require('mathjax3/mathjax3/adaptors/jsdomAdaptor.js').jsdomAdaptor;
const JSDOM = require('jsdom').JSDOM;

require('mathjax3/mathjax3/input/tex/base/BaseConfiguration.js');
require('mathjax3/mathjax3/input/tex/ams/AmsConfiguration.js');
require('mathjax3/mathjax3/input/tex/noundefined/NoUndefinedConfiguration.js');
require('mathjax3/mathjax3/input/tex/newcommand/NewcommandConfiguration.js');
require('mathjax3/mathjax3/input/tex/boldsymbol/BoldsymbolConfiguration.js');

//
//  Create the input and ouptut jax
//
const tex = new TeX({packages: argv.packages.split(/\s*,\s*/)});
const chtml = new CHTML({fontURL: argv.fontURL});

//
//  Create an HTML document using a JSDOM Document and the input and output jax
//
const adaptor = jsdomAdaptor(JSDOM);
const document = new JSDOM().window.document;
const html = new HTMLDocument(document, adaptor, {InputJax: tex, OutputJax: chtml});

//
//  Typeset a TeX string and return the serialized HTML
//
const Typeset = (string, display, em = 16, ex = 8, cwidth = 80*16) => {
    const math = new HTMLMathItem(string, tex, display);
    math.setMetrics(em, ex, cwidth, 100000, 1);
    math.compile();
    math.typeset(html)
    return adaptor.outerHTML(math.typesetRoot);
};

//
//  If the --css option was specified, output the CSS,
//  Otherwise, typeset the math and output the HTML
//
if (argv.css) {
  console.log(adaptor.textContent(chtml.styleSheet(html)));
} else {
  console.log(Typeset(argv._[0] || '', !argv.inline, argv.em, argv.ex, argv.width));
}

I think that should work for you.

I do hope you will report the error you are getting with the lite adaptor (or lite document).

pkra commented 6 years ago

I think that should work for you.

Since I was looking at the page-based tool, I actually failed to transfer this over. But it's early in the day...

I do hope you will report the error you are getting with the lite adaptor (or lite document).

Definitely. But I'm converting a few hundred equations and I can't get it to log out useful information.

dpvc commented 6 years ago

OK, here is a -page version for jsdom:

#! /usr/bin/env node

/*************************************************************************
 *
 *  mj3-tex2html-page-jsdom
 *
 *  Uses MathJax v3 to convert all TeX in an HTML document.
 *
 * ----------------------------------------------------------------------
 *
 *  Copyright (c) 2018 The MathJax Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

//
//  Get the command-line arguments
//
var argv = require('yargs')
  .demand(1).strict()
  .usage('$0 [options] file.html > converted.html')
  .options({
    em: {
      default: 16,
      describe: 'em-size in pixels'
    },
    ex: {
      default: 8,
      describe: 'ex-size in pixels'
    },
    packages: {
      default: 'base, ams, noundefined, newcommand, boldsymbol',
      describe: 'the packages to use, e.g. "base, ams"'
    },
    fontURL: {
      default: 'https://cdn.rawgit.com/mathjax/mathjax-v3/3.0.0-beta.1/mathjax2/css',
      describe: 'the URL to use for web fonts'
    }
  })
  .argv;

const fs = require('fs');

//
//  Load the packages needed for MathJax
//
const MathJax = require('mathjax3/mathjax3/mathjax.js').MathJax;
const TeX = require('mathjax3/mathjax3/input/tex.js').TeX;
const CHTML = require('mathjax3/mathjax3/output/chtml.js').CHTML;

require('mathjax3/mathjax3/input/tex/base/BaseConfiguration.js');
require('mathjax3/mathjax3/input/tex/ams/AmsConfiguration.js');
require('mathjax3/mathjax3/input/tex/noundefined/NoUndefinedConfiguration.js');
require('mathjax3/mathjax3/input/tex/newcommand/NewcommandConfiguration.js');
require('mathjax3/mathjax3/input/tex/boldsymbol/BoldsymbolConfiguration.js');

//
//  Load JSDOM
//
const JSDOM = require('jsdom').JSDOM;

//
//  Create DOM adaptor and register it for HTML documents
//
const adaptor = require('mathjax3/mathjax3/adaptors/jsdomAdaptor.js').jsdomAdaptor(JSDOM);
require('mathjax3/mathjax3/handlers/html.js').RegisterHTMLHandler(adaptor);

//
//  Read the HTML file
//
const htmlfile = fs.readFileSync(argv._[0], 'utf8');

//
//  Create input and output jax and a document using them on the content from the HTML file
//
const tex = new TeX({packages: argv.packages.split(/\s*,\s*/)});
const chtml = new CHTML({fontURL: argv.fontURL, exFactor: argv.ex / argv.em});
const html = MathJax.document(htmlfile, {InputJax: tex, OutputJax: chtml});

//
//  Typeset the document
//
html.findMath()
    .compile()
    .getMetrics()
    .typeset()
    .updateDocument();

//
//  Output the resulting HTML
//
console.log(adaptor.outerHTML(adaptor.parent(adaptor.body(html.document))));
pkra commented 6 years ago

Thanks!

The errors in the lite adaptor were due to unescaped &, < and >. That seems expected behavior to me so I won't file a bug unless you prefer otherwise.

dpvc commented 6 years ago

OK, I'll look into the unescaped character issue. It should be fixable.

dpvc commented 6 years ago

PS, can you provide a specific example equation or two?