fix: inline element support in table of content (#430)

This commit is contained in:
iku 2023-04-28 02:38:03 +08:00 committed by GitHub
parent 4eee159896
commit b56a175dcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 24 deletions

View File

@ -73,6 +73,7 @@
"emoji-mart": "5.5.2",
"fast-average-color": "^9.3.0",
"fast-deep-equal": "3.1.3",
"hast-util-to-html": "^8.0.4",
"hast-util-to-text": "^3.1.2",
"i18next": "^22.4.15",
"idb-keyval": "6.2.0",
@ -84,6 +85,7 @@
"katex": "^0.16.6",
"langchain": "^0.0.63",
"lottie-react": "^2.4.0",
"mdast-util-to-hast": "^12.3.0",
"mdast-util-to-string": "3.2.0",
"mdast-util-toc": "6.1.1",
"medium-zoom": "1.0.8",

View File

@ -137,6 +137,9 @@ dependencies:
fast-deep-equal:
specifier: 3.1.3
version: 3.1.3
hast-util-to-html:
specifier: ^8.0.4
version: 8.0.4
hast-util-to-text:
specifier: ^3.1.2
version: 3.1.2
@ -170,6 +173,9 @@ dependencies:
lottie-react:
specifier: ^2.4.0
version: 2.4.0(react-dom@18.2.0)(react@18.2.0)
mdast-util-to-hast:
specifier: ^12.3.0
version: 12.3.0
mdast-util-to-string:
specifier: 3.2.0
version: 3.2.0

View File

@ -1,9 +1,19 @@
import { toHtml } from "hast-util-to-html"
import DOMPurify from "isomorphic-dompurify"
import katex from "katex"
import type { List } from "mdast"
import { toHast } from "mdast-util-to-hast"
import type { Result as TocResult } from "mdast-util-toc"
import React, { useEffect, useRef, useState } from "react"
import { Link } from "react-scroll"
const inlineElements = ["delete", "strong", "emphasis", "inlineCode"]
function getLinkNode(node: any): List["children"] {
if (node.type === "link") return node.children
else return getLinkNode(node.children[0])
}
function getIds(items: TocResult["map"]) {
return (
items?.children?.reduce((acc: string[], item) => {
@ -64,17 +74,20 @@ function renderItems(
{items?.children?.map((item, index) => (
<li key={index}>
{item.children.map((child: any, i) => {
const children =
child.children[0].children?.[0]?.children ||
child.children[0].children
let content = "",
isInlineMath = false
children.map((child: any) => {
const children = getLinkNode(child) || []
let content = ""
children.forEach((child: any) => {
if (child.type === "inlineMath") {
isInlineMath = true
content += katex.renderToString(child.value, { output: "html" })
} else if (inlineElements.includes(child.type)) {
content += toHtml(toHast(child) || [])
} else {
content += child.value
}
content += child.value
})
content = `${prefix}${index + 1}. ${DOMPurify.sanitize(content)}`
return (
<span key={index + "-" + i}>
{child.type === "paragraph" && child.children?.[0]?.url && (
@ -95,22 +108,11 @@ function renderItems(
" truncate inline-block max-w-full align-bottom hover:text-accent"
}
>
{isInlineMath ? (
<span
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
katex.renderToString(
`${prefix}${index + 1}. ${content}`,
{
output: "html",
},
),
),
}}
/>
) : (
`${prefix}${index + 1}. ${content}`
)}
<span
dangerouslySetInnerHTML={{
__html: content,
}}
/>
</Link>
)}
{child.type === "list" &&