tools: build all.html by combining generated HTML
Combine the toc and api contents from the generated doc/api/*.html files. This ensures that the single page version of the documentation exactly matches the individual pages. PR-URL: https://github.com/nodejs/node/pull/21568 Fixes: https://github.com/nodejs/node/issues/20100 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
This commit is contained in:
parent
a27b0a35bd
commit
f85962fe4d
8
Makefile
8
Makefile
@ -650,12 +650,16 @@ gen-json = tools/doc/generate.js --format=json $< > $@
|
|||||||
gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html \
|
gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html \
|
||||||
--analytics=$(DOCS_ANALYTICS) $< > $@
|
--analytics=$(DOCS_ANALYTICS) $< > $@
|
||||||
|
|
||||||
out/doc/api/%.json: doc/api/%.md
|
out/doc/api/%.json: doc/api/%.md tools/doc/generate.js tools/doc/json.js
|
||||||
$(call available-node, $(gen-json))
|
$(call available-node, $(gen-json))
|
||||||
|
|
||||||
out/doc/api/%.html: doc/api/%.md
|
out/doc/api/%.html: doc/api/%.md tools/doc/generate.js tools/doc/html.js
|
||||||
$(call available-node, $(gen-html))
|
$(call available-node, $(gen-html))
|
||||||
|
|
||||||
|
out/doc/api/all.html: $(filter-out out/doc/api/all.html, $(apidocs_html)) \
|
||||||
|
tools/doc/allhtml.js
|
||||||
|
$(call available-node, tools/doc/allhtml.js)
|
||||||
|
|
||||||
.PHONY: docopen
|
.PHONY: docopen
|
||||||
docopen: $(apidocs_html)
|
docopen: $(apidocs_html)
|
||||||
@$(PYTHON) -mwebbrowser file://$(PWD)/out/doc/api/all.html
|
@$(PYTHON) -mwebbrowser file://$(PWD)/out/doc/api/all.html
|
||||||
|
73
tools/doc/allhtml.js
Normal file
73
tools/doc/allhtml.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Build all.html by combining the generated toc and apicontent from each
|
||||||
|
// of the generated html files.
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const source = `${__dirname}/../../out/doc/api`;
|
||||||
|
|
||||||
|
// Get a list of generated API documents.
|
||||||
|
const htmlFiles = fs.readdirSync(source, 'utf8')
|
||||||
|
.filter((name) => name.includes('.html') && name !== 'all.html');
|
||||||
|
|
||||||
|
// Read the table of contents.
|
||||||
|
const toc = fs.readFileSync(source + '/_toc.html', 'utf8');
|
||||||
|
|
||||||
|
// Extract (and concatenate) the toc and apicontent from each document.
|
||||||
|
let contents = '';
|
||||||
|
let apicontent = '';
|
||||||
|
|
||||||
|
// Identify files that should be skipped. As files are processed, they
|
||||||
|
// are added to this list to prevent dupes.
|
||||||
|
const seen = {
|
||||||
|
'all.html': true,
|
||||||
|
'index.html': true
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const link of toc.match(/<a.*?>/g)) {
|
||||||
|
const href = /href="(.*?)"/.exec(link)[1];
|
||||||
|
if (!htmlFiles.includes(href) || seen[href]) continue;
|
||||||
|
const data = fs.readFileSync(source + '/' + href, 'utf8');
|
||||||
|
|
||||||
|
// Split the doc.
|
||||||
|
const match = /(<\/ul>\s*)?<\/div>\s*<div id="apicontent">/.exec(data);
|
||||||
|
|
||||||
|
contents += data.slice(0, match.index)
|
||||||
|
.replace(/[\s\S]*?<div id="toc">\s*<h2>.*?<\/h2>\s*(<ul>\s*)?/, '');
|
||||||
|
|
||||||
|
apicontent += data.slice(match.index + match[0].length)
|
||||||
|
.replace(/(<\/div>\s*)*\s*<script[\s\S]*/, '')
|
||||||
|
.replace(/<a href="(\w[^#"]*)#/g, (match, href) => {
|
||||||
|
return htmlFiles.includes(href) ? '<a href="#' : match;
|
||||||
|
})
|
||||||
|
.trim() + '\n';
|
||||||
|
|
||||||
|
// Mark source as seen.
|
||||||
|
seen[href] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace various mentions of _toc with all.
|
||||||
|
let all = toc.replace(/_toc\.html/g, 'all.html')
|
||||||
|
.replace('_toc.json', 'all.json')
|
||||||
|
.replace('api-section-_toc', 'api-section-all')
|
||||||
|
.replace('data-id="_toc"', 'data-id="all"');
|
||||||
|
|
||||||
|
// Clean up the title.
|
||||||
|
all = all.replace(/<title>.*?\| /, '<title>');
|
||||||
|
|
||||||
|
// Insert the combined table of contents.
|
||||||
|
const tocStart = /<div id="toc">\s*<h2>.*?<\/h2>\s*/.exec(all);
|
||||||
|
all = all.slice(0, tocStart.index + tocStart[0].length) +
|
||||||
|
'<ul>\n' + contents + '</ul>\n' +
|
||||||
|
all.slice(tocStart.index + tocStart[0].length);
|
||||||
|
|
||||||
|
// Replace apicontent with the concatenated set of apicontents from each source.
|
||||||
|
const apiStart = /<div id="apicontent">\s*/.exec(all);
|
||||||
|
const apiEnd = /(\s*<\/div>)*\s*<script /.exec(all);
|
||||||
|
all = all.slice(0, apiStart.index + apiStart[0].length) +
|
||||||
|
apicontent +
|
||||||
|
all.slice(apiEnd.index);
|
||||||
|
|
||||||
|
// Write results.
|
||||||
|
fs.writeFileSync(source + '/all.html', all, 'utf8');
|
Loading…
x
Reference in New Issue
Block a user