Skip to content

Commit

Permalink
fix: duplicated footnote id
Browse files Browse the repository at this point in the history
  • Loading branch information
634750802 committed May 22, 2024
1 parent 44d02f5 commit 8c51e91
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 43 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-is": "^18.3.0",
"@types/react-syntax-highlighter": "^15.5.11",
"ace-builds": "^1.32.5",
"ai": "^3.0.22",
Expand All @@ -136,6 +137,7 @@
"next-themes": "^0.2.1",
"postcss": "^8",
"react-ace": "^10.1.0",
"react-is": "^18.3.1",
"react-json-view-lite": "^1.2.1",
"react-responsive": "^9.0.2",
"recharts": "^2.10.4",
Expand Down
55 changes: 18 additions & 37 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 40 additions & 6 deletions src/components/remark-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,54 @@ import { MessageContextSourceCard } from '@/components/chat/message-content-sour
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
import { cn } from '@/lib/utils';
import { HoverCardArrow, HoverCardPortal } from '@radix-ui/react-hover-card';
import { cache, Suspense, use, useDeferredValue, useState } from 'react';
import { cache, cloneElement, createContext, Suspense, use, useContext, useDeferredValue, useId, useState } from 'react';
import { isElement, isFragment } from 'react-is';
import * as prod from 'react/jsx-runtime';
import rehypeReact, { Options as RehypeReactOptions } from 'rehype-react';
import remarkGfm from 'remark-gfm';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import { unified } from 'unified';

function dirtyRewrite (some: any, id: string): any {
if (some == null) return some;
if (typeof some !== 'object') return some;

if (isElement(some) || isFragment(some)) {
return cloneElement(some, {
...some.props,
...some.props.id ? { id: `${id}--${some.props.id}` } : {},
children: dirtyRewrite(some.props.children, id),
});
}

if (some instanceof Array) {
return some.map(item => dirtyRewrite(item, id));
}

return some;
}

const production: RehypeReactOptions = {
Fragment: (prod as any).Fragment,
jsx: (prod as any).jsx,
jsxs: (prod as any).jsxs,
components: {
section ({ ...props }) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const reactId = useContext(RemarkContentContext);

if (!(props as any)['data-footnotes']) return <section {...props} />;
return (
<section {...props} className={cn(props.className, 'sr-only')} />
<section {...props} className={cn(props.className, 'sr-only')}>
{dirtyRewrite(props.children, reactId)}
</section>
);
},
a ({ ...props }) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const reactId = useContext(RemarkContentContext);

// eslint-disable-next-line react-hooks/rules-of-hooks
const [link, setLink] = useState<{ title: string, href: string }>();

Expand All @@ -32,7 +60,7 @@ const production: RehypeReactOptions = {
if (open) {
const id = props.href?.replace(/^#/, '');
if (id) {
const li = document.getElementById(id);
const li = document.getElementById(reactId + '--' + id);
if (li) {
const a = li.querySelector(`a:first-child`) as HTMLAnchorElement | null;
if (a) {
Expand Down Expand Up @@ -74,11 +102,17 @@ const processor = unified()
.use(rehypeReact, production)
.freeze();

const RemarkContentContext = createContext<string>('');

export function RemarkContent ({ children = '' }: { children: string | undefined }) {
const id = useId();

return (
<Suspense fallback={<div className="whitespace-pre-wrap">{children}</div>}>
{useDeferredValue(<RemarkContentInternal text={children} />)}
</Suspense>
<RemarkContentContext.Provider value={id}>
<Suspense fallback={<div className="whitespace-pre-wrap">{children}</div>}>
{useDeferredValue(<RemarkContentInternal text={children} />)}
</Suspense>
</RemarkContentContext.Provider>
);
}

Expand Down

0 comments on commit 8c51e91

Please sign in to comment.