feat: enable automatic conversion of math code to $$ during export

This commit is contained in:
shiquda 2025-03-19 09:31:30 +08:00 committed by 亢奋猫
parent e0ba3b8968
commit 8374cd508d
9 changed files with 45 additions and 11 deletions

View File

@ -709,6 +709,8 @@
"markdown_export.path_placeholder": "Export Path", "markdown_export.path_placeholder": "Export Path",
"markdown_export.select": "Select", "markdown_export.select": "Select",
"markdown_export.help": "If provided, exports will be automatically saved to this path; otherwise, a save dialog will appear.", "markdown_export.help": "If provided, exports will be automatically saved to this path; otherwise, a save dialog will appear.",
"markdown_export.force_dollar_math.title": "Force $$ for LaTeX formulas",
"markdown_export.force_dollar_math.help": "When enabled, $$ will be forcibly used to mark LaTeX formulas when exporting to Markdown. Note: This option also affects all export methods through Markdown, such as Notion, Yuque, etc.",
"notion.api_key": "Notion API Key", "notion.api_key": "Notion API Key",
"notion.api_key_placeholder": "Enter Notion API Key", "notion.api_key_placeholder": "Enter Notion API Key",
"notion.auto_split": "Auto split when exporting", "notion.auto_split": "Auto split when exporting",
@ -1089,4 +1091,4 @@
"visualization": "Visualization" "visualization": "Visualization"
} }
} }
} }

View File

@ -709,6 +709,8 @@
"markdown_export.path_placeholder": "エクスポートパス", "markdown_export.path_placeholder": "エクスポートパス",
"markdown_export.select": "選択", "markdown_export.select": "選択",
"markdown_export.help": "入力された場合、エクスポート時に自動的にこのパスに保存されます。未入力の場合、保存ダイアログが表示されます。", "markdown_export.help": "入力された場合、エクスポート時に自動的にこのパスに保存されます。未入力の場合、保存ダイアログが表示されます。",
"markdown_export.force_dollar_math.title": "LaTeX数式に$$を強制使用",
"markdown_export.force_dollar_math.help": "有効にすると、Markdownにエクスポートする際にLaTeX数式を$$で強制的にマークします。注意この設定はNotion、Yuqueなど、Markdownを通じたすべてのエクスポート方法にも影響します。",
"notion.api_key": "Notion APIキー", "notion.api_key": "Notion APIキー",
"notion.api_key_placeholder": "Notion APIキーを入力してください", "notion.api_key_placeholder": "Notion APIキーを入力してください",
"notion.auto_split": "ダイアログをエクスポートすると自動ページ分割", "notion.auto_split": "ダイアログをエクスポートすると自動ページ分割",
@ -1089,4 +1091,4 @@
"visualization": "可視化" "visualization": "可視化"
} }
} }
} }

View File

@ -709,6 +709,8 @@
"markdown_export.path_placeholder": "Путь экспорта", "markdown_export.path_placeholder": "Путь экспорта",
"markdown_export.select": "Выбрать", "markdown_export.select": "Выбрать",
"markdown_export.help": "Если указано, файлы будут автоматически сохраняться в этот путь; в противном случае появится диалоговое окно сохранения.", "markdown_export.help": "Если указано, файлы будут автоматически сохраняться в этот путь; в противном случае появится диалоговое окно сохранения.",
"markdown_export.force_dollar_math.title": "Принудительно использовать $$ для формул LaTeX",
"markdown_export.force_dollar_math.help": "Если включено, при экспорте в Markdown для обозначения формул LaTeX будет принудительно использоваться $$. Примечание: Эта опция также влияет на все методы экспорта через Markdown, такие как Notion, Yuque и т.д.",
"notion.api_key": "Ключ API Notion", "notion.api_key": "Ключ API Notion",
"notion.api_key_placeholder": "Введите ключ API Notion", "notion.api_key_placeholder": "Введите ключ API Notion",
"notion.auto_split": "Автоматическое разбиение на страницы при экспорте диалога", "notion.auto_split": "Автоматическое разбиение на страницы при экспорте диалога",
@ -1089,4 +1091,4 @@
"visualization": "Визуализация" "visualization": "Визуализация"
} }
} }
} }

View File

