import type { AnchorHTMLAttributes } from "react";
import { CITE_SCHEME } from "../../lib/citations/inline";
import type { CitationView } from "../../lib/report/views";
import { Markdown } from "../Markdown";
import { CitationsProvider } from "./CitationsContext";
import { InlineCite } from "./InlineCite";
// Report markdown with its citations live: every `[label](cite:)` link
// (lib/citations/inline.ts) becomes an InlineCite for that id; every other
// link renders as Markdown's own external link, except a `#` link to a
// place on the same page, which stays in the tab. The house markdown setup
// (Markdown.tsx — markdown-to-jsx, raw HTML escaped, token-styled) is
// unchanged; this only swaps its link component. A `cite:` link inside code is
// code, never a citation: markdown-to-jsx makes no link there.
//
// The views come from the page's one CitationsProvider (a page with many
// markdown blocks serializes its citation map once). A block rendered on its
// own may pass `citations`, and gets a provider of its own.
const EXTERNAL_LINK_CLASS = "text-brand underline decoration-brand/40 hover:decoration-brand";
export function citeIdOf(href: string | undefined): string | null {
return href?.startsWith(CITE_SCHEME) ? href.slice(CITE_SCHEME.length).trim() : null;
}
type Citations = Readonly>;
// The `` of cited markdown: one stable component.
function CiteLink({ href, children: label, ...rest }: AnchorHTMLAttributes) {
const id = citeIdOf(href);
if (id !== null) return {label};
if (href?.startsWith("#")) {
return (
{label}
);
}
return (
{label}
);
}
export function CitedMarkdown({
children,
citations,
className,
}: {
children: string;
citations?: Citations;
className?: string;
}) {
const md = (
{children}
);
return citations ? {md} : md;
}