增加公式转换
This commit is contained in:
parent
eda1c1a2e9
commit
e0ffdbd010
83
3rdparty/cmark-gfm/.github/workflows/ci.yml
vendored
83
3rdparty/cmark-gfm/.github/workflows/ci.yml
vendored
@ -1,83 +0,0 @@
|
|||||||
name: CI tests
|
|
||||||
|
|
||||||
on: [push, workflow_dispatch]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linux:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
cmake_opts:
|
|
||||||
- '-DCMARK_SHARED=ON'
|
|
||||||
- ''
|
|
||||||
compiler:
|
|
||||||
- c: 'clang'
|
|
||||||
cpp: 'clang++'
|
|
||||||
- c: 'gcc'
|
|
||||||
cpp: 'g++'
|
|
||||||
env:
|
|
||||||
CMAKE_OPTIONS: ${{ matrix.cmake_opts }}
|
|
||||||
CC: ${{ matrix.compiler.c }}
|
|
||||||
CXX: ${{ matrix.compiler.cpp }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- name: Install valgrind
|
|
||||||
run: |
|
|
||||||
sudo apt install -y valgrind
|
|
||||||
- name: Build and test
|
|
||||||
run: |
|
|
||||||
make
|
|
||||||
make test
|
|
||||||
make leakcheck
|
|
||||||
|
|
||||||
macos:
|
|
||||||
|
|
||||||
runs-on: macOS-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
cmake_opts:
|
|
||||||
- '-DCMARK_SHARED=ON'
|
|
||||||
- ''
|
|
||||||
compiler:
|
|
||||||
- c: 'clang'
|
|
||||||
cpp: 'clang++'
|
|
||||||
- c: 'gcc'
|
|
||||||
cpp: 'g++'
|
|
||||||
env:
|
|
||||||
CMAKE_OPTIONS: ${{ matrix.cmake_opts }}
|
|
||||||
CC: ${{ matrix.compiler.c }}
|
|
||||||
CXX: ${{ matrix.compiler.cpp }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- name: Build and test
|
|
||||||
env:
|
|
||||||
CMAKE_OPTIONS: -DCMARK_SHARED=OFF
|
|
||||||
run: |
|
|
||||||
make
|
|
||||||
make test
|
|
||||||
|
|
||||||
windows:
|
|
||||||
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
cmake_opts:
|
|
||||||
- '-DCMARK_SHARED=ON'
|
|
||||||
- ''
|
|
||||||
env:
|
|
||||||
CMAKE_OPTIONS: ${{ matrix.cmake_opts }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
- name: Build and test
|
|
||||||
run: |
|
|
||||||
chcp 65001
|
|
||||||
nmake.exe /nologo /f Makefile.nmake test
|
|
||||||
shell: cmd
|
|
||||||
77
3rdparty/cmark-gfm/.github/workflows/codeql.yml
vendored
77
3rdparty/cmark-gfm/.github/workflows/codeql.yml
vendored
@ -1,77 +0,0 @@
|
|||||||
# For most projects, this workflow file will not need changing; you simply need
|
|
||||||
# to commit it to your repository.
|
|
||||||
#
|
|
||||||
# You may wish to alter this file to override the set of languages analyzed,
|
|
||||||
# or to provide custom queries or build logic.
|
|
||||||
#
|
|
||||||
# ******** NOTE ********
|
|
||||||
# We have attempted to detect the languages in your repository. Please check
|
|
||||||
# the `language` matrix defined below to confirm you have the correct set of
|
|
||||||
# supported CodeQL languages.
|
|
||||||
#
|
|
||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ "master" ]
|
|
||||||
schedule:
|
|
||||||
- cron: '45 14 * * 3'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
|
||||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'cpp', 'javascript', 'python', 'ruby' ]
|
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
|
|
||||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
|
||||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
|
||||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
||||||
# By default, queries listed here will override any specified in a config file.
|
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
||||||
|
|
||||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
||||||
# queries: security-extended,security-and-quality
|
|
||||||
|
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v2
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
||||||
|
|
||||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
||||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
||||||
|
|
||||||
# - run: |
|
|
||||||
# echo "Run, Build Application using script"
|
|
||||||
# ./location_of_script_within_repo/buildscript.sh
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
with:
|
|
||||||
category: "/language:${{matrix.language}}"
|
|
||||||
@ -30,7 +30,7 @@ SET(CMAKE_CXX_FLAGS_RELEASE"-O3 -s")
|
|||||||
SET(CMAKE_BUILD_TYPE "Release")
|
SET(CMAKE_BUILD_TYPE "Release")
|
||||||
|
|
||||||
MESSAGE(STATUS ${PROJECT_BINARY_DIR})
|
MESSAGE(STATUS ${PROJECT_BINARY_DIR})
|
||||||
MESSAGE(STATUS "----------编译模式 START-------------")
|
MESSAGE(STATUS "---------- START-------------")
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
MESSAGE(STATUS "[CMAKE_BUILD_TYPE]当前值[Debug]")
|
MESSAGE(STATUS "[CMAKE_BUILD_TYPE]当前值[Debug]")
|
||||||
SET(CMAKE_BUILD_TYPE "Debug")
|
SET(CMAKE_BUILD_TYPE "Debug")
|
||||||
@ -40,7 +40,7 @@ else()
|
|||||||
SET(CMAKE_BUILD_TYPE "Release")
|
SET(CMAKE_BUILD_TYPE "Release")
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/release/)
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/release/)
|
||||||
endif()
|
endif()
|
||||||
MESSAGE(STATUS "----------编译模式 END---------------")
|
MESSAGE(STATUS "---------- END---------------")
|
||||||
|
|
||||||
#设置QT .cmake文件路径
|
#设置QT .cmake文件路径
|
||||||
#自编译QT静态库
|
#自编译QT静态库
|
||||||
@ -74,10 +74,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/MicroTeX/src)
|
|||||||
FIND_PACKAGE(Qt6 REQUIRED Core Gui Widgets)
|
FIND_PACKAGE(Qt6 REQUIRED Core Gui Widgets)
|
||||||
|
|
||||||
#输出路径
|
#输出路径
|
||||||
MESSAGE(STATUS "----------基础路径输出 START-------------")
|
MESSAGE(STATUS "---------- START-------------")
|
||||||
MESSAGE(STATUS "QT_DIR_PATH=${QT_DIR}")
|
MESSAGE(STATUS "QT_DIR_PATH=${QT_DIR}")
|
||||||
MESSAGE(STATUS "JSON_DIR_PATH=${JSON}")
|
MESSAGE(STATUS "JSON_DIR_PATH=${JSON}")
|
||||||
MESSAGE(STATUS "----------基础路径输出 END---------------")
|
MESSAGE(STATUS "---------- END---------------")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -148,8 +148,8 @@ target_link_libraries(
|
|||||||
Qt6::Gui
|
Qt6::Gui
|
||||||
Qt6::Widgets
|
Qt6::Widgets
|
||||||
CURL::libcurl
|
CURL::libcurl
|
||||||
#libcmark-gfm-extensions_static
|
|
||||||
#libcmark-gfm_static
|
#libcmark-gfm_static
|
||||||
|
#libcmark-gfm-extensions_static
|
||||||
LaTeX
|
LaTeX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -62,4 +62,30 @@ typedef struct model_data{
|
|||||||
std::string request_body;
|
std::string request_body;
|
||||||
}model_data;
|
}model_data;
|
||||||
|
|
||||||
|
const QStringList latex_symbols = {
|
||||||
|
"\\Alpha",
|
||||||
|
"\\Beta",
|
||||||
|
"\\Gamma",
|
||||||
|
"\\Delta",
|
||||||
|
"\\Epsilon",
|
||||||
|
"\\Zeta",
|
||||||
|
"\\Eta",
|
||||||
|
"\\Theta",
|
||||||
|
"\\Iota",
|
||||||
|
"\\Kappa",
|
||||||
|
"\\Lambda",
|
||||||
|
"\\Mu",
|
||||||
|
"\\Nu",
|
||||||
|
"\\Xi",
|
||||||
|
"\\Omicron",
|
||||||
|
"\\Pi",
|
||||||
|
"\\Rho",
|
||||||
|
"\\Sigma",
|
||||||
|
"\\Tau",
|
||||||
|
"\\Upsilon",
|
||||||
|
"\\Phi",
|
||||||
|
"\\Chi",
|
||||||
|
"\\Psi",
|
||||||
|
"\\Omega"
|
||||||
|
};
|
||||||
#endif // CTAI_BASE_H
|
#endif // CTAI_BASE_H
|
||||||
@ -47,6 +47,11 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
|
|||||||
m_msg_save = new QPushButton();
|
m_msg_save = new QPushButton();
|
||||||
m_msg_menu = new QPushButton();
|
m_msg_menu = new QPushButton();
|
||||||
m_msg_fold = new QPushButton();
|
m_msg_fold = new QPushButton();
|
||||||
|
m_msg_display_combobox=new QComboBox();
|
||||||
|
m_msg_display_label=new QLabel("显示模式:");
|
||||||
|
m_msg_display_label->setObjectName("m_msg_menu_label");
|
||||||
|
|
||||||
|
m_msg_display_combobox->setObjectName("m_msg_display_combobox");
|
||||||
|
|
||||||
m_msg_copy->setObjectName("m_msg_copy");
|
m_msg_copy->setObjectName("m_msg_copy");
|
||||||
m_msg_save->setObjectName("m_msg_save");
|
m_msg_save->setObjectName("m_msg_save");
|
||||||
@ -54,7 +59,11 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
|
|||||||
m_msg_fold->setObjectName("m_msg_fold");
|
m_msg_fold->setObjectName("m_msg_fold");
|
||||||
m_msg_fold->setIcon(QIcon(":res/img/btn/btn_info_up.png"));
|
m_msg_fold->setIcon(QIcon(":res/img/btn/btn_info_up.png"));
|
||||||
m_msg_fold->setIconSize(QSize(25, 25));
|
m_msg_fold->setIconSize(QSize(25, 25));
|
||||||
|
m_msg_display_combobox->addItem("原始文本");
|
||||||
|
m_msg_display_combobox->addItem("LaTeX Markdown");
|
||||||
header_opts_Layout->addItem(sparcer_item);
|
header_opts_Layout->addItem(sparcer_item);
|
||||||
|
header_opts_Layout->addWidget(m_msg_display_label);
|
||||||
|
header_opts_Layout->addWidget(m_msg_display_combobox);
|
||||||
header_opts_Layout->addWidget(m_msg_copy);
|
header_opts_Layout->addWidget(m_msg_copy);
|
||||||
header_opts_Layout->addWidget(m_msg_save);
|
header_opts_Layout->addWidget(m_msg_save);
|
||||||
header_opts_Layout->addWidget(m_msg_menu);
|
header_opts_Layout->addWidget(m_msg_menu);
|
||||||
@ -123,6 +132,7 @@ void ctai_history_textedit::connect_signals(msg_type msg_type_mode)
|
|||||||
connect(m_msg_menu, SIGNAL(clicked()), this, SLOT(on_menu_clicked()));
|
connect(m_msg_menu, SIGNAL(clicked()), this, SLOT(on_menu_clicked()));
|
||||||
connect(m_msg_fold, SIGNAL(clicked()), this, SLOT(on_fold_clicked()));
|
connect(m_msg_fold, SIGNAL(clicked()), this, SLOT(on_fold_clicked()));
|
||||||
connect(m_msg_tokens, SIGNAL(clicked()), this, SLOT(on_tokens_clicked()));
|
connect(m_msg_tokens, SIGNAL(clicked()), this, SLOT(on_tokens_clicked()));
|
||||||
|
connect(m_msg_display_combobox, SIGNAL(currentTextChanged(QString)), this, SLOT(on_display_changed(QString)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -130,7 +140,19 @@ void ctai_history_textedit::connect_signals(msg_type msg_type_mode)
|
|||||||
}
|
}
|
||||||
connect(m_msg_history, SIGNAL(textChanged()), this, SLOT(on_sync_text_height()));
|
connect(m_msg_history, SIGNAL(textChanged()), this, SLOT(on_sync_text_height()));
|
||||||
}
|
}
|
||||||
|
void ctai_history_textedit::on_display_changed(QString mode)
|
||||||
|
{
|
||||||
|
// 根据显示模式设置文本
|
||||||
|
if (mode == "原始文本")
|
||||||
|
{
|
||||||
|
m_msg_history->setText(m_current_content);
|
||||||
|
}
|
||||||
|
else if (mode == "LaTeX Markdown")
|
||||||
|
{
|
||||||
|
m_msg_history->setMarkdown(m_math_convert->replace_tags_svg(m_current_content));
|
||||||
|
qDebug()<<"LaTeX Markdown:"<<m_msg_history->toMarkdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
// tokens按钮实现功能的槽函数
|
// tokens按钮实现功能的槽函数
|
||||||
void ctai_history_textedit::on_tokens_clicked()
|
void ctai_history_textedit::on_tokens_clicked()
|
||||||
{
|
{
|
||||||
@ -260,12 +282,10 @@ void ctai_history_textedit::add_user_message(const model_data &message)
|
|||||||
disp_data = QSL(message.send_user_data);
|
disp_data = QSL(message.send_user_data);
|
||||||
m_msg_sned_id = QSL(message.send_user_id);
|
m_msg_sned_id = QSL(message.send_user_id);
|
||||||
m_msg_history->setMarkdown(disp_data);
|
m_msg_history->setMarkdown(disp_data);
|
||||||
m_math_convert->math_convert_svg(disp_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctai_history_textedit::add_system_message(const model_data &message)
|
void ctai_history_textedit::add_system_message(const model_data &message)
|
||||||
{
|
{
|
||||||
QString disp_data;
|
|
||||||
m_msg_sned_id = QSL(message.postback_send_id);
|
m_msg_sned_id = QSL(message.postback_send_id);
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
@ -274,13 +294,13 @@ void ctai_history_textedit::add_system_message(const model_data &message)
|
|||||||
// 流式模式下追加内容
|
// 流式模式下追加内容
|
||||||
m_current_content += message.postback_model_data;
|
m_current_content += message.postback_model_data;
|
||||||
m_msg_history->setMarkdown(m_current_content);
|
m_msg_history->setMarkdown(m_current_content);
|
||||||
|
//m_msg_history->setHtml(m_math_convert->replace_tags_svg(m_current_content));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 非流式模式直接设置全部内容
|
// 非流式模式直接设置全部内容
|
||||||
disp_data = QSL(message.postback_model_data);
|
|
||||||
m_msg_history->setMarkdown(disp_data);
|
|
||||||
m_current_content = QSL(message.postback_model_data);
|
m_current_content = QSL(message.postback_model_data);
|
||||||
|
m_msg_history->setMarkdown(m_current_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 增加tokens信息
|
// 增加tokens信息
|
||||||
|
|||||||
@ -22,6 +22,8 @@
|
|||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QAbstractScrollArea>
|
#include <QAbstractScrollArea>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QComboBox>
|
||||||
// Qt对话框
|
// Qt对话框
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@ -60,6 +62,7 @@ private slots:
|
|||||||
void on_menu_clicked(); // 菜单按钮
|
void on_menu_clicked(); // 菜单按钮
|
||||||
void on_fold_clicked(); // 折叠按钮
|
void on_fold_clicked(); // 折叠按钮
|
||||||
void on_tokens_clicked(); // tokens按钮
|
void on_tokens_clicked(); // tokens按钮
|
||||||
|
void on_display_changed(QString); // 显示模式改变
|
||||||
void on_save_text(); // 保存文本
|
void on_save_text(); // 保存文本
|
||||||
void on_save_html(); // 保存html
|
void on_save_html(); // 保存html
|
||||||
void on_save_markdown(); // 保存markdown
|
void on_save_markdown(); // 保存markdown
|
||||||
@ -83,7 +86,7 @@ private:
|
|||||||
QPushButton *m_msg_system_header_ico={};
|
QPushButton *m_msg_system_header_ico={};
|
||||||
QPushButton *m_msg_user_header_ico={};
|
QPushButton *m_msg_user_header_ico={};
|
||||||
QLineEdit *m_msg_header={};
|
QLineEdit *m_msg_header={};
|
||||||
QTextEdit *m_msg_history={};
|
QTextEdit *m_msg_history={};
|
||||||
QPushButton *m_msg_user_del={};
|
QPushButton *m_msg_user_del={};
|
||||||
QPushButton *m_msg_system_del={};
|
QPushButton *m_msg_system_del={};
|
||||||
QPushButton *m_msg_copy={};
|
QPushButton *m_msg_copy={};
|
||||||
@ -93,6 +96,8 @@ private:
|
|||||||
QPushButton *m_msg_tokens={};
|
QPushButton *m_msg_tokens={};
|
||||||
QPushButton *m_history_to_send={};
|
QPushButton *m_history_to_send={};
|
||||||
QPushButton *m_restart_to_send={};
|
QPushButton *m_restart_to_send={};
|
||||||
|
QLabel *m_msg_display_label={};
|
||||||
|
QComboBox *m_msg_display_combobox={};
|
||||||
//tokens消耗显示
|
//tokens消耗显示
|
||||||
QMenu *m_msg_tokens_menu={};
|
QMenu *m_msg_tokens_menu={};
|
||||||
QAction *m_menu_prompt_tokens={};
|
QAction *m_menu_prompt_tokens={};
|
||||||
@ -116,8 +121,7 @@ private:
|
|||||||
QString m_msg_sned_id={};
|
QString m_msg_sned_id={};
|
||||||
//本次信息
|
//本次信息
|
||||||
QString m_current_content;
|
QString m_current_content;
|
||||||
QSpacerItem *bottom_spacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
QSpacerItem *bottom_spacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ctai_history_textedit_H
|
#endif // ctai_history_textedit_H
|
||||||
|
|||||||
@ -117,6 +117,7 @@ void ctai_history_widget::on_rows_height_changed(bool fold_state)
|
|||||||
setRowHeight(row, 87);
|
setRowHeight(row, 87);
|
||||||
resizeRowToContents(row);
|
resizeRowToContents(row);
|
||||||
}
|
}
|
||||||
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -127,8 +128,7 @@ void ctai_history_widget::on_rows_height_changed(bool fold_state)
|
|||||||
setRowHeight(row, currentHeight + 100);
|
setRowHeight(row, currentHeight + 100);
|
||||||
resizeRowToContents(row);
|
resizeRowToContents(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scrollToBottom();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctai_history_widget::on_msg_remove(QString send_id)
|
void ctai_history_widget::on_msg_remove(QString send_id)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ ctai_math_convert::~ctai_math_convert()
|
|||||||
void ctai_math_convert::set_convert_opts()
|
void ctai_math_convert::set_convert_opts()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void ctai_math_convert::save_svg(QPixmap &img, const QString &svg)
|
void ctai_math_convert::save_svg(QPixmap &img)
|
||||||
{
|
{
|
||||||
QString uid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
QString uid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||||
QString svgName = QDir::currentPath() + "/svg/" + uid + ".png";
|
QString svgName = QDir::currentPath() + "/svg/" + uid + ".png";
|
||||||
@ -28,9 +28,9 @@ QByteArray ctai_math_convert::svg_to_base64(QPixmap &pix)
|
|||||||
data = data.toBase64();
|
data = data.toBase64();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
void ctai_math_convert::math_convert_svg(const QString &latex)
|
QString ctai_math_convert::math_convert_svg(const QString &math)
|
||||||
{
|
{
|
||||||
auto render = tex::LaTeX::parse(latex.toStdWString(), m_width, m_text_size, m_lineSpace, m_color);
|
auto render = tex::LaTeX::parse(math.toStdWString(), m_width, m_text_size, m_lineSpace, m_color);
|
||||||
qDebug() << render->getWidth() << render->getHeight();
|
qDebug() << render->getWidth() << render->getHeight();
|
||||||
QPixmap pix(render->getWidth(), render->getHeight());
|
QPixmap pix(render->getWidth(), render->getHeight());
|
||||||
pix.fill(Qt::white);
|
pix.fill(Qt::white);
|
||||||
@ -38,13 +38,81 @@ void ctai_math_convert::math_convert_svg(const QString &latex)
|
|||||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
tex::Graphics2D_qt g2(&painter);
|
tex::Graphics2D_qt g2(&painter);
|
||||||
render->draw(g2, 0, 0);
|
render->draw(g2, 0, 0);
|
||||||
if (save_mode)
|
save_svg(pix);
|
||||||
{
|
return QString::fromUtf8(svg_to_base64(pix));
|
||||||
save_svg(pix, latex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//输出base64
|
|
||||||
qDebug() << "svg_to_base64:" << QString::fromUtf8(svg_to_base64(pix));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ctai_math_convert::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 ctai_math_convert::clean_latex_for_mula(const QString &formula)
|
||||||
|
{
|
||||||
|
QString result = formula;
|
||||||
|
// 清理可能的多余空白字符
|
||||||
|
result = result.trimmed();
|
||||||
|
// 处理可能的换行符
|
||||||
|
result.replace(QRegularExpression(R"(\s+)"), " ");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ctai_math_convert::replace_tags_svg(const QString &text)
|
||||||
|
{
|
||||||
|
//QString result("4566545646\\[\n f'(a) = \\lim_{h \\to 0} \\frac{f(a + h) - f(a)}{h}\n \\]654564646");
|
||||||
|
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<QPair<int, int>> replacements;
|
||||||
|
QStringList svgResults;
|
||||||
|
// 定义基础图片标签
|
||||||
|
const QString html_base = "<img src=\"data:image/png;base64,";
|
||||||
|
const QString markdown_base = ")
|
||||||
|
{
|
||||||
|
QRegularExpressionMatch match = iterator.next();
|
||||||
|
QString matchedText = match.captured(0);
|
||||||
|
// 调试输出
|
||||||
|
debug_latex_match(result, match);
|
||||||
|
// 清理和转换公式
|
||||||
|
//QString cleanFormula = clean_latex_for_mula(matchedText);
|
||||||
|
QString svg_markdown = markdown_base + math_convert_svg(matchedText) + ")";
|
||||||
|
QString svg_html = html_base + math_convert_svg(matchedText) + "/>";
|
||||||
|
// 保存替换信息
|
||||||
|
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 result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,11 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QRegularExpressionMatchIterator>
|
||||||
|
#include "ctai_base.h"
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
class TexGuard {
|
class TexGuard {
|
||||||
public:
|
public:
|
||||||
TexGuard() {
|
TexGuard() {
|
||||||
@ -26,23 +31,27 @@ class ctai_math_convert :public QObject
|
|||||||
public:
|
public:
|
||||||
explicit ctai_math_convert();
|
explicit ctai_math_convert();
|
||||||
~ctai_math_convert();
|
~ctai_math_convert();
|
||||||
// 追加内容并处理Markdown
|
QString replace_tags_svg(const QString &text);
|
||||||
void math_convert_svg(const QString& text);
|
|
||||||
void set_convert_opts();
|
void set_convert_opts();
|
||||||
void save_svg(QPixmap& img,const QString& svg);
|
void save_svg(QPixmap& img);
|
||||||
QByteArray svg_to_base64(QPixmap& pix);
|
|
||||||
private:
|
private:
|
||||||
|
void debug_latex_match(const QString &text, const QRegularExpressionMatch &match);
|
||||||
|
QString clean_latex_for_mula(const QString &formula);
|
||||||
|
QString math_convert_svg(const QString& text);
|
||||||
|
QByteArray svg_to_base64(QPixmap& pix);
|
||||||
TexGuard texGuard;
|
TexGuard texGuard;
|
||||||
//宽度
|
//宽度
|
||||||
int m_width=600;
|
int m_width=300;
|
||||||
//文本大小
|
//文本大小
|
||||||
int m_text_size=20;
|
int m_text_size=14;
|
||||||
//行距
|
//行距
|
||||||
float m_lineSpace=20 / 3.f;
|
float m_lineSpace=20 / 3.f;
|
||||||
//颜色
|
//颜色
|
||||||
tex::color m_color=0xff424242;
|
tex::color m_color=0xff424242;
|
||||||
//处理后保存模式
|
//处理后保存模式
|
||||||
bool save_mode=false;
|
bool save_mode=false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user