Files
c0ntroller.de/src/pages/book/[...slug].astro
T
2026-09-07 18:24:15 +02:00

114 lines
3.0 KiB
Plaintext

---
import { getCollection, render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import BookNavigation from '../../components/BookNavigation.astro';
import "katex/dist/katex.min.css";
// @ts-expect-error Theme is not provided as ".css"
import "rehype-callouts/theme/obsidian";
import "../../styles/md-custom.css";
export async function getStaticPaths() {
const pages = await getCollection('book');
pages.sort((a, b) => a.id.localeCompare(b.id));
return pages.map((page, index) => {
return {
params: { slug: page.id },
props: {
page,
prevPage: index > 0 ? pages[index - 1] : null,
nextPage: index < pages.length - 1 ? pages[index + 1] : null,
allPages: pages
}
};
});
}
const { page, prevPage, nextPage, allPages } = Astro.props;
const { Content } = await render(page);
const chapters = allPages.reduce((acc, p) => {
const [chapter] = p.id.split('/');
if (!acc[chapter]) acc[chapter] = [];
acc[chapter].push(p);
return acc;
}, {} as Record<string, typeof allPages>);
---
<BaseLayout title={page.data.title} theme="book">
<div class="glass-container content prose" style="view-transition-name:main-glass;">
<h1 style={`view-transition-name: book-headline-${page.id.replaceAll("/", "-")};`}>{page.data.title}</h1>
<Content />
</div>
<BookNavigation
prevUrl={prevPage ? `/book/${prevPage.id}` : undefined}
prevTitle={prevPage?.data.title}
nextUrl={nextPage ? `/book/${nextPage.id}` : undefined}
nextTitle={nextPage?.data.title}
>
<div slot="toc" class="mini-toc">
{Object.entries(chapters).map(([chapter, items]) => (
<div class="mini-chapter">
<h4>{chapter.replace(/-/g, ' ').toUpperCase()}</h4>
<ul>
{items.map(item => (
<li>
<a
href={`/book/${item.id}`}
class={item.id === page.id ? 'active' : ''}
>
{item.data.title}
</a>
</li>
))}
</ul>
</div>
))}
</div>
</BookNavigation>
</BaseLayout>
<style>
.content {
line-height: 1.8;
padding: 2rem 3rem;
}
.mini-toc {
text-align: left;
}
.mini-chapter {
margin-bottom: 1rem;
}
.mini-chapter h4 {
margin: 0 0 0.5rem 0;
font-size: 0.9rem;
opacity: 0.7;
color: var(--text-main);
}
.mini-chapter ul {
list-style: none;
padding: 0;
margin: 0;
}
.mini-chapter li {
margin-bottom: 0.25rem;
}
.mini-chapter a {
display: block;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.95rem;
color: var(--text-muted);
text-decoration: none;
}
.mini-chapter a:hover {
background: rgb(from var(--accent-base) r g b / 0.1);
color: var(--accent-base);
}
.mini-chapter a.active {
background: rgb(from var(--accent-base) r g b / 0.2);
color: var(--accent-base);
font-weight: 600;
}
</style>