Skip to content

Commit b67ff02

Browse files
committed
docs: use dockhand for static generation
Drop Gatsby, use a simplified custom static site generator that uses GFM and a template for extremely lightweight docs.
1 parent f672a32 commit b67ff02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2239
-57826
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ npm-debug.log
77
/test/packages/test-package/random-data.txt
88
/test/root
99
/node_modules/.bin
10-
/docs/public/
11-
/docs/.cache/
10+
/docs/output/
1211
/docs/node_modules/
1312
/man/
1413
/npmrc

Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ mandocs: $(mandocs)
4949

5050
htmldocs:
5151
cd docs && node ../bin/npm-cli.js install --legacy-peer-deps --no-audit && \
52-
node ../bin/npm-cli.js run build:static >&2 && \
53-
rm -rf node_modules .cache public/*js public/*json public/404* public/page-data public/manifest*
52+
node ../bin/npm-cli.js run build >&2
5453

5554
docs: mandocs htmldocs
5655

@@ -67,7 +66,7 @@ docs-clean:
6766
.building_marked-man \
6867
man \
6968
docs/node_modules \
70-
docs/public \
69+
docs/output \
7170
docs/.cache
7271

7372
## build-time tools for the documentation

docs/LICENSE

Lines changed: 0 additions & 22 deletions
This file was deleted.

docs/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"github_repo": "npm/cli",
3+
"github_branch": "latest",
4+
"github_path": "docs/content"
5+
}

docs/dockhand.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env node
2+
3+
const path = require('path');
4+
const fs = require('fs');
5+
const yaml = require('yaml');
6+
const cmark = require('cmark-gfm');
7+
const mkdirp = require('mkdirp');
8+
const jsdom = require('jsdom');
9+
const npm = require('../lib/npm.js')
10+
11+
const config = require('./config.json');
12+
13+
const docsRoot = __dirname;
14+
const inputRoot = path.join(docsRoot, 'content');
15+
const outputRoot = path.join(docsRoot, 'output');
16+
17+
const template = fs.readFileSync('template.html').toString();
18+
19+
walk(inputRoot);
20+
21+
function walk(root, dirRelative) {
22+
const dirPath = dirRelative ? path.join(root, dirRelative) : root;
23+
24+
fs.readdirSync(dirPath).forEach((childFilename) => {
25+
const childRelative = dirRelative ? path.join(dirRelative, childFilename) : childFilename;
26+
const childPath = path.join(root, childRelative);
27+
28+
if (fs.lstatSync(childPath).isDirectory()) {
29+
walk(root, childRelative);
30+
}
31+
else {
32+
translate(childRelative);
33+
}
34+
});
35+
}
36+
37+
function translate(childPath) {
38+
const inputPath = path.join(inputRoot, childPath);
39+
40+
if (!inputPath.match(/\.md$/)) {
41+
console.log(`warning: unknown file type ${inputPath}, ignored`);
42+
return;
43+
}
44+
45+
const outputPath = path.join(outputRoot, childPath.replace(/\.md$/, '.html'));
46+
47+
let md = fs.readFileSync(inputPath).toString();
48+
let frontmatter = { };
49+
50+
// Take the leading frontmatter out of the markdown
51+
md = md.replace(/^---\n([\s\S]+)\n---\n/, (header, fm) => {
52+
frontmatter = yaml.parse(fm, 'utf8');
53+
return '';
54+
});
55+
56+
// Replace any tokens in the source
57+
md = md.replace(/@VERSION@/, npm.version);
58+
59+
// Render the markdown into an HTML snippet using a GFM renderer.
60+
const content = cmark.renderHtmlSync(md, {
61+
'smart': true,
62+
'githubPreLang': true,
63+
'strikethroughDoubleTilde': true,
64+
'unsafe': false,
65+
extensions: {
66+
'table': true,
67+
'strikethrough': true,
68+
'tagfilter': true,
69+
'autolink': true
70+
}
71+
});
72+
73+
// Inject this data into the template, using a mustache-like
74+
// replacement scheme.
75+
const html = template.replace(/\{\{\s*([\w\.]+)\s*\}\}/g, (token, key) => {
76+
switch (key) {
77+
case 'content':
78+
return content;
79+
case 'path':
80+
return childPath;
81+
case 'url_path':
82+
return encodeURI(childPath);
83+
84+
case 'title':
85+
case 'section':
86+
case 'description':
87+
return frontmatter[key];
88+
89+
case 'config.github_repo':
90+
case 'config.github_branch':
91+
case 'config.github_path':
92+
return config[key.replace(/^config\./, '')];
93+
94+
default:
95+
console.log(`warning: unknown token '${token}' in ${inputPath}`);
96+
return '';
97+
}
98+
console.log(key);
99+
return key;
100+
});
101+
102+
const dom = new jsdom.JSDOM(html);
103+
const document = dom.window.document;
104+
105+
// Rewrite relative URLs in links and image sources to be relative to
106+
// this file; this is for supporting `file://` links. HTML pages need
107+
// suffix appended.
108+
const links = [
109+
{ tag: 'a', attr: 'href', suffix: '.html' },
110+
{ tag: 'img', attr: 'src' }
111+
];
112+
113+
for (let linktype of links) {
114+
for (let tag of document.querySelectorAll(linktype.tag)) {
115+
let url = tag.getAttribute(linktype.attr);
116+
117+
if (url.startsWith('/')) {
118+
const childDepth = childPath.split('/').length - 1;
119+
const prefix = childDepth > 0 ? '../'.repeat(childDepth) : './';
120+
121+
url = url.replace(/^\//, prefix);
122+
123+
if (linktype.suffix) {
124+
url += linktype.suffix;
125+
}
126+
127+
tag.setAttribute(linktype.attr, url);
128+
}
129+
}
130+
}
131+
132+
const output = dom.serialize();
133+
134+
mkdirp.sync(path.dirname(outputPath));
135+
fs.writeFileSync(outputPath, output);
136+
}
137+
138+
function debug(str) {
139+
console.log(str);
140+
}

docs/gatsby-browser.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

docs/gatsby-config.js

Lines changed: 0 additions & 96 deletions
This file was deleted.

docs/gatsby-node.js

Lines changed: 0 additions & 43 deletions
This file was deleted.

docs/gatsby-ssr.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)