重新构建cmark-gfm

This commit is contained in:
JackLee 2025-03-06 15:38:38 +08:00
parent 6890c4b71d
commit 3c3d360b55
7 changed files with 55 additions and 66 deletions

View File

@ -62,7 +62,7 @@ include_directories(${JSON}/include)
find_package(CURL REQUIRED)
#cmark
find_package(cmark CONFIG REQUIRED)
#find_package(cmark CONFIG REQUIRED)
#cmark-gfm
add_subdirectory(${PROJECT_SOURCE_DIR}/3rdparty/cmark-gfm)
@ -151,7 +151,7 @@ target_link_libraries(
Qt6::Gui
Qt6::Widgets
CURL::libcurl
cmark::cmark
#cmark::cmark
libcmark-gfm-extensions_static
libcmark-gfm_static
microtex

16
src/ctai_cmark_gfm.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "ctai_cmark_gfm.h"
ctai_cmark_gfm::ctai_cmark_gfm(QTextEdit *textEdit)
: m_textEdit(textEdit), m_buffer()
{
}
ctai_cmark_gfm::~ctai_cmark_gfm()
{
}
void ctai_cmark_gfm::appendMarkdown(const QString &markdown)
{
}

24
src/ctai_cmark_gfm.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef CTAI_CMARK_GFM_H
#define CTAI_CMARK_GFM_H
#include "cmark-gfm.h"
#include "cmark-gfm-extension_api.h"
#include "cmark-gfm-core-extensions.h"
#include <QString>
#include <QTextEdit>
class ctai_cmark_gfm {
public:
explicit ctai_cmark_gfm(QTextEdit* textEdit);
~ctai_cmark_gfm();
// 追加内容并处理Markdown
void appendMarkdown(const QString& text);
private:
static constexpr size_t BUFFER_SIZE = 4096;
QTextEdit* m_textEdit;
QString m_buffer;
};
#endif

View File

@ -91,6 +91,7 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
// 5. 历史信息QTextEdit
historyLayout = new QVBoxLayout();
m_msg_history = new QTextEdit();
m_cmark_gfm=new ctai_cmark_gfm(m_msg_history);
m_msg_history->setAcceptRichText(true);
m_msg_history->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_msg_history->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
@ -126,7 +127,7 @@ void ctai_history_textedit::connect_signals(msg_type msg_type_mode)
{
connect(m_msg_user_del, SIGNAL(clicked()), this, SLOT(on_delete_clicked()));
}
connect(m_msg_history->document(), SIGNAL(contentsChanged()), this, SLOT(on_text_height()));
connect(m_msg_history, SIGNAL(textChanged()), this, SLOT(on_sync_text_height()));
}
// tokens按钮实现功能的槽函数
@ -196,6 +197,7 @@ void ctai_history_textedit::on_save_clicked()
m_msg_save_menu->addAction(m_msg_save_pdf);
m_msg_save_menu->exec(QCursor::pos());
}
// 实现折叠功能的槽函数
void ctai_history_textedit::on_fold_clicked()
{
@ -206,7 +208,7 @@ void ctai_history_textedit::on_fold_clicked()
updateGeometry();
emit row_height_changed(m_is_folded);
}
void ctai_history_textedit::on_text_height()
void ctai_history_textedit::on_sync_text_height()
{
// 防抖动处理如果上次更新在100ms内则延迟处理
static QTimer debounceTimer;
@ -243,8 +245,8 @@ void ctai_history_textedit::on_text_height()
{
QTimer::singleShot(100, [parent]()
{
QEvent e(QEvent::LayoutRequest);
QApplication::sendEvent(parent, &e); });
QEvent e(QEvent::LayoutRequest);
QApplication::sendEvent(parent, &e); });
}
}
}
@ -254,7 +256,7 @@ void ctai_history_textedit::on_text_height()
void ctai_history_textedit::add_user_message(const model_data &message)
{
QString disp_data;
disp_data = ctai_markdown::md_to_html(QSL(message.send_user_data));
disp_data = QSL(message.send_user_data);
m_msg_sned_id = QSL(message.send_user_id);
m_msg_history->setHtml(disp_data);
}
@ -269,12 +271,12 @@ void ctai_history_textedit::add_system_message(const model_data &message)
{
// 流式模式下追加内容
m_current_content += message.postback_model_data;
m_msg_history->setHtml(ctai_markdown::md_to_html(m_current_content));
m_cmark_gfm->appendMarkdown(QSL(message.postback_model_data));
}
else
{
// 非流式模式直接设置全部内容
disp_data = ctai_markdown::md_to_html(QSL(message.postback_model_data));
disp_data = QSL(message.postback_model_data);
m_msg_history->setHtml(disp_data);
m_current_content = QSL(message.postback_model_data);
}

View File

@ -29,7 +29,7 @@
#include <mutex>
// 项目相关头文件
#include "ctai_base.h"
#include "ctai_markdown.h"
#include "ctai_cmark_gfm.h"
typedef struct tokens_args{
QString prompt_tokens={};
@ -63,13 +63,14 @@ private slots:
void on_save_html(); // 保存html
void on_save_markdown(); // 保存markdown
void on_save_pdf(); // 保存pdf
void on_text_height();
void on_sync_text_height();
signals:
void delete_requested(QString); // 请求删除此消息
void row_height_changed(bool);
private:
void connect_signals(msg_type msg_type_mode); // 连接信号和槽
void connect_signals(msg_type msg_type_mode);// 连接信号和槽
private:
ctai_cmark_gfm* m_cmark_gfm;
QFrame *hLine;
QSpacerItem *sparcer_item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
QVBoxLayout *mainLayout={};

View File

@ -1,40 +0,0 @@
#include "ctai_markdown.h"
namespace ctai_markdown {
QString md_to_html(const QString& text) {
// 转换为UTF-8编码的字符串
QByteArray markdown = text.toUtf8();
// 使用cmark解析Markdown
char *html = cmark_markdown_to_html(
markdown.constData(),
markdown.size(),
CMARK_OPT_DEFAULT
);
// 转换回QString并处理代码块
QString result = QString::fromUtf8(html);
free(html);
//qDebug()<<"处理的块:"<<result;
return process_code_blocks(result.toUtf8());
}
QString process_code_blocks(QString html) {
// 添加代码块样式
html.replace(
"<pre><code>",
"<pre><code style='display:block; padding:1em; "
"background-color:#f6f8fa; border-radius:4px; "
"font-family:Consolas,monospace; font-size:13px;'>"
);
// 添加内联代码样式
html.replace(
"<code>",
"<code style='padding:0.2em 0.4em; background-color:#f6f8fa; "
"border-radius:3px; font-family:Consolas,monospace;'>"
);
return html;
}
} // namespace ctai_parse

View File

@ -1,14 +0,0 @@
#ifndef CTAI_MARKDOWN_H
#define CTAI_MARKDOWN_H
#include <cmark.h>
#include <QString>
#include <QDebug>
namespace ctai_markdown {
// Markdown 转 HTML
QString md_to_html(const QString& text);
// 处理代码块样式
QString process_code_blocks(QString html);
}
#endif // CTAI_PARSESTRING_H