1const fs = require("fs").promises; 2const marked = require("marked"); 3const jsdom = require("jsdom"); 4const { JSDOM } = jsdom; 5const path = require("path"); 6 7marked.setOptions({ 8 renderer: new marked.Renderer(), 9 highlight: function (code, forlanguage) { 10 const hljs = require("highlight.js"); 11 language = hljs.getLanguage(forlanguage) ? forlanguage : "plaintext"; 12 return hljs.highlight(code, { language }).value; 13 }, 14 pedantic: false, 15 gfm: true, 16 breaks: false, 17 sanitize: false, 18 smartLists: true, 19 smartypants: false, 20 xhtml: false, 21}); 22 23async function renderit(infile) { 24 console.log(`Reading ${infile}`); 25 basename = path.basename(infile, ".md"); 26 const outfile = path.join(path.dirname(infile), `${basename}.html`); 27 let f1 = await fs.readFile(infile, "utf-8"); 28 // oh the irony 29 if (f1.charCodeAt(0) == 0xfeff) { 30 f1 = f1.substring(3); 31 } 32 33 // render 34 const rawHtml = marked(f1); 35 36 // now fix 37 const dom = new JSDOM(rawHtml); 38 const document = dom.window.document; 39 40 // // setup doctype 41 // if (document.doctype) { 42 // console.log("have a doctype " + document.doctype); 43 // } else { 44 // document.doctype = document.implementation.createDocumentType("html","",""); 45 // document.insertBefore(document.childNodes[0], document.doctype); 46 // } 47 48 const head = dom.window.document.getElementsByTagName("head")[0]; 49 50 // add CSS 51 head.innerHTML = 52 head.innerHTML + 53 `<meta charset="utf-8">` + 54 `<link rel='stylesheet' type='text/css' media='screen' href='../reports-v2.css'>`; 55 56 // Is there a title? 57 if (dom.window.document.getElementsByTagName("title").length >= 1) { 58 console.log("Already had a <title>… not changing."); 59 } else { 60 const title = document.createElement("title"); 61 const first_h1_text = document.getElementsByTagName("h1")[0].textContent.replace(')Part', ') Part'); 62 title.appendChild(document.createTextNode(first_h1_text)) 63 head.appendChild(title); 64 } 65 66 67 // calculate the header object 68 const header = dom.window.document.createElement("div"); 69 header.setAttribute("class", "header"); 70 // taken from prior TRs 71 header.innerHTML = `<table class="header" cellpadding="0" cellspacing="0" width="100%"> 72 <tbody> 73 <tr> 74 <td class="icon"><a href="http://www.unicode.org/"><img style="vertical-align:middle;border:0" alt="[Unicode]" 75 src="http://www.unicode.org/webscripts/logo60s2.gif" 76 height="33" 77 width="34" /></a> <a class="bar" href="http://www.unicode.org/reports/">Technical Reports</a></td> 78 </tr> 79 <tr> 80 <td class="gray"> </td> 81 </tr> 82 </tbody> 83 </table>`; 84 85 // Move all elements out of the top level body and into a subelement 86 const body = dom.window.document.getElementsByTagName("body")[0]; 87 const bp = body.parentNode; 88 div = dom.window.document.createElement("div"); 89 div.setAttribute("class", "body"); 90 let sawFirstTable = false; 91 for (const e of body.childNodes) { 92 body.removeChild(e); 93 if (div.childNodes.length === 0 && e.tagName === 'P') { 94 // update title element to <h2 class="uaxtitle"/> 95 const newTitle = document.createElement('h2'); 96 newTitle.setAttribute("class", "uaxtitle"); 97 newTitle.appendChild(document.createTextNode(e.textContent)); 98 div.appendChild(newTitle); 99 } else { 100 if (!sawFirstTable && e.tagName === 'TABLE') { 101 // Update first table to simple width=90% 102 e.setAttribute("class", "simple"); 103 e.setAttribute("width", "90%"); 104 sawFirstTable = true; 105 } 106 div.appendChild(e); 107 } 108 } 109 body.appendChild(header); 110 body.appendChild(div); 111 112 // now, fix all links from ….md#… to ….html#… 113 for (const e of dom.window.document.getElementsByTagName("a")) { 114 const href = e.getAttribute("href"); 115 let m; 116 if ((m = /^(.*)\.md#(.*)$/.exec(href))) { 117 e.setAttribute("href", `${m[1]}.html#${m[2]}`); 118 } else if ((m = /^(.*)\.md$/.exec(href))) { 119 e.setAttribute("href", `${m[1]}.html`); 120 } 121 } 122 123 // OK, done munging the DOM, write it out. 124 console.log(`Writing ${outfile}`); 125 // TODO: assume that DOCTYPE is not written. 126 await fs.writeFile(outfile, `<!DOCTYPE html>\n` + dom.serialize()); 127 return outfile; 128} 129 130async function fixall() { 131 outbox = "./dist"; 132 133 // TODO: move source file copy into JavaScript? 134 // srcbox = '../../../docs/ldml'; 135 136 const fileList = (await fs.readdir(outbox)) 137 .filter((f) => /\.md$/.test(f)) 138 .map((f) => path.join(outbox, f)); 139 return Promise.all(fileList.map(renderit)); 140} 141 142fixall().then( 143 (x) => console.dir(x), 144 (e) => { 145 console.error(e); 146 process.exitCode = 1; 147 } 148); 149