mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 22:18:00 +08:00
* show cms blog posts in www * remove contentlayer from www * outputFileTracingExcludes * update remotePatterns * fetch cms posts server-side with revalidation * add cms env vars to turbo.json * add www env vars to turbo.json * include cms posts in www sitemap * add migration to remove image from cms post * update cms meta image mapping in www
41 lines
1.1 KiB
TypeScript
41 lines
1.1 KiB
TypeScript
type TocItem = { content: string; slug: string; lvl: number }
|
|
|
|
function stripFencedCodeBlocks(markdown: string): string {
|
|
const segments = markdown.split('```')
|
|
let acc = ''
|
|
for (let i = 0; i < segments.length; i++) {
|
|
if (i % 2 === 0) acc += segments[i]
|
|
}
|
|
return acc
|
|
}
|
|
|
|
function slugify(input: string): string {
|
|
return input
|
|
.trim()
|
|
.toLowerCase()
|
|
.replace(/[`~!@#$%^&*()+=|{}\[\]\\:\";'<>?,./]+/g, '')
|
|
.replace(/\s+/g, '-')
|
|
}
|
|
|
|
export async function generateTocFromMarkdown(markdown: string, maxDepth: number) {
|
|
const noCode = stripFencedCodeBlocks(markdown)
|
|
const lines = noCode.split(/\r?\n/)
|
|
const items: TocItem[] = []
|
|
|
|
for (const line of lines) {
|
|
const m = /^(#{1,6})\s+(.*)$/.exec(line)
|
|
if (!m) continue
|
|
const depth = m[1].length
|
|
if (depth > maxDepth) continue
|
|
const text = m[2].trim()
|
|
if (!text) continue
|
|
items.push({ content: text, slug: slugify(text), lvl: depth })
|
|
}
|
|
|
|
const content = items
|
|
.map((h) => `${' '.repeat(Math.max(0, h.lvl - 1))}- [${h.content}](#${h.slug})`)
|
|
.join('\n')
|
|
|
|
return { content, json: items }
|
|
}
|