import fs from 'fs' import path from 'path' import matter from 'gray-matter' import { unified } from 'unified' import remarkParse from 'remark-parse' import remarkGfm from 'remark-gfm' import remarkRehype from 'remark-rehype' import rehypeHighlight from 'rehype-highlight' import rehypeStringify from 'rehype-stringify' const fsPromises = fs.promises const postsDirectory = path.join(process.cwd(), 'posts') async function markdownToHtml(content) { return unified() .use(remarkParse) .use(remarkGfm) .use(remarkRehype) .use(rehypeHighlight) .use(rehypeStringify) .process(content) } export async function getPostSlugs() { return (await fsPromises.readdir(postsDirectory)).filter(fileName => fileName.match(/\.md$/)).map(fileName => { return fileName.replace(/\.md$/, '') }) } export async function _getPostBySlug(slug) { const fileName = `${slug}.md` const fullPath = path.join(postsDirectory, fileName) const fileContents = await fsPromises.readFile(fullPath, 'utf8') const matterResult = matter(fileContents, { excerpt: true }) const processedContent = await markdownToHtml(matterResult.content) const processedExcerpt = await markdownToHtml(matterResult.excerpt) return { ...matterResult.data, slug, date: matterResult.data.date.toISOString().substring(0, 10), excerptHtml: processedExcerpt.toString(), contentHtml: processedContent.toString(), sortKey: matterResult.data.date, } } export async function getPostBySlug(slug) { const data = await _getPostBySlug(slug) delete data.sortKey return data } export async function getSortedPostsData() { const allPostsData = await Promise.all((await getPostSlugs()).map(_getPostBySlug)) return allPostsData.sort(({ sortKey: a }, { sortKey: b }) => { [a, b] = [Date.parse(a), Date.parse(b)] if (a < b) { return 1 } else if (a > b) { return -1 } else { return 0 } }).map((x) => { delete x.contentHtml delete x.sortKey return x }) }