修改页面风格

This commit is contained in:
2026-06-18 11:07:23 +08:00 Unverified
parent 7c3679e885
commit 9d6de3158e
15 changed files with 1293 additions and 5617 deletions
+86 -12
View File
@@ -1,4 +1,5 @@
---
import ArticleSidebar from '@/components/ArticleSidebar.astro';
import BaseLayout from '@/layouts/BaseLayout.astro';
import { getAllPosts } from '@/lib/posts';
@@ -11,20 +12,93 @@ export function getStaticPaths() {
const { post } = Astro.props;
const { Content } = post;
const allPosts = getAllPosts();
function slugifyHeading(value: string): string {
return value
.trim()
.toLowerCase()
.replace(/<[^>]+>/g, '')
.replace(/[`*_~[\]()]/g, '')
.replace(/[^\p{Letter}\p{Number}\s-]/gu, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
function makeToc(raw: string) {
const used = new Map<string, number>();
let inFence = false;
return raw
.split(/\r?\n/)
.flatMap((line) => {
if (/^\s*```/.test(line)) {
inFence = !inFence;
return [];
}
if (inFence) return [];
const match = /^(#{1,3})\s+(.+?)\s*#*$/.exec(line);
if (!match) return [];
const text = match[2].replace(/<[^>]+>/g, '').trim();
if (!text) return [];
const baseId = slugifyHeading(text) || 'section';
const count = used.get(baseId) ?? 0;
used.set(baseId, count + 1);
return [{
depth: match[1].length,
text,
id: count === 0 ? baseId : `${baseId}-${count}`,
}];
});
}
const toc = makeToc(post.rawContent?.() ?? '');
const relatedPosts = allPosts
.filter((item) => item.slug !== post.slug)
.filter((item) => item.categories.some((category) => post.categories.includes(category)))
.slice(0, 8);
---
<BaseLayout title={post.title} description={post.summary}>
<article class="article">
<header class="article-header">
<time datetime={post.date.toISOString()}>{post.dateText}</time>
<h1>{post.title}</h1>
<div class="meta-list">
{post.categories.map((category) => <a href={`/categories/${encodeURIComponent(category)}/`}>{category}</a>)}
{post.tags.map((tag) => <a href={`/tags/${encodeURIComponent(tag)}/`}>#{tag}</a>)}
<section class="post-layout">
<article class="article post-article">
<header class="article-header">
<time datetime={post.date.toISOString()}>{post.dateText}</time>
<h1>{post.title}</h1>
<div class="meta-list">
{post.categories.map((category) => <a href={`/categories/${encodeURIComponent(category)}/`}>{category}</a>)}
{post.tags.map((tag) => <a href={`/tags/${encodeURIComponent(tag)}/`}>#{tag}</a>)}
</div>
</header>
<div class="prose" data-toc={JSON.stringify(toc)}>
<Content />
</div>
</header>
<div class="prose">
<Content />
</div>
</article>
</article>
<ArticleSidebar post={post} toc={toc} relatedPosts={relatedPosts} />
</section>
</BaseLayout>
<script is:inline>
(() => {
const prose = document.querySelector('.prose[data-toc]');
if (!prose) return;
let toc = [];
try {
toc = JSON.parse(prose.dataset.toc || '[]');
} catch {
toc = [];
}
prose.querySelectorAll('h1, h2, h3').forEach((heading, index) => {
const item = toc[index];
if (item?.id && !heading.id) heading.id = item.id;
});
})();
</script>