build.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* global marked */
  2. import '../marked.min.js';
  3. import { promises } from 'fs';
  4. import { join, dirname, parse, format } from 'path';
  5. import { markedHighlight } from 'marked-highlight';
  6. import { HighlightJS } from 'highlight.js';
  7. import titleize from 'titleize';
  8. const { mkdir, rm, readdir, stat, readFile, writeFile, copyFile } = promises;
  9. const { highlight, highlightAuto } = HighlightJS;
  10. const cwd = process.cwd();
  11. const inputDir = join(cwd, 'docs');
  12. const outputDir = join(cwd, 'public');
  13. const templateFile = join(inputDir, '_document.html');
  14. const isUppercase = str => /[A-Z_]+/.test(str);
  15. const getTitle = str => str === 'INDEX' ? '' : titleize(str.replace(/_/g, ' ')) + ' - ';
  16. const markedInstance = new marked.Marked(markedHighlight((code, language) => {
  17. if (!language) {
  18. return highlightAuto(code).value;
  19. }
  20. return highlight(code, { language }).value;
  21. }));
  22. async function init() {
  23. console.log('Cleaning up output directory ' + outputDir);
  24. await rm(outputDir, { force: true, recursive: true });
  25. await mkdir(outputDir);
  26. console.log(`Copying file ${join(inputDir, 'LICENSE.md')}`);
  27. await copyFile(join(cwd, 'LICENSE.md'), join(inputDir, 'LICENSE.md'));
  28. console.log(`Copying file ${join(outputDir, 'marked.min.js')}`);
  29. await copyFile(join(cwd, 'marked.min.js'), join(outputDir, 'marked.min.js'));
  30. const tmpl = await readFile(templateFile, 'utf8');
  31. console.log('Building markdown...');
  32. await build(inputDir, tmpl);
  33. console.log('Build complete!');
  34. }
  35. const ignoredFiles = [
  36. join(cwd, 'docs', 'build.js'),
  37. join(cwd, 'docs', '.eslintrc.json'),
  38. join(cwd, 'docs', '_document.html'),
  39. ];
  40. async function build(currentDir, tmpl) {
  41. const files = await readdir(currentDir);
  42. for (const file of files) {
  43. const filename = join(currentDir, file);
  44. if (ignoredFiles.includes(filename)) {
  45. continue;
  46. }
  47. const stats = await stat(filename);
  48. const { mode } = stats;
  49. if (stats.isDirectory()) {
  50. await build(filename, tmpl);
  51. } else {
  52. let html = await readFile(filename, 'utf8');
  53. const parsed = parse(filename);
  54. if (parsed.ext === '.md' && isUppercase(parsed.name)) {
  55. const mdHtml = markedInstance.parse(html);
  56. html = tmpl
  57. .replace('<!--{{title}}-->', getTitle(parsed.name))
  58. .replace('<!--{{content}}-->', mdHtml);
  59. parsed.ext = '.html';
  60. parsed.name = parsed.name.toLowerCase();
  61. delete parsed.base;
  62. }
  63. parsed.dir = parsed.dir.replace(inputDir, outputDir);
  64. const outfile = format(parsed);
  65. await mkdir(dirname(outfile), { recursive: true });
  66. console.log('Writing file ' + outfile);
  67. await writeFile(outfile, html, { mode });
  68. }
  69. }
  70. }
  71. init().catch(console.error);