Files
crypto_monitor/static/ai_review_render.js
T
2026-05-27 16:32:30 +08:00

135 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AI 日复盘 / 周复盘:Markdown 子集渲染 + 五节大标题图标兜底
*/
(function (global) {
"use strict";
var SECTION_FIXES = [
{ re: /^\*\*1\.\s*(?!📊)总体盈亏结构\*\*/m, rep: "**1. 📊 总体盈亏结构**" },
{ re: /^\*\*2\.\s*(?!🧠)心态与执行\*\*/m, rep: "**2. 🧠 心态与执行**" },
{ re: /^\*\*3\.\s*(?!🏷️)行为标签\*\*/m, rep: "**3. 🏷️ 行为标签**" },
{ re: /^\*\*4\.\s*(?!✅)改进建议\*\*/m, rep: "**4. ✅ 改进建议**" },
{ re: /^\*\*5\.\s*(?!📈)图表(?:分析)?\*\*/m, rep: "**5. 📈 图表分析**" },
{ re: /^1\.\s*(?!📊)总体盈亏结构/m, rep: "**1. 📊 总体盈亏结构**" },
{ re: /^2\.\s*(?!🧠)心态与执行/m, rep: "**2. 🧠 心态与执行**" },
{ re: /^3\.\s*(?!🏷️)行为标签/m, rep: "**3. 🏷️ 行为标签**" },
{ re: /^4\.\s*(?!✅)改进建议/m, rep: "**4. ✅ 改进建议**" },
{ re: /^5\.\s*(?!📈)图表/m, rep: "**5. 📈 图表分析**" },
];
function escapeHtml(s) {
return String(s || "")
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
function parseInline(raw) {
var s = escapeHtml(raw);
s = s.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
s = s.replace(/`([^`]+)`/g, "<code>$1</code>");
return s;
}
function enhanceReviewHeadings(text) {
var out = String(text || "");
SECTION_FIXES.forEach(function (item) {
out = out.replace(item.re, item.rep);
});
if (/^【系统说明/m.test(out) && !/^️/m.test(out)) {
out = out.replace(/^【系统说明/gm, "️ 【系统说明");
}
if (/^原始记录:/m.test(out) && !/^📎/m.test(out)) {
out = out.replace(/^原始记录:/gm, "📎 **原始记录**");
}
return out;
}
function renderMarkdown(text) {
var src = enhanceReviewHeadings(text);
var lines = src.replace(/\r\n/g, "\n").split("\n");
var html = [];
var inUl = false;
var inOl = false;
function closeLists() {
if (inUl) {
html.push("</ul>");
inUl = false;
}
if (inOl) {
html.push("</ol>");
inOl = false;
}
}
lines.forEach(function (line) {
var trimmed = line.trim();
if (!trimmed) {
closeLists();
return;
}
var hm = trimmed.match(/^(#{1,3})\s+(.+)$/);
if (hm) {
closeLists();
var level = hm[1].length + 1;
if (level > 4) level = 4;
html.push("<h" + level + ">" + parseInline(hm[2]) + "</h" + level + ">");
return;
}
var ulm = trimmed.match(/^[-*]\s+(.+)$/);
if (ulm) {
if (!inUl) {
closeLists();
html.push("<ul>");
inUl = true;
}
html.push("<li>" + parseInline(ulm[1]) + "</li>");
return;
}
var olm = trimmed.match(/^\d+\.\s+(.+)$/);
if (olm && !/^\*\*/.test(trimmed)) {
if (!inOl) {
closeLists();
html.push("<ol>");
inOl = true;
}
html.push("<li>" + parseInline(olm[1]) + "</li>");
return;
}
closeLists();
if (/^📎\s*\*\*原始记录\*\*/.test(trimmed) || /^原始记录:/.test(trimmed)) {
html.push('<div class="md-raw-block-title">' + parseInline(trimmed) + "</div>");
return;
}
html.push("<p>" + parseInline(trimmed) + "</p>");
});
closeLists();
return html.join("\n");
}
function setElementMarkdown(el, rawText) {
if (!el) return;
var raw = String(rawText || "");
el.dataset.markdownRaw = raw;
el.classList.add("ai-result-md");
el.innerHTML = renderMarkdown(raw);
}
function getElementMarkdown(el) {
if (!el) return "";
if (el.dataset && el.dataset.markdownRaw != null) {
return el.dataset.markdownRaw;
}
return el.innerText || "";
}
global.AiReviewRender = {
enhanceReviewHeadings: enhanceReviewHeadings,
renderMarkdown: renderMarkdown,
setElementMarkdown: setElementMarkdown,
getElementMarkdown: getElementMarkdown,
};
})(typeof window !== "undefined" ? window : this);