- 归档 OnlyOffice live bridge、Page AI、mindmap、design governance 与相关 bug 条目 - 补齐 MinerU OCR 后端 runtime 合同与 smoke/test 基线 - 收口 ChatOnly/Doubao、ObjectIdentity、Page Aggregate compat 与 runtime owner 文档口径 验证: - cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1 - cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1 - git diff --check - git diff --cached --check - codegraph index . --force && codegraph status . - codegraph sync . && codegraph status .
108 lines
3.7 KiB
JavaScript
108 lines
3.7 KiB
JavaScript
export function createSidebarPageAiMarkdownRuntime(context) {
|
|
const { escapeHtml } = context;
|
|
|
|
function textFromUnknown(value) {
|
|
if (value == null) return '';
|
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
if (Array.isArray(value)) return value.map(textFromUnknown).filter(Boolean).join(' ');
|
|
if (typeof value !== 'object') return '';
|
|
var parts = [];
|
|
['text', 'title', 'content', 'children', 'blocks', 'body'].forEach(function(key) {
|
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
var text = textFromUnknown(value[key]);
|
|
if (text) parts.push(text);
|
|
}
|
|
});
|
|
return parts.join(' ');
|
|
}
|
|
|
|
function renderPageAiMarkdownInline(text) {
|
|
var html = escapeHtml(String(text || ''));
|
|
var codeSpans = [];
|
|
html = html.replace(/`([^`\n]+)`/g, function(_, code) {
|
|
var key = '\u0000CODE' + codeSpans.length + '\u0000';
|
|
codeSpans.push('<code>' + code + '</code>');
|
|
return key;
|
|
});
|
|
html = html.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>');
|
|
html = html.replace(/(^|[^*])\*([^*\n]+)\*/g, '$1<em>$2</em>');
|
|
codeSpans.forEach(function(value, index) {
|
|
html = html.replace('\u0000CODE' + index + '\u0000', value);
|
|
});
|
|
return html;
|
|
}
|
|
|
|
function renderPageAiMarkdown(content) {
|
|
var lines = String(content || '').replace(/\r\n?/g, '\n').split('\n');
|
|
var blocks = [];
|
|
var index = 0;
|
|
function isBlockBoundary(line) {
|
|
return !line.trim() ||
|
|
/^```/.test(line.trim()) ||
|
|
/^#{1,6}\s+/.test(line) ||
|
|
/^\s*[-*]\s+/.test(line) ||
|
|
/^\s*\d+[.)]\s+/.test(line);
|
|
}
|
|
while (index < lines.length) {
|
|
var line = lines[index];
|
|
if (!line.trim()) {
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (/^```/.test(line.trim())) {
|
|
index += 1;
|
|
var codeLines = [];
|
|
while (index < lines.length && !/^```/.test(lines[index].trim())) {
|
|
codeLines.push(lines[index]);
|
|
index += 1;
|
|
}
|
|
if (index < lines.length) index += 1;
|
|
blocks.push('<pre><code>' + escapeHtml(codeLines.join('\n')) + '</code></pre>');
|
|
continue;
|
|
}
|
|
var heading = line.match(/^(#{1,6})\s+(.+)$/);
|
|
if (heading) {
|
|
var level = Math.min(6, heading[1].length);
|
|
blocks.push('<h' + level + '>' + renderPageAiMarkdownInline(heading[2]) + '</h' + level + '>');
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (/^\s*[-*]\s+/.test(line)) {
|
|
var unordered = [];
|
|
while (index < lines.length && /^\s*[-*]\s+/.test(lines[index])) {
|
|
unordered.push('<li>' + renderPageAiMarkdownInline(lines[index].replace(/^\s*[-*]\s+/, '')) + '</li>');
|
|
index += 1;
|
|
}
|
|
blocks.push('<ul>' + unordered.join('') + '</ul>');
|
|
continue;
|
|
}
|
|
if (/^\s*\d+[.)]\s+/.test(line)) {
|
|
var ordered = [];
|
|
while (index < lines.length && /^\s*\d+[.)]\s+/.test(lines[index])) {
|
|
ordered.push('<li>' + renderPageAiMarkdownInline(lines[index].replace(/^\s*\d+[.)]\s+/, '')) + '</li>');
|
|
index += 1;
|
|
}
|
|
blocks.push('<ol>' + ordered.join('') + '</ol>');
|
|
continue;
|
|
}
|
|
var paragraph = [];
|
|
while (index < lines.length && !isBlockBoundary(lines[index])) {
|
|
paragraph.push(renderPageAiMarkdownInline(lines[index]));
|
|
index += 1;
|
|
}
|
|
if (paragraph.length) {
|
|
blocks.push('<p>' + paragraph.join('<br />') + '</p>');
|
|
} else {
|
|
index += 1;
|
|
}
|
|
}
|
|
return blocks.join('') || escapeHtml(String(content || ''));
|
|
}
|
|
|
|
return {
|
|
textFromUnknown,
|
|
renderPageAiMarkdown,
|
|
renderPageAiMarkdownInline
|
|
};
|
|
}
|