Skip to content
Permalink
Browse files
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.
  • Loading branch information
ethomson authored and isaacs committed Oct 23, 2020
1 parent 09d40b3 commit aec77acf886d73f85e747cafdf7a2b360befba16
Showing with 2,259 additions and 57,826 deletions.
  1. +1 −2 .gitignore
  2. +2 −3 Makefile
  3. +0 −22 docs/LICENSE
  4. +5 −0 docs/config.json
  5. +160 −0 docs/dockhand.js
  6. +0 −8 docs/gatsby-browser.js
  7. +0 −96 docs/gatsby-config.js
  8. +0 −43 docs/gatsby-node.js
  9. +0 −6 docs/gatsby-ssr.js
  10. +1,948 −47,876 docs/package-lock.json
  11. +7 −35 docs/package.json
  12. +0 −57 docs/src/components/Accordion.js
  13. +0 −22 docs/src/components/Button.js
  14. +0 −72 docs/src/components/DocLinks.js
  15. +0 −25 docs/src/components/FoundTypo.js
  16. +0 −33 docs/src/components/MobileSidebar.js
  17. +0 −30 docs/src/components/Sidebar.js
  18. +0 −40 docs/src/components/home/DarkBlock.js
  19. +0 −39 docs/src/components/home/FeatureCard.js
  20. +0 −83 docs/src/components/home/Features.js
  21. +0 −29 docs/src/components/home/Footer.js
  22. +0 −120 docs/src/components/home/Terminal.js
  23. +0 −73 docs/src/components/home/Windows.js
  24. +0 −101 docs/src/components/home/cubes.js
  25. +0 −25 docs/src/components/home/hero.js
  26. +0 −24 docs/src/components/layout.js
  27. +0 −50 docs/src/components/links.js
  28. +0 −136 docs/src/components/navbar.js
  29. +0 −27 docs/src/components/scripts.js
  30. +0 −88 docs/src/components/seo.js
  31. +0 −2,782 docs/src/images/background-boxes.svg
  32. +0 −2,767 docs/src/images/background-cubes.svg
  33. +0 −1 docs/src/images/background-rectangles.svg
  34. +0 −1 docs/src/images/bracket.svg
  35. +0 −1 docs/src/images/cli-logo.svg
  36. +0 −1 docs/src/images/down-carrot.svg
  37. +0 −1 docs/src/images/hamburger-close.svg
  38. +0 −1 docs/src/images/hamburger.svg
  39. +0 −1 docs/src/images/manager-icon.svg
  40. +0 −1 docs/src/images/network-icon.svg
  41. BIN docs/src/images/npm-icon.png
  42. +0 −1 docs/src/images/orange-cube.svg
  43. +0 −1 docs/src/images/pink-gradient-cube.svg
  44. +0 −1 docs/src/images/purple-cube.svg
  45. +0 −1 docs/src/images/purple-gradient-cube.svg
  46. +0 −1 docs/src/images/red-cube.svg
  47. +0 −2,809 docs/src/images/right-shadow-box.svg
  48. +0 −1 docs/src/images/terminal-icon.svg
  49. +0 −1 docs/src/images/test-icon.svg
  50. +0 −1 docs/src/images/up-carrot.svg
  51. +0 −1 docs/src/images/x.svg
  52. +0 −167 docs/src/main.css
  53. +0 −12 docs/src/pages/404.js
  54. +0 −16 docs/src/pages/index.js
  55. +0 −40 docs/src/templates/Page.js
  56. +0 −50 docs/src/theme.js
  57. +135 −0 docs/template.html
  58. +1 −1 lib/help.js
@@ -7,8 +7,7 @@ npm-debug.log
/test/packages/test-package/random-data.txt
/test/root
/node_modules/.bin
/docs/public/
/docs/.cache/
/docs/output/
/docs/node_modules/
/man/
/npmrc
@@ -49,8 +49,7 @@ mandocs: $(mandocs)

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

docs: mandocs htmldocs

@@ -67,7 +66,7 @@ docs-clean:
.building_marked-man \
man \
docs/node_modules \
docs/public \
docs/output \
docs/.cache

## build-time tools for the documentation

This file was deleted.

@@ -0,0 +1,5 @@
{
"github_repo": "npm/cli",
"github_branch": "latest",
"github_path": "docs/content"
}
@@ -0,0 +1,160 @@
#!/usr/bin/env node

