初步
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
type MarkdownModule = {
|
||||
frontmatter: Record<string, unknown>;
|
||||
Content: unknown;
|
||||
rawContent?: () => string;
|
||||
file?: string;
|
||||
};
|
||||
|
||||
export type BlogPost = MarkdownModule & {
|
||||
title: string;
|
||||
slug: string;
|
||||
date: Date;
|
||||
dateText: string;
|
||||
tags: string[];
|
||||
categories: string[];
|
||||
summary: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
const modules = import.meta.glob<MarkdownModule>('/source/_posts/**/*.md', { eager: true });
|
||||
|
||||
function asArray(value: unknown): string[] {
|
||||
if (Array.isArray(value)) return value.map(String).filter(Boolean);
|
||||
if (typeof value === 'string' && value.trim()) return [value.trim()];
|
||||
return [];
|
||||
}
|
||||
|
||||
function toDate(value: unknown): Date {
|
||||
if (value instanceof Date) return value;
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
const date = new Date(value);
|
||||
if (!Number.isNaN(date.valueOf())) return date;
|
||||
}
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
function formatDate(date: Date): string {
|
||||
return new Intl.DateTimeFormat('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
function fallbackSlug(path: string): string {
|
||||
return path
|
||||
.split('/')
|
||||
.pop()
|
||||
?.replace(/\.md$/, '')
|
||||
.toLowerCase() ?? 'post';
|
||||
}
|
||||
|
||||
function makeSummary(module: MarkdownModule): string {
|
||||
const explicit = module.frontmatter.summary ?? module.frontmatter.description;
|
||||
if (typeof explicit === 'string' && explicit.trim()) return explicit.trim();
|
||||
|
||||
const raw = module.rawContent?.() ?? '';
|
||||
return raw
|
||||
.replace(/```[\s\S]*?```/g, '')
|
||||
.replace(/<[^>]+>/g, '')
|
||||
.replace(/[#>*_`~\-\[\]\(\)]/g, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
.slice(0, 120);
|
||||
}
|
||||
|
||||
export function getAllPosts(): BlogPost[] {
|
||||
return Object.entries(modules)
|
||||
.map(([path, module]) => {
|
||||
const date = toDate(module.frontmatter.date);
|
||||
const slug = String(module.frontmatter.abbrlink ?? fallbackSlug(path));
|
||||
const title = String(module.frontmatter.title ?? slug);
|
||||
|
||||
return {
|
||||
...module,
|
||||
title,
|
||||
slug,
|
||||
date,
|
||||
dateText: formatDate(date),
|
||||
tags: asArray(module.frontmatter.tags),
|
||||
categories: asArray(module.frontmatter.categories),
|
||||
summary: makeSummary(module),
|
||||
href: `/posts/${slug}/`,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
||||
}
|
||||
|
||||
export function getAllTags(): string[] {
|
||||
return [...new Set(getAllPosts().flatMap((post) => post.tags))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
||||
}
|
||||
|
||||
export function getAllCategories(): string[] {
|
||||
return [...new Set(getAllPosts().flatMap((post) => post.categories))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
||||
}
|
||||
Reference in New Issue
Block a user