-
+
+
+
+ {title}
+ {showRss && (
+
+
+
+ )}
-
+ {showProgress &&
}
{children}
diff --git a/lib/posts.ts b/lib/posts.ts
index 02b44de..4877cfb 100644
--- a/lib/posts.ts
+++ b/lib/posts.ts
@@ -2,9 +2,16 @@ import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import readingTime from 'reading-time';
+import { notFound } from 'next/navigation';
const postsDirectory = path.join(process.cwd(), 'posts');
+export interface Heading {
+ level: number;
+ text: string;
+ slug: string;
+}
+
export interface PostData {
id: string;
date: string;
@@ -12,6 +19,8 @@ export interface PostData {
description: string;
content: string;
readingTime: string;
+ headings: Heading[];
+ wip: boolean;
}
export interface PostMeta {
@@ -20,6 +29,22 @@ export interface PostMeta {
title: string;
description: string;
readingTime: string;
+ wip: boolean;
+}
+
+function extractHeadings(content: string): Heading[] {
+ const regex = /^(#{2,3})\s+(.+)$/gm;
+ const headings: Heading[] = [];
+ let match;
+ while ((match = regex.exec(content)) !== null) {
+ const text = match[2].trim();
+ const slug = text
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, '-')
+ .replace(/(^-|-$)/g, '');
+ headings.push({ level: match[1].length, text, slug });
+ }
+ return headings;
}
export function getSortedPostsData(): PostMeta[] {
@@ -40,6 +65,7 @@ export function getSortedPostsData(): PostMeta[] {
title: matterResult.data.title as string,
description: matterResult.data.description as string,
readingTime: stats.text,
+ wip: matterResult.data.wip ?? false,
};
});
@@ -65,6 +91,7 @@ export function getAllPostIds() {
export async function getPostData(id: string): Promise
{
const fullPath = path.join(postsDirectory, `${id}.mdx`);
+ if (!fs.existsSync(fullPath)) notFound();
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
const stats = readingTime(matterResult.content);
@@ -76,5 +103,7 @@ export async function getPostData(id: string): Promise {
title: matterResult.data.title,
description: matterResult.data.description,
readingTime: stats.text,
+ headings: extractHeadings(matterResult.content),
+ wip: matterResult.data.wip ?? false,
};
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index b6e1c08..72bdc28 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"react-dom": "19.1.0",
"reading-time": "^1.5.0",
"rehype-pretty-code": "^0.14.3",
+ "rehype-slug": "^6.0.0",
"remark": "^15.0.1",
"remark-html": "^16.0.1",
"rss": "^1.2.2",