1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
var docFrame;
var logtextbox;
var destFile;
var embedFonts = false;
var finalMathJaxURL = null;
function log(text)
{
logtextbox.setAttribute("value", logtextbox.getAttribute("value") + "\n" + text);
}
function init()
{
try {
docFrame = document.getElementById("docFrame");
logtextbox = document.getElementById("logtextbox");
// parse command line arguments
var cmdLine = window.arguments[0];
cmdLine = cmdLine.QueryInterface(Components.interfaces.nsICommandLine);
embedFonts = cmdLine.handleFlag("embed-fonts", false);
finalMathJaxURL = cmdLine.handleFlagWithParam("final-mathjax-url", false);
if (!embedFonts && !finalMathJaxURL) {
alert("You must eiher specify --embed-fonts or --final-mathjax-url");
window.close();
return;
}
sourceFilePath = cmdLine.getArgument(0);
destFilePath = cmdLine.getArgument(1);
if ( !sourceFilePath || !destFilePath ) {
alert("Not enough parameters, expecting two arguments:\nInput file, output file");
window.close();
return;
}
sourceFile = cmdLine.resolveFile(sourceFilePath);
if (! (sourceFile.exists() && sourceFile.isFile()) ) {
alert("Invalid source file path.");
window.close();
return;
}
sourceURI = cmdLine.resolveURI(sourceFilePath);
// create a nsIFile object for the output file
try{
destFile = cmdLine.resolveURI(destFilePath).QueryInterface(Components.interfaces.nsIFileURL).file;
}catch(e){
alert("Invalid destination file.\n\nException:\n" + e);
window.close();
return;
}
// add iframeLoaded() as an onload event handler, then navigate to the source file
docFrame.addEventListener("DOMContentLoaded", iframeLoaded, true);
docFrame.setAttribute("src", sourceURI.spec);
} catch (e) {
alert("Error in init():\n\n" + e);
window.close();
return;
}
}
function iframeLoaded()
{
/*
// print every MathJax signal to the log
docFrame.contentWindow.MathJax.Hub.Startup.signal.Interest(
function (message) {log("Startup: "+message)}
);
docFrame.contentWindow.MathJax.Hub.signal.Interest(
function (message) {log("Hub: "+message)}
);
*/
// tell MathJax to call serialize() when finished
docFrame.contentWindow.MathJax.Hub.Register.StartupHook("End", function() {serialize();});
}
function fileURLtoDataURI(url)
{
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var url_object = ios.newURI(url, "", null);
var file = url_object.QueryInterface(Components.interfaces.nsIFileURL).file;
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
fstream.init(file, -1, -1, false);
var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
bstream.setInputStream(fstream);
var bytes = bstream.readBytes(bstream.available());
b64bytes = btoa(bytes);
return "data:;base64," + b64bytes;
}
function serialize()
{
var MathJaxURL = docFrame.contentWindow.MathJax.Hub.config.root;
var searchURIList = new Array();
var replacementURIList = new Array();
log("serialize: preprocessing");
// remove the MathJax status message window
msgdiv = docFrame.contentDocument.getElementById("MathJax_Message");
msgdiv.parentNode.removeChild(msgdiv);
/* Loop through all CSS rules to find all @font-face rules.
At this point, they refer to local absolute paths using file:// URLs.
Replace them either with appropriate URLs relative to finalMathJaxURL
or with data URIs. */
for (var i = 0; i<docFrame.contentDocument.styleSheets.length; i++) {
var stylesheet = docFrame.contentDocument.styleSheets[i];
for (var j=0; j< stylesheet.cssRules.length; j++) {
var rule = stylesheet.cssRules[j];
if (rule.cssText.match("font-face")) {
url = rule.style.getPropertyValue("src");
url = url.match(/url\(\"(.+)\"\)/)[1];
// Since the properties seem read-only here, we populate
// searchURIList and replacementURIList to do text substitution
// after serialization
searchURIList.push(url);
if (embedFonts) {
replacementURIList.push(fileURLtoDataURI(url));
} else {
replacementURIList.push(url.replace(MathJaxURL, finalMathJaxURL));
}
}
}
}
// find and remove the MathJax <script> tag
try{
var scriptTags = docFrame.contentDocument.getElementsByTagName("script");
for (var i=0; i<scriptTags.length; i++) {
if (scriptTags[i].getAttribute("src") && scriptTags[i].getAttribute("src").match(/MathJax.js/i))
scriptTags[i].parentNode.removeChild(scriptTags[i]);
}
}catch(e){alert(e);}
log("serialize: serializing");
var serializer = new XMLSerializer();
var xhtml = serializer.serializeToString(docFrame.contentDocument);
log("serialize: postprocessing");
// make the MathJax URL relative again
// xhtml = xhtml.replace(findMathJaxURL, "MathJax");
try{
r1 = RegExp("<!--/\\*--><!\\[CDATA\\[/\\*><!--\\*/", "g");
xhtml = xhtml.replace(r1, "");
r2 = RegExp("/\\*\\]\\]>\\*/-->", "g");
xhtml = xhtml.replace(r2, "");
r3 = RegExp("/\\*\\]\\]>\\*///-->", "g");
xhtml = xhtml.replace(r3, "");
}catch(e){alert(e);}
for (var i=0; i<searchURIList.length; i++)
xhtml = xhtml.replace(searchURIList[i], replacementURIList[i]);
save(xhtml);
window.close();
}
function save(xhtml)
{
try {
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(destFile, 0x02 | 0x08 | 0x20, 0666, 0);
// write, create, truncate
// write in UTF-8 encoding
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(xhtml);
converter.close(); // this closes foStream
} catch (e) {
alert("Error in save():\n\n" + e);
}
}
|