const path = require('path');
const fs = require('fs');
const yaml = require('yaml');
const cmark = require('cmark-gfm');
const mkdirp = require('mkdirp');
const jsdom = require('jsdom');
const npm = require('../lib/npm.js')

const config = require('./config.json');

const docsRoot = __dirname;
const inputRoot = path.join(docsRoot, 'content');
const outputRoot = path.join(docsRoot, 'output');

const template = fs.readFileSync('template.html').toString();

walk(inputRoot);

function walk(root, dirRelative) {
const dirPath = dirRelative ? path.join(root, dirRelative) : root;

fs.readdirSync(dirPath).forEach((childFilename) => {
const childRelative = dirRelative ? path.join(dirRelative, childFilename) : childFilename;
const childPath = path.join(root, childRelative);

if (fs.lstatSync(childPath).isDirectory()) {
walk(root, childRelative);
}
else {
translate(childRelative);
}
});
}

function translate(childPath) {
const inputPath = path.join(inputRoot, childPath);

if (!inputPath.match(/\.md$/)) {
console.log(`warning: unknown file type ${inputPath}, ignored`);
return;
}

const outputPath = path.join(outputRoot, childPath.replace(/\.md$/, '.html'));

let md = fs.readFileSync(inputPath).toString();
let frontmatter = { };

// Take the leading frontmatter out of the markdown
md = md.replace(/^---\n([\s\S]+)\n---\n/, (header, fm) => {
frontmatter = yaml.parse(fm, 'utf8');
return '';
});

// Replace any tokens in the source
md = md.replace(/@VERSION@/, npm.version);

// Render the markdown into an HTML snippet using a GFM renderer.
const content = cmark.renderHtmlSync(md, {
'smart': true,
'githubPreLang': true,
'strikethroughDoubleTilde': true,
'unsafe': false,
extensions: {
'table': true,
'strikethrough': true,
'tagfilter': true,
'autolink': true
}
});

// Inject this data into the template, using a mustache-like
// replacement scheme.
const html = template.replace(/\{\{\s*([\w\.]+)\s*\}\}/g, (token, key) => {
switch (key) {
case 'content':
return content;
case 'path':
return childPath;
case 'url_path':
return encodeURI(childPath);

case 'title':
case 'section':
case 'description':
return frontmatter[key];

case 'config.github_repo':
case 'config.github_branch':
case 'config.github_path':
return config[key.replace(/^config\./, '')];

default:
console.log(`warning: unknown token '${token}' in ${inputPath}`);
return '';
}
console.log(key);
return key;
});

const dom = new jsdom.JSDOM(html);
const document = dom.window.document;

// Rewrite relative URLs in links and image sources to be relative to
// this file; this is for supporting `file://` links. HTML pages need
// suffix appended.
const links = [
{ tag: 'a', attr: 'href', suffix: '.html' },
{ tag: 'img', attr: 'src' }
];

for (let linktype of links) {
for (let tag of document.querySelectorAll(linktype.tag)) {
let url = tag.getAttribute(linktype.attr);

if (url.startsWith('/')) {
const childDepth = childPath.split('/').length - 1;
const prefix = childDepth > 0 ? '../'.repeat(childDepth) : './';

url = url.replace(/^\//, prefix);

if (linktype.suffix) {
url += linktype.suffix;
}

tag.setAttribute(linktype.attr, url);
}
}
}

// Give headers a unique id so that they can be linked within the doc
const headerIds = [ ];
for (let header of document.querySelectorAll('h1, h2, h3, h4, h5, h6')) {
if (header.getAttribute('id')) {
headerIds.push(header.getAttribute('id'));
continue;
}

const headerText = header.textContent.replace(/[A-Z]/g, x => x.toLowerCase()).replace(/ /g, '-').replace(/[^a-z0-9\-]/g, '');
let headerId = headerText;
let headerIncrement = 1;

while (headerIds.includes(headerId)) {
headerId = headerText + (++headerIncrement);
}

headerIds.push(headerId);
header.setAttribute('id', headerId);
}

const output = dom.serialize();

mkdirp.sync(path.dirname(outputPath));
fs.writeFileSync(outputPath, output);
}

function debug(str) {
console.log(str);
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit aec77ac

Please sign in to comment.