[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-oomol-lab--epub-translator":3,"tool-oomol-lab--epub-translator":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",142651,2,"2026-04-06T23:34:12",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107888,"2026-04-06T11:32:50",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":10,"last_commit_at":59,"category_tags":60,"status":17},4487,"LLMs-from-scratch","rasbt\u002FLLMs-from-scratch","LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目，旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型（LLM）。它不仅是同名技术著作的官方代码库，更提供了一套完整的实践方案，涵盖模型开发、预训练及微调的全过程。\n\n该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型，却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码，用户能够透彻掌握 Transformer 架构、注意力机制等关键原理，从而真正理解大模型是如何“思考”的。此外，项目还包含了加载大型预训练权重进行微调的代码，帮助用户将理论知识延伸至实际应用。\n\nLLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API，而是渴望探究模型构建细节的技术人员而言，这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计：将复杂的系统工程拆解为清晰的步骤，配合详细的图表与示例，让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础，还是为未来研发更大规模的模型做准备",90106,"2026-04-06T11:19:32",[35,15,13,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":76,"owner_email":76,"owner_twitter":76,"owner_website":77,"owner_url":78,"languages":79,"stars":87,"forks":88,"last_commit_at":89,"license":90,"difficulty_score":32,"env_os":91,"env_gpu":91,"env_ram":91,"env_deps":92,"category_tags":97,"github_topics":98,"view_count":32,"oss_zip_url":76,"oss_zip_packed_at":76,"status":17,"created_at":103,"updated_at":104,"faqs":105,"releases":136},4877,"oomol-lab\u002Fepub-translator","epub-translator","Translate EPUB books using Large Language Models while preserving the original text. The translated content is displayed side-by-side with the original, creating bilingual books perfect for language learning and cross-reference reading.","epub-translator 是一款利用大语言模型将 EPUB 电子书转化为双语对照版本的开源工具。它能在完整保留原书排版、图片及结构的基础上，将翻译内容与原文并排展示，生成适合对照阅读的双语书籍。\n\n这一工具主要解决了读者在阅读外文原著时难以兼顾语言学习与上下文理解的痛点。传统翻译往往覆盖原文或破坏原有格式，而 epub-translator 让学习者、研究人员及文学爱好者能够同时看到两种语言，既方便查阅生词和句式，又不会丢失原始语境，是语言学习和跨文化研究的得力助手。\n\n该工具既提供了无需编程基础的在线网页版和可视化界面（OOMOL Studio），方便普通用户直接上传文件使用；也提供了灵活的 Python API，支持开发者集成到自己的工作流中，甚至自定义进度追踪。其核心技术亮点在于智能的文本块处理机制，能够精准识别书籍结构，确保译文与原文在页面上完美对齐，同时兼容多种主流大模型接口，让用户可以根据需求自由选择翻译引擎。无论是想精进外语的学生，还是需要处理大量文献的研究者，都能通过它轻松获得高质量的双语阅读体验。","\u003Cdiv align=center>\n  \u003Ch1>EPUB Translator\u003C\u002Fh1>\n  \u003Cp>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Factions\u002Fworkflows\u002Fmerge-build.yml\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Foomol-lab\u002Fepub-translator\u002Fmerge-build.yml\" alt=\"ci\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpip_install-epub--translator-blue\" alt=\"pip install epub-translator\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fepub-translator.svg\" alt=\"pypi epub-translator\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Fepub-translator.svg\" alt=\"python versions\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fblob\u002Fmain\u002FLICENSE\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Foomol-lab\u002Fepub-translator\" alt=\"license\" \u002F>\u003C\u002Fa>\n  \u003C\u002Fp>\n  \u003Cp>\u003Ca href=\"https:\u002F\u002Fhub.oomol.com\u002Fpackage\u002Fbooks-translator?open=true\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fstatic.oomol.com\u002Fassets\u002Fbutton.svg\" alt=\"Open in OOMOL Studio\" \u002F>\u003C\u002Fa>\u003C\u002Fp>\n  \u003Cp>English | \u003Ca href=\".\u002FREADME_zh-CN.md\">中文\u003C\u002Fa>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\n\nWant to read a book in a foreign language without losing the original context? EPUB Translator transforms any EPUB into a bilingual edition with AI-powered translations displayed side-by-side with the original text.\n\nWhether you're learning a new language, conducting academic research, or simply enjoying foreign literature, you get both versions in one book - preserving all formatting, images, and structure.\n\n![Translation Effect](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_fa044a6760bd.png)\n\n### Online Version\n\nIf you'd like to try EPUB Translator without setting it up locally, you can use [Inkora - EPUB Translator](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator), the official online app for the same bilingual EPUB translation workflow. It lets you upload an EPUB file and try the main experience directly in your browser.\n\n[![EPUB Translator Online Version](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_ef8e5c46e010.png)](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator)\n\n## Installation\n\n```bash\npip install epub-translator\n```\n\n**Requirements**: Python 3.11, 3.12, or 3.13\n\n## Quick Start\n\n### Using OOMOL Studio (Recommended)\n\nThe easiest way to use EPUB Translator is through OOMOL Studio with a visual interface:\n\n[![Watch the Tutorial](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_97232b81d651.png)](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=QsAdiskxfXI)\n\n### Using Python API\n\n```python\nfrom epub_translator import LLM, translate, language, SubmitKind\n\n# Initialize LLM with your API credentials\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n\n# Translate EPUB file using language constants\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n```\n\n### With Progress Tracking\n\n```python\nfrom tqdm import tqdm\n\nwith tqdm(total=100, desc=\"Translating\", unit=\"%\") as pbar:\n    last_progress = 0.0\n\n    def on_progress(progress: float):\n        nonlocal last_progress\n        increment = (progress - last_progress) * 100\n        pbar.update(increment)\n        last_progress = progress\n\n    translate(\n        source_path=\"source.epub\",\n        target_path=\"translated.epub\",\n        target_language=\"English\",\n        submit=SubmitKind.APPEND_BLOCK,\n        llm=llm,\n        on_progress=on_progress,\n    )\n```\n\n## API Reference\n\n### `LLM` Class\n\nInitialize the LLM client for translation:\n\n```python\nLLM(\n    key: str,                          # API key\n    url: str,                          # API endpoint URL\n    model: str,                        # Model name (e.g., \"gpt-4\")\n    token_encoding: str,               # Token encoding (e.g., \"o200k_base\")\n    cache_path: PathLike | None = None,           # Cache directory path\n    timeout: float | None = None,                  # Request timeout in seconds\n    top_p: float | tuple[float, float] | None = None,\n    temperature: float | tuple[float, float] | None = None,\n    retry_times: int = 5,                         # Number of retries on failure\n    retry_interval_seconds: float = 6.0,          # Interval between retries\n    log_dir_path: PathLike | None = None,         # Log directory path\n)\n```\n\n### `translate` Function\n\nTranslate an EPUB file:\n\n```python\ntranslate(\n    source_path: PathLike | str,       # Source EPUB file path\n    target_path: PathLike | str,       # Output EPUB file path\n    target_language: str,              # Target language (e.g., \"English\", \"Chinese\")\n    submit: SubmitKind,                # How to insert translations (REPLACE, APPEND_TEXT, or APPEND_BLOCK)\n    user_prompt: str | None = None,    # Custom translation instructions\n    max_retries: int = 5,              # Maximum retries for failed translations\n    max_group_tokens: int = 2600,      # Maximum tokens per translation group\n    concurrency: int = 1,              # Number of concurrent translation tasks (default: 1)\n    llm: LLM | None = None,            # Single LLM instance for both translation and filling\n    translation_llm: LLM | None = None,  # LLM instance for translation (overrides llm)\n    fill_llm: LLM | None = None,       # LLM instance for XML filling (overrides llm)\n    on_progress: Callable[[float], None] | None = None,  # Progress callback (0.0-1.0)\n    on_fill_failed: Callable[[FillFailedEvent], None] | None = None,  # Error callback\n)\n```\n\n**Note**: Either `llm` or both `translation_llm` and `fill_llm` must be provided. Using separate LLMs allows for task-specific optimization.\n\n#### Submit Modes\n\nThe `submit` parameter controls how translated content is inserted into the document. Use `SubmitKind` enum to specify the insertion mode:\n\n```python\nfrom epub_translator import SubmitKind\n\n# Three available modes:\n# - SubmitKind.REPLACE: Replace original content with translation (single-language output)\n# - SubmitKind.APPEND_TEXT: Append translation as inline text (bilingual output)\n# - SubmitKind.APPEND_BLOCK: Append translation as block elements (bilingual output, recommended)\n```\n\n**Mode Comparison:**\n\n- **`SubmitKind.REPLACE`**: Creates a single-language translation by replacing original text with translated content. Useful for creating books in the target language only.\n\n- **`SubmitKind.APPEND_TEXT`**: Appends translations as inline text immediately after the original content. Both languages appear in the same paragraph, creating a continuous reading flow.\n\n- **`SubmitKind.APPEND_BLOCK`** (Recommended): Appends translations as separate block elements (paragraphs) after the original. This creates clear visual separation between languages, making it ideal for side-by-side bilingual reading.\n\n**Example:**\n\n```python\n# For bilingual books (recommended)\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# For single-language translation\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.REPLACE,\n    llm=llm,\n)\n```\n\n#### Language Constants\n\nEPUB Translator provides predefined language constants for convenience. You can use these constants instead of writing language names as strings:\n\n```python\nfrom epub_translator import language\n\n# Usage example:\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# You can also use custom language strings:\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"Icelandic\",  # For languages not in the constants\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n```\n\n### Error Handling with `on_fill_failed`\n\nMonitor translation errors using the `on_fill_failed` callback. The system automatically retries failed translations up to `max_retries` times (default: 5). Most errors are recovered during retries and don't affect the final output.\n\n```python\nfrom epub_translator import FillFailedEvent\n\ndef handle_fill_error(event: FillFailedEvent):\n    # Only log critical errors that will affect the final EPUB\n    if event.over_maximum_retries:\n        print(f\"Critical error after {event.retried_count} attempts:\")\n        print(f\"  {event.error_message}\")\n        print(\"  This error will be present in the final EPUB file!\")\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    on_fill_failed=handle_fill_error,\n)\n```\n\n**Understanding Error Severity:**\n\nThe `FillFailedEvent` contains:\n- `error_message: str` - Description of the error\n- `retried_count: int` - Current retry attempt number (1 to max_retries)\n- `over_maximum_retries: bool` - Whether the error is critical\n\n**Error Categories:**\n\n- **Recoverable errors** (`over_maximum_retries=False`): Errors during retry attempts. The system will continue retrying and may resolve these automatically. Safe to ignore in most cases.\n\n- **Critical errors** (`over_maximum_retries=True`): Errors that persist after all retry attempts. These will appear in the final EPUB file and should be investigated.\n\n**Advanced Usage:**\n\nFor verbose logging during translation debugging:\n\n```python\ndef handle_fill_error(event: FillFailedEvent):\n    if event.over_maximum_retries:\n        # Critical: affects final output\n        print(f\"❌ CRITICAL: {event.error_message}\")\n    else:\n        # Informational: system is retrying\n        print(f\"⚠️  Retry {event.retried_count}: {event.error_message}\")\n```\n\n### Dual-LLM Architecture\n\nUse separate LLM instances for translation and XML structure filling with different optimization parameters:\n\n```python\n# Create two LLM instances with different temperatures\ntranslation_llm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    temperature=0.8,  # Higher temperature for creative translation\n)\n\nfill_llm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    temperature=0.3,  # Lower temperature for structure preservation\n)\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    translation_llm=translation_llm,\n    fill_llm=fill_llm,\n)\n```\n\n## Configuration Examples\n\n### OpenAI\n\n```python\nllm = LLM(\n    key=\"sk-...\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n```\n\n### Azure OpenAI\n\n```python\nllm = LLM(\n    key=\"your-azure-key\",\n    url=\"https:\u002F\u002Fyour-resource.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fyour-deployment\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n```\n\n### Other OpenAI-Compatible Services\n\nAny service with an OpenAI-compatible API can be used:\n\n```python\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fyour-service.com\u002Fv1\",\n    model=\"your-model\",\n    token_encoding=\"o200k_base\",  # Match your model's encoding\n)\n```\n\n## Advanced Features\n\n### Custom Translation Prompts\n\nProvide specific translation instructions:\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"English\",\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    user_prompt=\"Use formal language and preserve technical terminology\",\n)\n```\n\n### Caching for Progress Recovery\n\nEnable caching to resume translation progress after failures:\n\n```python\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    cache_path=\".\u002Ftranslation_cache\",  # Translations are cached here\n)\n```\n\n### Concurrent Translation\n\nSpeed up translation by processing multiple text segments concurrently. Use the `concurrency` parameter to control how many translation tasks run in parallel:\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"English\",\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    concurrency=4,  # Process 4 segments concurrently\n)\n```\n\n**Performance Tips:**\n\n- Start with `concurrency=4` and adjust based on your API rate limits and system resources\n- Higher concurrency values can significantly reduce translation time for large books\n- The translation order is preserved regardless of concurrency settings\n- Monitor your API provider's rate limits to avoid throttling\n\n**Thread Safety:**\n\nWhen using `concurrency > 1`, ensure that any custom callback functions (`on_progress`, `on_fill_failed`) are thread-safe. Built-in callbacks are thread-safe by default.\n\n### Token Usage Monitoring\n\nTrack token consumption during translation to monitor API costs and usage:\n\n```python\nfrom epub_translator import LLM, translate, language, SubmitKind\n\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# Access token statistics after translation\nprint(f\"Total tokens: {llm.total_tokens}\")\nprint(f\"Input tokens: {llm.input_tokens}\")\nprint(f\"Input cache tokens: {llm.input_cache_tokens}\")\nprint(f\"Output tokens: {llm.output_tokens}\")\n```\n\n**Available Statistics:**\n\n- `total_tokens` - Total number of tokens used (input + output)\n- `input_tokens` - Number of prompt\u002Finput tokens\n- `input_cache_tokens` - Number of cached input tokens (when using prompt caching)\n- `output_tokens` - Number of generated\u002Fcompletion tokens\n\n**Real-time Monitoring:**\n\nYou can also monitor token usage in real-time during translation:\n\n```python\nfrom tqdm import tqdm\nimport time\n\nwith tqdm(total=100, desc=\"Translating\", unit=\"%\") as pbar:\n    last_progress = 0.0\n    start_time = time.time()\n\n    def on_progress(progress: float):\n        nonlocal last_progress\n        increment = (progress - last_progress) * 100\n        pbar.update(increment)\n        last_progress = progress\n\n        # Update token stats in progress bar\n        pbar.set_postfix({\n            'tokens': llm.total_tokens,\n            'cost_est': f'${llm.total_tokens * 0.00001:.4f}'  # Estimate based on your pricing\n        })\n\n    translate(\n        source_path=\"source.epub\",\n        target_path=\"translated.epub\",\n        target_language=language.ENGLISH,\n        submit=SubmitKind.APPEND_BLOCK,\n        llm=llm,\n        on_progress=on_progress,\n    )\n\n    elapsed = time.time() - start_time\n    print(f\"\\nTranslation completed in {elapsed:.1f}s\")\n    print(f\"Total tokens used: {llm.total_tokens:,}\")\n    print(f\"Average tokens\u002Fsecond: {llm.total_tokens\u002Felapsed:.1f}\")\n```\n\n**Dual-LLM Token Tracking:**\n\nWhen using separate LLMs for translation and filling, each LLM tracks its own statistics:\n\n```python\ntranslation_llm = LLM(key=\"...\", url=\"...\", model=\"gpt-4\", token_encoding=\"o200k_base\")\nfill_llm = LLM(key=\"...\", url=\"...\", model=\"gpt-4\", token_encoding=\"o200k_base\")\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    translation_llm=translation_llm,\n    fill_llm=fill_llm,\n)\n\nprint(f\"Translation tokens: {translation_llm.total_tokens}\")\nprint(f\"Fill tokens: {fill_llm.total_tokens}\")\nprint(f\"Combined total: {translation_llm.total_tokens + fill_llm.total_tokens}\")\n```\n\n**Note:** Token statistics are cumulative across all API calls made by the LLM instance. The counts only increase and are thread-safe when using concurrent translation.\n\n## Related Projects\n\n### PDF Craft\n\n[PDF Craft](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fpdf-craft) converts PDF files into EPUB and other formats, with a focus on scanned books. Combine PDF Craft with EPUB Translator to convert and translate scanned PDF books into bilingual EPUB format.\n\n**Workflow**: Scanned PDF → [PDF Craft] → EPUB → [EPUB Translator] → Bilingual EPUB\n\nFor a complete tutorial, watch: [Convert scanned PDF books to EPUB format and translate them into bilingual books](https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1tMQZY5EYY\u002F)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues)\n- **Online App**: [Inkora - EPUB Translator](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator)\n","\u003Cdiv align=center>\n  \u003Ch1>EPUB翻译器\u003C\u002Fh1>\n  \u003Cp>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Factions\u002Fworkflows\u002Fmerge-build.yml\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Foomol-lab\u002Fepub-translator\u002Fmerge-build.yml\" alt=\"ci\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpip_install-epub--translator-blue\" alt=\"pip install epub-translator\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fepub-translator.svg\" alt=\"pypi epub-translator\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Fepub-translator\u002F\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Fepub-translator.svg\" alt=\"python versions\" \u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fblob\u002Fmain\u002FLICENSE\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Foomol-lab\u002Fepub-translator\" alt=\"license\" \u002F>\u003C\u002Fa>\n  \u003C\u002Fp>\n  \u003Cp>\u003Ca href=\"https:\u002F\u002Fhub.oomol.com\u002Fpackage\u002Fbooks-translator?open=true\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Fstatic.oomol.com\u002Fassets\u002Fbutton.svg\" alt=\"在OOMOL Studio中打开\" \u002F>\u003C\u002Fa>\u003C\u002Fp>\n  \u003Cp>English | \u003Ca href=\".\u002FREADME_zh-CN.md\">中文\u003C\u002Fa>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\n\n想要在不丢失原文语境的情况下阅读外文书籍吗？EPUB翻译器能够借助AI技术，将任意EPUB格式的电子书转换为双语文本对照版本，让译文与原文并排呈现。\n\n无论您是在学习新语言、进行学术研究，还是单纯享受外国文学作品，这款工具都能帮您在一本书中同时获得两种语言版本，且完整保留原书的排版、图片和结构。\n\n![翻译效果](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_fa044a6760bd.png)\n\n### 在线版本\n\n如果您不想在本地安装EPUB翻译器，可以使用官方推出的在线应用[Inkora - EPUB翻译器](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator)，它提供了同样的双语文本翻译流程。只需上传一个EPUB文件，即可直接在浏览器中体验主要功能。\n\n[![EPUB翻译器在线版本](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_ef8e5c46e010.png)](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator)\n\n## 安装\n\n```bash\npip install epub-translator\n```\n\n**要求**：Python 3.11、3.12 或 3.13\n\n## 快速入门\n\n### 使用OOMOL Studio（推荐）\n\n通过OOMOL Studio的可视化界面使用EPUB翻译器是最简单的方式：\n\n[![观看教程](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_readme_97232b81d651.png)](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=QsAdiskxfXI)\n\n### 使用Python API\n\n```python\nfrom epub_translator import LLM, translate, language, SubmitKind\n\n# 使用您的API密钥初始化LLM客户端\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n\n# 使用语言常量翻译EPUB文件\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n```\n\n### 带进度跟踪\n\n```python\nfrom tqdm import tqdm\n\nwith tqdm(total=100, desc=\"翻译\", unit=\"%\") as pbar:\n    last_progress = 0.0\n\n    def on_progress(progress: float):\n        nonlocal last_progress\n        increment = (progress - last_progress) * 100\n        pbar.update(increment)\n        last_progress = progress\n\n    translate(\n        source_path=\"source.epub\",\n        target_path=\"translated.epub\",\n        target_language=\"English\",\n        submit=SubmitKind.APPEND_BLOCK,\n        llm=llm,\n        on_progress=on_progress,\n    )\n```\n\n## API参考\n\n### `LLM`类\n\n初始化用于翻译的LLM客户端：\n\n```python\nLLM(\n    key: str,                          # API密钥\n    url: str,                          # API端点URL\n    model: str,                        # 模型名称（例如，“gpt-4”）\n    token_encoding: str,               # 令牌编码方式（例如，“o200k_base”）\n    cache_path: PathLike | None = None,           # 缓存目录路径\n    timeout: float | None = None,                  # 请求超时时间（秒）\n    top_p: float | tuple[float, float] | None = None,\n    temperature: float | tuple[float, float] | None = None,\n    retry_times: int = 5,                         # 失败后重试次数\n    retry_interval_seconds: float = 6.0,          # 重试间隔时间（秒）\n    log_dir_path: PathLike | None = None,         # 日志目录路径\n)\n```\n\n### `translate`函数\n\n翻译EPUB文件：\n\n```python\ntranslate(\n    source_path: PathLike | str,       # 源EPUB文件路径\n    target_path: PathLike | str,       # 目标EPUB文件路径\n    target_language: str,              # 目标语言（例如，“英语”、“中文”）\n    submit: SubmitKind,                # 插入译文的方式（REPLACE、APPEND_TEXT或APPEND_BLOCK）\n    user_prompt: str | None = None,    # 自定义翻译指令\n    max_retries: int = 5,              # 翻译失败后的最大重试次数\n    max_group_tokens: int = 2600,      # 每组翻译的最大令牌数\n    concurrency: int = 1,              # 并发翻译任务数量（默认为1）\n    llm: LLM | None = None,            # 单一LLM实例用于翻译和填充\n    translation_llm: LLM | None = None,  # 专门用于翻译的LLM实例（覆盖llm）\n    fill_llm: LLM | None = None,       # 专门用于XML填充的LLM实例（覆盖llm）\n    on_progress: Callable[[float], None] | None = None,  # 进度回调函数（0.0–1.0）\n    on_fill_failed: Callable[[FillFailedEvent], None] | None = None,  # 错误回调函数\n)\n```\n\n**注意**：必须提供`llm`，或者同时提供`translation_llm`和`fill_llm`。使用独立的LLM实例可以根据具体任务需求进行优化。\n\n#### 提交模式\n\n`submit`参数决定了译文如何插入到文档中。请使用`SubmitKind`枚举来指定插入方式：\n\n```python\nfrom epub_translator import SubmitKind\n\n# 三种可用模式：\n# - SubmitKind.REPLACE：用译文替换原文内容，生成单语种输出\n# - SubmitKind.APPEND_TEXT：将译文以内联文本形式追加到原文之后，两种语言出现在同一段落中，保持连续的阅读流\n# - SubmitKind.APPEND_BLOCK：将译文以块级元素的形式追加到原文之后，两种语言之间有清晰的视觉分隔，非常适合双语文本对照阅读\n```\n\n**模式对比：**\n\n- **`SubmitKind.REPLACE`**：通过用译文替换原文内容，生成单语种翻译版本。适用于仅需目标语言版本的书籍。\n\n- **`SubmitKind.APPEND_TEXT`**：将译文以内联文本形式紧随原文之后插入。两种语言在同一段落中交替出现，形成流畅的阅读体验。\n\n- **`SubmitKind.APPEND_BLOCK`**（推荐）：将译文以独立的块级元素（段落）形式插入到原文之后。这种方式能够在视觉上清晰地区分两种语言，特别适合双语文本对照阅读。\n\n**示例：**\n\n# 用于双语书籍（推荐）\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# 用于单语翻译\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.REPLACE,\n    llm=llm,\n)\n```\n\n#### 语言常量\n\nEPUB Translator 提供了预定义的语言常量，以方便使用。您可以使用这些常量，而无需将语言名称写成字符串：\n\n```python\nfrom epub_translator import language\n\n# 使用示例：\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# 您也可以使用自定义的语言字符串：\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"Icelandic\",  # 对于不在常量中的语言\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n```\n\n### 使用 `on_fill_failed` 进行错误处理\n\n通过 `on_fill_failed` 回调函数监控翻译错误。系统会自动重试失败的翻译，最多尝试 `max_retries` 次（默认为5次）。大多数错误在重试过程中都会被修复，不会影响最终输出。\n\n```python\nfrom epub_translator import FillFailedEvent\n\ndef handle_fill_error(event: FillFailedEvent):\n    \u002F\u002F 只记录会影响最终 EPUB 文件的关键错误\n    if event.over_maximum_retries:\n        print(f\"关键错误，在 {event.retried_count} 次尝试后：\")\n        print(f\"  {event.error_message}\")\n        print(\"  此错误将出现在最终的 EPUB 文件中！\")\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    on_fill_failed=handle_fill_error,\n)\n```\n\n**理解错误严重性：**\n\n`FillFailedEvent` 包含：\n- `error_message: str` - 错误描述\n- `retried_count: int` - 当前的重试次数（1 到 max_retries）\n- `over_maximum_retries: bool` - 错误是否严重\n\n**错误分类：**\n\n- **可恢复错误**（`over_maximum_retries=False`）：重试过程中出现的错误。系统会继续重试，通常可以自动解决。大多数情况下可以忽略。\n  \n- **严重错误**（`over_maximum_retries=True`）：所有重试尝试都失败后的错误。这些错误会出现在最终的 EPUB 文件中，需要进一步调查。\n\n**高级用法：**\n\n在调试翻译过程时进行详细日志记录：\n\n```python\ndef handle_fill_error(event: FillFailedEvent):\n    if event.over_maximum_retries:\n        \u002F\u002F 严重：影响最终输出\n        print(f\"❌ 严重：{event.error_message}\")\n    else:\n        \u002F\u002F 信息性：系统正在重试\n        print(f\"⚠️  重试 {event.retried_count} 次：{event.error_message}\")\n```\n\n### 双 LLM 架构\n\n使用不同的 LLM 实例分别进行翻译和 XML 结构填充，并设置不同的优化参数：\n\n```python\n\u002F\u002F 创建两个具有不同温度的 LLM 实例\ntranslation_llm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    temperature=0.8,  \u002F\u002F 较高的温度用于创意翻译\n)\n\nfill_llm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    temperature=0.3,  \u002F\u002F 较低的温度用于保持结构完整性\n)\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    translation_llm=translation_llm,\n    fill_llm=fill_llm,\n)\n```\n\n## 配置示例\n\n### OpenAI\n\n```python\nllm = LLM(\n    key=\"sk-...\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n```\n\n### Azure OpenAI\n\n```python\nllm = LLM(\n    key=\"your-azure-key\",\n    url=\"https:\u002F\u002Fyour-resource.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fyour-deployment\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n```\n\n### 其他兼容 OpenAI 的服务\n\n任何具有 OpenAI 兼容 API 的服务都可以使用：\n\n```python\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fyour-service.com\u002Fv1\",\n    model=\"your-model\",\n    token_encoding=\"o200k_base\",  \u002F\u002F 根据您的模型编码进行匹配\n)\n```\n\n## 高级功能\n\n### 自定义翻译提示\n\n提供特定的翻译指导：\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"English\",\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    user_prompt=\"使用正式语言并保留技术术语\",\n)\n```\n\n### 缓存以恢复进度\n\n启用缓存功能，以便在发生故障后恢复翻译进度：\n\n```python\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n    cache_path=\".\u002Ftranslation_cache\",  \u002F\u002F 翻译结果将在此处缓存\n)\n```\n\n### 并发翻译\n\n通过同时处理多个文本段来加快翻译速度。使用 `concurrency` 参数控制同时运行的翻译任务数量：\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"English\",\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    concurrency=4,  \u002F\u002F 同时处理 4 个文本段\n)\n```\n\n**性能提示：**\n\n- 建议从 `concurrency=4` 开始，根据您的 API 速率限制和系统资源进行调整\n- 更高的并发值可以显著缩短大型书籍的翻译时间\n- 无论并发设置如何，翻译顺序都会保持不变\n- 请密切关注您的 API 提供商的速率限制，以免被限流\n\n**线程安全：**\n\n当使用 `concurrency > 1` 时，请确保任何自定义回调函数（`on_progress`、`on_fill_failed`）都是线程安全的。内置回调函数默认是线程安全的。\n\n### 令牌使用监控\n\n在翻译过程中跟踪令牌消耗情况，以便监控 API 成本和使用情况：\n\n```python\nfrom epub_translator import LLM、translate、language 和 SubmitKind\n\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# 翻译后的访问令牌统计信息\nprint(f\"总令牌数: {llm.total_tokens}\")\nprint(f\"输入令牌数: {llm.input_tokens}\")\nprint(f\"输入缓存令牌数: {llm.input_cache_tokens}\")\nprint(f\"输出令牌数: {llm.output_tokens}\")\n```\n\n**可用的统计信息：**\n\n- `total_tokens` - 使用的总令牌数（输入 + 输出）\n- `input_tokens` - 提示\u002F输入令牌的数量\n- `input_cache_tokens` - 缓存的输入令牌数量（使用提示缓存时）\n- `output_tokens` - 生成\u002F完成令牌的数量\n\n**实时监控：**\n\n您还可以在翻译过程中实时监控令牌使用情况：\n\n```python\nfrom tqdm import tqdm\nimport time\n\nwith tqdm(total=100, desc=\"翻译中\", unit=\"%\") as pbar:\n    last_progress = 0.0\n    start_time = time.time()\n\n    def on_progress(progress: float):\n        nonlocal last_progress\n        increment = (progress - last_progress) * 100\n        pbar.update(increment)\n        last_progress = progress\n\n        # 在进度条中更新令牌统计信息\n        pbar.set_postfix({\n            'tokens': llm.total_tokens,\n            'cost_est': f'${llm.total_tokens * 0.00001:.4f}'  # 根据您的定价估算\n        })\n\n    translate(\n        source_path=\"source.epub\",\n        target_path=\"translated.epub\",\n        target_language=language.ENGLISH,\n        submit=SubmitKind.APPEND_BLOCK,\n        llm=llm,\n        on_progress=on_progress,\n    )\n\n    elapsed = time.time() - start_time\n    print(f\"\\n翻译完成，耗时{elapsed:.1f}秒\")\n    print(f\"总共使用的令牌数: {llm.total_tokens:,}\")\n    print(f\"平均每秒使用的令牌数: {llm.total_tokens\u002Felapsed:.1f}\")\n```\n\n**双LLM令牌跟踪：**\n\n当分别使用不同的LLM进行翻译和填充时，每个LLM都会跟踪各自的统计信息：\n\n```python\ntranslation_llm = LLM(key=\"...\", url=\"...\", model=\"gpt-4\", token_encoding=\"o200k_base\")\nfill_llm = LLM(key=\"...\", url=\"...\", model=\"gpt-4\", token_encoding=\"o200k_base\")\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    translation_llm=translation_llm,\n    fill_llm=fill_llm,\n)\n\nprint(f\"翻译使用的令牌数: {translation_llm.total_tokens}\")\nprint(f\"填充使用的令牌数: {fill_llm.total_tokens}\")\nprint(f\"合计总数: {translation_llm.total_tokens + fill_llm.total_tokens}\")\n```\n\n**注意：** 令牌统计信息是LLM实例所有API调用的累计值。这些计数只会增加，并且在使用并发翻译时是线程安全的。\n\n## 相关项目\n\n### PDF Craft\n\n[PDF Craft](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fpdf-craft) 可以将PDF文件转换为EPUB等格式，尤其擅长处理扫描版书籍。您可以将PDF Craft与EPUB Translator结合使用，将扫描版PDF书籍转换并翻译成双语EPUB格式。\n\n**工作流程**：扫描版PDF → [PDF Craft] → EPUB → [EPUB Translator] → 双语EPUB\n\n完整教程请观看：[如何将扫描版PDF书籍转换为EPUB格式并翻译成双语书](https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1tMQZY5EYY\u002F)\n\n## 贡献\n\n欢迎贡献！请随时提交Pull Request。\n\n## 许可证\n\n本项目采用MIT许可证授权——详情请参阅[LICENSE](LICENSE)文件。\n\n## 支持\n\n- **问题**：[GitHub Issues](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues)\n- **在线应用**：[Inkora - EPUB Translator](https:\u002F\u002Finkora.oomol.com\u002Fepub-translator)","# EPUB Translator 快速上手指南\n\nEPUB Translator 是一款基于 AI 的开源工具，能够将任意 EPUB 电子书转换为双语对照版本。它在保留原文格式、图片和结构的同时，利用大语言模型生成侧边对照的译文，非常适合语言学习、学术研究或外文阅读。\n\n## 环境准备\n\n在开始之前，请确保您的开发环境满足以下要求：\n\n*   **操作系统**：Windows \u002F macOS \u002F Linux\n*   **Python 版本**：3.11, 3.12 或 3.13\n*   **依赖项**：需具备访问大语言模型 API 的能力（如 OpenAI、Azure OpenAI 或其他兼容接口）\n\n## 安装步骤\n\n使用 pip 直接安装最新稳定版：\n\n```bash\npip install epub-translator\n```\n\n> **提示**：如果下载速度较慢，可以使用国内镜像源加速安装：\n> ```bash\n> pip install epub-translator -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n> ```\n\n如需进度条支持（可选），建议安装 `tqdm`：\n\n```bash\npip install tqdm\n```\n\n## 基本使用\n\n### 1. 初始化 LLM 客户端\n\n首先，配置您的大语言模型 API 信息。以下以 OpenAI 为例：\n\n```python\nfrom epub_translator import LLM\n\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n```\n\n### 2. 执行翻译\n\n使用 `translate` 函数将源文件翻译为目标语言。推荐采用 `APPEND_BLOCK` 模式，该模式会将译文作为独立段落附加在原文后，形成清晰的双语对照效果。\n\n```python\nfrom epub_translator import translate, language, SubmitKind\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,  # 目标语言，也可用字符串如 \"Chinese\"\n    submit=SubmitKind.APPEND_BLOCK,    # 推荐模式：双语对照\n    llm=llm,\n)\n```\n\n### 3. 带进度监控的翻译（可选）\n\n若需实时查看翻译进度，可结合 `tqdm` 使用回调函数：\n\n```python\nfrom tqdm import tqdm\n\nwith tqdm(total=100, desc=\"Translating\", unit=\"%\") as pbar:\n    last_progress = 0.0\n\n    def on_progress(progress: float):\n        nonlocal last_progress\n        increment = (progress - last_progress) * 100\n        pbar.update(increment)\n        last_progress = progress\n\n    translate(\n        source_path=\"source.epub\",\n        target_path=\"translated.epub\",\n        target_language=\"Chinese\",\n        submit=SubmitKind.APPEND_BLOCK,\n        llm=llm,\n        on_progress=on_progress,\n    )\n```\n\n运行完成后，您将在指定路径获得保留原格式的双语 EPUB 文件。","一位正在攻读比较文学的研究生，需要深入研读一本未引进中文版的英文原版学术专著，以便在论文中精准引用并分析其核心观点。\n\n### 没有 epub-translator 时\n- **查阅效率极低**：遇到生僻术语或复杂长句时，必须频繁切换屏幕去查词典或使用网页翻译，打断阅读心流，难以保持专注。\n- **语境严重丢失**：通用的全文翻译工具往往会破坏原书的章节结构、脚注甚至图片排版，导致引用时无法定位原文位置。\n- **对照验证困难**：为了确认翻译的准确性，需要在两个独立的文件（原文电子书和翻译文档）之间来回翻找，极易出错且耗时。\n- **学习成本高昂**：若想通过阅读提升专业英语能力，缺乏“原文 - 译文”逐段对照的环境，难以揣摩作者的用词精妙之处。\n\n### 使用 epub-translator 后\n- **沉浸式双语阅读**：epub-translator 利用大模型将译文直接嵌入原书，生成左右分栏或段落对照的双语版本，无需切换窗口即可流畅阅读。\n- **完美保留格式**：工具在翻译过程中完整保留了原书的目录、脚注、图片及排版样式，确保学术引用的页码和上下文准确无误。\n- **即时对照参考**：每一段英文下方（或侧边）即是对应的中文译文，研究者可随时比对细节，快速验证关键概念的理解是否偏差。\n- **辅助语言进阶**：这种原生集成的双语模式让读者能在学习专业知识的同时，自然习得地道的学术表达方式，实现阅读与学习的双重收益。\n\nepub-translator 通过将 AI 翻译无缝融入原始文档结构，把枯燥的跨语言查阅变成了高效的双语对照研读体验。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Foomol-lab_epub-translator_fa044a67.png","oomol-lab","OOMOL Lab","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Foomol-lab_19eb65c7.png","OpenSource projects from the @oomol team",null,"https:\u002F\u002Foomol.com\u002F","https:\u002F\u002Fgithub.com\u002Foomol-lab",[80,84],{"name":81,"color":82,"percentage":83},"Python","#3572A5",98,{"name":85,"color":86,"percentage":32},"Jinja","#a52a22",689,54,"2026-04-06T06:15:48","MIT","未说明",{"notes":93,"python":94,"dependencies":95},"该工具主要作为 Python 库运行，需配置兼容 OpenAI 接口的大语言模型（如 OpenAI、Azure OpenAI 或其他兼容服务）的 API Key。支持通过缓存机制恢复翻译进度，并允许使用双 LLM 架构分别优化翻译质量和结构填充。未提及本地部署大型模型，因此无特定 GPU 或显存要求，运行资源主要取决于所选用的远程 API 服务及并发设置。","3.11, 3.12, 3.13",[96],"tqdm",[15,13,14,35],[99,100,101,102],"epub","oomol","translation","ai","2026-03-27T02:49:30.150509","2026-04-07T13:29:03.576812",[106,111,116,121,126,131],{"id":107,"question_zh":108,"answer_zh":109,"source_url":110},22164,"处理 EPUB 文件时遇到 XML 格式验证失败或报错，如何解决？","请升级到最新版本（如 0.1.5 或更高）。新版修复了原生 xml.etree.ElementTree.Element 缺少 .parent 属性的兼容性问题。此外，只要日志中 over_maximum_retries 为 False，其他的警告信息通常不会影响最终的翻译结果和质量，可以忽略。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F108",{"id":112,"question_zh":113,"answer_zh":114,"source_url":115},22165,"翻译结果中出现原文丢失、句子被截断或内容不完整的情况怎么办？","该问题在版本 0.1.1 中已修复。新版代码设计了上下文重叠机制，提交给 LLM 的文本包含实际翻译文本周围的上下文，允许模型读取超出实际翻译范围的内容，从而避免最终裁剪时丢失正文。如果遇到此问题，请务必升级到 0.1.1 或更高版本。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F30",{"id":117,"question_zh":118,"answer_zh":119,"source_url":120},22166,"在 Windows 系统下运行时，提示找不到文件或 ZIP 路径读取失败（如 META-INF\\container.xml），如何解决？","这是路径分隔符兼容性问题。Windows 默认使用反斜杠 (\\)，而 ZIP 文件内部必须使用正斜杠 (\u002F)。该问题在版本 0.1.1 的大重构中已得到优化和修复。如果遇到此错误，请将 epub-translator 升级到 0.1.1 或更高版本。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F69",{"id":122,"question_zh":123,"answer_zh":124,"source_url":125},22167,"项目是否支持智谱 AI (Zhipu) 的 GLM 系列模型？如何配置？","项目支持任何兼容 OpenAI API 接口的模型，包括智谱的 GLM 系列。你可以直接使用 OpenAI 兼容的配置方式：\n- Base URL: https:\u002F\u002Fopen.bigmodel.cn\u002Fapi\u002Fpaas\u002Fv4\u002F\n- Model: 例如 \"glm-4\"\n- Token Encoding: 通常与使用的语言有关，不影响翻译核心逻辑，可尝试默认值或根据模型文档设置。\n虽然官方未专门测试所有 GLM 型号，但理论上不会有大问题。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F129",{"id":127,"question_zh":128,"answer_zh":129,"source_url":130},22168,"使用“思考型”模型（Reasoning Models）进行翻译时出现异常或输出了思维链内容，该如何处理？","epub-translator 设计上假定使用非思考模型，因为翻译任务不需要复杂的规划，使用思考模型会造成大量 Token 浪费。如果你必须使用此类模型（且无法关闭其思考输出功能），可以通过在配置中添加 extra_body 参数来禁用推理\u002F思考功能，以防止输出混乱。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F25",{"id":132,"question_zh":133,"answer_zh":134,"source_url":135},22169,"EPUB 文件中包含 MathML 公式时，翻译结果出现中英文混合或段落结构混乱，有解决办法吗？","这是一个已知问题，特别是在 APPEND_BLOCK 模式下，p 标签内的 MathML 公式可能导致生成混合段落。维护者已在相关 Issue 中确认并跟进修复（参考版本更新日志或后续补丁）。建议检查是否已升级到包含该修复的最新版本，或者暂时避免在包含复杂公式的章节使用特定的分块模式。","https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F119",[137,142,147,152,157,162,167,172,177,182],{"id":138,"version":139,"summary_zh":140,"released_at":141},135896,"v0.1.9","# 发布 v0.1.9\n\n本次发布修复了 EPUB 元数据文件中命名空间处理的问题。\n\n## 🐛 错误修复\n\n### 修复了 TOC 和 OPF 文件中命名空间结构的保留问题 (#127)\n\n修复了一个问题：在翻译过程中，目录 (TOC) 和 OPF 元数据文件中的 XML 命名空间结构未能正确保留，这可能导致与部分电子阅读器的兼容性问题。\n\n相关 Pull Request：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F127\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.8...v0.1.9","2026-02-07T07:50:47",{"id":143,"version":144,"summary_zh":145,"released_at":146},135897,"v0.1.8","# 发布 v0.1.8\n\n本次发布新增了令牌使用监控功能，并修复了 MathML 行内元素检测问题。\n\n## ✨ 新特性\n\n### 令牌使用统计 (#125)\n\n实现了全面的令牌使用跟踪功能，帮助在翻译过程中监控 API 成本和资源消耗。`LLM` 类现在提供关于令牌使用的实时统计信息。\n\n**主要特性：**\n- 跟踪总令牌数、输入令牌数、缓存的输入令牌数以及输出令牌数\n- 在翻译过程中实时监控令牌消耗\n- 支持双 LLM 场景，为翻译和填充操作分别提供独立的统计信息\n- 易于与进度回调集成，实现实时成本估算\n\n**新的 LLM 属性：**\n- `total_tokens` - 总共使用的令牌数量（输入 + 输出）\n- `input_tokens` - 提示词\u002F输入令牌的数量\n- `input_cache_tokens` - 缓存的输入令牌数量（使用提示词缓存时）\n- `output_tokens` - 生成的完成令牌数量\n\n**使用示例：**\n```python\nfrom epub_translator import LLM, translate, language, SubmitKind\n\nllm = LLM(\n    key=\"your-api-key\",\n    url=\"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n    model=\"gpt-4\",\n    token_encoding=\"o200k_base\",\n)\n\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n)\n\n# 翻译完成后访问令牌统计信息\nprint(f\"总令牌数: {llm.total_tokens}\")\nprint(f\"输入令牌数: {llm.input_tokens}\")\nprint(f\"输出令牌数: {llm.output_tokens}\")\n```\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F125  \n相关 issue：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F33\n\n## 🐛 问题修复\n\n### 改进的行内元素检测 (#124)\n\n通过使用基于元素的 `is_inline_element()` 函数代替基于字符串的标签比较，增强了 MathML 行内元素的检测能力。同时，还为数学表达式添加了空白字符规范化处理，以确保 LaTeX 渲染的一致性。\n\n**技术变更：**\n- 将基于字符串的行内标签检测替换为基于元素的 `is_inline_element()` 检查\n- 添加了 `normalize_whitespace()` 方法，用于清理 LaTeX 表达式的格式\n- 提高了对行内与块级数学元素检测的一致性\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F124\n\n### 修复 MathML display 属性处理问题 (#123)\n\n修复了一个问题：当 `\u003Cmath>` 元素没有显式指定 `display=\"block\"` 属性时，无法正确识别为行内元素。现在代码会统一使用 `DISPLAY_ATTRIBUTE` 常量来进行属性检查，从而保证一致性。\n\n**技术变更：**\n- 将硬编码的 `\"display\"` 字符串替换为 `DISPLAY_ATTRIBUTE` 常量\n- 提高了整个代码库中 MathML display 属性处理的一致性\n- 更好地符合 MathML 规范，以准确检测行内元素\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F123\n\n## 📦 安装","2026-02-07T07:50:19",{"id":148,"version":149,"summary_zh":150,"released_at":151},135898,"v0.1.7","# 发布 v0.1.7\n\n本次发布改进了 MathML 的处理，并修复了与内联数学公式及用户提示模板相关的严重 bug。\n\n## ✨ 新特性\n\n### LLM 的 LaTeX 渲染 (#121)\n\n将基于 XSLT 的 MathML 到 LaTeX 转换替换为 `mathml2latex` 库，从而在翻译过程中为大型语言模型提供更可靠的数学公式渲染。这提升了包含数学表达式的文档的翻译质量。\n\n**技术变更：**\n- 从 `epub_translator\u002Fdata\u002Fmmltex\u002F` 中移除了旧版 XSLT 样式表\n- 添加了 `mathml2latex`（>=0.2.12, \u003C0.3.0）作为新的依赖项\n- 使用 `mathml2latex` 和 BeautifulSoup 实现了新的 `_render_latex` 辅助函数\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F121\n\n## 🐛 Bug 修复\n\n### 修复内联数学公式的混排问题 (#120)\n\n修复了 [#119](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F119) 问题：当段落中包含内联 MathML 公式（例如 `\u003Cmath display=\"inline\">`）时，在 `APPEND_BLOCK` 模式下会生成原始文本和译文混杂的内容，而非正确分隔的双语段落。\n\n**技术改进：**\n- 引入了 `find_block_depth()` 函数（现已成为 `epub_translator.segment` 中的公共 API）\n- 将基于字符串的 `is_inline_tag` 替换为基于元素的 `is_inline_element`，以实现更准确的检测\n- 增强了对 MathML 元素 `display` 属性的检查\n- 改进了内联元素层级关系的评估逻辑\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F120  \n相关 Issue：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F119\n\n### 修复缺失的用户提示 (#118)\n\n修复了 [#117](https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F117) 问题：`user_prompt` 参数未被纳入翻译模板中。现在，该提示已正确包裹在 `\u003Crules>` 标签内，并传递给 LLM。\n\n**模板变更：**\n```jinja\n{% if user_prompt -%}\n\u003Crules>\n{{ user_prompt }}\n\u003C\u002Frules>\n{% endif -%}\n```\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F118  \n相关 Issue：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fissues\u002F117\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.7\n```\n\n或升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 🔄 从 v0.1.6 迁移\n\n本版本与 v0.1.6 完全兼容，无需更改代码。\n\n**新增依赖：**\n- `mathml2latex`（>=0.2.12, \u003C0.3.0）——将由 pip 自动安装\n\n**Bug 修复：**\n- 如果您在使用 `APPEND_BLOCK` 模式时遇到内联数学公式的混排问题，本版本将自动修复\n- 如果您的自定义提示未能生效，现在它们将被正确地包含在翻译结果中\n\n## 🙏 致谢\n\n特别感谢所有报告问题并帮助改进本次发布的贡献者！\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.6...v0.1.7","2026-02-04T11:15:54",{"id":153,"version":154,"summary_zh":155,"released_at":156},135899,"v0.1.6","# 发布 v0.1.6\n\n本次发布引入了并发翻译支持和 XML 元素权重优化，以提升翻译性能和质量。\n\n## ✨ 新特性\n\n### 并发翻译支持 (#112)\n\n在 `translate()` 函数中新增了 `concurrency` 参数，支持并行处理多个文本段落，从而显著加快大型 EPUB 文件的翻译速度。\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=\"English\",\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    concurrency=4,  # 同时处理 4 个段落\n)\n```\n\n**性能提示：**\n- 建议从 `concurrency=4` 开始，并根据 API 的速率限制进行调整。\n- 较高的并发度可以大幅缩短大型书籍的翻译时间。\n- 请密切关注 API 提供商的速率限制，以免被限流。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F112\n\n### 默认令牌上限提高 (#112)\n\n`max_group_tokens` 的默认值已从 1200 提高到 2600，允许更大规模的文本段落一次性翻译，从而提升上下文连贯性和翻译质量。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F112\n\n### XML 元素权重系统 (#110)\n\n实现了基于 XML 元素 ID 的加权优先级系统，可有效提升复杂文档结构的翻译质量。该优化为自动生效，无需用户手动配置。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F110\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.6\n```\n\n或升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 从 v0.1.5 迁移\n\n本版本与 v0.1.5 完全兼容。新的 `concurrency` 参数默认值为 1，因此在不启用并发翻译的情况下，行为与 v0.1.5 相同。现有代码无需任何修改。\n\n**变更内容：**\n- 新增 `concurrency` 参数（默认值：1）——如需启用并发翻译，请添加此参数。\n- `max_group_tokens` 默认值由 1200 提升至 2600——如果您已显式设置该值，则无需更改。\n\n**启用并发翻译的方法：**\n\n```python\ntranslate(\n    source_path=\"source.epub\",\n    target_path=\"translated.epub\",\n    target_language=language.ENGLISH,\n    submit=SubmitKind.APPEND_BLOCK,\n    llm=llm,\n    concurrency=4,  # 添加这一行\n)\n```\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.5...v0.1.6","2026-01-12T10:18:10",{"id":158,"version":159,"summary_zh":160,"released_at":161},135900,"v0.1.5","# 发布 v0.1.5\n\n此热修复版本解决了在翻译包含嵌套内联元素的 EPUB 文件时发生的严重崩溃问题。\n\n## 🐛 错误修复\n\n### 修复了嵌套内联元素导致的崩溃 (#109)\n\n修复了在处理包含嵌套内联元素（例如 `\u003Cspan>` 内的 `\u003Cmath>`）的平台结构时出现的 `ValueError: Element not found in parent` 崩溃问题。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F109\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.5\n```\n\n或者升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 从 v0.1.4 迁移\n\n与 v0.1.4 完全向后兼容，无需更改代码。\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.4...v0.1.5","2026-01-11T03:43:07",{"id":163,"version":164,"summary_zh":165,"released_at":166},135901,"v0.1.4","# 发布 v0.1.4\n\n本次发布引入了灵活的翻译提交模式，用户可以选择单语种翻译或双语输出格式。\n\n## ⚠️ 重大变更\n\n### 新增必填参数：`submit`\n\n`translate()` 函数现在需要一个 `submit` 参数：\n\n**变更前：**\n```python\ntranslate(source_path, target_path, language.ENGLISH, llm=llm)\n```\n\n**变更后：**\n```python\nfrom epub_translator import SubmitKind\n\ntranslate(source_path, target_path, language.ENGLISH,\n          submit=SubmitKind.APPEND_BLOCK, llm=llm)\n```\n\n对于双语书籍（之前的默认行为），请使用 `SubmitKind.APPEND_BLOCK`。\n\n## ✨ 新特性\n\n### 翻译提交模式 (#105)\n\n提供了三种插入翻译的模式：\n\n- **`SubmitKind.REPLACE`**：用翻译替换原文（单语种输出）\n- **`SubmitKind.APPEND_TEXT`**：以内联文本形式追加（双语，连续流动）\n- **`SubmitKind.APPEND_BLOCK`**（推荐）：以独立段落形式追加（双语，清晰分隔）\n\n```python\n# 双语书籍\ntranslate(source_path, target_path, language.ENGLISH,\n          submit=SubmitKind.APPEND_BLOCK, llm=llm)\n\n# 单语种翻译\ntranslate(source_path, target_path, language.ENGLISH,\n          submit=SubmitKind.REPLACE, llm=llm)\n```\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F105\n\n### 平台节点支持 (#105)\n\n改进了对复杂 EPUB 结构的处理，这些结构中块级元素包含交错的文本内容。此前，块级元素之间的文本可能会丢失或错位。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F105\n\n## 🐛 错误修复\n\n### 非内联元素保留 (#105)\n\n当使用 `SubmitKind.REPLACE` 时，原块中的非内联元素（如图片）现在会被保留。\n\n### 引号规范化 (#105)\n\n为翻译后的目录和元数据添加了自动转换功能，将特殊引号统一转换为标准引号，包括法语的角引号（« »、‹ ›）以及中文书名号（《》、〈〉）。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F105\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.4\n```\n\n或者升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 从 v0.1.3 迁移\n\n在您的 `translate()` 调用中添加 `submit` 参数。对于双语书籍，请使用 `SubmitKind.APPEND_BLOCK`。\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.3...v0.1.4","2026-01-10T11:17:41",{"id":168,"version":169,"summary_zh":170,"released_at":171},135902,"v0.1.3","# 发布 v0.1.3\n\n本次发布主要聚焦于提升 EPUB 兼容性以及优化翻译流程。\n\n## 🐛 错误修复\n\n### EPUB 格式兼容性 (#96)\n\n- 在 spine 处理中增强了媒体类型识别\n- 为 21 种标准 HTML5 空元素添加了自闭合标签规范化处理\n- 改进了对非标准 EPUB 格式的兼容性\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F96\n\n### Mimetype 文件顺序 (#98)\n\n根据 EPUB OCF 规范，修复了 mimetype 文件的位置，使其始终作为 ZIP 文件中的第一个条目出现。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F98\n\n### 流式处理优化 (#101)\n\n将 XMLStreamMapper 从批处理模式重构为单元素处理模式，简化了内部逻辑。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F101\n\n## ✨ 新特性\n\n### 增强的填充模板算法 (#99)\n\n改进了 fill.jinja 模板，由基于位置的匹配改为语义类型匹配。新增了正式的算法步骤和特殊场景规则，以更好地进行错误恢复。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F99\n\n### 缓存种子内容支持 (#100)\n\n新增了 `cache_seed_content` 参数，用于更智能地失效缓存。运行时版本和目标语言现在会被纳入缓存键中，从而在版本更新时自动失效缓存。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F100\n\n### 片段合并重构 (#102)\n\n通过串行分组处理重构了流式处理逻辑，更好地处理资源片段中的嵌套内容。\n\n相关 PR：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fpull\u002F102\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.3\n```\n\n或升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 从 v0.1.2 迁移\n\n完全向后兼容 v0.1.2。新的 `cache_seed_content` 参数为可选。\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.2...v0.1.3","2026-01-09T09:48:10",{"id":173,"version":174,"summary_zh":175,"released_at":176},135903,"v0.1.2","# 发布 v0.1.2\n\n本次发布对翻译引擎进行了重大的架构改进，包括全面重构 XML 处理流程、增强错误处理机制以及支持元数据翻译。新架构不仅提升了翻译质量，还增强了系统的鲁棒性，并为翻译过程提供了更多控制能力。\n\n## ⚠️ 重大变更\n\n### API 签名变更\n\n`translate()` 函数的签名已更新，以提供更高的灵活性：\n\n**v0.1.1：**\n```python\ndef translate(\n    llm: LLM,                          # 必需的第一个参数\n    source_path: Path,\n    target_path: Path,\n    target_language: str,\n    user_prompt: str | None = None,\n    max_retries: int = 5,\n    max_group_tokens: int = 1200,\n    on_progress: Callable[[float], None] | None = None,\n) -> None:\n```\n\n**v0.1.2：**\n```python\ndef translate(\n    source_path: PathLike | str,       # 现在是第一个参数\n    target_path: PathLike | str,       # 现在是第二个参数\n    target_language: str,\n    user_prompt: str | None = None,\n    max_retries: int = 5,\n    max_group_tokens: int = 1200,\n    llm: LLM | None = None,            # 可选的关键字参数\n    translation_llm: LLM | None = None, # 新增：用于翻译的独立 LLM\n    fill_llm: LLM | None = None,       # 新增：用于 XML 填充的独立 LLM\n    on_progress: Callable[[float], None] | None = None,\n    on_fill_failed: Callable[[FillFailedEvent], None] | None = None,  # 新增\n) -> None:\n```\n\n**迁移指南：**\n\n旧代码：\n```python\ntranslate(llm, source_path, target_path, \"English\")\n```\n\n新代码（选项 1 - 使用关键字参数）：\n```python\ntranslate(source_path, target_path, \"English\", llm=llm)\n```\n\n新代码（选项 2 - 使用双 LLM）：\n```python\ntranslate(\n    source_path,\n    target_path,\n    \"English\",\n    translation_llm=translation_llm,\n    fill_llm=fill_llm,\n)\n```\n\n**路径类型变更：**\n- `source_path` 和 `target_path` 现在接受 `PathLike | str`，而不再仅限于 `Path` 类型。\n- 您现在可以直接传递字符串路径，无需再用 `Path()` 包装。\n\n### 内部 API 变更\n\n**高级用户请注意：** 许多内部类和函数已被重构或移除：\n- 移除了 `XMLGroupContext`，改用 `XMLStreamMapper`。\n- 移除了占位符系统，改用 XML 中断回调。\n- 重构了片段处理逻辑，新增了 `InlineSegment` 和 `BlockSegment` 类。\n- 使用爬山算法替代了之前的渐进式锁定方法。\n\n对于大多数使用高级 `translate()` 函数的用户来说，这些变化是透明的。\n\n## ✨ 主要特性\n\n### 新增：`FillFailedEvent` 错误事件与错误回调系统 (#93, #94)\n\n新增的错误监控系统使您可以以编程方式处理翻译错误：\n\n```python\nfrom epub_translator import FillFailedEvent\n\ndef handle_error(event: FillFailedEvent):\n    print(f\"第 {event.retried_count} 次尝试时发生错误：{event.error_message}\")\n    if event.over_maximum_","2026-01-08T09:37:30",{"id":178,"version":179,"summary_zh":180,"released_at":181},135904,"v0.1.1","这是一个补丁版本，修复了与缓存和 XML 命名空间处理相关的两个严重 bug。\n\n## 🐛 Bug 修复\n\n### 缓存文件处理 (#77)\n- **修复了失败的缓存文件会被保存的问题**\n- 之前，当翻译失败时，损坏或不完整的缓存条目会被持久化保存\n- 这可能导致后续的翻译尝试使用无效的缓存数据\n- 现在，只有成功的翻译结果才会被保存到缓存中，从而确保缓存的可靠性\n\n### XML 命名空间恢复 (#76)\n- **修复了 XML 命名空间无法正确恢复的严重问题**\n- 解决了 XML 处理过程中命名空间字典管理方面的问题\n- 为 XML 命名空间操作增加了全面的测试覆盖\n- 提高了翻译过程中 XML 结构保持的健壮性\n\n## 📦 安装\n\n```bash\npip install epub-translator==0.1.1\n```\n\n或者从旧版本升级：\n\n```bash\npip install --upgrade epub-translator\n```\n\n## 🙏 致谢\n\n感谢所有报告这些问题并帮助验证修复的人！\n\n**完整变更日志**: https:\u002F\u002Fgithub.com\u002Foomol-lab\u002Fepub-translator\u002Fcompare\u002Fv0.1.0...v0.1.1","2025-12-31T08:48:01",{"id":183,"version":184,"summary_zh":185,"released_at":186},135905,"v0.1.0","我们很高兴地宣布 EPUB Translator v0.1.0 正式发布！此次发布标志着一个重要里程碑，我们在翻译质量、性能和用户体验方面都取得了显著提升。\n\n## 🎉 亮点\n\n- **严格的翻译对齐**：增强的校正机制确保译文与 XML 结构精准匹配，避免文本丢失和错位。\n- **格式完整保留**：译文中内联格式标签（如粗体、斜体等）得到完全保留。\n- **进度跟踪**：通过新增的 `on_progress` 回调函数，可实时监控翻译进度。\n- **智能缓存**：内置缓存支持，可在失败时从上次中断处继续翻译。\n- **全面翻译**：除章节内容外，现还可翻译目录和元数据。\n\n## ✨ 功能特性\n\n### 严格的翻译对齐\n- **增强的校正机制**确保译文精确嵌入 XML 结构中。\n- **防止文本丢失**，解决内容遗漏问题。\n- **消除源文与译文之间的错位**。\n- 严格验证循环将持续进行，直至所有内容都被正确翻译并定位。\n- 显著提升复杂书籍结构的翻译可靠性。\n\n### 完整的格式保留\n- **保留所有内联格式标签**，包括 `\u003Cem>`、`\u003Cstrong>`、`\u003Ci>`、`\u003Cb>` 等样式元素。\n- 维持句子和段落内的格式一致性。\n- 译文继承与原文完全一致的 XML 结构。\n- 再也不会出现译文中粗体或斜体强调丢失的情况。\n- 无论是通过标签还是 CSS 样式应用的格式，都将被完整保留。\n\n### 进度监控\n- 在 `translate()` 函数中新增了 `on_progress` 回调参数。\n- 翻译过程中提供实时进度更新（范围为 0.0 到 1.0）。\n- 进度按权重计算：目录占 3%，元数据占 2%，章节占 95%。\n- 非常适合用于构建进度条和跟踪翻译状态。\n\n### 缓存系统\n- 在 `LLM` 类中新增了 `cache_path` 参数，用于持久化缓存。\n- 翻译失败后会自动从上次成功状态恢复。\n- 通过避免重复翻译相同内容，降低 API 调用成本。\n- 如果缓存目录不存在，将自动创建。\n\n### 数学表达式处理\n- 修复了在 EPUB 文件中遇到 MathML 元素时导致程序崩溃的问题。\n- 现在数学表达式会在翻译过程中被安全跳过（原样保留）。\n- 即使书中包含数学符号，也不会再导致翻译过程失败。\n- MathML 内容将以原始形式存在，不会被修改。\n\n### 元数据和目录翻译\n- 可翻译 EPUB 元数据字段（标题、描述、作者、出版商等）。\n- 智能字段过滤功能可跳过技术性元数据（语言代码、标识符、日期等）。\n- 目录翻译完整且层次结构得以保留。\n- 批量翻译功能进一步提升效率。","2025-12-30T08:47:49"]