#include "ctaiMathConvert.h" ctaiMathConvert::ctaiMathConvert() { } ctaiMathConvert::~ctaiMathConvert() { } void ctaiMathConvert::set_convert_opts() { } void ctaiMathConvert::save_svg(QPixmap &img) { QString uid = QUuid::createUuid().toString(QUuid::WithoutBraces); QString svgName = QDir::currentPath() + "/svg/" + uid + ".png"; bool ok = img.save(svgName); } QByteArray ctaiMathConvert::svg_to_base64(QPixmap &pix) { QByteArray data; QBuffer buffer(&data); QImage img = pix.toImage(); img.save(&buffer, "PNG"); data = data.toBase64(); return data; } QString ctaiMathConvert::math_convert_svg(const QString &math) { QString res = QDir::currentPath() + "/res/"; auto render = LaTeX::parse(math.toStdWString(), m_render_width, m_text_size, m_lineSpace, m_color); QPixmap pix(render->getWidth() + m_padding * 2, render->getHeight() + m_padding * 2); pix.fill(Qt::white); QPainter painter(&pix); painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing); Graphics2D_qt g2(&painter); render->draw(g2, m_padding, m_padding); // save_svg(pix); return QString::fromUtf8(svg_to_base64(pix)); } void ctaiMathConvert::debug_latex_match(const QString &text, const QRegularExpressionMatch &match) { qDebug() << "=== LaTeX匹配信息 ==="; qDebug() << "匹配位置:" << match.capturedStart() << "-" << match.capturedEnd(); qDebug() << "匹配文本:" << match.captured(0); qDebug() << "数学内容:" << match.captured(1); // 显示匹配位置的上下文 int contextSize = 20; int start = qMax(0, match.capturedStart() - contextSize); int end = qMin(text.length(), match.capturedEnd() + contextSize); QString context = text.mid(start, end - start); qDebug() << "上下文:" << context; qDebug() << "=================="; } QString ctaiMathConvert::clean_latex_for_mula(const QString &formula) { QString result = formula; // 清理可能的多余空白字符 result = result.trimmed(); // 处理可能的换行符 result.replace(QRegularExpression(R"(\s+)"), " "); return result; } QString ctaiMathConvert::replace_tags_svg(const QString &text, int font_size) { m_text_size = font_size * 1.5; QString result = text; // 使用改进的正则表达式模式 QRegularExpression latexPattern( QString(R"(\\[(](.*?)\\[)]|\\[{](.*?)\\[}]|\\[[](.*?)\\])"), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption); // 添加调试信息 qDebug() << "输入文本:" << result; qDebug() << "正则表达式:" << latexPattern.pattern(); qDebug() << "正则表达式是否有效:" << latexPattern.isValid(); QRegularExpressionMatchIterator iterator = latexPattern.globalMatch(result); // 收集所有替换操作 QList> replacements; QStringList svgResults; // 定义基础图片标签 const QString markdown_base = "![math](data:image/png;base64,"; while (iterator.hasNext()) { QRegularExpressionMatch match = iterator.next(); QString matchedText = match.captured(0); if (debug_node_print) { debug_latex_match(result, match); } // 清理和转换公式 QString cleanFormula = clean_latex_for_mula(matchedText); QString svg_markdown = markdown_base + math_convert_svg(cleanFormula) + ")"; // 保存替换信息 replacements.prepend({match.capturedStart(), match.capturedLength()}); svgResults.prepend(svg_markdown); } // 从后向前执行替换,避免位置改变影响 for (int i = 0; i < replacements.size(); ++i) { const auto &rep = replacements[i]; result.replace(rep.first, rep.second, svgResults[i]); } return markdown_to_html(result); } QString ctaiMathConvert::markdown_to_html(const QString &text) { // 转换为UTF-8编码的字符串 QByteArray markdown = text.toUtf8(); // 启用所有 GFM 扩展选项 int options = CMARK_OPT_SOURCEPOS | CMARK_OPT_VALIDATE_UTF8 | CMARK_OPT_HARDBREAKS | CMARK_OPT_SMART | CMARK_OPT_GITHUB_PRE_LANG | CMARK_OPT_LIBERAL_HTML_TAG | CMARK_OPT_FOOTNOTES | CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE | CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES | CMARK_NODE_TEXT| CMARK_OPT_FULL_INFO_STRING; // 解析Markdown为AST cmark_node *doc = cmark_parse_document(markdown.constData(), markdown.size(), options); if (debug_node_print) { // 递归打印AST节点 print_ast_node(doc, 0); } // 转换为HTML char *html = cmark_render_html(doc, options, NULL); QString result = QString::fromUtf8(html); replace_symbol(result); // 释放内存 cmark_node_free(doc); free(html); replace_css(result); return fix_img_str_line_height(result.toUtf8()); } void ctaiMathConvert::replace_css(QString& context){ context.replace("