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 `
${text}
` }, } const highlighter = await createHighlighter({ themes: ["github-dark-dimmed"], 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: "github-dark-dimmed", 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.`)