mirror of
https://github.com/theoludwig/theoludwig.git
synced 2025-05-29 22:37:44 +02:00
refactor: blog directory
This commit is contained in:
@ -1,65 +0,0 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import { cache } from 'react'
|
||||
import matter from 'gray-matter'
|
||||
|
||||
export const POSTS_PATH = path.join(process.cwd(), 'posts')
|
||||
|
||||
export interface FrontMatter {
|
||||
title: string
|
||||
description: string
|
||||
isPublished: boolean
|
||||
publishedOn: string
|
||||
}
|
||||
|
||||
export interface Post {
|
||||
frontmatter: FrontMatter
|
||||
slug: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export const getPosts = cache(async (): Promise<Post[]> => {
|
||||
const posts = await fs.promises.readdir(POSTS_PATH)
|
||||
const postsWithTime = await Promise.all(
|
||||
posts.map(async (postFilename) => {
|
||||
const [slug, extension] = postFilename.split('.')
|
||||
if (slug == null || extension == null) {
|
||||
throw new Error('Invalid postFilename.')
|
||||
}
|
||||
const blogPostPath = path.join(POSTS_PATH, `${slug}.${extension}`)
|
||||
const blogPostContent = await fs.promises.readFile(blogPostPath, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
const { data, content } = matter(blogPostContent) as unknown as {
|
||||
data: FrontMatter
|
||||
content: string
|
||||
}
|
||||
const date = new Date(data.publishedOn)
|
||||
return {
|
||||
slug,
|
||||
content,
|
||||
frontmatter: data,
|
||||
time: date.getTime()
|
||||
}
|
||||
})
|
||||
)
|
||||
const postsWithTimeSorted = postsWithTime
|
||||
.filter((post) => {
|
||||
return post.frontmatter.isPublished
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return b.time - a.time
|
||||
})
|
||||
return postsWithTimeSorted
|
||||
})
|
||||
|
||||
export const getPostBySlug = cache(
|
||||
async (slug: string): Promise<Post | undefined> => {
|
||||
const posts = await getPosts()
|
||||
const post = posts.find((post) => {
|
||||
return post.slug === slug
|
||||
})
|
||||
return post
|
||||
}
|
||||
)
|
@ -1,32 +0,0 @@
|
||||
import type { Plugin, Transformer } from 'unified'
|
||||
import type { Literal, Node } from 'unist'
|
||||
import { visit } from 'unist-util-visit'
|
||||
import type { Highlighter } from 'shiki'
|
||||
|
||||
export interface RemarkSyntaxHighlightingPluginOptions {
|
||||
highlighter: Highlighter
|
||||
}
|
||||
|
||||
export interface RemarkSyntaxHighlightingNode extends Node {
|
||||
lang: string
|
||||
meta: string
|
||||
children: undefined
|
||||
value: string
|
||||
data: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const remarkSyntaxHighlightingPlugin: Plugin<
|
||||
[RemarkSyntaxHighlightingPluginOptions],
|
||||
Literal
|
||||
> = (options) => {
|
||||
const transformer: Transformer<RemarkSyntaxHighlightingNode> = (tree) => {
|
||||
visit<RemarkSyntaxHighlightingNode, string>(tree, 'code', (node) => {
|
||||
node.type = 'html'
|
||||
node.children = undefined
|
||||
node.value = options.highlighter.codeToHtml(node.value, {
|
||||
lang: node.lang
|
||||
})
|
||||
})
|
||||
}
|
||||
return transformer
|
||||
}
|
Reference in New Issue
Block a user