fix: CJK 加粗失效(CommonMark flanking 缺陷)+ 拉大 Markdown 段间距

This commit is contained in:
Rick Ye
2026-09-08 00:23:14 +08:00
parent d1cee518fa
commit 9074d15deb
2 changed files with 25 additions and 15 deletions
+2
View File
@@ -30,6 +30,8 @@
"react-dom": "19.2.8", "react-dom": "19.2.8",
"react-icons": "5.7.0", "react-icons": "5.7.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"remark-cjk-friendly": "^2.3.1",
"remark-cjk-friendly-gfm-strikethrough": "^2.3.1",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"shadow-plugin": "2.1.0", "shadow-plugin": "2.1.0",
"shiki": "^1.29.2", "shiki": "^1.29.2",
@@ -1,6 +1,8 @@
import { memo, useEffect, useState, type ReactNode } from 'react' import { memo, useEffect, useState, type ReactNode } from 'react'
import ReactMarkdown, { type Components } from 'react-markdown' import ReactMarkdown, { type Components } from 'react-markdown'
import remarkGfm from 'remark-gfm' import remarkGfm from 'remark-gfm'
import remarkCjkFriendly from 'remark-cjk-friendly'
import remarkCjkFriendlyGfmStrikethrough from 'remark-cjk-friendly-gfm-strikethrough'
import { import {
useLLMOutput, useLLMOutput,
type BlockMatch, type BlockMatch,
@@ -96,41 +98,41 @@ const LANG_ALIAS: Record<string, string> = {
const mdComponents: Components = { const mdComponents: Components = {
p({ children }) { p({ children }) {
return <p className="leading-normal">{children}</p> return <p className="my-4 leading-normal">{children}</p>
}, },
h1({ children }) { h1({ children }) {
return <h3 className="mb-1 mt-3 text-[17px] font-semibold text-ink first:mt-0">{children}</h3> return <h3 className="mb-2 mt-5 text-[17px] font-semibold text-ink first:mt-0">{children}</h3>
}, },
h2({ children }) { h2({ children }) {
return <h4 className="mb-1 mt-3 text-[15.5px] font-semibold text-ink first:mt-0">{children}</h4> return <h4 className="mb-2 mt-5 text-[15.5px] font-semibold text-ink first:mt-0">{children}</h4>
}, },
h3({ children }) { h3({ children }) {
return <h5 className="mb-1 mt-2.5 text-[14.5px] font-semibold text-ink first:mt-0">{children}</h5> return <h5 className="mb-1.5 mt-4 text-[14.5px] font-semibold text-ink first:mt-0">{children}</h5>
}, },
h4({ children }) { h4({ children }) {
return <h6 className="mb-1 mt-2.5 text-[14.5px] font-semibold text-ink first:mt-0">{children}</h6> return <h6 className="mb-1.5 mt-4 text-[14.5px] font-semibold text-ink first:mt-0">{children}</h6>
}, },
h5: ({ children }) => <h6 className="mb-1 mt-2.5 text-[14px] font-semibold text-ink">{children}</h6>, h5: ({ children }) => <h6 className="mb-1.5 mt-4 text-[14px] font-semibold text-ink">{children}</h6>,
h6: ({ children }) => <h6 className="mb-1 mt-2.5 text-[13.5px] font-semibold text-ink-2">{children}</h6>, h6: ({ children }) => <h6 className="mb-1.5 mt-4 text-[13.5px] font-semibold text-ink-2">{children}</h6>,
ul({ children }) { ul({ children }) {
return <ul className="my-2 list-disc space-y-1.5 pl-5 marker:text-ink-3">{children}</ul> return <ul className="my-4 list-disc space-y-2 pl-5 marker:text-ink-3">{children}</ul>
}, },
ol({ children }) { ol({ children }) {
return <ol className="my-2 list-decimal space-y-1.5 pl-5 marker:text-ink-3">{children}</ol> return <ol className="my-4 list-decimal space-y-2 pl-5 marker:text-ink-3">{children}</ol>
}, },
li({ children }) { li({ children }) {
return <li className="leading-normal">{children}</li> return <li className="leading-normal">{children}</li>
}, },
blockquote({ children }) { blockquote({ children }) {
return ( return (
<blockquote className="my-3 border-l-2 border-line pl-3 text-[13.5px] italic text-ink-3"> <blockquote className="my-4 border-l-2 border-line pl-3 text-[13.5px] italic text-ink-3">
{children} {children}
</blockquote> </blockquote>
) )
}, },
table({ children }) { table({ children }) {
return ( return (
<div className="my-3 overflow-x-auto"> <div className="my-4 overflow-x-auto">
<table className="w-full border-collapse text-[13.5px]">{children}</table> <table className="w-full border-collapse text-[13.5px]">{children}</table>
</div> </div>
) )
@@ -169,7 +171,7 @@ const mdComponents: Components = {
}, },
pre({ children }) { pre({ children }) {
return ( return (
<pre className="my-3 overflow-x-auto rounded-card bg-inset p-3 text-ink-2">{children}</pre> <pre className="my-4 overflow-x-auto rounded-card bg-inset p-3 text-ink-2">{children}</pre>
) )
}, },
a({ children, href }) { a({ children, href }) {
@@ -191,16 +193,22 @@ const mdComponents: Components = {
return <del className="text-ink-3">{children}</del> return <del className="text-ink-3">{children}</del>
}, },
img({ src, alt }) { img({ src, alt }) {
return <img src={src} alt={alt} className="my-2 max-w-full rounded-card border border-line" /> return <img src={src} alt={alt} className="my-3 max-w-full rounded-card border border-line" />
}, },
hr() { hr() {
return <hr className="my-3 border-line" /> return <hr className="my-4 border-line" />
} }
} }
const MarkdownComponent: LLMOutputComponent = ({ blockMatch }) => ( const MarkdownComponent: LLMOutputComponent = ({ blockMatch }) => (
<div className="space-y-5 text-base text-ink"> <div className="space-y-5 text-base text-ink">
<ReactMarkdown remarkPlugins={[remarkGfm]} components={mdComponents}> {/* remark-cjk-friendly:CommonMark 的 flanking 规则不认 CJK——`**` 紧邻
* 汉字与全角标点(如 出自**《书名》**)时无法开合加粗,解析层修复;
* 删除线同理(GFM ~~ 的伴随插件) */}
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkCjkFriendly, remarkCjkFriendlyGfmStrikethrough]}
components={mdComponents}
>
{blockMatch.output} {blockMatch.output}
</ReactMarkdown> </ReactMarkdown>
</div> </div>