• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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