问题
我以前是这样调用 Lute 的
Lute.New().Md2BlockDOM(`xxxxx`)
直到我遇到了以下 2 钟情况,发现同样的 Markdown 源码,这种调用方式生成的 dom 与思源笔记生成的 dom 不一致。
一种是引用 ((20250204141259-tcoyqqe 'xcvfv'))
,
一种是 #### b<span data-type="text" style="color: var(--b3-font-color9);">bb</span>{: style="color: var(--b3-font-color9);"}bb
这两种方式如果使用 Lute.New().Md2BlockDOM(`xxxxx`)
调用的话,结果与思源笔记解析的结果不一致。
详见 Issue #14310 · siyuan-note/siyuan
解决方法
解决方法就像上面 issue 当中 @88250 和 @JeffreyChen 两位大佬所说的那样,先对 Lute 进行配置。
现已把两位大佬的回复封装成简单的调用方法。
调用方式:getLute().Md2BlockDOM(`xxxxx`);
封装函数如下:
function getLute() {
const setLute = (options) => {
const lute = window.Lute.New();
lute.SetSpellcheck(window.siyuan.config.editor.spellcheck);
lute.SetProtyleMarkNetImg(window.siyuan.config.editor.displayNetImgMark);
lute.SetFileAnnotationRef(true);
lute.SetHTMLTag2TextMark(true);
lute.SetTextMark(true);
lute.SetHeadingID(false);
lute.SetYamlFrontMatter(false);
lute.PutEmojis(options.emojis);
lute.SetEmojiSite(options.emojiSite);
lute.SetHeadingAnchor(options.headingAnchor);
lute.SetInlineMathAllowDigitAfterOpenMarker(true);
lute.SetToC(false);
lute.SetIndentCodeBlock(false);
lute.SetParagraphBeginningSpace(true);
lute.SetSetext(false);
lute.SetFootnotes(false);
lute.SetLinkRef(false);
lute.SetSanitize(options.sanitize);
lute.SetChineseParagraphBeginningSpace(options.paragraphBeginningSpace);
lute.SetRenderListStyle(options.listStyle);
lute.SetImgPathAllowSpace(true);
lute.SetKramdownIAL(true);
lute.SetTag(true);
lute.SetSuperBlock(true);
lute.SetMark(true);
lute.SetInlineAsterisk(window.siyuan.config.editor.markdown.inlineAsterisk);
lute.SetInlineUnderscore(window.siyuan.config.editor.markdown.inlineUnderscore);
lute.SetSup(window.siyuan.config.editor.markdown.inlineSup);
lute.SetSub(window.siyuan.config.editor.markdown.inlineSub);
lute.SetTag(window.siyuan.config.editor.markdown.inlineTag);
lute.SetInlineMath(window.siyuan.config.editor.markdown.inlineMath);
lute.SetGFMStrikethrough1(false);
lute.SetGFMStrikethrough(window.siyuan.config.editor.markdown.inlineStrikethrough);
lute.SetMark(window.siyuan.config.editor.markdown.inlineMark);
lute.SetSpin(true);
lute.SetProtyleWYSIWYG(true);
if (options.lazyLoadImage) {
lute.SetImageLazyLoading(options.lazyLoadImage);
}
lute.SetBlockRef(true);
if (window.siyuan.emojis[0].items.length > 0) {
const emojis = {};
window.siyuan.emojis[0].items.forEach(item => {
emojis[item.keywords] = options.emojiSite + "/" + item.unicode;
});
lute.PutEmojis(emojis);
}
return lute;
};
// 1. 优化查找函数(仅匹配 .editor.protyle 结尾路径)
function findProtylePaths(obj) {
const results = [];
const seen = new Set();
function walk(obj, path = '') {
if (!obj || seen.has(obj)) return;
seen.add(obj);
for (const [key, value] of Object.entries(obj)) {
const currentPath = path ? `${path}.${key}` : key;
// 检查是否以 .editor.protyle 结尾
if (currentPath.endsWith('.editor.protyle')) {
results.push({ path: currentPath, value });
}
if (typeof value === 'object') {
walk(value, currentPath);
}
}
}
walk(obj);
return results;
}
// 2. 获取目标对象
const protylePaths = findProtylePaths(window.siyuan);
const firstProtyle = protylePaths[0]?.value;
if (firstProtyle) {
// 3. 动态设置 lute 并调用
firstProtyle.lute = setLute({
emojiSite: firstProtyle.options?.hint?.emojiPath,
emojis: firstProtyle.options?.hint?.emoji,
headingAnchor: false,
listStyle: firstProtyle.options?.preview?.markdown?.listStyle,
paragraphBeginningSpace: firstProtyle.options?.preview?.markdown?.paragraphBeginningSpace,
sanitize: firstProtyle.options?.preview?.markdown?.sanitize,
});
// 4. 获取lute实例
return firstProtyle.lute;
} else {
console.warn('未找到符合条件的 protyle 对象');
return Lute.New();
}
}
鸣谢
@88250 @JeffreyChen 感谢两位大佬!
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于