diff --git a/src/components/Markdown/Markdawn.tsx b/src/components/Markdown/Markdawn.tsx index 51c71ba..80a8c03 100644 --- a/src/components/Markdown/Markdawn.tsx +++ b/src/components/Markdown/Markdawn.tsx @@ -180,12 +180,65 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element { export function preprocessMarkDawn(text: string): string { let scenebreakIndex = 0; + const visitedSlugs: string[] = []; + const result = text.split("\n").map((line) => { if (line === "* * *" || line === "---") { scenebreakIndex++; return ``; } + + if (line.startsWith("# ")) { + return markdawnHeadersParser(headerLevels.h1, line, visitedSlugs); + } + + if (line.startsWith("## ")) { + return markdawnHeadersParser(headerLevels.h2, line, visitedSlugs); + } + + if (line.startsWith("### ")) { + return markdawnHeadersParser(headerLevels.h3, line, visitedSlugs); + } + + if (line.startsWith("#### ")) { + return markdawnHeadersParser(headerLevels.h4, line, visitedSlugs); + } + + if (line.startsWith("##### ")) { + return markdawnHeadersParser(headerLevels.h5, line, visitedSlugs); + } + + if (line.startsWith("###### ")) { + return markdawnHeadersParser(headerLevels.h6, line, visitedSlugs); + } + return line; }); return result.join("\n"); } + +enum headerLevels { + h1 = 1, + h2 = 2, + h3 = 3, + h4 = 4, + h5 = 5, + h6 = 6, +} + +function markdawnHeadersParser( + headerLevel: headerLevels, + line: string, + visitedSlugs: string[] +): string { + const lineText = line.slice(headerLevel + 1); + let slug = slugify(lineText); + let newSlug = slug; + let index = 2; + while (visitedSlugs.includes(newSlug)) { + newSlug = `${slug}-${index}`; + index++; + } + visitedSlugs.push(newSlug); + return `<${headerLevels[headerLevel]} id="${newSlug}">${lineText}`; +} diff --git a/src/components/Markdown/TOC.tsx b/src/components/Markdown/TOC.tsx index ed2ce6b..8e50a0e 100644 --- a/src/components/Markdown/TOC.tsx +++ b/src/components/Markdown/TOC.tsx @@ -13,44 +13,55 @@ export default function TOC(props: TOCProps): JSX.Element { const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title); return ( -
+ <>

Table of content

-
    -
  1. +
    +

    router.replace(`#${toc.slug}`)}> {{toc.title}} -

  2. - {toc.children.map((h2, h2Index) => ( - <> -
  3. - {`${h2Index + 1}. `} - router.replace(`#${h2.slug}`)}> - {{h2.title}} - -
  4. -
      - {h2.children.map((h3, h3Index) => ( -
    1. - {`${h2Index + 1}.${ - h3Index + 1 - }. `} - router.replace(`#${h3.slug}`)}> - {{h3.title}} - -
    2. - ))} -
    - - ))} -
-
+

+ + + + ); +} + +type TOCLevelProps = { + tocchildren: TOC[]; + parentNumbering: string; + router: NextRouter; +}; + +function TOCLevel(props: TOCLevelProps): JSX.Element { + const { tocchildren, parentNumbering, router } = props; + return ( +
    + {tocchildren.map((child, childIndex) => ( + <> +
  1. + {`${parentNumbering}${ + childIndex + 1 + }.`} + router.replace(`#${child.slug}`)}> + {{child.title}} + +
  2. + + + ))} +
); } @@ -69,13 +80,23 @@ export function getTocFromMarkdawn(text: string, title?: string): TOC { let h5 = -1; let scenebreak = 0; let scenebreakIndex = 0; + + function getTitle(line: string): string { + return line.slice(line.indexOf(`">`) + 2, line.indexOf("`)); + } + text.split("\n").map((line) => { - if (line.startsWith("# ")) { - toc.slug = slugify(line); - } else if (line.startsWith("## ")) { + if (line.startsWith("

= 0) { - toc.children[h2].children[h3].children[h4].children[h5].children.push({ - title: `Scene break ${scenebreak}`, - slug: slugify(`scene-break-${scenebreakIndex}`), - children: [], - }); + toc.children[h2].children[h3].children[h4].children[h5].children.push( + child + ); } else if (h4 >= 0) { - toc.children[h2].children[h3].children[h4].children.push({ - title: `Scene break ${scenebreak}`, - slug: slugify(`scene-break-${scenebreakIndex}`), - children: [], - }); + toc.children[h2].children[h3].children[h4].children.push(child); } else if (h3 >= 0) { - toc.children[h2].children[h3].children.push({ - title: `Scene break ${scenebreak}`, - slug: slugify(`scene-break-${scenebreakIndex}`), - children: [], - }); + toc.children[h2].children[h3].children.push(child); } else if (h2 >= 0) { - toc.children[h2].children.push({ - title: `Scene break ${scenebreak}`, - slug: slugify(`scene-break-${scenebreakIndex}`), - children: [], - }); + toc.children[h2].children.push(child); } else { - toc.children.push({ - title: `Scene break ${scenebreak}`, - slug: slugify(`scene-break-${scenebreakIndex}`), - children: [], - }); + toc.children.push(child); } } }); + return toc; }