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