@ -709,6 +709,8 @@
"markdown_export.path_placeholder": "导出路径", "markdown_export.path_placeholder": "导出路径",
"markdown_export.select": "选择", "markdown_export.select": "选择",
"markdown_export.help": "若填入,则每次导出时将自动保存到该路径;否则,将弹出保存对话框", "markdown_export.help": "若填入,则每次导出时将自动保存到该路径;否则,将弹出保存对话框",
"markdown_export.force_dollar_math.title": "强制使用$$来标记LaTeX公式",
"markdown_export.force_dollar_math.help": "开启后导出Markdown时会将强制使用$$来标记LaTeX公式。注意该项也会影响所有通过Markdown导出的方式如Notion、语雀等。",
"notion.api_key": "Notion 密钥", "notion.api_key": "Notion 密钥",
"notion.api_key_placeholder": "请输入Notion 密钥", "notion.api_key_placeholder": "请输入Notion 密钥",
"notion.auto_split": "导出对话时自动分页", "notion.auto_split": "导出对话时自动分页",
@ -1089,4 +1091,4 @@
"visualization": "可视化" "visualization": "可视化"
} }
} }
} }

View File

@ -709,6 +709,8 @@
"markdown_export.path_placeholder": "匯出路徑", "markdown_export.path_placeholder": "匯出路徑",
"markdown_export.select": "選擇", "markdown_export.select": "選擇",
"markdown_export.help": "若填入,每次匯出時將自動儲存至該路徑;否則,將彈出儲存對話框。", "markdown_export.help": "若填入,每次匯出時將自動儲存至該路徑;否則,將彈出儲存對話框。",
"markdown_export.force_dollar_math.title": "LaTeX公式強制使用$$",
"markdown_export.force_dollar_math.help": "開啟後匯出Markdown時會強制使用$$來標記LaTeX公式。注意該項也會影響所有透過Markdown匯出的方式如Notion、語雀等。",
"notion.api_key": "Notion 金鑰", "notion.api_key": "Notion 金鑰",
"notion.api_key_placeholder": "請輸入 Notion 金鑰", "notion.api_key_placeholder": "請輸入 Notion 金鑰",
"notion.auto_split": "匯出對話時自動分頁", "notion.auto_split": "匯出對話時自動分頁",
@ -1089,4 +1091,4 @@
"visualization": "視覺化" "visualization": "視覺化"
} }
} }
} }

View File

