89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
|
|
import matter from 'gray-matter'
|
|
|
|
import remarkGfm from 'remark-gfm'
|
|
import rehypeHighlight from 'rehype-highlight'
|
|
import rehypeSlug from 'rehype-slug'
|
|
import remarkToc from 'remark-toc'
|
|
|
|
import nix from 'highlight.js/lib/languages/nix'
|
|
|
|
const fsPromises = fs.promises
|
|
const postsDirectory = path.join(process.cwd(), 'posts')
|
|
|
|
export const mdxOptions = {
|
|
remarkPlugins: [
|
|
remarkGfm,
|
|
[remarkToc, {tight: true}],
|
|
],
|
|
rehypePlugins: [
|
|
[rehypeHighlight, {languages: {nix}}],
|
|
rehypeSlug,
|
|
],
|
|
};
|
|
|
|
export async function getPostSlugs() {
|
|
return (await fsPromises.readdir(postsDirectory)).filter(fileName => fileName.match(/\.md$/)).map(fileName => {
|
|
return fileName.replace(/\.md$/, '')
|
|
})
|
|
}
|
|
|
|
function mdxify(serialize) {
|
|
return async function mdxifyInner(post) {
|
|
if (post.excerptRaw) {
|
|
post.excerptMdx = await serialize(post.excerptRaw, { mdxOptions })
|
|
delete post.excerptRaw
|
|
}
|
|
if (post.contentRaw) {
|
|
post.contentMdx = await serialize(post.contentRaw, { mdxOptions })
|
|
delete post.contentRaw
|
|
}
|
|
return post
|
|
}
|
|
}
|
|
|
|
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 })
|
|
|
|
return {
|
|
...matterResult.data,
|
|
slug,
|
|
date: matterResult.data.date.toISOString().substring(0, 10),
|
|
excerptRaw: matterResult.excerpt,
|
|
contentRaw: matterResult.content,
|
|
sortKey: matterResult.data.date,
|
|
}
|
|
}
|
|
|
|
export async function getPostBySlug(slug, serialize) {
|
|
const data = await _getPostBySlug(slug)
|
|
delete data.sortKey
|
|
delete data.excerptRaw
|
|
return mdxify(serialize)(data)
|
|
}
|
|
|
|
export async function getSortedPostsData(serialize) {
|
|
const mdxifyPost = mdxify(serialize)
|
|
const allPostsData = await Promise.all((await getPostSlugs()).map(_getPostBySlug))
|
|
|
|
return Promise.all(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.sortKey
|
|
delete x.contentRaw
|
|
return x
|
|
}).map(mdxifyPost))
|
|
}
|