import { NextRouter } from "next/router"; import { slugify } from "queries/helpers"; import { preprocessMarkDawn } from "./Markdawn"; type TOCProps = { text: string; title?: string; router: NextRouter; }; export default function TOC(props: TOCProps): JSX.Element { const { router, text, title } = props; 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}}
    1. {h2.children.map((h3, h3Index) => (
    2. {`${h2Index + 1}.${ h3Index + 1 }. `} router.replace(`#${h3.slug}`)}> {{h3.title}}
    3. ))}
    ))}
); } export type TOC = { title: string; slug: string; children: TOC[]; }; export function getTocFromMarkdawn(text: string, title?: string): TOC { if (!title) title = "Return to top"; let toc: TOC = { title: title, slug: slugify(title) || "", children: [] }; let h2 = -1; let h3 = -1; let h4 = -1; let h5 = -1; let scenebreak = 0; let scenebreakIndex = 0; text.split("\n").map((line) => { if (line.startsWith("# ")) { toc.slug = slugify(line); } else if (line.startsWith("## ")) { toc.children.push({ title: line.slice("## ".length), slug: slugify(line), children: [], }); h2++; h3 = -1; h4 = -1; h5 = -1; scenebreak = 0; } else if (line.startsWith("### ")) { toc.children[h2].children.push({ title: line.slice("### ".length), slug: slugify(line), children: [], }); h3++; h4 = -1; h5 = -1; scenebreak = 0; } else if (line.startsWith("#### ")) { toc.children[h2].children[h3].children.push({ title: line.slice("#### ".length), slug: slugify(line), children: [], }); h4++; h5 = -1; scenebreak = 0; } else if (line.startsWith("##### ")) { toc.children[h2].children[h3].children[h4].children.push({ title: line.slice("##### ".length), slug: slugify(line), children: [], }); h5++; scenebreak = 0; } else if (line.startsWith("###### ")) { toc.children[h2].children[h3].children[h4].children[h5].children.push({ title: line.slice("###### ".length), slug: slugify(line), children: [], }); } else 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: [], }); } else if (h4 >= 0) { toc.children[h2].children[h3].children[h4].children.push({ title: `Scene break ${scenebreak}`, slug: slugify(`scene-break-${scenebreakIndex}`), children: [], }); } else if (h3 >= 0) { toc.children[h2].children[h3].children.push({ title: `Scene break ${scenebreak}`, slug: slugify(`scene-break-${scenebreakIndex}`), children: [], }); } else if (h2 >= 0) { toc.children[h2].children.push({ title: `Scene break ${scenebreak}`, slug: slugify(`scene-break-${scenebreakIndex}`), children: [], }); } else { toc.children.push({ title: `Scene break ${scenebreak}`, slug: slugify(`scene-break-${scenebreakIndex}`), children: [], }); } } }); return toc; }