node-ldapjs/scripts/build-docs.js

132 lines
3.2 KiB
JavaScript
Raw Normal View History

2020-12-13 08:06:45 +00:00
const fs = require('fs/promises')
const path = require('path')
2021-11-13 06:58:00 +00:00
const { marked } = require('marked')
2020-12-13 08:06:45 +00:00
const fm = require('front-matter')
2021-02-24 23:02:30 +00:00
const { highlight } = require('highlight.js')
2021-02-24 22:06:13 +00:00
marked.use({
highlight: (code, lang) => {
2021-02-24 23:02:30 +00:00
if (lang) {
2021-11-13 07:08:01 +00:00
return highlight(code, { language: lang }).value
2021-02-24 22:06:13 +00:00
}
2021-02-24 23:02:30 +00:00
return code
2021-02-24 22:06:13 +00:00
}
})
2020-12-13 08:06:45 +00:00
function tocHTML (toc) {
let html = '<ul>\n'
for (const li of toc) {
html += '<li>\n'
html += `<div>\n<a href="#${li.slug}">${li.text}</a>\n</div>\n`
if (li.children && li.children.length > 0) {
html += tocHTML(li.children)
}
html += '</li>\n'
}
html += '</ul>\n'
return html
}
function markdownTOC (markdown) {
const tokens = marked.lexer(markdown)
const slugger = new marked.Slugger()
const toc = []
let currentHeading
let ignoreFirst = true
for (const token of tokens) {
if (token.type === 'heading') {
if (token.depth === 1) {
if (ignoreFirst) {
ignoreFirst = false
continue
}
currentHeading = {
text: token.text,
slug: slugger.slug(token.text),
children: []
}
toc.push(currentHeading)
} else if (token.depth === 2) {
if (!currentHeading) {
continue
}
currentHeading.children.push({
text: token.text,
slug: slugger.slug(token.text)
})
}
}
}
return {
toc: tocHTML(toc),
html: marked.parser(tokens)
}
}
2021-02-25 07:31:26 +00:00
function createHTML (template, text) {
2020-12-13 08:06:45 +00:00
const { attributes, body } = fm(text)
const { toc, html } = markdownTOC(body)
2021-02-25 07:31:26 +00:00
attributes.toc_html = toc
attributes.content = html
for (const prop in attributes) {
template = template.replace(new RegExp(`%\\(${prop}\\)s`, 'ig'), attributes[prop])
}
2020-12-13 08:06:45 +00:00
2021-02-25 07:31:26 +00:00
return template
}
2020-12-13 08:06:45 +00:00
2021-02-25 07:31:26 +00:00
async function copyRecursive (src, dest) {
const stats = await fs.stat(src)
const isDirectory = stats.isDirectory()
if (isDirectory) {
await fs.mkdir(dest)
const files = await fs.readdir(src)
for (const file of files) {
await copyRecursive(path.join(src, file), path.join(dest, file))
}
} else {
await fs.copyFile(src, dest)
}
2020-12-13 08:06:45 +00:00
}
async function createDocs () {
2020-12-13 16:58:24 +00:00
const docs = path.resolve(__dirname, '..', 'docs')
const dist = path.resolve(__dirname, '..', 'public')
2020-12-13 18:26:13 +00:00
const branding = path.join(docs, 'branding')
2021-02-25 07:31:26 +00:00
const src = path.join(branding, 'public')
2020-12-13 08:06:45 +00:00
2021-11-13 07:08:01 +00:00
try {
await fs.rm(dist, { recursive: true })
} catch (ex) {
if (ex.code !== 'ENOENT') {
throw ex
}
}
2021-02-25 07:31:26 +00:00
await copyRecursive(src, dist)
const highlightjsStyles = path.resolve(__dirname, '..', 'node_modules', 'highlight.js', 'styles')
await fs.copyFile(path.join(highlightjsStyles, 'default.css'), path.join(dist, 'media', 'css', 'highlight.css'))
2020-12-13 08:06:45 +00:00
2021-02-25 07:31:26 +00:00
const template = await fs.readFile(path.join(branding, 'template.html'), { encoding: 'utf8' })
2020-12-13 08:06:45 +00:00
const files = await fs.readdir(docs)
for (const file of files) {
if (!file.endsWith('.md')) {
continue
}
const text = await fs.readFile(path.join(docs, file), { encoding: 'utf8' })
2021-02-25 07:31:26 +00:00
const html = createHTML(template, text)
2020-12-13 08:06:45 +00:00
await fs.writeFile(path.join(dist, file.replace(/md$/, 'html')), html)
}
}
2020-12-13 16:58:24 +00:00
createDocs().catch(ex => {
console.error(ex)
2021-02-25 07:31:26 +00:00
process.exitCode = 1
2020-12-13 16:58:24 +00:00
})