ctai/ctai_cmark-gfm.cpp
2025-03-05 19:39:50 +08:00

112 lines
2.8 KiB
C++

#include "ctai_cmark-gfm.h"
namespace ctai_cmark_gfm {
MarkdownStreamProcessor::MarkdownStreamProcessor(QTextEdit* textEdit)
: m_textEdit(textEdit)
, m_buffer()
, m_tempText() {
}
MarkdownStreamProcessor::~MarkdownStreamProcessor() {
// 确保在销毁时处理所有剩余的缓冲内容
if (!m_buffer.isEmpty()) {
handleBufferOverflow();
}
}
void MarkdownStreamProcessor::appendMarkdown(const QString& text) {
// 将新内容添加到缓冲区
QString newBuffer = m_buffer + text;
// 检查是否超出缓冲区大小
if (newBuffer.size() > BUFFER_SIZE) {
handleBufferOverflow();
newBuffer = text;
}
// 检查是否只包含开始标记
if (hasMarkdownStart(text) && !hasMarkdownEnd(text)) {
m_buffer = newBuffer;
m_tempText = text;
m_textEdit->append(text);
return;
}
// 检查是否包含结束标记
if (hasMarkdownEnd(text)) {
QString fullContent = m_buffer + text;
QString rendered = renderMarkdown(fullContent);
replaceTempText(rendered);
m_buffer.clear();
return;
}
m_buffer = newBuffer;
}
bool MarkdownStreamProcessor::hasMarkdownStart(const QString& text) {
// 检查常见的Markdown开始标记
static const QStringList startMarkers = {
"```", "~~~", "#", ">", "*", "_", "-", "+", "[", "|"
};
for (const QString& marker : startMarkers) {
if (text.contains(marker)) {
return true;
}
}
return false;
}
bool MarkdownStreamProcessor::hasMarkdownEnd(const QString& text) {
// 检查常见的Markdown结束标记
static const QStringList endMarkers = {
"```", "~~~", "\n\n", "]", "*", "_"
};
for (const QString& marker : endMarkers) {
if (text.contains(marker)) {
return true;
}
}
return false;
}
QString MarkdownStreamProcessor::renderMarkdown(const QString& text) {
QByteArray textUtf8 = text.toUtf8();
char* rendered = cmark_markdown_to_html(
textUtf8.constData(),
textUtf8.size(),
CMARK_OPT_DEFAULT
);
QString result = QString::fromUtf8(rendered);
free(rendered);
return result;
}
void MarkdownStreamProcessor::handleBufferOverflow() {
if (!m_buffer.isEmpty()) {
QString rendered = renderMarkdown(m_buffer);
replaceTempText(rendered);
m_buffer.clear();
}
}
void MarkdownStreamProcessor::replaceTempText(const QString& newContent) {
if (!m_tempText.isEmpty()) {
// 获取当前文本
QString currentText = m_textEdit->toPlainText();
// 替换临时文本
currentText.replace(m_tempText, newContent);
m_textEdit->setHtml(currentText);
m_tempText.clear();
} else {
m_textEdit->append(newContent);
}
}
}