diff --git a/components/ttcmd/index.tsx b/components/ttcmd/index.tsx index 08b3dad..bc83cd9 100644 --- a/components/ttcmd/index.tsx +++ b/components/ttcmd/index.tsx @@ -4,7 +4,6 @@ import { createElements } from "@/lib/tcmd"; import React, { FC, Suspense, useEffect, useMemo, useState } from "react"; import { MDSkeletonLoader } from "../loader"; -import { Token } from "@/types"; export const TTCMD: FC< { body: string; escapeTOC?: (tokens: Token[]) => boolean } @@ -80,6 +79,5 @@ export const TTCMDRenderer: FC<{ tokens: Token[] }> = ( }; function renderer(tokens: Token[]) { - const usedIds: string[] = []; return tokens.map((t) =>
{t.render(t)}
); } diff --git a/lib/tcmd/TokenIdentifiers.tsx b/lib/tcmd/TokenIdentifiers.tsx index 6e82568..c2c5a37 100644 --- a/lib/tcmd/TokenIdentifiers.tsx +++ b/lib/tcmd/TokenIdentifiers.tsx @@ -1,9 +1,3 @@ -import { - IdentifiedToken, - Token, - TokenAttributes, - TokenRenderer, -} from "@/types"; import { sanitize } from "isomorphic-dompurify"; import Link from "next/link"; import { Fragment } from "react"; @@ -114,6 +108,8 @@ export const buildOnlyDefaultElements = () => { ); }); + const usedIds: string[] = []; + const rendersContentOnly = true; const rendersChildrenOnly = true; @@ -292,12 +288,14 @@ export const buildOnlyDefaultElements = () => { // heading registerIdentifier("heading", /^#+\s(.*?)$/gm, (s, rx) => { + const content = s.match(new RegExp(rx, ""))?.at(1) || + "Unable to parse heading"; return { - content: s.match(new RegExp(rx, ""))?.at(1) || - "Unable to parse heading", + content: content, raw: s, metadata: { strength: s.match(/#/g)?.length.toString() || "1", + id: generateId(content, usedIds), }, uuid: crypto.randomUUID(), rendersContentOnly, @@ -698,3 +696,18 @@ function search( lastIndex: oldEnd === end ? end : start + s.match(openRx)![0].length, }; } + +// Finds a unique id for things like headings +function generateId(t: string, usedIds: string[]) { + let id = t.toLowerCase().replace(/[^a-z\s]/ig, "").trim().replaceAll( + " ", + "-", + ); + let idNum = 1; + while (usedIds.includes(id)) { + id = id.replace(/-[0-9]+$/g, ""); + id += "-" + idNum; + idNum++; + } + return id; +} diff --git a/lib/tcmd/index.ts b/lib/tcmd/index.ts index 9e93631..ccb1ba8 100644 --- a/lib/tcmd/index.ts +++ b/lib/tcmd/index.ts @@ -1,6 +1,5 @@ "use client"; -import { FrontMatter, Token, TokenMarker } from "@/types"; import { zipArrays } from "../zip"; import { buildOnlyDefaultElements, TokenRenderers } from "./TokenIdentifiers"; diff --git a/types.d.ts b/types.d.ts index 142510f..9e1c21c 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,46 +1,3 @@ -import { ReactNode } from "react"; - -type InlineToken = { - type: - | "text" - | "bold" - | "anchor" - | "image" - | "popover" - | "italic" - | "inline-code"; - content: string; - data?: any; - uuid: string; -}; - -type InlineTokenInsert = { - start: number; - end: number; -} & InlineToken; - -type Line = string | InlineToken[]; - -type MultilineToken = { - type: "code" | "p"; - lines: SingleLineToken[]; -}; - -type SingleLineCfg = { - rx: RegExp; - create: (line: string) => SingleLineToken; - replaceRx: RegExp; - shouldMendNextLine?: boolean; -}; - -type SingleLineToken = { - type: "h1" | "h2" | "h3" | "text" | `list${number}`; - line: Line; - raw: string; - mends?: boolean; - cfg?: SingleLineCfg; - uuid: string; -}; type IdentifiedToken = { metadata: Record; children?: Token[]; @@ -69,32 +26,3 @@ type TokenMarker = { }; type FrontMatter = Record; - -type MultilineCfg = { - rx: RegExp; - closeRx?: RegExp; - create: (tokens: Token[]) => SingleLineToken[]; - replace: (line: string) => string; -}; - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -type BlockToken = { - type: "block" | "grid" | "card" | "accordion"; - metadata: any; - children: BlockChildren[]; - parent?: string; - closed: boolean; - uuid: string; -}; - -type BlockChildren = ParagraphToken | BlockToken | SingleLineToken; - -type ParagraphToken = { - content: SingleLineToken[]; - allowsInline: boolean; - type: "p" | "code"; - metadata: any; - closed: boolean; - uuid: string; -};