diff --git a/docutranslate/app.py b/docutranslate/app.py
index e3ec5ca..3acb0bc 100644
--- a/docutranslate/app.py
+++ b/docutranslate/app.py
@@ -207,7 +207,7 @@ async def lifespan(app: FastAPI):
global_logger.propagate = False
global_logger.setLevel(logging.INFO)
print("应用启动完成,多任务状态已初始化。")
- print(f"服务接口文档: http://127.0.0.1:{app.state.port_to_use}/docs")
+ print(f"服务接口文档: http://1227.0.0.1:{app.state.port_to_use}/docs")
print(f"请用浏览器访问 http://127.0.0.1:{app.state.port_to_use}\n")
yield
# 清理任何可能残留的临时目录
@@ -469,6 +469,10 @@ class TextWorkflowParams(BaseWorkflowParams):
"\n",
description="当 insert_mode 为 'append' 或 'prepend' 时,用于分隔原文和译文的分隔符。",
)
+ segment_mode: Literal["line", "paragraph"] = Field(
+ "line",
+ description="分段模式。'line':按行分段(每行独立翻译),'paragraph':按段落分段(连续非空行合并为段落)。",
+ )
class JsonWorkflowParams(BaseWorkflowParams):
@@ -961,6 +965,7 @@ async def _perform_translation(
"glossary_dict",
"insert_mode",
"separator",
+ "segment_mode",
"timeout",
"retry",
"system_proxy_enable",
diff --git a/docutranslate/static/i18nData.json b/docutranslate/static/i18nData.json
index 4695b47..ba64903 100644
--- a/docutranslate/static/i18nData.json
+++ b/docutranslate/static/i18nData.json
@@ -23,6 +23,10 @@
"separatorLabel": "分隔符",
"separatorPlaceholderSimple": "例如: \\n---\\n",
"separatorHelp": "当插入模式为附加或前置时,用于分隔原文和译文的字符。\\n 代表换行。",
+ "segmentModeLabel": "分段模式",
+ "segmentModeLine": "按行分段 (每行独立翻译)",
+ "segmentModeParagraph": "按段落分段 (合并连续非空行)",
+ "segmentModeHelp": "选择如何将文本分割成块进行翻译。",
"docxSettingsTitleText": "DOCX翻译选项",
"insertModeHelpDocx": "选择如何将翻译后的文本插入。",
"separatorPlaceholderStructured": "例如: ---",
@@ -46,10 +50,14 @@
"jsonSettingsTitleText": "JSON路径配置",
"jsonPathLabel": "需要翻译的JSON路径",
"jsonPathPlaceholder": "每行一个路径, 例如:\n$.name\n$.*",
- "jsonPathHelp": "采用jsonpath-ng的路径选择语法,每一行表示一个json路径。\n 将翻译路径匹配对象内的所有字符串",
+ "jsonPathHelp": "采用jsonpath-ng的路径选择语法,每一行表示一个json路径。\n 将翻译路径匹配对象内的所有字符串",
"parsingSettingsTitleText": "解析配置",
"parsingEngineLabel": "解析引擎",
"parsingEngineHelp": "如果上传的文件本身是.md格式,此项可不选。",
+ "engineOptionIdentity": "已经是Markdown格式",
+ "engineOptionMineru": "Mineru(推荐)",
+ "engineOptionDocling": "Docling",
+ "engineOptionMineruDeploy": "Mineru部署服务",
"getMineruTokenTitle": "获取Mineru Token",
"mineruTokenPlaceholder": "使用Mineru引擎时需要",
"modelVersionLabel": "Mineru 模型版本",
@@ -73,6 +81,20 @@
"skipTranslationLabel": "跳过翻译",
"platformLabel": "选择平台",
"platformCustom": "自定义接口",
+ "platform302AI": "302.AI",
+ "platformOpenAI": "OpenAI",
+ "platformGemini": "Gemini",
+ "platformDeepSeek": "DeepSeek",
+ "platformDashScope": "阿里云百炼(DashScope)",
+ "platformVolces": "火山引擎(volces)",
+ "platformSiliconflow": "硅基流动(siliconflow CN)",
+ "platformBigmodel": "智谱AI(bigmodel CN)",
+ "platformDmxapiCN": "DMXAPI_CN",
+ "platformDmxapiGlobal": "DMXAPI_GLOBAL",
+ "platformJuguang": "聚光AI(juguang CN)",
+ "platformOpenRouter": "OpenRouter",
+ "platformLMStudio": "LM Studio",
+ "platformOllama": "Ollama",
"baseUrlLabel": "API 地址 (Base URL)",
"baseUrlPlaceholder": "OpenAi兼容地址",
"getApiKeyTitle": "获取API Key",
@@ -82,6 +104,17 @@
"systemProxyLabel": "启用系统代理",
"translationSettingsTitleText": "翻译配置",
"targetLanguageLabel": "目标语言",
+ "langZh": "中文(简体中文)",
+ "langEn": "英文(English)",
+ "langEs": "西班牙文(Español)",
+ "langFr": "法文(Français)",
+ "langDe": "德文(Deutsch)",
+ "langJa": "日文(日本語)",
+ "langKo": "韩文(한국어)",
+ "langRu": "俄文(Русский)",
+ "langPt": "葡萄牙文(Português)",
+ "langAr": "阿拉伯文(العَرَبِيَّة)",
+ "langVi": "越南文(tiếng Việt)",
"targetLanguageCustom": "其它 (自定义)",
"customLangPlaceholder": "请输入目标语言, 例如: Italian",
"thinkingModeLabel": "思考模式",
@@ -108,7 +141,7 @@
"glossaryGenConfigCustom": "自定义",
"importConfigBtn": "导入配置",
"exportConfigBtn": "导出配置",
- "githubInfo": "GitHub主页(欢迎star❤):
\n https://github.com/xunbu/docutranslate",
+ "githubInfo": "GitHub主页(欢迎star❤):
\n https://github.com/xunbu/docutranslate",
"qqGroupInfo": "交流QQ群: 1047781902",
"taskListTitle": "任务列表",
"newTaskBtn": "新建任务",
@@ -127,7 +160,16 @@
"taskCardStartBtn": "开始翻译",
"downloadMdEmbedded": "Markdown(嵌图)",
"downloadMdZip": "Markdown压缩包",
+ "downloadTxt": "TXT",
+ "downloadJson": "JSON",
+ "downloadDocx": "DOCX",
+ "downloadXlsx": "XLSX",
+ "downloadCsv": "CSV",
+ "downloadSrt": "SRT",
+ "downloadEpub": "EPUB",
"downloadAss": "ASS",
+ "downloadHtml": "HTML",
+ "downloadPdf": "PDF",
"previewTitle": "预览",
"previewBilingualBtn": "双语",
"previewTranslatedOnlyBtn": "仅译文",
@@ -152,10 +194,12 @@
"glossaryTableDestination": "译文 (dst)",
"init_i18n_failed_alert": "加载界面翻译资源失败,请检查网络连接或联系管理员。",
"init_failed_alert": "初始化失败,无法连接到后端服务。请检查服务是否运行或刷新页面。",
- "status_selectFileFirst": "请先选择文件",
- "status_fillRequired": "请填写所有必填项",
+ "apiHrefInfo302ai": "👈 通过此链接注册可享1美金免费额度",
+ "glossaryEmpty": "术语表为空。",
+ "status_selectFileFirst": "请先选择文件!",
+ "status_fillRequired": "请填写所有必填项!",
"btn_initializing": "初始化中...",
- "status_encodingAndSubmitting": "文件编码和提交中...",
+ "status_encodingAndSubmitting": "文件编码与提交中...",
"status_requestOk": "请求成功,任务已开始",
"btn_cancelTranslation": "取消翻译",
"status_requestFail": "请求失败",
@@ -163,35 +207,29 @@
"status_cancelling": "取消中...",
"status_cancelSent": "已发送取消请求",
"status_cancelFail": "取消失败",
- "status_gettingStatus": "获取状态中...",
"btn_reTranslate": "重新翻译",
- "status_updateError": "状态更新失败",
+ "status_gettingStatus": "获取状态...",
+ "status_updateError": "状态更新出错",
"preview_loading": "加载预览中...",
- "preview_cantReadOriginal": "无法读取原文文件内容",
+ "preview_cantReadOriginal": "无法读取原始文件内容。",
"preview_cantPreviewType": "无法预览此文件类型",
- "preview_noOriginalCache": "无原文文件缓存,无法预览",
- "preview_loadFailed": "预览加载失败",
- "pdf_preparing": "PDF生成中,请稍候...",
- "pdf_print_failed": "调用打印功能失败,请尝试手动右键打印",
- "pdf_fetch_failed": "获取预览内容失败,无法生成PDF",
+ "preview_noOriginalCache": "未找到原始文件缓存,无法预览。",
+ "preview_loadFailed": "加载预览失败",
+ "pdf_preparing": "正在准备PDF...",
+ "pdf_print_failed": "调用打印功能失败。请尝试手动保存为PDF。",
+ "pdf_fetch_failed": "获取译文内容失败,无法生成PDF。",
"preview_bilingual": "双语预览",
"preview_translatedOnly": "仅译文预览",
- "admin_tasklist_failed": "管理员模式:加载任务列表失败",
+ "admin_tasklist_failed": "管理员模式:加载任务列表失败。",
"configImportSuccess": "配置导入成功!",
- "configImportError": "配置导入失败,请检查文件格式是否正确。",
- "apiHrefInfo302ai": "👈 通过此链接注册可享1美元免费额度",
- "glossaryEmpty": "术语表为空",
- "engineOptionIdentity": "已经是Markdown格式",
- "engineOptionMineru": "Mineru(推荐)",
- "engineOptionDocling": "Docling",
- "engineOptionMineruDeploy": "Mineru部署服务"
+ "configImportError": "配置导入失败,文件格式错误。"
},
"en": {
"pageTitle": "DocuTranslate - Interactive Document Translation",
"tutorialBtn": "Tutorial",
- "projectContributeBtn": "Project Contribution",
+ "projectContributeBtn": "Contribute",
"workflowTitle": "Select Workflow",
- "workflowOptionMarkdown": "Convert to Markdown then Translate (.pdf/.md/.png, etc.)",
+ "workflowOptionMarkdown": "To Markdown then Translate (.pdf/.md/.png, etc.)",
"workflowOptionTxt": "Plain Text Translation (.txt)",
"workflowOptionEpub": "EPUB Translation (.epub)",
"workflowOptionDocx": "DOCX Translation (.docx)",
@@ -200,49 +238,57 @@
"workflowOptionAss": "ASS Subtitle Translation (.ass)",
"workflowOptionJson": "JSON Translation (.json)",
"workflowOptionHtml": "HTML Translation (.html)",
- "autoWorkflowLabel": "Auto-select Workflow",
+ "autoWorkflowLabel": "Auto-select workflow",
"txtSettingsTitleText": "TXT Translation Options",
"insertModeLabel": "Insert Mode",
- "insertModeReplace": "Replace Original (Replace)",
- "insertModeAppend": "Append to Original (Append)",
- "insertModePrepend": "Prepend to Original (Prepend)",
+ "insertModeReplace": "Replace Original",
+ "insertModeAppend": "Append to Original",
+ "insertModePrepend": "Prepend to Original",
"insertModeHelpTxt": "Choose how to insert the translated text.",
"separatorLabel": "Separator",
"separatorPlaceholderSimple": "e.g., \\n---\\n",
- "separatorHelp": "Character used to separate original and translated text in append or prepend mode. \\n represents a newline.",
+ "separatorHelp": "Character to separate original and translated text in append/prepend mode. \\n represents a newline.",
+ "segmentModeLabel": "Segment Mode",
+ "segmentModeLine": "By Line (Translate each line)",
+ "segmentModeParagraph": "By Paragraph (Merge consecutive lines)",
+ "segmentModeHelp": "Choose how to segment the text before translation.",
"docxSettingsTitleText": "DOCX Translation Options",
"insertModeHelpDocx": "Choose how to insert the translated text.",
"separatorPlaceholderStructured": "e.g., ---",
- "separatorHelpDocx": "In append mode, the translation will start a new paragraph. This is used to add extra content between the original and translated paragraphs. \\n can be used for newlines within the separator.",
+ "separatorHelpDocx": "In append mode, the translation will be in a new paragraph. This adds extra content between them. \\n for internal newlines.",
"xlsxSettingsTitleText": "XLSX Translation Options",
- "insertModeHelpXlsx": "Choose how to insert the translated text into cells.",
- "xlsxTranslateRegionsLabel": "Translation Regions (Optional)",
+ "insertModeHelpXlsx": "Choose how to insert translated text into cells.",
+ "xlsxTranslateRegionsLabel": "Translate Regions (Optional)",
"xlsxTranslateRegionsPlaceholder": "One region per line, e.g., Sheet1!A1:B10 (applies to all sheets if sheet name is omitted)",
"srtSettingsTitleText": "SRT Translation Options",
"insertModeHelpSrt": "Choose how to insert the translated text.",
"epubSettingsTitleText": "EPUB Translation Options",
"insertModeHelpEpub": "Choose how to insert the translated text.",
- "separatorHelpEpub": "In append mode, the translation will start a new block. This is used to add extra content between the original and translated blocks. \\n can be used for newlines within the separator.",
+ "separatorHelpEpub": "In append mode, the translation will be a new block. This adds extra content between them. \\n for internal newlines.",
"htmlSettingsTitleText": "HTML Translation Options",
"insertModeHelpHtml": "Choose how to insert the translated text.",
- "separatorHelpHtml": "In append mode, the translation will start a new block. This is used to add extra content between the original and translated blocks. \\n can be used for newlines within the separator.",
+ "separatorHelpHtml": "In append mode, the translation will be a new block. This adds extra content between them. \\n for internal newlines.",
"assSettingsTitleText": "ASS Translation Options",
"insertModeHelpAss": "Choose how to insert the translated text.",
- "separatorPlaceholderAss": "e.g., \\N (newline character)",
- "separatorHelpAss": "Character used to separate original and translated text in append or prepend mode. \\N is the newline character for the ASS format.",
+ "separatorPlaceholderAss": "e.g., \\N (newline)",
+ "separatorHelpAss": "Character to separate original and translated text in append/prepend mode. \\N is the newline for ASS format.",
"jsonSettingsTitleText": "JSON Path Configuration",
"jsonPathLabel": "JSON Paths to Translate",
"jsonPathPlaceholder": "One path per line, e.g.:\n$.name\n$.*",
- "jsonPathHelp": "Uses jsonpath-ng syntax. Each line represents a JSON path.\n All strings within the matched objects will be translated.",
+ "jsonPathHelp": "Uses jsonpath-ng syntax. Each line is a JSON path. All strings within matching objects will be translated.",
"parsingSettingsTitleText": "Parsing Configuration",
"parsingEngineLabel": "Parsing Engine",
- "parsingEngineHelp": "If the uploaded file is already in .md format, this option is not required.",
+ "parsingEngineHelp": "Not required if the uploaded file is already in .md format.",
+ "engineOptionIdentity": "Already Markdown format",
+ "engineOptionMineru": "Mineru (Recommended)",
+ "engineOptionDocling": "Docling",
+ "engineOptionMineruDeploy": "Mineru Deploy Service",
"getMineruTokenTitle": "Get Mineru Token",
"mineruTokenPlaceholder": "Required when using Mineru engine",
"modelVersionLabel": "Mineru Model Version",
"modelVersionVlm": "VLM",
"modelVersionPipline": "Pipeline",
- "modelVersionHelp": "mineru VLM is a newer model in closed beta.",
+ "modelVersionHelp": "Mineru VLM is a newer internal test model.",
"mineruDeployBaseUrlLabel": "Service Address (Base URL)",
"mineruDeployBaseUrlPlaceholder": "e.g., http://127.0.0.1:8000",
"mineruDeployBackendLabel": "Backend Type",
@@ -259,9 +305,23 @@
"aiSettingsTitleText": "Translation Model",
"skipTranslationLabel": "Skip Translation",
"platformLabel": "Select Platform",
- "platformCustom": "Custom API",
+ "platformCustom": "Custom Endpoint",
+ "platform302AI": "302.AI",
+ "platformOpenAI": "OpenAI",
+ "platformGemini": "Gemini",
+ "platformDeepSeek": "DeepSeek",
+ "platformDashScope": "DashScope (Aliyun)",
+ "platformVolces": "VolcEngine (volces)",
+ "platformSiliconflow": "SiliconFlow (CN)",
+ "platformBigmodel": "Zhipu AI (bigmodel CN)",
+ "platformDmxapiCN": "DMXAPI_CN",
+ "platformDmxapiGlobal": "DMXAPI_GLOBAL",
+ "platformJuguang": "Juguang AI (juguang CN)",
+ "platformOpenRouter": "OpenRouter",
+ "platformLMStudio": "LM Studio",
+ "platformOllama": "Ollama",
"baseUrlLabel": "API Address (Base URL)",
- "baseUrlPlaceholder": "OpenAI-compatible Address",
+ "baseUrlPlaceholder": "OpenAI-compatible address",
"getApiKeyTitle": "Get API Key",
"apiKeyPlaceholder": "Please enter your API Key",
"modelIdLabel": "Model ID",
@@ -269,33 +329,44 @@
"systemProxyLabel": "Enable System Proxy",
"translationSettingsTitleText": "Translation Configuration",
"targetLanguageLabel": "Target Language",
+ "langZh": "Chinese (Simplified)",
+ "langEn": "English",
+ "langEs": "Spanish",
+ "langFr": "French",
+ "langDe": "German",
+ "langJa": "Japanese",
+ "langKo": "Korean",
+ "langRu": "Russian",
+ "langPt": "Portuguese",
+ "langAr": "Arabic",
+ "langVi": "Vietnamese",
"targetLanguageCustom": "Other (Custom)",
"customLangPlaceholder": "Enter target language, e.g., Italian",
"thinkingModeLabel": "Thinking Mode",
- "thinkingModeTooltip": "Sets whether mixed-inference models should 'think'. Currently supported by Zhipu's glm4.5 series, Volcengine's seed1.6 series, SiliconFlow, Google's Gemini series, and 302AI (partial). Disabling thinking is recommended.",
+ "thinkingModeTooltip": "Sets whether the hybrid inference model should 'think'. Supported by Zhipu's glm4.5 series, VolcEngine's seed1.6 series, SiliconFlow, Google's Gemini series, and 302AI (partial). Disabling is recommended.",
"thinkingModeEnable": "Enable",
"thinkingModeDisable": "Disable (Recommended)",
"thinkingModeDefault": "Default",
"customPromptLabel": "Custom Prompt",
- "customPromptPlaceholder": "Optional, e.g., 'Do not translate proper names.'",
+ "customPromptPlaceholder": "Optional, e.g., 'Do not translate personal names.'",
"chunkSizeLabel": "Chunk Size",
"resetBtn": "Reset",
"concurrentLabel": "Concurrency",
"retryLabel": "Retries",
"glossaryGenTitle": "Glossary",
"glossaryLabel": "Glossary (Optional)",
- "glossaryHelp": "Select one or more CSV files. Files must contain 'src' and 'dst' headers, representing source and destination text respectively.",
+ "glossaryHelp": "Select one or more CSV files. Files must have 'src' and 'dst' columns for source and destination terms.",
"viewGlossaryBtn": "View Glossary",
"clearGlossaryBtn": "Clear",
"glossaryGenEnableLabel": "Auto-generate Glossary",
"glossaryCustomPromptLabel": "Custom Prompt",
- "glossaryCustomPromptPlaceholder": "Glossary generation prompt",
+ "glossaryCustomPromptPlaceholder": "Prompt for glossary generation",
"glossaryGenConfigLabel": "Glossary Generation Config",
"glossaryGenConfigSame": "Same as Translation Config",
"glossaryGenConfigCustom": "Custom",
"importConfigBtn": "Import Config",
"exportConfigBtn": "Export Config",
- "githubInfo": "GitHub (star welcome❤):
\n https://github.com/xunbu/docutranslate",
+ "githubInfo": "GitHub Home (stars❤ welcome):
\n https://github.com/xunbu/docutranslate",
"qqGroupInfo": "QQ Group: 1047781902",
"taskListTitle": "Task List",
"newTaskBtn": "New Task",
@@ -303,10 +374,10 @@
"taskCardIdLabel": "Task ID",
"taskCardIdPlaceholder": "Waiting for submission...",
"taskCardFileDrop": "Click or drag file here",
- "taskCardFileSelected": "File Selected",
+ "taskCardFileSelected": "File selected",
"taskCardFilenameLabel": "Filename: ",
- "taskCardLogLabel": "Log",
- "copyLogsTooltip": "Copy Logs",
+ "taskCardLogLabel": "Logs",
+ "copyLogsTooltip": "Copy logs",
"taskCardStatusWaiting": "Waiting for file upload...",
"taskCardPreviewBtn": "Preview",
"taskCardDownloadBtn": "Download",
@@ -314,7 +385,16 @@
"taskCardStartBtn": "Start Translation",
"downloadMdEmbedded": "Markdown (Embedded Images)",
"downloadMdZip": "Markdown (Zip)",
+ "downloadTxt": "TXT",
+ "downloadJson": "JSON",
+ "downloadDocx": "DOCX",
+ "downloadXlsx": "XLSX",
+ "downloadCsv": "CSV",
+ "downloadSrt": "SRT",
+ "downloadEpub": "EPUB",
"downloadAss": "ASS",
+ "downloadHtml": "HTML",
+ "downloadPdf": "PDF",
"previewTitle": "Preview",
"previewBilingualBtn": "Bilingual",
"previewTranslatedOnlyBtn": "Translated Only",
@@ -323,54 +403,50 @@
"previewTranslated": "Translated",
"closeBtn": "Close",
"downloadBtn": "Download",
- "tutorialModalTitle": "Tutorial",
- "tutorialModalBody": "
Video tutorials can be found by searching for docutranslate on Bilibili.
Welcome to DocuTranslate! Please follow these steps to translate your documents:
At the top of the left settings panel, first select the processing flow that best suits your file type.
.txt plain text files..epub e-book files..docx Word documents..xlsx or .csv spreadsheet files..srt subtitle files..ass advanced subtitle files..json files..html web page files.After selecting a workflow, the relevant configuration options will appear below. Please complete the settings in order (all configurations are automatically saved in your browser):
A. Workflow-Specific Options (Appear based on your choice in Step 1):
minerU engine, you need to enter your Token here.\\N is often used in ASS format, <br /> in EPUB format as a newline separator).$.* (translate all strings), $..description (translate all values with the key description).B. General Options (Apply to all workflows):
In the task list on the right, click or drag your document into the file upload area.
After the file is successfully selected, click the Start Translation button at the bottom right of the task card. The system will start processing the task, and you can view the real-time progress in the log area.
Once the translation is complete, action buttons will appear at the bottom of the task card:
Video tutorials are available on Bilibili, search for docutranslate.
Welcome to DocuTranslate! Follow these steps to translate your document:
At the top of the left settings panel, choose the process that best suits your file type.
.txt files..epub e-books..docx Word documents..xlsx or .csv spreadsheets..srt subtitle files..ass advanced subtitle files..json files..html web pages.After selecting a workflow, relevant options will appear below. Configure them sequentially (all settings are saved in your browser):
A. Workflow-Specific Options (Appear based on your choice in Step 1):
minerU engine.\\N for ASS, <br /> for EPUB).$.* (translate all), $..description (translate all 'description' values).B. General Options (Apply to all workflows):
In the task list on the right, click or drag your document into the file upload area.
After selecting a file, click the Start Translation button on the task card. The process will begin, and you can monitor real-time progress in the log area.
Once translation is complete, action buttons will appear on the task card:
当前没有任务,点击“新建任务”开始吧!
等待提交...
点击或拖拽文件到此处
当前没有任务,点击“新建任务”开始吧!
等待提交...
点击或拖拽文件到此处