depot/web/lukegbcom/lib/posts.js

90 lines
2.3 KiB
JavaScript
Raw Normal View History

2022-04-03 23:32:57 +00:00
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'
2022-04-03 23:32:57 +00:00
const fsPromises = fs.promises
const postsDirectory = path.join(process.cwd(), 'posts')
2022-04-05 02:18:57 +00:00
export const mdxOptions = {
remarkPlugins: [
remarkGfm,
[remarkToc, {tight: true}],
],
rehypePlugins: [
[rehypeHighlight, {languages: {nix}}],
rehypeSlug,
],
2022-04-05 02:18:57 +00:00
};
2022-04-03 23:32:57 +00:00
export async function getPostSlugs() {
return (await fsPromises.readdir(postsDirectory)).filter(fileName => fileName.match(/\.md$/)).map(fileName => {
return fileName.replace(/\.md$/, '')
})
}
2022-04-05 02:18:57 +00:00
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
}
}
2022-04-03 23:32:57 +00:00
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),
2022-04-05 02:18:57 +00:00
excerptRaw: matterResult.excerpt,
contentRaw: matterResult.content,
2022-04-03 23:32:57 +00:00
sortKey: matterResult.data.date,
}
}
2022-04-05 02:18:57 +00:00
export async function getPostBySlug(slug, serialize) {
2022-04-03 23:32:57 +00:00
const data = await _getPostBySlug(slug)
delete data.sortKey
2022-04-05 02:18:57 +00:00
delete data.excerptRaw
return mdxify(serialize)(data)
2022-04-03 23:32:57 +00:00
}
2022-04-05 02:18:57 +00:00
export async function getSortedPostsData(serialize) {
const mdxifyPost = mdxify(serialize)
2022-04-03 23:32:57 +00:00
const allPostsData = await Promise.all((await getPostSlugs()).map(_getPostBySlug))
2022-04-05 02:18:57 +00:00
return Promise.all(allPostsData.sort(({ sortKey: a }, { sortKey: b }) => {
2022-04-03 23:32:57 +00:00
[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
2022-04-05 02:18:57 +00:00
delete x.contentRaw
2022-04-03 23:32:57 +00:00
return x
2022-04-05 02:18:57 +00:00
}).map(mdxifyPost))
}