@wenyan-md/core 3.0.8 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js
CHANGED
|
@@ -100,6 +100,12 @@ async function loadCssBySource(source) {
|
|
|
100
100
|
throw new Error("Unknown source type");
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
function createSvgDataUrl(svg) {
|
|
104
|
+
if (!svg.hasAttribute("xmlns")) {
|
|
105
|
+
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
106
|
+
}
|
|
107
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.outerHTML)}`;
|
|
108
|
+
}
|
|
103
109
|
const __vite_glob_0_0$1 = "pre{background:#282c34}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}";
|
|
104
110
|
const __vite_glob_0_1$1 = "pre{background:#fafafa}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}";
|
|
105
111
|
const __vite_glob_0_2$1 = "pre{background:#282936}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e9e9f4;background:#282936}.hljs ::selection,.hljs::selection{background-color:#4d4f68;color:#e9e9f4}.hljs-comment{color:#626483}.hljs-tag{color:#62d6e8}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#e9e9f4}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#ea51b2}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#b45bcf}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#00f769}.hljs-strong{font-weight:700;color:#00f769}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#ebff87}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#a1efe4}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#62d6e8}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#b45bcf}.hljs-emphasis{color:#b45bcf;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#00f769}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}\n";
|
|
@@ -196,7 +202,7 @@ async function handleFrontMatter(markdown) {
|
|
|
196
202
|
const { attributes, body } = fm(markdown);
|
|
197
203
|
const result = { content: body || "" };
|
|
198
204
|
let head = "";
|
|
199
|
-
const { title, description, cover, author, source_url, need_open_comment, only_fans_can_comment, image_list } = attributes;
|
|
205
|
+
const { title, description, cover, author, source_url, need_open_comment, only_fans_can_comment, image_list, type } = attributes;
|
|
200
206
|
if (title) {
|
|
201
207
|
result.title = title;
|
|
202
208
|
}
|
|
@@ -207,9 +213,6 @@ async function handleFrontMatter(markdown) {
|
|
|
207
213
|
if (cover) {
|
|
208
214
|
result.cover = cover;
|
|
209
215
|
}
|
|
210
|
-
if (head) {
|
|
211
|
-
result.content = head + result.content;
|
|
212
|
-
}
|
|
213
216
|
if (author) {
|
|
214
217
|
result.author = author;
|
|
215
218
|
}
|
|
@@ -225,6 +228,12 @@ async function handleFrontMatter(markdown) {
|
|
|
225
228
|
if (image_list) {
|
|
226
229
|
result.image_list = image_list;
|
|
227
230
|
}
|
|
231
|
+
if (type) {
|
|
232
|
+
result.type = type;
|
|
233
|
+
}
|
|
234
|
+
if (head) {
|
|
235
|
+
result.content = head + result.content;
|
|
236
|
+
}
|
|
228
237
|
return result;
|
|
229
238
|
}
|
|
230
239
|
const parseOptions = {
|
|
@@ -467,6 +476,44 @@ function createMarkedClient() {
|
|
|
467
476
|
};
|
|
468
477
|
}
|
|
469
478
|
},
|
|
479
|
+
// Obsidian WikiLinks 图片语法扩展 ![[filename]] / ![[filename|alt]] / ![[filename|width]] / ![[filename|widthxheight]]
|
|
480
|
+
{
|
|
481
|
+
name: "wikiImage",
|
|
482
|
+
level: "inline",
|
|
483
|
+
start(src) {
|
|
484
|
+
return src.match(/!\[\[/)?.index;
|
|
485
|
+
},
|
|
486
|
+
tokenizer(src) {
|
|
487
|
+
const rule = /^!\[\[([^\]|]+?)(?:\|([^\]]*))?\]\]/;
|
|
488
|
+
const match = rule.exec(src);
|
|
489
|
+
if (!match) return;
|
|
490
|
+
const href = match[1].trim();
|
|
491
|
+
const modifier = match[2]?.trim() ?? "";
|
|
492
|
+
const dimOnly = /^(\d+)(?:x(\d+))?$/.exec(modifier);
|
|
493
|
+
const alt = dimOnly ? "" : modifier;
|
|
494
|
+
const width = dimOnly ? dimOnly[1] : "";
|
|
495
|
+
const height = dimOnly ? dimOnly[2] ?? "" : "";
|
|
496
|
+
return {
|
|
497
|
+
type: "wikiImage",
|
|
498
|
+
raw: match[0],
|
|
499
|
+
href,
|
|
500
|
+
alt,
|
|
501
|
+
width,
|
|
502
|
+
height,
|
|
503
|
+
tokens: []
|
|
504
|
+
};
|
|
505
|
+
},
|
|
506
|
+
renderer(token) {
|
|
507
|
+
const href = normalizeHref(token.href);
|
|
508
|
+
const altAttr = token.alt ? ` alt="${token.alt}"` : "";
|
|
509
|
+
const titleAttr = token.alt ? ` title="${token.alt}"` : "";
|
|
510
|
+
const styleParts = [];
|
|
511
|
+
if (token.width) styleParts.push(`width:${token.width}px`);
|
|
512
|
+
if (token.height) styleParts.push(`height:${token.height}px`);
|
|
513
|
+
const styleAttr = styleParts.length ? ` style="${styleParts.join("; ")}"` : "";
|
|
514
|
+
return `<img src="${href}"${altAttr}${titleAttr}${styleAttr}>`;
|
|
515
|
+
}
|
|
516
|
+
},
|
|
470
517
|
// 自定义图片语法扩展 ![](){...}
|
|
471
518
|
{
|
|
472
519
|
name: "attributeImage",
|
|
@@ -646,24 +693,7 @@ function containsMermaidCodeBlock(html) {
|
|
|
646
693
|
return html.includes("language-mermaid");
|
|
647
694
|
}
|
|
648
695
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
649
|
-
function
|
|
650
|
-
const mathElements = element.querySelectorAll("mjx-container");
|
|
651
|
-
mathElements.forEach((mathContainer) => {
|
|
652
|
-
const svg = mathContainer.querySelector("svg");
|
|
653
|
-
if (!svg) return;
|
|
654
|
-
svg.style.width = svg.getAttribute("width") || "";
|
|
655
|
-
svg.style.height = svg.getAttribute("height") || "";
|
|
656
|
-
svg.removeAttribute("width");
|
|
657
|
-
svg.removeAttribute("height");
|
|
658
|
-
const parent = mathContainer.parentElement;
|
|
659
|
-
if (parent) {
|
|
660
|
-
mathContainer.remove();
|
|
661
|
-
parent.appendChild(svg);
|
|
662
|
-
if (parent.classList.contains("block-equation")) {
|
|
663
|
-
parent.setAttribute("style", "text-align: center; margin-bottom: 1rem;");
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
});
|
|
696
|
+
function postRenderMermaidDiagrams(element) {
|
|
667
697
|
const mermaidSvgs = element.querySelectorAll('[data-wenyan-diagram="mermaid"] svg');
|
|
668
698
|
mermaidSvgs.forEach((svg) => {
|
|
669
699
|
svg.style.maxWidth = "100%";
|
|
@@ -671,21 +701,6 @@ function wechatPostRender(element) {
|
|
|
671
701
|
inlineMermaidSvgStyles(svg);
|
|
672
702
|
flattenMermaidMarkers(svg);
|
|
673
703
|
});
|
|
674
|
-
const codeElements = element.querySelectorAll("pre code");
|
|
675
|
-
codeElements.forEach((codeEl) => {
|
|
676
|
-
codeEl.innerHTML = codeEl.innerHTML.replace(/\n/g, "<br>").replace(/(>[^<]+)|(^[^<]+)/g, (str) => str.replace(/\s/g, " "));
|
|
677
|
-
});
|
|
678
|
-
const listElements = element.querySelectorAll("li");
|
|
679
|
-
listElements.forEach((li) => {
|
|
680
|
-
const doc = element.ownerDocument;
|
|
681
|
-
const section = doc.createElement("section");
|
|
682
|
-
while (li.firstChild) {
|
|
683
|
-
section.appendChild(li.firstChild);
|
|
684
|
-
}
|
|
685
|
-
li.appendChild(section);
|
|
686
|
-
});
|
|
687
|
-
element.style.color = "rgb(0, 0, 0)";
|
|
688
|
-
element.style.caretColor = "rgb(0, 0, 0)";
|
|
689
704
|
}
|
|
690
705
|
function inlineMermaidSvgStyles(svg) {
|
|
691
706
|
const styleElements = Array.from(svg.querySelectorAll("style"));
|
|
@@ -949,6 +964,41 @@ function isInlineStyleTarget(node) {
|
|
|
949
964
|
}
|
|
950
965
|
return node instanceof defaultView.SVGElement || node instanceof defaultView.HTMLElement;
|
|
951
966
|
}
|
|
967
|
+
function wechatPostRender(element) {
|
|
968
|
+
const mathElements = element.querySelectorAll("mjx-container");
|
|
969
|
+
mathElements.forEach((mathContainer) => {
|
|
970
|
+
const svg = mathContainer.querySelector("svg");
|
|
971
|
+
if (!svg) return;
|
|
972
|
+
svg.style.width = svg.getAttribute("width") || "";
|
|
973
|
+
svg.style.height = svg.getAttribute("height") || "";
|
|
974
|
+
svg.removeAttribute("width");
|
|
975
|
+
svg.removeAttribute("height");
|
|
976
|
+
const parent = mathContainer.parentElement;
|
|
977
|
+
if (parent) {
|
|
978
|
+
mathContainer.remove();
|
|
979
|
+
parent.appendChild(svg);
|
|
980
|
+
if (parent.classList.contains("block-equation")) {
|
|
981
|
+
parent.setAttribute("style", "text-align: center; margin-bottom: 1rem;");
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
postRenderMermaidDiagrams(element);
|
|
986
|
+
const codeElements = element.querySelectorAll("pre code");
|
|
987
|
+
codeElements.forEach((codeEl) => {
|
|
988
|
+
codeEl.innerHTML = codeEl.innerHTML.replace(/\n/g, "<br>").replace(/(>[^<]+)|(^[^<]+)/g, (str) => str.replace(/\s/g, " "));
|
|
989
|
+
});
|
|
990
|
+
const listElements = element.querySelectorAll("li");
|
|
991
|
+
listElements.forEach((li) => {
|
|
992
|
+
const doc = element.ownerDocument;
|
|
993
|
+
const section = doc.createElement("section");
|
|
994
|
+
while (li.firstChild) {
|
|
995
|
+
section.appendChild(li.firstChild);
|
|
996
|
+
}
|
|
997
|
+
li.appendChild(section);
|
|
998
|
+
});
|
|
999
|
+
element.style.color = "rgb(0, 0, 0)";
|
|
1000
|
+
element.style.caretColor = "rgb(0, 0, 0)";
|
|
1001
|
+
}
|
|
952
1002
|
const themeModifier = createCssModifier({});
|
|
953
1003
|
function renderTheme(wenyanElement, themeCss) {
|
|
954
1004
|
const modifiedCss = themeModifier(themeCss);
|
|
@@ -1492,6 +1542,8 @@ function getContentForZhihu(wenyanElement) {
|
|
|
1492
1542
|
return wenyanElement.outerHTML;
|
|
1493
1543
|
}
|
|
1494
1544
|
function getContentForToutiao(wenyanElement) {
|
|
1545
|
+
postRenderMermaidDiagrams(wenyanElement);
|
|
1546
|
+
processMermaid(wenyanElement);
|
|
1495
1547
|
const containers = wenyanElement.querySelectorAll("mjx-container");
|
|
1496
1548
|
const doc = wenyanElement.ownerDocument;
|
|
1497
1549
|
containers.forEach((container) => {
|
|
@@ -1500,11 +1552,7 @@ function getContentForToutiao(wenyanElement) {
|
|
|
1500
1552
|
return;
|
|
1501
1553
|
}
|
|
1502
1554
|
const img = doc.createElement("img");
|
|
1503
|
-
|
|
1504
|
-
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
1505
|
-
}
|
|
1506
|
-
const encodedSVG = encodeURIComponent(svg.outerHTML);
|
|
1507
|
-
img.src = `data:image/svg+xml,${encodedSVG}`;
|
|
1555
|
+
img.src = createSvgDataUrl(svg);
|
|
1508
1556
|
const style = svg.getAttribute("style");
|
|
1509
1557
|
if (style) {
|
|
1510
1558
|
img.setAttribute("style", style);
|
|
@@ -1519,10 +1567,67 @@ function getContentForToutiao(wenyanElement) {
|
|
|
1519
1567
|
});
|
|
1520
1568
|
return wenyanElement.outerHTML;
|
|
1521
1569
|
}
|
|
1570
|
+
function processMermaid(root) {
|
|
1571
|
+
const figures = root.querySelectorAll('[data-wenyan-diagram="mermaid"]');
|
|
1572
|
+
const doc = root.ownerDocument;
|
|
1573
|
+
figures.forEach((figure) => {
|
|
1574
|
+
const svg = figure.querySelector("svg");
|
|
1575
|
+
if (!svg) {
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
let svgString = svg.outerHTML;
|
|
1579
|
+
svgString = fixMermaidSvgForServerRender(svgString);
|
|
1580
|
+
const img = doc.createElement("img");
|
|
1581
|
+
const encodedData = btoa(unescape(encodeURIComponent(svgString)));
|
|
1582
|
+
img.src = `data:image/svg+xml;base64,${encodedData}`;
|
|
1583
|
+
const style = svg.getAttribute("style");
|
|
1584
|
+
if (style) {
|
|
1585
|
+
img.setAttribute("style", style);
|
|
1586
|
+
}
|
|
1587
|
+
const ariaLabel = figure.getAttribute("aria-label") || figure.getAttribute("title") || svg.getAttribute("aria-label") || svg.getAttribute("title");
|
|
1588
|
+
if (ariaLabel) {
|
|
1589
|
+
img.alt = ariaLabel;
|
|
1590
|
+
}
|
|
1591
|
+
figure.replaceWith(img);
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
function fixMermaidSvgForServerRender(svgString) {
|
|
1595
|
+
const baseFontSize = 16;
|
|
1596
|
+
let fixedSvg = svgString;
|
|
1597
|
+
fixedSvg = fixedSvg.replace(/([xy]|dx|dy)="([-0-9.]+)em"/g, (_, attr, val) => {
|
|
1598
|
+
const pxValue = parseFloat(val) * baseFontSize;
|
|
1599
|
+
return `${attr}="${pxValue}px"`;
|
|
1600
|
+
});
|
|
1601
|
+
let previousSvg;
|
|
1602
|
+
do {
|
|
1603
|
+
previousSvg = fixedSvg;
|
|
1604
|
+
fixedSvg = fixedSvg.replace(/<tspan(?![^>]*\b[xy]=)[^>]*>([\s\S]*?)<\/tspan>/g, "$1");
|
|
1605
|
+
} while (fixedSvg !== previousSvg);
|
|
1606
|
+
fixedSvg = fixedSvg.replace(/<tspan([^>]+)>/g, (match, attrs) => {
|
|
1607
|
+
const yMatch = attrs.match(/y="([-0-9.]+)(?:px)?"/);
|
|
1608
|
+
const dyMatch = attrs.match(/dy="([-0-9.]+)(?:px)?"/);
|
|
1609
|
+
if (yMatch && dyMatch) {
|
|
1610
|
+
const yVal = parseFloat(yMatch[1]);
|
|
1611
|
+
const dyVal = parseFloat(dyMatch[1]);
|
|
1612
|
+
const finalY = yVal + dyVal;
|
|
1613
|
+
let newAttrs = attrs.replace(/y="[-0-9.]+(?:px)?"\s*/, "").replace(/dy="[-0-9.]+(?:px)?"\s*/, "");
|
|
1614
|
+
return `<tspan ${newAttrs.trim()} y="${finalY}">`;
|
|
1615
|
+
}
|
|
1616
|
+
return match;
|
|
1617
|
+
});
|
|
1618
|
+
fixedSvg = fixedSvg.replace(/class="([^"]*?)text-inner-tspan([^"]*?)"/g, 'class="$1$2"');
|
|
1619
|
+
fixedSvg = fixedSvg.replace(/\sclass=""/g, "");
|
|
1620
|
+
return fixedSvg;
|
|
1621
|
+
}
|
|
1622
|
+
const DEFAULT_MERMAID_FONT_FAMILY = "'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Source Han Sans SC', Arial, sans-serif";
|
|
1522
1623
|
const DEFAULT_MERMAID_CONFIG = {
|
|
1624
|
+
fontFamily: DEFAULT_MERMAID_FONT_FAMILY,
|
|
1523
1625
|
htmlLabels: false,
|
|
1524
1626
|
flowchart: {
|
|
1525
1627
|
htmlLabels: false
|
|
1628
|
+
},
|
|
1629
|
+
themeVariables: {
|
|
1630
|
+
fontFamily: DEFAULT_MERMAID_FONT_FAMILY
|
|
1526
1631
|
}
|
|
1527
1632
|
};
|
|
1528
1633
|
async function replaceMermaidCodeBlocks(root, renderDiagram) {
|
|
@@ -1587,6 +1692,7 @@ function createMermaidRenderError(error) {
|
|
|
1587
1692
|
}
|
|
1588
1693
|
function createMermaidConfig(overrides = {}) {
|
|
1589
1694
|
const flowchartOverrides = getRecord(overrides.flowchart);
|
|
1695
|
+
const themeVariablesOverrides = getRecord(overrides.themeVariables);
|
|
1590
1696
|
return {
|
|
1591
1697
|
...DEFAULT_MERMAID_CONFIG,
|
|
1592
1698
|
startOnLoad: false,
|
|
@@ -1595,6 +1701,10 @@ function createMermaidConfig(overrides = {}) {
|
|
|
1595
1701
|
flowchart: {
|
|
1596
1702
|
...getRecord(DEFAULT_MERMAID_CONFIG.flowchart),
|
|
1597
1703
|
...flowchartOverrides
|
|
1704
|
+
},
|
|
1705
|
+
themeVariables: {
|
|
1706
|
+
...getRecord(DEFAULT_MERMAID_CONFIG.themeVariables),
|
|
1707
|
+
...themeVariablesOverrides
|
|
1598
1708
|
}
|
|
1599
1709
|
};
|
|
1600
1710
|
}
|
|
@@ -1625,12 +1735,15 @@ async function createWenyanCore(options = {}) {
|
|
|
1625
1735
|
async handleFrontMatter(markdown) {
|
|
1626
1736
|
return await handleFrontMatter(markdown);
|
|
1627
1737
|
},
|
|
1628
|
-
async renderMarkdown(markdown) {
|
|
1738
|
+
async renderMarkdown(markdown, disableMermaid = false) {
|
|
1629
1739
|
let html = await markedClient.parse(markdown);
|
|
1630
1740
|
if (isConvertMathJax) {
|
|
1631
1741
|
html = mathJaxParser.parser(html);
|
|
1632
1742
|
}
|
|
1633
|
-
|
|
1743
|
+
if (!disableMermaid) {
|
|
1744
|
+
html = await mermaidParser.parser(html);
|
|
1745
|
+
}
|
|
1746
|
+
return html;
|
|
1634
1747
|
},
|
|
1635
1748
|
async applyStylesWithTheme(wenyanElement, options2 = {}) {
|
|
1636
1749
|
const {
|
|
@@ -15,7 +15,7 @@ export interface ApplyStylesOptions {
|
|
|
15
15
|
}
|
|
16
16
|
export declare function createWenyanCore(options?: WenyanOptions): Promise<{
|
|
17
17
|
handleFrontMatter(markdown: string): Promise<FrontMatterResult>;
|
|
18
|
-
renderMarkdown(markdown: string): Promise<string>;
|
|
18
|
+
renderMarkdown(markdown: string, disableMermaid?: boolean): Promise<string>;
|
|
19
19
|
applyStylesWithTheme(wenyanElement: HTMLElement, options?: ApplyStylesOptions): Promise<string>;
|
|
20
20
|
applyStylesWithResolvedCss(wenyanElement: HTMLElement, options: {
|
|
21
21
|
themeCss: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function postRenderMermaidDiagrams(element: HTMLElement): void;
|
package/dist/wrapper.js
CHANGED
|
@@ -731,14 +731,14 @@ function ensureSvgPolyfills(window) {
|
|
|
731
731
|
value() {
|
|
732
732
|
const tagName = this.tagName.toLowerCase();
|
|
733
733
|
if (tagName === "text" || tagName === "tspan") {
|
|
734
|
-
const
|
|
735
|
-
const
|
|
734
|
+
const width = getEstimatedTextWidth(this);
|
|
735
|
+
const height = getEstimatedFontSize(this);
|
|
736
736
|
return {
|
|
737
737
|
x: 0,
|
|
738
|
-
y: -
|
|
738
|
+
y: -height,
|
|
739
739
|
width,
|
|
740
|
-
height
|
|
741
|
-
top: -
|
|
740
|
+
height,
|
|
741
|
+
top: -height,
|
|
742
742
|
right: width,
|
|
743
743
|
bottom: 0,
|
|
744
744
|
left: 0,
|
|
@@ -809,12 +809,61 @@ function ensureSvgPolyfills(window) {
|
|
|
809
809
|
configurable: true,
|
|
810
810
|
writable: true,
|
|
811
811
|
value() {
|
|
812
|
-
|
|
813
|
-
return Math.max(text.length * 8, 16);
|
|
812
|
+
return getEstimatedTextWidth(this);
|
|
814
813
|
}
|
|
815
814
|
});
|
|
816
815
|
}
|
|
817
816
|
}
|
|
817
|
+
function getEstimatedTextWidth(element) {
|
|
818
|
+
const text = element.textContent ?? "";
|
|
819
|
+
const fontSize = getEstimatedFontSize(element);
|
|
820
|
+
const visualLength = Array.from(text).reduce((length, character) => {
|
|
821
|
+
return length + (isWideCharacter(character) ? 2 : 1);
|
|
822
|
+
}, 0);
|
|
823
|
+
return Math.max(visualLength * (fontSize / 2), fontSize);
|
|
824
|
+
}
|
|
825
|
+
function getEstimatedFontSize(element) {
|
|
826
|
+
const inlineFontSize = element.getAttribute("font-size");
|
|
827
|
+
if (inlineFontSize) {
|
|
828
|
+
const parsed = Number.parseFloat(inlineFontSize);
|
|
829
|
+
if (Number.isFinite(parsed)) {
|
|
830
|
+
return parsed;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
const computedFontSize = element.ownerDocument.defaultView?.getComputedStyle(element).fontSize;
|
|
834
|
+
if (computedFontSize) {
|
|
835
|
+
const parsed = Number.parseFloat(computedFontSize);
|
|
836
|
+
if (Number.isFinite(parsed)) {
|
|
837
|
+
return parsed;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return 16;
|
|
841
|
+
}
|
|
842
|
+
function isWideCharacter(character) {
|
|
843
|
+
return character.codePointAt(0) > 255;
|
|
844
|
+
}
|
|
845
|
+
async function extractAndCleanImages(body) {
|
|
846
|
+
const html = await wenyanCoreInstance.renderMarkdown(body);
|
|
847
|
+
const dom = new JSDOM(`<body><section id="wenyan">${html}</section></body>`);
|
|
848
|
+
const document = dom.window.document;
|
|
849
|
+
const wenyan = document.getElementById("wenyan");
|
|
850
|
+
const images = Array.from(wenyan.querySelectorAll("img"));
|
|
851
|
+
const imagePaths = images.map((img) => img.getAttribute("src")).filter((src) => !!src).map((src) => {
|
|
852
|
+
try {
|
|
853
|
+
return decodeURI(src);
|
|
854
|
+
} catch {
|
|
855
|
+
return src;
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
for (const img of images) {
|
|
859
|
+
const parent = img.parentElement;
|
|
860
|
+
img.remove();
|
|
861
|
+
if (parent && parent.tagName === "P" && parent.textContent?.trim() === "") {
|
|
862
|
+
parent.remove();
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return { imagePaths, cleanedHtml: wenyan.outerHTML };
|
|
866
|
+
}
|
|
818
867
|
const nodeMermaidRenderer = createNodeMermaidRenderer();
|
|
819
868
|
const wenyanCoreInstance = await createWenyanCore({
|
|
820
869
|
mermaid: {
|
|
@@ -859,6 +908,13 @@ async function renderStyledContent(content, options = {}, coreInstance = wenyanC
|
|
|
859
908
|
async function prepareRenderContext(inputContent, options, getInputContent) {
|
|
860
909
|
const { content, absoluteDirPath } = await getInputContent(inputContent, options.file);
|
|
861
910
|
const preHandlerContent = await wenyanCoreInstance.handleFrontMatter(content);
|
|
911
|
+
if (preHandlerContent.type === "image" && !preHandlerContent.image_list) {
|
|
912
|
+
const { imagePaths, cleanedHtml } = await extractAndCleanImages(preHandlerContent.content);
|
|
913
|
+
if (imagePaths.length > 0) {
|
|
914
|
+
preHandlerContent.image_list = imagePaths;
|
|
915
|
+
preHandlerContent.content = cleanedHtml;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
862
918
|
if (preHandlerContent.image_list && preHandlerContent.image_list.length > 0) {
|
|
863
919
|
return { gzhContent: preHandlerContent, absoluteDirPath };
|
|
864
920
|
}
|
package/package.json
CHANGED