import fs from "fs" import path from "path" import matter from "gray-matter" import { remark } from "remark" import html from "remark-html" const postsDirectory = path.join(process.cwd(), "content/posts") export interface PostMeta { slug: string title: string description: string author: string date: string categories: string[] tags: string[] math: boolean mermaid: boolean } export function getAllPostSlugs(): string[] { return fs .readdirSync(postsDirectory) .filter((f) => f.endsWith(".md")) .map((f) => f.replace(/\.md$/, "")) } export function getAllPostsMeta(): PostMeta[] { return getAllPostSlugs() .map((slug) => { const fullPath = path.join(postsDirectory, `${slug}.md`) const { data } = matter(fs.readFileSync(fullPath, "utf8")) return { slug, ...(data as Omit) } }) .sort((a, b) => (a.date < b.date ? 1 : -1)) } export async function getPostBySlug(slug: string) { const fullPath = path.join(postsDirectory, `${slug}.md`) const { data, content } = matter(fs.readFileSync(fullPath, "utf8")) const processedHtml = await remark().use(html).process(content) return { meta: { slug, ...(data as Omit) }, contentHtml: processedHtml.toString(), } } export function getPostsByCategory(category: string): PostMeta[] { return getAllPostsMeta().filter((post) => post.categories.includes(category), ) } export function getPostsByTag(tag: string): PostMeta[] { return getAllPostsMeta().filter((post) => post.tags.includes(tag)) }