musings-ssg/index.ts

73 lines
3 KiB
TypeScript
Raw Permalink Normal View History

2025-03-31 21:46:32 -04:00
import { readdir } from "node:fs/promises";
import { join } from "node:path";
import { Converter } from 'showdown';
// Delete everything in output.
const allOutput = await readdir(join(import.meta.dir, "output"))
for (const file of allOutput) {
if (file === "index.css" || file === "page.css") continue;
Bun.file(join(import.meta.dir, "output", file)).delete()
}
// Create Markdown Pages
const allDocs = await readdir(join(import.meta.dir, "docs"))
const MDConvert = new Converter({headerLevelStart: 2, metadata: true})
for await (const doc of allDocs) {
const file = await Bun.file(join(import.meta.dir, "docs", doc)).text()
const format = MDConvert.makeHtml(file)
let style = await Bun.file(join(import.meta.dir, "output-style", "page.html")).text()
const name = MDConvert.getMetadata()["Name"] ? MDConvert.getMetadata()["Name"] : file.match(/# .+/gm)![0].replace("# ", "")
style = style.replaceAll("##NAME##", name).replaceAll("##CATEGORIES##", MDConvert.getMetadata()['Category'])
let divs = ''
const headers = file.matchAll(/^#+ .+/gm)
for await (const header of headers.toArray()) {
const head = header[0].replaceAll("#", "").trim()
if (head === name) continue;
const id = head.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()
divs += `<div class="nav-link-box"><a href="#${id}" class="nav-link">${head}</a></div>`
}
style = style.replace("##NAVLINKS##", divs)
Bun.write(join(import.meta.dir, "output", MDConvert.getMetadata()['Category'], `${name}.html` ), style.replace("##HTML##", format))
}
// Create index page.
const allMDs = await readdir(join(import.meta.dir, "docs"))
const docs = []
for await (const doc of allMDs) {
const file = Bun.file(join(import.meta.dir, "docs", doc))
const text = await file.text()
const params = text.match(/\-\-\-.+\-\-\-/gms)
const shelledInfo = params![0].replace("--- \n", "").replace("\n ---", "")
const lines = shelledInfo.split("\n")
const info: Record<string, string> = {}
for (const line of lines) {
const array = line.trim().split(": ")
// @ts-expect-error idk why it's complaining, but idc right now.
info[array[0]?.toLowerCase()] = array[1]
}
if (!info.name) info.name = text.match(/# .+/gm)![0].replace("# ", "")
docs.push(info)
}
const uniqueCategories = [...new Set(docs.map(item => item.category))];
let html = ``
for (const category of uniqueCategories) {
html += `<div id='${category}' class='sortedcolumn'>
<h2>${category}</h2>
`
const items = docs.filter(item => item.category === category)
items.forEach(item => {
html += `<a href="${category}/${item.name}.html" `
if (item.description) html += `title="${item.description}"`
html += `>${item.name}</a>\n`
})
html += '</div>'
}
const index = await Bun.file(join(import.meta.dir, "output-style", "index.html")).text()
const prepared = index.replace("##CATEGORIES##", html)
Bun.write(join(import.meta.dir, "output", "index.html"), prepared)
console.log(html)