feat(animation-sources): add content-driven guide system
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
export type MarkdownHeading = {
|
||||
id: string;
|
||||
text: string;
|
||||
level: 2 | 3;
|
||||
};
|
||||
|
||||
export function cleanMarkdownHeading(text: string) {
|
||||
return text
|
||||
.replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1")
|
||||
.replace(/[*_~`]/g, "")
|
||||
.trim();
|
||||
}
|
||||
|
||||
export function slugifyMarkdownHeading(text: string) {
|
||||
return cleanMarkdownHeading(text)
|
||||
.toLocaleLowerCase("tr-TR")
|
||||
.normalize("NFKD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/ı/g, "i")
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
export function parseMarkdownHeadings(markdown: string): MarkdownHeading[] {
|
||||
const headings: MarkdownHeading[] = [];
|
||||
|
||||
for (const line of markdown.split("\n")) {
|
||||
const match = /^(#{2,3})\s+(.+)$/.exec(line.trim());
|
||||
if (!match) continue;
|
||||
|
||||
const text = cleanMarkdownHeading(match[2]);
|
||||
const id = slugifyMarkdownHeading(text);
|
||||
if (!id || !text) continue;
|
||||
|
||||
headings.push({
|
||||
id,
|
||||
text,
|
||||
level: match[1].length as 2 | 3,
|
||||
});
|
||||
}
|
||||
|
||||
return headings;
|
||||
}
|
||||
Reference in New Issue
Block a user