import "./markdown.css"; import { ReactNode, forwardRef, useMemo } from "react"; import { Token, Tokens, marked } from "marked"; import { Link } from "react-router-dom"; interface MarkdownProps { content: string; } const Markdown = forwardRef((props: MarkdownProps, ref) => { let ctr = 0; function renderToken(t: Token): ReactNode { try { switch (t.type) { case "paragraph": { return
{t.tokens ? t.tokens.map(renderToken) : t.raw}
; } case "image": { return ; } case "heading": { switch (t.depth) { case 1: return

{t.tokens ? t.tokens.map(renderToken) : t.raw}

; case 2: return

{t.tokens ? t.tokens.map(renderToken) : t.raw}

; case 3: return

{t.tokens ? t.tokens.map(renderToken) : t.raw}

; case 4: return

{t.tokens ? t.tokens.map(renderToken) : t.raw}

; case 5: return
{t.tokens ? t.tokens.map(renderToken) : t.raw}
; case 6: return
{t.tokens ? t.tokens.map(renderToken) : t.raw}
; } throw new Error("Invalid heading"); } case "codespan": { return {t.raw}; } case "code": { return
{t.raw}
; } case "br": { return
; } case "hr": { return
; } case "strong": { return {t.tokens ? t.tokens.map(renderToken) : t.raw}; } case "blockquote": { return
{t.tokens ? t.tokens.map(renderToken) : t.raw}
; } case "link": { return ( {t.tokens ? t.tokens.map(renderToken) : t.raw} ); } case "list": { if (t.ordered) { return
    {t.items.map(renderToken)}
; } else { return ; } } case "list_item": { return
  • {t.tokens ? t.tokens.map(renderToken) : t.raw}
  • ; } case "em": { return {t.tokens ? t.tokens.map(renderToken) : t.raw}; } case "del": { return {t.tokens ? t.tokens.map(renderToken) : t.raw}; } case "table": { return ( {(t.header as Tokens.TableCell[]).map(v => ( ))} {(t.rows as Tokens.TableCell[][]).map(v => ( {v.map((d, d_key) => ( ))} ))}
    {v.tokens ? v.tokens.map(renderToken) : v.text}
    {d.tokens ? d.tokens.map(renderToken) : d.text}
    ); } case "text": { if ("tokens" in t) { return (t.tokens as Array).map(renderToken); } return t.raw; } case "space": { return " "; } default: { console.debug(`Unknown token ${t.type}`); } } } catch (e) { console.error(e); } } const parsed = useMemo(() => { return marked.lexer(props.content); }, [props.content]); return (
    {parsed.filter(a => a.type !== "footnote" && a.type !== "footnotes").map(a => renderToken(a))}
    ); }); export default Markdown;