fix(tui): render CJK emphasis next to punctuation (#10730)

- fixes #10154
This commit is contained in:
Bucky 2026-10-20 17:04:48 +08:00 • committed by GitHub
parent 1d01b3b1f8
commit b2d0da6fe3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 57 additions and 4 deletions

15
package-lock.json generated
View file

@ -4466,6 +4466,18 @@
"node": ">= 20"
}
},
"node_modules/marked-cjk-friendly": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/marked-cjk-friendly/-/marked-cjk-friendly-0.1.2.tgz",
"integrity": "sha512-GUj8HjiEbur9yhgUo52FBgKizggF1QtT6gVdrYdWW6ZB4lVVjgS3EyyXPyfyRD0V4ghGRPlO7MO80rgSWbm0eA==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"peerDependencies": {
"marked": ">=15.0.0"
}
},
"node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
@ -6422,7 +6434,8 @@
"license": "MIT",
"dependencies": {
"get-east-asian-width": "1.6.0",
"marked": "18.0.11"
"marked": "18.0.11",
"marked-cjk-friendly": "0.1.2"
},
"devDependencies": {
"@xterm/headless": "5.5.0",

View file

@ -551,7 +551,8 @@
"license": "MIT",
"dependencies": {
"get-east-asian-width": "1.6.0",
"marked": "18.0.11"
"marked": "18.0.11",
"marked-cjk-friendly": "0.1.2"
},
"engines": {
"node": ">=22.19.0"
@ -1160,6 +1161,18 @@
"node": ">= 20"
}
},
"node_modules/marked-cjk-friendly": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/marked-cjk-friendly/-/marked-cjk-friendly-0.1.2.tgz",
"integrity": "sha512-GUj8HjiEbur9yhgUo52FBgKizggF1QtT6gVdrYdWW6ZB4lVVjgS3EyyXPyfyRD0V4ghGRPlO7MO80rgSWbm0eA==",
"license": "MIT",
"peerDependencies": {
"marked": ">=15.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/minimatch": {
"version": "10.2.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",

View file

@ -53,7 +53,8 @@
"types": "./dist/index.d.ts",
"dependencies": {
"get-east-asian-width": "1.6.0",
"marked": "18.0.11"
"marked": "18.0.11",
"marked-cjk-friendly": "0.1.2"
},
"devDependencies": {
"@xterm/headless": "5.5.0",

View file

@ -1,4 +1,5 @@
import { Marked, type Token, Tokenizer, type TokenizerExtension, type Tokens } from "marked";
import markedCjkFriendly from "marked-cjk-friendly";
import { renderLatex } from "../latex.ts";
import { getCapabilities, hyperlink, isImageLine } from "../terminal-image.ts";
import type { Component } from "../tui.ts";
@ -172,7 +173,10 @@ const markdownParser = new Marked();
markdownParser.setOptions({
tokenizer: new StrictStrikethroughTokenizer(),
});
markdownParser.use({ extensions: [...LATEX_MARKDOWN_EXTENSIONS] });
markdownParser.use({
tokenizer: { emStrong: markedCjkFriendly().tokenizer?.emStrong },
extensions: [...LATEX_MARKDOWN_EXTENSIONS],
});
/**
* Default text styling for markdown content.

View file

@ -1585,6 +1585,28 @@ bar`,
});
});
// #10154
describe("CJK emphasis", () => {
const tagTheme: MarkdownTheme = {
...defaultMarkdownTheme,
bold: (text) => `<b>${text}</b>`,
italic: (text) => `<i>${text}</i>`,
};
const render = (text: string) => new Markdown(text, 0, 0, tagTheme).render(80).map((line) => line.trimEnd());
it("renders emphasis delimited next to CJK punctuation", () => {
assert.deepStrictEqual(render("**这是测试。**后面"), ["<b>这是测试。</b>后面"]);
assert.deepStrictEqual(render("**一句话说清:**一台机器"), ["<b>一句话说清:</b>一台机器"]);
assert.deepStrictEqual(render("**要点到此为止。**20 小时"), ["<b>要点到此为止。</b>20 小时"]);
assert.deepStrictEqual(render("字**「引用」**字"), ["字<b>「引用」</b>字"]);
assert.deepStrictEqual(render("*斜体。*后面"), ["<i>斜体。</i>后面"]);
});
it("keeps CommonMark flanking rules for non-CJK text", () => {
assert.deepStrictEqual(render("**end.**Then next"), ["**end.**Then next"]);
});
});
describe("Links", () => {
afterEach(() => {
resetCapabilitiesCache();