---
import { getCollection } from 'astro:content';
import BaseLayout from '@/layouts/BaseLayout.astro';
import Masthead from '@/components/Masthead.astro';
import { renderMarkdown } from '@/lib/shortcodes';
const page = (await getCollection('pages')).find((entry) => entry.data.slug === 'links');
if (!page) throw new Error('Missing links page content.');
type Link = { name: string; url: string; avatar: string; description: string };
type Section = { name: string; links: Link[]; contentLines: string[] };
const sections: Section[] = [{ name: '其他', links: [], contentLines: [] }];
let section = sections[0];
let shortcodeDepth = 0;
const escapeHtml = (value: string) => value.replace(/[&<>"']/g, (character) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[character]!);
const renderNestedCard = (link: Link) => `
})
${escapeHtml(link.description)}
`;
for (const line of (page.body ?? '').split(/\r?\n/)) {
if (/^\s*\[(?:collapse|hint|tip|tabs)\b[^\]]*\]\s*$/i.test(line)) {
shortcodeDepth += 1;
section.contentLines.push(line);
continue;
}
if (/^\s*\[\/(?:collapse|hint|tip|tabs)\]\s*$/i.test(line)) {
shortcodeDepth = Math.max(0, shortcodeDepth - 1);
section.contentLines.push(line);
continue;
}
const heading = line.match(/^##\s+(.+?)\s*#*$/);
if (heading && shortcodeDepth === 0) {
section = { name: heading[1].trim(), links: [], contentLines: [] };
sections.push(section);
continue;
}
const link = line.match(/^\s*\[([^\]]+)\]\(([^)]+)\)\+\(([^)]+)\)\/\((.*)\)\s*$/)
?? line.match(/^\s*\[([^\]]+)\]\(([^)]+)\)\+\(([^)]+)\)\/(.*?)\s*\)?$/);
if (link && shortcodeDepth === 0) {
section.links.push({ name: link[1], url: link[2], avatar: link[3], description: link[4] });
continue;
}
section.contentLines.push(shortcodeDepth > 0 && link ? renderNestedCard({ name: link[1], url: link[2], avatar: link[3], description: link[4] }) : line);
}
if (!sections[0].links.length && !sections[0].contentLines.some((line) => line.trim())) sections.shift();
---
{sections.map((group) =>
{group.name}
{group.links.length > 0 &&
{group.links.map((link) => -
)}
}
{group.contentLines.some((line) => line.trim()) && }
)}