57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
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<PostMeta, "slug">) }
|
|
})
|
|
.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<PostMeta, "slug">) },
|
|
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))
|
|
}
|