summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Ruby <rubys@intertwingly.net>2018-06-27 14:14:54 -0400
committerVse Mozhet Byt <vsemozhetbyt@gmail.com>2018-07-02 21:33:30 +0300
commitf85962fe4d3afa55aedcfdab3aa61258c5af3e2a (patch)
tree4f0c7831d7529ed8cafb65bc1e2cd471d11cff7a
parenta27b0a35bde63e8dd03ca591b1cdfbc8cb6ca994 (diff)
downloadandroid-node-v8-f85962fe4d3afa55aedcfdab3aa61258c5af3e2a.tar.gz
android-node-v8-f85962fe4d3afa55aedcfdab3aa61258c5af3e2a.tar.bz2
android-node-v8-f85962fe4d3afa55aedcfdab3aa61258c5af3e2a.zip
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>
-rw-r--r--Makefile8
-rw-r--r--tools/doc/allhtml.js73
2 files changed, 79 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 38bb840674..f407066cf5 100644
--- a/Makefile
+++ b/Makefile
@@ -650,12 +650,16 @@ gen-json = tools/doc/generate.js --format=json $< > $@
gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html \
--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))
-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))
+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
docopen: $(apidocs_html)
@$(PYTHON) -mwebbrowser file://$(PWD)/out/doc/api/all.html
diff --git a/tools/doc/allhtml.js b/tools/doc/allhtml.js
new file mode 100644
index 0000000000..fad530f1c4
--- /dev/null
+++ b/tools/doc/allhtml.js
@@ -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');