www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

run-mathjax-offline.node.js (5094B)


      1 // DO NOT run this on arbitrary unknown directory structures, as it evals the contents of the (user-provided) default.js configuration file.
      2 const fs = require('fs');
      3 const mjAPI = require('mathjax-node');
      4 const jsdom = require('jsdom');
      5 
      6 // Dynamically load the original MathJax config from …/MathJax/config/default.js
      7 mjAPI.config({
      8   fontURL: 'MathJax/fonts/HTML-CSS/',
      9   MathJax: (function() {
     10     var cfg = {};
     11     var MathJax = {
     12       Hub: {
     13         Config: function(c) { cfg = c; }
     14       },
     15       Ajax: {
     16         loadComplete: function() { return; }
     17       }
     18     };
     19     cfgbytes = fs.readFileSync('doc/phc-thesis/MathJax/config/default.js');
     20     eval(cfgbytes + '');
     21     return cfg;
     22   })(),
     23 });
     24 
     25 jsdom.env('doc/phc-thesis/index.html', function(err, window) {
     26   var getmath = function () {
     27     var m = window.document.getElementsByClassName('math');
     28     var mm = [];
     29     for (var i = 0; i < m.length; i++) {
     30       mm[i] = m.item(i);
     31     }
     32     return mm;
     33   };
     34   var mm = getmath();
     35   var addedCSS = [];
     36   var processMathElement = function(i) {
     37     if (i >= mm.length) {
     38       process.stdout.write('\nSaving modified HTML file…\n');
     39       fs.writeFileSync('doc/phc-thesis/index2.html', jsdom.serializeDocument(window.document));
     40       return;
     41     } else {
     42       process.stdout.write((i+1)+'/'+mm.length+' '+(mm[i].tagName.toLowerCase() == 'div' ? 'display' : 'inline ')+'\r');
     43       mjAPI.typeset({
     44         math: mm[i].textContent,
     45         format: (mm[i].tagName.toLowerCase() == 'div' ? 'TeX' : 'inline-TeX'),
     46         htmlNode: true,
     47         css: true,
     48       }, function(result) {
     49         if (result.errors) {
     50           console.log(mm[i].textContent);
     51           process.exit(1);
     52         } else {
     53           // mark the initial element as hidden
     54           mm[i].classList.add('math-initial-hidden');
     55 
     56           // Add the CSS to the document
     57           if (addedCSS.indexOf(result.css) == -1){
     58             addedCSS.push(result.css);
     59             // Inject font-display: block; to prevent the browsers from stalling while applying fonts each time a new one is loaded.
     60             var css = result.css.split('@font-face {').join('@font-face {font-display: block; ');
     61             var styleElt = window.document.createElement('style');
     62             styleElt.setAttribute('type', 'text/css');
     63             var styleTxt = window.document.createTextNode(css);
     64             styleElt.appendChild(styleTxt);
     65             window.document.head.appendChild(styleElt);
     66           }
     67           
     68           // wrap the generated element in a class="MathJax_Preview" node
     69           preview = window.document.createElement((mm[i].tagName.toLowerCase() == 'div' ? 'div' : 'span'));
     70           preview.setAttribute('class', 'MathJax_Preview');
     71           preview.appendChild(result.htmlNode);
     72           mm[i].parentNode.insertBefore(preview, mm[i]);
     73           //console.log(result.htmlNode);
     74           processMathElement(i+1);
     75         }
     76       });
     77     }
     78   };
     79   // Remove the script which loads MathJax automatically, as it slows down things a lot when it re-renders the math.
     80   var scriptsInHead = window.document.head.getElementsByTagName('script');
     81   for (var i = 0; i < scriptsInHead.length; i++) {
     82     var e = scriptsInHead.item(i);
     83     if (e.innerHTML.trim() == decodeURI("(function()%20%7Bdocument.write('%3Cscr'%20+%20'ipt%20type=%22text/javascript%22%20src=%22MathJax/MathJax.js?config=default%22%3E%3C/scr'%20+%20'ipt%3E');%7D)();")) {
     84       e.parentNode.removeChild(e);
     85     }
     86   }
     87   // Fix the font size (mathjax-node cannot know easily the webpage's font size in advance).
     88   var patchFontSizeCode = "(function() { var outer = document.createElement('div'); outer.style.width = '0px'; outer.style.height = '0px'; outer.style.overflow = 'hidden'; var d = document.createElement('div'); /* 1.18rem from scribble's stylesheet, times 118% in the MathJax-generated CSS. */ outer.style.fontSize = (1.18 * 1.18) + 'rem'; d.style.width = '1000em'; outer.appendChild(d); document.body.appendChild(outer); window.setTimeout(function() { var sz = d.clientWidth / 1000; document.body.removeChild(outer); if (sz > 3) { var st = document.createElement('style'); st.appendChild(document.createTextNode('html .mjx-chtml { font-size: '+sz+'px; } html .mjx-chtml .mjx-chtml { font-size: inherit; }')); document.head.appendChild(st); } }, 0)})();";
     89   var patchFontSize = window.document.createElement('script');
     90   patchFontSize.appendChild(window.document.createTextNode(patchFontSizeCode));
     91   patchFontSize.setAttribute('type', 'text/javascript');
     92   window.document.body.insertBefore(patchFontSize, window.document.body.childNodes[0] || null);
     93   
     94   // set the initial <span class="math math-initial-hidden"></span> and <div …></div> elements hidden, as we manually injected a preview.
     95   hidestyle = window.document.createElement('style');
     96   hidestyle.setAttribute('type', 'text/css');
     97   hidestyle.appendChild(window.document.createTextNode('html .math-initial-hidden { display:none; visibility:hidden; } html .MathJax_Preview { color: inherit; }'));
     98   window.document.head.appendChild(hidestyle);
     99   processMathElement(0);
    100 });