From 38fc733b99ec27dca515d2dfb3d2d1acbe35607c Mon Sep 17 00:00:00 2001
From: shixy <18705837259@163.com>
Date: Sat, 14 Mar 2026 16:13:02 +0800
Subject: [PATCH 1/2] fix(markdown-to-html): preserve inline code inside
bold/emphasis
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The `extractText()` helper in `preprocessCjkEmphasis()` only handled
`text` nodes and nodes with `children`. `inlineCode` AST nodes (which
have a `value` but no `children`) fell through to the default empty-
string return, silently dropping their content.
For example `**算出 \`logits\`**` rendered as `算出 `
with the code span completely lost.
Add an `inlineCode` branch that wraps the node value in backticks so
the downstream `marked` pass can turn it into a proper `` element.
Co-Authored-By: Claude Opus 4.6
---
.../vendor/baoyu-md/src/renderer.test.ts | 36 +++++++++++++++++++
.../scripts/vendor/baoyu-md/src/renderer.ts | 1 +
2 files changed, 37 insertions(+)
create mode 100644 skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
new file mode 100644
index 0000000..57e7a08
--- /dev/null
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
@@ -0,0 +1,36 @@
+import assert from "node:assert/strict";
+import test from "node:test";
+
+import { initRenderer, renderMarkdown } from "./renderer.ts";
+
+const render = (md: string) => {
+ const r = initRenderer();
+ return renderMarkdown(md, r).html;
+};
+
+test("bold with inline code (no underscore)", () => {
+ const html = render("**算出 `logits`,算出 `loss`。**");
+ assert.match(html, /]*>logits<\/code>/);
+ assert.match(html, /]*>loss<\/code>/);
+});
+
+test("bold with inline code (contains underscore)", () => {
+ const html = render("**变成 `input_ids`。**");
+ assert.match(html, /]*>input_ids<\/code>/);
+});
+
+test("emphasis with inline code", () => {
+ const html = render("*查看 `hidden_states`*");
+ assert.match(html, /]*>hidden_states<\/code>/);
+});
+
+test("plain inline code (regression)", () => {
+ const html = render("`lm_head`");
+ assert.match(html, /]*>lm_head<\/code>/);
+});
+
+test("bold without code (regression)", () => {
+ const html = render("**纯粗体文本**");
+ assert.match(html, /]*>纯粗体文本<\/strong>/);
+ assert.doesNotMatch(html, / {
if (node.type === "text") return node.value;
+ if (node.type === "inlineCode") return `\`${node.value}\``;
if (node.children) return node.children.map(extractText).join("");
return "";
};
From 2aa979078952f07386c8a271cf299b3244965dce Mon Sep 17 00:00:00 2001
From: shixy <18705837259@163.com>
Date: Sat, 14 Mar 2026 17:12:03 +0800
Subject: [PATCH 2/2] fix: preserve inline code in cjk emphasis
---
packages/baoyu-md/src/renderer.test.ts | 64 +++++++++++++++++++
packages/baoyu-md/src/renderer.ts | 8 +++
.../vendor/baoyu-md/src/renderer.test.ts | 28 ++++++++
.../scripts/vendor/baoyu-md/src/renderer.ts | 9 ++-
.../vendor/baoyu-md/src/renderer.test.ts | 64 +++++++++++++++++++
.../scripts/vendor/baoyu-md/src/renderer.ts | 8 +++
.../vendor/baoyu-md/src/renderer.test.ts | 64 +++++++++++++++++++
.../scripts/vendor/baoyu-md/src/renderer.ts | 8 +++
8 files changed, 252 insertions(+), 1 deletion(-)
create mode 100644 packages/baoyu-md/src/renderer.test.ts
create mode 100644 skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.test.ts
create mode 100644 skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.test.ts
diff --git a/packages/baoyu-md/src/renderer.test.ts b/packages/baoyu-md/src/renderer.test.ts
new file mode 100644
index 0000000..702804c
--- /dev/null
+++ b/packages/baoyu-md/src/renderer.test.ts
@@ -0,0 +1,64 @@
+import assert from "node:assert/strict";
+import test from "node:test";
+
+import { initRenderer, renderMarkdown } from "./renderer.ts";
+
+const render = (md: string) => {
+ const r = initRenderer();
+ return renderMarkdown(md, r).html;
+};
+
+test("bold with inline code (no underscore)", () => {
+ const html = render("**算出 `logits`,算出 `loss`。**");
+ assert.match(html, /]*>logits<\/code>/);
+ assert.match(html, /]*>loss<\/code>/);
+});
+
+test("bold with inline code (contains underscore)", () => {
+ const html = render("**变成 `input_ids`。**");
+ assert.match(html, /]*>input_ids<\/code>/);
+});
+
+test("emphasis with inline code", () => {
+ const html = render("*查看 `hidden_states`*");
+ assert.match(html, /]*>hidden_states<\/code>/);
+});
+
+test("plain inline code (regression)", () => {
+ const html = render("`lm_head`");
+ assert.match(html, /]*>lm_head<\/code>/);
+});
+
+test("bold without code (regression)", () => {
+ const html = render("**纯粗体文本**");
+ assert.match(html, /]*>纯粗体文本<\/strong>/);
+ assert.doesNotMatch(html, / {
+ const html = render("**``a`b``**");
+ assert.match(html, /]*>a`b<\/code>/);
+});
+
+test("emphasis with inline code containing backticks", () => {
+ const html = render("*``a`b``*");
+ assert.match(html, /]*>]*>a`b<\/code><\/em>/);
+});
+
+test("bold with inline code containing consecutive backticks", () => {
+ const html = render("**```a``b```**");
+ assert.match(html, /]*>a``b<\/code>/);
+});
+
+test("bold with inline code containing only backticks", () => {
+ const html = render("**```` `` ````**");
+ assert.match(html, /]*>``<\/code>/);
+});
+
+test("bold with inline code containing only spaces", () => {
+ const oneSpace = render("**`` ``**");
+ assert.match(oneSpace, /]*> <\/code>/);
+
+ const twoSpaces = render("**`` ``**");
+ assert.match(twoSpaces, /]*> <\/code>/);
+});
diff --git a/packages/baoyu-md/src/renderer.ts b/packages/baoyu-md/src/renderer.ts
index 7a1234c..2549737 100644
--- a/packages/baoyu-md/src/renderer.ts
+++ b/packages/baoyu-md/src/renderer.ts
@@ -109,6 +109,13 @@ function parseFrontMatterAndContent(markdownText: string): ParseResult {
}
}
+function wrapInlineCode(value: string): string {
+ const runs = value.match(/`+/g);
+ const fence = "`".repeat(Math.max(...(runs?.map((run) => run.length) ?? [0])) + 1);
+ const padding = /^ *$/.test(value) ? "" : " ";
+ return `${fence}${padding}${value}${padding}${fence}`;
+}
+
export function initRenderer(opts: IOpts = {}): RendererAPI {
const footnotes: [number, string, string][] = [];
let footnoteIndex = 0;
@@ -369,6 +376,7 @@ function preprocessCjkEmphasis(markdown: string): string {
const tree = processor.parse(markdown);
const extractText = (node: any): string => {
if (node.type === "text") return node.value;
+ if (node.type === "inlineCode") return wrapInlineCode(node.value);
if (node.children) return node.children.map(extractText).join("");
return "";
};
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
index 57e7a08..702804c 100644
--- a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.test.ts
@@ -34,3 +34,31 @@ test("bold without code (regression)", () => {
assert.match(html, /]*>纯粗体文本<\/strong>/);
assert.doesNotMatch(html, / {
+ const html = render("**``a`b``**");
+ assert.match(html, /]*>a`b<\/code>/);
+});
+
+test("emphasis with inline code containing backticks", () => {
+ const html = render("*``a`b``*");
+ assert.match(html, /]*>]*>a`b<\/code><\/em>/);
+});
+
+test("bold with inline code containing consecutive backticks", () => {
+ const html = render("**```a``b```**");
+ assert.match(html, /]*>a``b<\/code>/);
+});
+
+test("bold with inline code containing only backticks", () => {
+ const html = render("**```` `` ````**");
+ assert.match(html, /]*>``<\/code>/);
+});
+
+test("bold with inline code containing only spaces", () => {
+ const oneSpace = render("**`` ``**");
+ assert.match(oneSpace, /]*> <\/code>/);
+
+ const twoSpaces = render("**`` ``**");
+ assert.match(twoSpaces, /]*> <\/code>/);
+});
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts
index 692f216..2549737 100644
--- a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts
@@ -109,6 +109,13 @@ function parseFrontMatterAndContent(markdownText: string): ParseResult {
}
}
+function wrapInlineCode(value: string): string {
+ const runs = value.match(/`+/g);
+ const fence = "`".repeat(Math.max(...(runs?.map((run) => run.length) ?? [0])) + 1);
+ const padding = /^ *$/.test(value) ? "" : " ";
+ return `${fence}${padding}${value}${padding}${fence}`;
+}
+
export function initRenderer(opts: IOpts = {}): RendererAPI {
const footnotes: [number, string, string][] = [];
let footnoteIndex = 0;
@@ -369,7 +376,7 @@ function preprocessCjkEmphasis(markdown: string): string {
const tree = processor.parse(markdown);
const extractText = (node: any): string => {
if (node.type === "text") return node.value;
- if (node.type === "inlineCode") return `\`${node.value}\``;
+ if (node.type === "inlineCode") return wrapInlineCode(node.value);
if (node.children) return node.children.map(extractText).join("");
return "";
};
diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.test.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.test.ts
new file mode 100644
index 0000000..702804c
--- /dev/null
+++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.test.ts
@@ -0,0 +1,64 @@
+import assert from "node:assert/strict";
+import test from "node:test";
+
+import { initRenderer, renderMarkdown } from "./renderer.ts";
+
+const render = (md: string) => {
+ const r = initRenderer();
+ return renderMarkdown(md, r).html;
+};
+
+test("bold with inline code (no underscore)", () => {
+ const html = render("**算出 `logits`,算出 `loss`。**");
+ assert.match(html, /]*>logits<\/code>/);
+ assert.match(html, /]*>loss<\/code>/);
+});
+
+test("bold with inline code (contains underscore)", () => {
+ const html = render("**变成 `input_ids`。**");
+ assert.match(html, /]*>input_ids<\/code>/);
+});
+
+test("emphasis with inline code", () => {
+ const html = render("*查看 `hidden_states`*");
+ assert.match(html, /]*>hidden_states<\/code>/);
+});
+
+test("plain inline code (regression)", () => {
+ const html = render("`lm_head`");
+ assert.match(html, /]*>lm_head<\/code>/);
+});
+
+test("bold without code (regression)", () => {
+ const html = render("**纯粗体文本**");
+ assert.match(html, /]*>纯粗体文本<\/strong>/);
+ assert.doesNotMatch(html, / {
+ const html = render("**``a`b``**");
+ assert.match(html, /]*>a`b<\/code>/);
+});
+
+test("emphasis with inline code containing backticks", () => {
+ const html = render("*``a`b``*");
+ assert.match(html, /]*>]*>a`b<\/code><\/em>/);
+});
+
+test("bold with inline code containing consecutive backticks", () => {
+ const html = render("**```a``b```**");
+ assert.match(html, /]*>a``b<\/code>/);
+});
+
+test("bold with inline code containing only backticks", () => {
+ const html = render("**```` `` ````**");
+ assert.match(html, /]*>``<\/code>/);
+});
+
+test("bold with inline code containing only spaces", () => {
+ const oneSpace = render("**`` ``**");
+ assert.match(oneSpace, /]*> <\/code>/);
+
+ const twoSpaces = render("**`` ``**");
+ assert.match(twoSpaces, /]*> <\/code>/);
+});
diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts
index 7a1234c..2549737 100644
--- a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts
+++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts
@@ -109,6 +109,13 @@ function parseFrontMatterAndContent(markdownText: string): ParseResult {
}
}
+function wrapInlineCode(value: string): string {
+ const runs = value.match(/`+/g);
+ const fence = "`".repeat(Math.max(...(runs?.map((run) => run.length) ?? [0])) + 1);
+ const padding = /^ *$/.test(value) ? "" : " ";
+ return `${fence}${padding}${value}${padding}${fence}`;
+}
+
export function initRenderer(opts: IOpts = {}): RendererAPI {
const footnotes: [number, string, string][] = [];
let footnoteIndex = 0;
@@ -369,6 +376,7 @@ function preprocessCjkEmphasis(markdown: string): string {
const tree = processor.parse(markdown);
const extractText = (node: any): string => {
if (node.type === "text") return node.value;
+ if (node.type === "inlineCode") return wrapInlineCode(node.value);
if (node.children) return node.children.map(extractText).join("");
return "";
};
diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.test.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.test.ts
new file mode 100644
index 0000000..702804c
--- /dev/null
+++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.test.ts
@@ -0,0 +1,64 @@
+import assert from "node:assert/strict";
+import test from "node:test";
+
+import { initRenderer, renderMarkdown } from "./renderer.ts";
+
+const render = (md: string) => {
+ const r = initRenderer();
+ return renderMarkdown(md, r).html;
+};
+
+test("bold with inline code (no underscore)", () => {
+ const html = render("**算出 `logits`,算出 `loss`。**");
+ assert.match(html, /]*>logits<\/code>/);
+ assert.match(html, /]*>loss<\/code>/);
+});
+
+test("bold with inline code (contains underscore)", () => {
+ const html = render("**变成 `input_ids`。**");
+ assert.match(html, /]*>input_ids<\/code>/);
+});
+
+test("emphasis with inline code", () => {
+ const html = render("*查看 `hidden_states`*");
+ assert.match(html, /]*>hidden_states<\/code>/);
+});
+
+test("plain inline code (regression)", () => {
+ const html = render("`lm_head`");
+ assert.match(html, /]*>lm_head<\/code>/);
+});
+
+test("bold without code (regression)", () => {
+ const html = render("**纯粗体文本**");
+ assert.match(html, /]*>纯粗体文本<\/strong>/);
+ assert.doesNotMatch(html, / {
+ const html = render("**``a`b``**");
+ assert.match(html, /]*>a`b<\/code>/);
+});
+
+test("emphasis with inline code containing backticks", () => {
+ const html = render("*``a`b``*");
+ assert.match(html, /]*>]*>a`b<\/code><\/em>/);
+});
+
+test("bold with inline code containing consecutive backticks", () => {
+ const html = render("**```a``b```**");
+ assert.match(html, /]*>a``b<\/code>/);
+});
+
+test("bold with inline code containing only backticks", () => {
+ const html = render("**```` `` ````**");
+ assert.match(html, /]*>``<\/code>/);
+});
+
+test("bold with inline code containing only spaces", () => {
+ const oneSpace = render("**`` ``**");
+ assert.match(oneSpace, /]*> <\/code>/);
+
+ const twoSpaces = render("**`` ``**");
+ assert.match(twoSpaces, /]*> <\/code>/);
+});
diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts
index 7a1234c..2549737 100644
--- a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts
+++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts
@@ -109,6 +109,13 @@ function parseFrontMatterAndContent(markdownText: string): ParseResult {
}
}
+function wrapInlineCode(value: string): string {
+ const runs = value.match(/`+/g);
+ const fence = "`".repeat(Math.max(...(runs?.map((run) => run.length) ?? [0])) + 1);
+ const padding = /^ *$/.test(value) ? "" : " ";
+ return `${fence}${padding}${value}${padding}${fence}`;
+}
+
export function initRenderer(opts: IOpts = {}): RendererAPI {
const footnotes: [number, string, string][] = [];
let footnoteIndex = 0;
@@ -369,6 +376,7 @@ function preprocessCjkEmphasis(markdown: string): string {
const tree = processor.parse(markdown);
const extractText = (node: any): string => {
if (node.type === "text") return node.value;
+ if (node.type === "inlineCode") return wrapInlineCode(node.value);
if (node.children) return node.children.map(extractText).join("");
return "";
};