UNPKG

apos-docs

Version:

Documentation static site generator built with Eleventy.

205 lines (168 loc) 5.82 kB
const fs = require("fs"); const htmlmin = require('html-minifier'); const markdownIt = require('markdown-it'); const yaml = require('js-yaml'); const { parseDocument } = require('htmlparser2'); const domutils = require('domutils'); const site = require('./docs/_data/site.json') let config = { ...(process.env.ELEVENTY_PRODUCTION && site.pathPrefix && { pathPrefix: site.pathPrefix }), dir: { input: 'docs', includes: '../_includes', }, markdownTemplateEngine: false, } let version = String(Date.now()); module.exports = eleventyConfig => { eleventyConfig.setUseGitIgnore(false); eleventyConfig.addPassthroughCopy("./docs/**/*.{jpg,png,gif}"); // The stylesheet is read straight from disk by the cssinject transform, so eleventy // doesn't know it's a dependency. eleventyConfig.addWatchTarget("./styles/"); eleventyConfig.addFilter('version', value => `${value}?v=${version}`); eleventyConfig.addFilter('pageurlrewrite', value => { let isREADME = new RegExp('readme/$', 'i'); if (isREADME.test(value)) { return value.replace(isREADME, ""); } return value; }); eleventyConfig.addFilter('pagetitle', content => { let root = parseDocument(content); let h1 = domutils.findOne(e => e.tagName === 'h1', root.children); let pageTitle = site.title; if (h1) { let currentTitle = domutils.textContent(h1); // Useful on the home page. Don't want "apos-docs - apos-docs" if (currentTitle !== site.title) { pageTitle = `${currentTitle} - ${site.title}`; } } return pageTitle; }); eleventyConfig.addFilter('pagedescription', content => { let root = parseDocument(content); let p = domutils.findOne(e => e.tagName === 'p', root.children); let pageDescription = site.description; if (p) { pageDescription = domutils.textContent(p); } return pageDescription; }); eleventyConfig.addFilter('toc', function(content) { let root = parseDocument(content); var tags = ['h2', 'h3', 'h4']; let isCHANGELOG = new RegExp('changelog/$', 'i'); if (isCHANGELOG.test(this.page.url)) { tags = ['h2']; } let h = domutils.findAll(e => tags.some(t => e.tagName == t), root.children); let prev = [{ tagName: 'h1', href: '', title: '', children: [] }]; for (let e of h) { while (e.tagName <= prev[prev.length - 1].tagName) { prev.pop(); } let newChild = { tagName: e.tagName, href: `#${e.attribs.id}`, title: domutils.textContent(e), children: [] }; prev[prev.length - 1].children.push(newChild) prev.push(newChild); } return prev[0].children; }); eleventyConfig.addFilter('edit', value => { let isMainReadme = new RegExp(`^\./${config.dir.input}/README.md$`); let isChangelog = new RegExp(`^\./${config.dir.input}/changelog.md$`); if (isMainReadme.test(value)) { value = 'README.md' } else if (isChangelog.test(value)) { value = 'CHANGELOG.md' } return new URL(value, site.repo); }); eleventyConfig.addDataExtension("yml", contents => yaml.load(contents)); eleventyConfig.addCollection('readme', collection => collection.getAllSorted().map(page => { if (page.fileSlug === 'README') { page.url = page.url.replace('/README', ''); page.outputPath = page.outputPath.replace('/README', ''); } }) ); eleventyConfig.addGlobalData("eleventyComputed.permalink", () => { return data => { if (data.page.fileSlug.endsWith('.draft')) { return false; } return data.permalink; } }); eleventyConfig.addGlobalData("eleventyComputed.eleventyExcludeFromCollections", () => { return data => { if (data.page.fileSlug.endsWith('.draft')) { return true; } return data.eleventyExcludeFromCollections; } }); let options = { html: true, breaks: true, linkify: false, typographer: true, }; let md = markdownIt(options); md.use(require('markdown-it-anchor'), { tabIndex: false }); md.use(require('markdown-it-emoji')); md.use(require('markdown-it-footnote')); md.use(require('markdown-it-sub')); md.use(require('markdown-it-sup')); md.use(require('./_plugins/prism')) md.use(require('./_plugins/link'), { eleventyConfig, config, site }) md.use(require('./_plugins/admonition')) md.use(require('./_plugins/imagerow')) eleventyConfig.setLibrary("md", md); eleventyConfig.addTransform('cssinject', async (content, outputPath) => { if (outputPath && outputPath.endsWith('.html')) { const postcss = require('postcss') let css = fs.readFileSync('styles/index.css') await postcss([ require('@tailwindcss/postcss')({ optimize: { minify: !!process.env.ELEVENTY_PRODUCTION } }), ]) .process(css, { from: 'styles/index.css', document: content }) .then(result => { const reCSS = new RegExp('<link rel="stylesheet" href="/index.css">') const code = `<style type="text/css">\n${result.css}\n</style>` content = content.replace(reCSS, (_) => code) }) } return content }) eleventyConfig.addTransform('htmlmin', (content, outputPath) => { if (process.env.ELEVENTY_PRODUCTION && outputPath && outputPath.endsWith('.html')) { return htmlmin.minify(content, { // minifyCSS: true, collapseBooleanAttributes: true, collapseInlineTagWhitespace: false, collapseWhitespace: true, decodeEntities: true, removeComments: true, removeEmptyAttributes: true, sortAttributes: true, sortClassName: true, useShortDoctype: true, }); } return content; }); return config; };