chadtmiller.com/knotless
git that lives in your Atmosphere account
7
// What the docs need beyond Markdown: their links, written to read on
// GitHub and in the repository's pages, made the site's; and their
// Mermaid blocks drawn by Pele, as the repository's pages draw them.
import { dirname, join, posix, relative } from 'node:path'
import { fileURLToPath } from 'node:url'
import { render } from 'pele'
const here = dirname(fileURLToPath(import.meta.url))
const content = join(here, 'src/content/docs')
/** Where a file outside docs/ is read: its page on knotless.dev. */
const REPO = 'https://knotless.dev/chadtmiller.com/knotless'
const walk = (node, visit) => {
visit(node)
for (const child of node.children ?? []) walk(child, visit)
}
/** The page a link in `page`, a path under docs/, lands on, as a URL. */
function resolve(page, url, base) {
if (/^[a-z]+:|^#|^\//.test(url)) return url
const [path, anchor] = url.split('#')
const target = posix.normalize(posix.join('docs', posix.dirname(page), path))
const hash = anchor ? `#${anchor}` : ''
if (target.startsWith('docs/') && target.endsWith('.md') && target !== 'docs/design.md') {
const slug = target.slice('docs/'.length).replace(/\.md$/, '').replace(/(^|\/)README$/, '')
return `${base}/${slug ? `${slug.toLowerCase()}/` : ''}${hash}`
}
if (target === 'docs/design.md') return `${base}/design/${hash}`
// A directory has no extension: lexicons/dev/knotless, web.
const kind = posix.extname(target) ? 'blob' : 'tree'
return `${REPO}/${kind}/main/${target}${hash}`
}
/** Links between pages go to the site's pages; links out of docs/, to the repository. */
export function remarkLinks({ base }) {
return (tree, file) => {
const page = relative(content, file.path).replace(/(^|\/)index\.md$/, '$1README.md')
walk(tree, (node) => {
if (node.type === 'link' || node.type === 'definition') node.url = resolve(page, node.url, base)
})
}
}
/** Each ```mermaid block, drawn: an SVG whose colours follow the page's. */
export function remarkMermaid() {
return (tree, file) => {
walk(tree, (node) => {
if (node.type !== 'code' || node.lang !== 'mermaid') return
let svg
try {
;({ svg } = render(node.value))
} catch (e) {
throw new Error(`${file.path}: a diagram does not draw: ${e.message}`)
}
node.type = 'html'
node.value = `<div class="diagram">${svg}</div>`
delete node.lang
delete node.meta
})
}
}