import fs from "fs"; import path from "path"; import matter from "gray-matter"; const postsDirectory = path.join(process.cwd(), "content"); const tagsFilePath = path.join(postsDirectory, "tags.json"); type PostData = { id: string; href: string; venue: string; date: string; tags: string[]; image: string | undefined; title?: string; excerpt?: string; video?: string; [key: string]: string | string[] | null | undefined; }; function getPostFilePaths(dir: string, fileList: string[] = []) { const files = fs.readdirSync(dir); files.forEach((file) => { const filePath = path.join(dir, file); if (fs.statSync(filePath).isDirectory()) { getPostFilePaths(filePath, fileList); } else if (filePath.endsWith(".mdx")) { fileList.push(filePath); } }); return fileList; } export function getSortedPostsData(category?: string): PostData[] { const directory = category ? path.join(postsDirectory, category) : postsDirectory; const filePaths = getPostFilePaths(directory); const allPostsData = filePaths.map((filePath) => { const id = path.basename(filePath).replace(/\.mdx$/, "").replace(/^\d{4}-\d{2}-\d{2}-/, ''); const relativePath = path.relative(postsDirectory, filePath).replace(/\.mdx$/, ""); const pathParts = relativePath.split(path.sep); pathParts.pop(); // remove the old filename pathParts.push(id); const href = pathParts.join('/'); // use forward slashes for URLs const fileContents = fs.readFileSync(filePath, "utf8"); const matterResult = matter(fileContents); const dateFromFileName = path.basename(filePath).substring(0, 10); const tags = matterResult.data.tags ? Array.isArray(matterResult.data.tags) ? matterResult.data.tags : matterResult.data.tags.split(/, ?/) : []; const venue = matterResult.data.venue ? matterResult.data.venue: "arxive"; const image = matterResult.data.teaser || matterResult.data.image || null; return { id, href, venue, date: matterResult.data.date ?? dateFromFileName, ...matterResult.data, tags, image, }; }); return allPostsData.sort((a, b) => { if (!a.date || a.date < b.date) { return 1; } else { return -1; } }); } export function getAllTags(minCount: number = 1, category?: "experience" | "research") { const allPosts = getSortedPostsData(category); const tags: { [tag: string]: number } = {}; allPosts.forEach((post) => { post.tags.forEach((tag: string) => { if (tag in tags) { tags[tag]++; } else { tags[tag] = 1; } }); }); return Object.entries(tags) .map(([name, count]) => ({ name, count })) .filter(tag => tag.count >= minCount); } export function getPostsByTag(tag: string) { const allPosts = getSortedPostsData(); return allPosts.filter((post) => post.tags.includes(tag)); } export function getTagData(tag: string) { if (!fs.existsSync(tagsFilePath)) { return null; } const tagsFile = fs.readFileSync(tagsFilePath, "utf8"); const tagsData = JSON.parse(tagsFile); return tagsData[tag] || null; }