systems-obscure/scripts/generate-post-index.js

71 lines
1.7 KiB
JavaScript

import fs from "fs"
import matter from "gray-matter"
import { marked } from "marked"
import { createHighlighter } from "shiki"
import { transformerColorizedBrackets } from "@shikijs/colorized-brackets"
import { processBlogImages } from "./process-blog-imgs.js"
import { transformImagePaths } from "./transform-img-paths.js"
const renderer = {
image({ href, text }) {
return `<figure><img src=${href} /><figcaption>${text}</figcaption></figure>`
},
}
const highlighter = await createHighlighter({
themes: ["dark-plus"],
langs: [
"javascript",
"typescript",
"jsx",
"tsx",
"html",
"css",
"json",
"markdown",
"bash",
"python",
"yaml",
],
})
// Copy blog images to /public and compress
processBlogImages()
const files = fs.readdirSync("posts").filter((x) => x.endsWith(".md"))
const posts = files.map((file) => {
const raw = fs.readFileSync(`posts/${file}`, "utf8")
const { data, content: markdown } = matter(raw)
// Convert img urls to source from /public whilst markdown
const transformedMarkdown = transformImagePaths(markdown)
// Appy syntax highlighting
let html = transformedMarkdown.replace(
/```(\w+)?\n([\s\S]*?)```/g,
(match, lang, code) => {
return highlighter.codeToHtml(code.trim(), {
lang: lang || "text",
theme: "dark-plus",
transformers: [transformerColorizedBrackets()],
})
}
)
// Convert img tags to figure tags
marked.use({ renderer })
console.info(`Processing ${file}...`)
return {
slug: file.replace(".md", ""),
title: data.title,
date: data.date,
tags: data.tags,
html: marked(html),
}
})
fs.writeFileSync("./public/post-index.json", JSON.stringify(posts, null, 2))
console.info(`✅ Generated ${posts.length} posts.`)