@ -2,8 +2,8 @@ import { DeleteOutlined, FolderOpenOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
import { useTheme } from '@renderer/context/ThemeProvider' import { useTheme } from '@renderer/context/ThemeProvider'
import { RootState, useAppDispatch } from '@renderer/store' import { RootState, useAppDispatch } from '@renderer/store'
import { setmarkdownExportPath } from '@renderer/store/settings' import { setForceDollarMathInMarkdown, setmarkdownExportPath } from '@renderer/store/settings'
import { Button } from 'antd' import { Button, Switch } from 'antd'
import Input from 'antd/es/input/Input' import Input from 'antd/es/input/Input'
import { FC } from 'react' import { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -17,6 +17,7 @@ const MarkdownExportSettings: FC = () => {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const markdownExportPath = useSelector((state: RootState) => state.settings.markdownExportPath) const markdownExportPath = useSelector((state: RootState) => state.settings.markdownExportPath)
const forceDollarMathInMarkdown = useSelector((state: RootState) => state.settings.forceDollarMathInMarkdown)
const handleSelectFolder = async () => { const handleSelectFolder = async () => {
const path = await window.api.file.selectFolder() const path = await window.api.file.selectFolder()
@ -29,6 +30,10 @@ const MarkdownExportSettings: FC = () => {
dispatch(setmarkdownExportPath(null)) dispatch(setmarkdownExportPath(null))
} }
const handleToggleForceDollarMath = (checked: boolean) => {
dispatch(setForceDollarMathInMarkdown(checked))
}
return ( return (
<SettingGroup theme={theme}> <SettingGroup theme={theme}>
<SettingTitle>{t('settings.data.markdown_export.title')}</SettingTitle> <SettingTitle>{t('settings.data.markdown_export.title')}</SettingTitle>
@ -56,6 +61,14 @@ const MarkdownExportSettings: FC = () => {
<SettingRow> <SettingRow>
<SettingHelpText>{t('settings.data.markdown_export.help')}</SettingHelpText> <SettingHelpText>{t('settings.data.markdown_export.help')}</SettingHelpText>
</SettingRow> </SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.data.markdown_export.force_dollar_math.title')}</SettingRowTitle>
<Switch checked={forceDollarMathInMarkdown} onChange={handleToggleForceDollarMath} />
</SettingRow>
<SettingRow>
<SettingHelpText>{t('settings.data.markdown_export.force_dollar_math.help')}</SettingHelpText>
</SettingRow>
</SettingGroup> </SettingGroup>
) )
} }

View File

@ -75,6 +75,7 @@ export interface SettingsState {
notionApiKey: string | null notionApiKey: string | null
notionPageNameKey: string | null notionPageNameKey: string | null
markdownExportPath: string | null markdownExportPath: string | null
forceDollarMathInMarkdown: boolean
thoughtAutoCollapse: boolean thoughtAutoCollapse: boolean
notionAutoSplit: boolean notionAutoSplit: boolean
notionSplitSize: number notionSplitSize: number
@ -143,6 +144,7 @@ const initialState: SettingsState = {
notionApiKey: '', notionApiKey: '',
notionPageNameKey: 'Name', notionPageNameKey: 'Name',
markdownExportPath: null, markdownExportPath: null,
forceDollarMathInMarkdown: false,
thoughtAutoCollapse: true, thoughtAutoCollapse: true,
notionAutoSplit: false, notionAutoSplit: false,
notionSplitSize: 90, notionSplitSize: 90,
@ -325,6 +327,9 @@ const settingsSlice = createSlice({
setmarkdownExportPath: (state, action: PayloadAction<string | null>) => { setmarkdownExportPath: (state, action: PayloadAction<string | null>) => {
state.markdownExportPath = action.payload state.markdownExportPath = action.payload
}, },
setForceDollarMathInMarkdown: (state, action: PayloadAction<boolean>) => {
state.forceDollarMathInMarkdown = action.payload
},
setThoughtAutoCollapse: (state, action: PayloadAction<boolean>) => { setThoughtAutoCollapse: (state, action: PayloadAction<boolean>) => {
state.thoughtAutoCollapse = action.payload state.thoughtAutoCollapse = action.payload
}, },
@ -407,6 +412,7 @@ export const {
setNotionApiKey, setNotionApiKey,
setNotionPageNameKey, setNotionPageNameKey,
setmarkdownExportPath, setmarkdownExportPath,
setForceDollarMathInMarkdown,
setThoughtAutoCollapse, setThoughtAutoCollapse,
setNotionAutoSplit, setNotionAutoSplit,
setNotionSplitSize, setNotionSplitSize,

View File

@ -5,14 +5,15 @@ import { getMessageTitle } from '@renderer/services/MessagesService'
import store from '@renderer/store' import store from '@renderer/store'
import { setExportState } from '@renderer/store/runtime' import { setExportState } from '@renderer/store/runtime'
import { Message, Topic } from '@renderer/types' import { Message, Topic } from '@renderer/types'
import { removeSpecialCharactersForFileName } from '@renderer/utils/index' import { convertMathFormula, removeSpecialCharactersForFileName } from '@renderer/utils/index'
import { markdownToBlocks } from '@tryfabric/martian' import { markdownToBlocks } from '@tryfabric/martian'
import dayjs from 'dayjs' import dayjs from 'dayjs'
export const messageToMarkdown = (message: Message) => { export const messageToMarkdown = (message: Message) => {
const { forceDollarMathInMarkdown } = store.getState().settings
const roleText = message.role === 'user' ? '🧑‍💻 User' : '🤖 Assistant' const roleText = message.role === 'user' ? '🧑‍💻 User' : '🤖 Assistant'
const titleSection = `### ${roleText}` const titleSection = `### ${roleText}`
const contentSection = message.content const contentSection = forceDollarMathInMarkdown ? convertMathFormula(message.content) : message.content
return [titleSection, '', contentSection].join('\n') return [titleSection, '', contentSection].join('\n')
} }

View File

@ -246,8 +246,12 @@ export function loadScript(url: string) {
} }
export function convertMathFormula(input) { export function convertMathFormula(input) {
// 使用正则表达式匹配并替换公式格式 if (!input) return input
return input.replaceAll(/\\\[/g, '$$$$').replaceAll(/\\\]/g, '$$$$')
let result = input
result = result.replaceAll('\\[', '$$$$').replaceAll('\\]', '$$$$')
result = result.replaceAll('\\(', '$$').replaceAll('\\)', '$$')
return result
} }
export function getBriefInfo(text: string, maxLength: number = 50): string { export function getBriefInfo(text: string, maxLength: number = 50): string {