mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-13 22:29:48 +08:00
feat(baoyu-markdown-to-html): add remark-cjk-friendly for CJK emphasis
Preprocess markdown with remark-cjk-friendly to properly handle CJK emphasis markers before HTML conversion.
This commit is contained in:
+1395
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"fflate": "^0.8.2",
|
||||||
|
"front-matter": "^4.0.2",
|
||||||
|
"highlight.js": "^11.11.1",
|
||||||
|
"juice": "^11.0.1",
|
||||||
|
"marked": "^15.0.6",
|
||||||
|
"reading-time": "^1.5.0",
|
||||||
|
"remark-cjk-friendly": "^1.1.0",
|
||||||
|
"remark-parse": "^11.0.0",
|
||||||
|
"remark-stringify": "^11.0.0",
|
||||||
|
"unified": "^11.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,10 @@ import frontMatter from "front-matter";
|
|||||||
import hljs from "highlight.js/lib/core";
|
import hljs from "highlight.js/lib/core";
|
||||||
import { marked, type RendererObject, type Tokens } from "marked";
|
import { marked, type RendererObject, type Tokens } from "marked";
|
||||||
import readingTime, { type ReadTimeResults } from "reading-time";
|
import readingTime, { type ReadTimeResults } from "reading-time";
|
||||||
|
import { unified } from "unified";
|
||||||
|
import remarkParse from "remark-parse";
|
||||||
|
import remarkCjkFriendly from "remark-cjk-friendly";
|
||||||
|
import remarkStringify from "remark-stringify";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
markedAlert,
|
markedAlert,
|
||||||
@@ -552,12 +556,47 @@ interface CliOptions {
|
|||||||
keepTitle: boolean;
|
keepTitle: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function preprocessCjkEmphasis(markdown: string): string {
|
||||||
|
const processor = unified()
|
||||||
|
.use(remarkParse)
|
||||||
|
.use(remarkCjkFriendly);
|
||||||
|
const tree = processor.parse(markdown);
|
||||||
|
const visit = (node: any, parent?: any, index?: number) => {
|
||||||
|
if (node.children) {
|
||||||
|
for (let i = 0; i < node.children.length; i++) {
|
||||||
|
visit(node.children[i], node, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.type === "strong" && parent && typeof index === "number") {
|
||||||
|
const text = extractText(node);
|
||||||
|
parent.children[index] = { type: "html", value: `<strong>${text}</strong>` };
|
||||||
|
}
|
||||||
|
if (node.type === "emphasis" && parent && typeof index === "number") {
|
||||||
|
const text = extractText(node);
|
||||||
|
parent.children[index] = { type: "html", value: `<em>${text}</em>` };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const extractText = (node: any): string => {
|
||||||
|
if (node.type === "text") return node.value;
|
||||||
|
if (node.children) return node.children.map(extractText).join("");
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
visit(tree);
|
||||||
|
const stringify = unified().use(remarkStringify);
|
||||||
|
let result = stringify.stringify(tree);
|
||||||
|
result = result.replace(/&#x([0-9A-Fa-f]+);/g, (_, hex) =>
|
||||||
|
String.fromCodePoint(parseInt(hex, 16))
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function renderMarkdown(raw: string, renderer: RendererAPI): {
|
function renderMarkdown(raw: string, renderer: RendererAPI): {
|
||||||
html: string;
|
html: string;
|
||||||
readingTime: ReadTimeResults;
|
readingTime: ReadTimeResults;
|
||||||
} {
|
} {
|
||||||
|
const preprocessed = preprocessCjkEmphasis(raw);
|
||||||
const { markdownContent, readingTime: readingTimeResult } =
|
const { markdownContent, readingTime: readingTimeResult } =
|
||||||
renderer.parseFrontMatterAndContent(raw);
|
renderer.parseFrontMatterAndContent(preprocessed);
|
||||||
|
|
||||||
const html = marked.parse(markdownContent) as string;
|
const html = marked.parse(markdownContent) as string;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user