fix: 修复 Mermaid 代码块缩进和 API 兼容性问题
- 添加智能缩进清理:移除统一缩进但保持相对缩进 - 添加 Mermaid API 版本检测和兼容性处理 - 支持 Mermaid 10.x (render Promise API) - 支持 Mermaid 8.x (mermaidAPI.render 回调 API) - 添加降级方案 (mermaid.init 方法) - 增强错误处理和调试日志 - 修复代码提取时的空格问题
This commit is contained in:
104
argontheme.js
104
argontheme.js
@@ -3964,11 +3964,41 @@ function convertMermaidCodeblocks(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 提取代码
|
// 提取代码
|
||||||
let code = element.textContent.trim();
|
let code = element.textContent;
|
||||||
|
|
||||||
|
// 清理代码:移除前后空白,但保留内部换行
|
||||||
|
code = code.trim();
|
||||||
|
|
||||||
|
// 如果代码为空,跳过
|
||||||
if (!code) {
|
if (!code) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移除每行开头的统一缩进(保持相对缩进)
|
||||||
|
const lines = code.split('\n');
|
||||||
|
if (lines.length > 1) {
|
||||||
|
// 找到最小缩进
|
||||||
|
let minIndent = Infinity;
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line.trim().length > 0) {
|
||||||
|
const indent = line.match(/^\s*/)[0].length;
|
||||||
|
if (indent < minIndent) {
|
||||||
|
minIndent = indent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 移除最小缩进
|
||||||
|
if (minIndent > 0 && minIndent !== Infinity) {
|
||||||
|
code = lines.map(line => {
|
||||||
|
if (line.trim().length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return line.substring(minIndent);
|
||||||
|
}).join('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 创建容器
|
// 创建容器
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
container.className = 'mermaid-from-codeblock';
|
container.className = 'mermaid-from-codeblock';
|
||||||
@@ -4881,13 +4911,39 @@ void 0;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logDebug(`准备渲染图表: ${chartId}, 代码长度: ${code.length}`);
|
||||||
|
this.logDebug(`代码内容: ${code.substring(0, 200)}`);
|
||||||
|
|
||||||
// 创建容器
|
// 创建容器
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
container.className = 'mermaid-container';
|
container.className = 'mermaid-container';
|
||||||
container.id = chartId;
|
container.id = chartId;
|
||||||
|
|
||||||
|
// 检查 Mermaid API
|
||||||
|
if (typeof window.mermaid === 'undefined') {
|
||||||
|
this.logError('Mermaid 库未加载');
|
||||||
|
this.handleRenderError(element, new Error('Mermaid 库未加载'), code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window.mermaid.render !== 'function') {
|
||||||
|
this.logError('Mermaid.render 方法不存在');
|
||||||
|
this.handleRenderError(element, new Error('Mermaid.render 方法不存在'), code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 渲染图表
|
// 渲染图表
|
||||||
window.mermaid.render(`mermaid-svg-${chartId}`, code).then(result => {
|
const renderPromise = window.mermaid.render(`mermaid-svg-${chartId}`, code);
|
||||||
|
|
||||||
|
// 检查返回值是否是 Promise
|
||||||
|
if (!renderPromise || typeof renderPromise.then !== 'function') {
|
||||||
|
this.logError('Mermaid.render 没有返回 Promise,可能是版本不兼容');
|
||||||
|
// 尝试使用旧版 API
|
||||||
|
this.renderChartLegacy(element, code, container, chartId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPromise.then(result => {
|
||||||
// 渲染成功
|
// 渲染成功
|
||||||
container.innerHTML = result.svg;
|
container.innerHTML = result.svg;
|
||||||
|
|
||||||
@@ -4907,14 +4963,58 @@ void 0;
|
|||||||
this.logDebug(`图表渲染成功: ${chartId}`);
|
this.logDebug(`图表渲染成功: ${chartId}`);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
// 渲染失败
|
// 渲染失败
|
||||||
|
this.logError(`图表渲染失败: ${chartId}`, error);
|
||||||
this.handleRenderError(element, error, code);
|
this.handleRenderError(element, error, code);
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
this.logError(`渲染异常: ${chartId}`, error);
|
||||||
this.handleRenderError(element, error, '');
|
this.handleRenderError(element, error, '');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用旧版 Mermaid API 渲染(兼容 Mermaid 8.x)
|
||||||
|
* @param {HTMLElement} element - 原始代码块元素
|
||||||
|
* @param {string} code - Mermaid 代码
|
||||||
|
* @param {HTMLElement} container - 容器元素
|
||||||
|
* @param {string} chartId - 图表 ID
|
||||||
|
*/
|
||||||
|
renderChartLegacy(element, code, container, chartId) {
|
||||||
|
try {
|
||||||
|
this.logDebug('尝试使用旧版 Mermaid API');
|
||||||
|
|
||||||
|
// Mermaid 8.x 使用 mermaidAPI.render
|
||||||
|
if (typeof window.mermaidAPI !== 'undefined' && typeof window.mermaidAPI.render === 'function') {
|
||||||
|
window.mermaidAPI.render(`mermaid-svg-${chartId}`, code, (svgCode) => {
|
||||||
|
container.innerHTML = svgCode;
|
||||||
|
container.dataset.mermaidCode = code;
|
||||||
|
container.dataset.currentTheme = this.getMermaidTheme();
|
||||||
|
element.parentNode.replaceChild(container, element);
|
||||||
|
this.rendered.add(container);
|
||||||
|
this.applyStyles(container);
|
||||||
|
this.logDebug(`图表渲染成功(旧版 API): ${chartId}`);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 最后的降级方案:直接使用 mermaid.init()
|
||||||
|
container.className = 'mermaid';
|
||||||
|
container.textContent = code;
|
||||||
|
element.parentNode.replaceChild(container, element);
|
||||||
|
|
||||||
|
if (typeof window.mermaid.init === 'function') {
|
||||||
|
window.mermaid.init(undefined, container);
|
||||||
|
this.rendered.add(container);
|
||||||
|
this.logDebug(`图表渲染成功(init 方法): ${chartId}`);
|
||||||
|
} else {
|
||||||
|
this.handleRenderError(element, new Error('无可用的 Mermaid 渲染方法'), code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logError('旧版 API 渲染失败', error);
|
||||||
|
this.handleRenderError(element, error, code);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理渲染错误
|
* 处理渲染错误
|
||||||
* @param {HTMLElement} element - 原始代码块元素
|
* @param {HTMLElement} element - 原始代码块元素
|
||||||
|
|||||||
Reference in New Issue
Block a user