1'use strict'; 2 3// Build all.html by combining the generated toc and apicontent from each 4// of the generated html files. 5 6const fs = require('fs'); 7 8const source = `${__dirname}/../../out/doc/api`; 9 10// Get a list of generated API documents. 11const htmlFiles = fs.readdirSync(source, 'utf8') 12 .filter((name) => name.includes('.html') && name !== 'all.html'); 13 14// Read the table of contents. 15const toc = fs.readFileSync(source + '/index.html', 'utf8'); 16 17// Extract (and concatenate) the toc and apicontent from each document. 18let contents = ''; 19let apicontent = ''; 20 21// Identify files that should be skipped. As files are processed, they 22// are added to this list to prevent dupes. 23const seen = { 24 'all.html': true, 25 'index.html': true 26}; 27 28for (const link of toc.match(/<a.*?>/g)) { 29 const href = /href="(.*?)"/.exec(link)[1]; 30 if (!htmlFiles.includes(href) || seen[href]) continue; 31 const data = fs.readFileSync(source + '/' + href, 'utf8'); 32 33 // Split the doc. 34 const match = /(<\/ul>\s*)?<\/div>\s*<div id="apicontent">/.exec(data); 35 36 contents += data.slice(0, match.index) 37 .replace(/[\s\S]*?<div id="toc">\s*<h2>.*?<\/h2>\s*(<ul>\s*)?/, ''); 38 39 apicontent += data.slice(match.index + match[0].length) 40 .replace(/<!-- API END -->[\s\S]*/, '') 41 .replace(/<a href="(\w[^#"]*)#/g, (match, href) => { 42 return htmlFiles.includes(href) ? '<a href="#' : match; 43 }) 44 .trim() + '\n'; 45 46 // Mark source as seen. 47 seen[href] = true; 48} 49 50// Replace various mentions of index with all. 51let all = toc.replace(/index\.html/g, 'all.html') 52 .replace('<a href="all.html">', '<a href="index.html">') 53 .replace('index.json', 'all.json') 54 .replace('api-section-index', 'api-section-all') 55 .replace('data-id="index"', 'data-id="all"') 56 .replace(/<li class="edit_on_github">.*?<\/li>/, ''); 57 58// Clean up the title. 59all = all.replace(/<title>.*?\| /, '<title>'); 60 61// Insert the combined table of contents. 62const tocStart = /<div id="toc">\s*<h2>.*?<\/h2>\s*/.exec(all); 63all = all.slice(0, tocStart.index + tocStart[0].length) + 64 '<ul>\n' + contents + '</ul>\n' + 65 all.slice(tocStart.index + tocStart[0].length); 66 67// Replace apicontent with the concatenated set of apicontents from each source. 68const apiStart = /<div id="apicontent">\s*/.exec(all); 69const apiEnd = all.lastIndexOf('<!-- API END -->'); 70all = all.slice(0, apiStart.index + apiStart[0].length) + 71 apicontent + 72 all.slice(apiEnd); 73 74// Write results. 75fs.writeFileSync(source + '/all.html', all, 'utf8'); 76 77// Validate all hrefs have a target. 78const ids = new Set(); 79const idRe = / id="(\w+)"/g; 80let match; 81while (match = idRe.exec(all)) { 82 ids.add(match[1]); 83} 84 85const hrefRe = / href="#(\w+)"/g; 86while (match = hrefRe.exec(all)) { 87 if (!ids.has(match[1])) throw new Error(`link not found: ${match[1]}`); 88} 89