BabelDOC 0.1.6__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. babeldoc-0.1.7/.github/ISSUE_TEMPLATE/bug_report.yaml +85 -0
  2. babeldoc-0.1.7/.github/ISSUE_TEMPLATE/feature_request.yaml +33 -0
  3. {babeldoc-0.1.6 → babeldoc-0.1.7}/PKG-INFO +11 -1
  4. {babeldoc-0.1.6 → babeldoc-0.1.7}/README.md +10 -0
  5. babeldoc-0.1.7/babeldoc/__init__.py +1 -0
  6. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/backend/pdf_creater.py +10 -3
  7. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/frontend/il_creater.py +1 -1
  8. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/add_debug_information.py +1 -1
  9. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/il_translator.py +21 -1
  10. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/layout_parser.py +1 -1
  11. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/paragraph_finder.py +1 -1
  12. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/remove_descent.py +1 -1
  13. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/styles_and_formulas.py +1 -1
  14. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/typesetting.py +2 -2
  15. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/utils/fontmap.py +1 -1
  16. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/high_level.py +1 -0
  17. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/main.py +22 -1
  18. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/progress_monitor.py +29 -14
  19. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/translation_config.py +9 -2
  20. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/CONTRIBUTING.md +3 -1
  21. {babeldoc-0.1.6 → babeldoc-0.1.7}/pyproject.toml +2 -2
  22. {babeldoc-0.1.6 → babeldoc-0.1.7}/uv.lock +1 -1
  23. babeldoc-0.1.6/.github/ISSUE_TEMPLATE/bug_report.md +0 -34
  24. babeldoc-0.1.6/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  25. babeldoc-0.1.6/babeldoc/__init__.py +0 -1
  26. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/dependabot.yml +0 -0
  27. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/labels.yml +0 -0
  28. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/release-drafter.yml +0 -0
  29. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/workflows/codeql.yml +0 -0
  30. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/workflows/labeler.yml +0 -0
  31. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/workflows/publish-to-pypi.yml +0 -0
  32. {babeldoc-0.1.6 → babeldoc-0.1.7}/.github/workflows/test.yml +0 -0
  33. {babeldoc-0.1.6 → babeldoc-0.1.7}/.gitignore +0 -0
  34. {babeldoc-0.1.6 → babeldoc-0.1.7}/.pre-commit-config.yaml +0 -0
  35. {babeldoc-0.1.6 → babeldoc-0.1.7}/LICENSE +0 -0
  36. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/asynchronize/__init__.py +0 -0
  37. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/const.py +0 -0
  38. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/converter.py +0 -0
  39. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/__init__.py +0 -0
  40. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/backend/__init__.py +0 -0
  41. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/frontend/__init__.py +0 -0
  42. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/il_version_1.py +0 -0
  43. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/il_version_1.rnc +0 -0
  44. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/il_version_1.rng +0 -0
  45. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/il_version_1.xsd +0 -0
  46. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/midend/__init__.py +0 -0
  47. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/translator/__init__.py +0 -0
  48. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/translator/cache.py +0 -0
  49. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/translator/translator.py +0 -0
  50. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/utils/layout_helper.py +0 -0
  51. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/utils/style_helper.py +0 -0
  52. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/document_il/xml_converter.py +0 -0
  53. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/docvision/README.md +0 -0
  54. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/docvision/__init__.py +0 -0
  55. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/docvision/doclayout.py +0 -0
  56. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/docvision/rpc_doclayout.py +0 -0
  57. {babeldoc-0.1.6 → babeldoc-0.1.7}/babeldoc/pdfinterp.py +0 -0
  58. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/CODE_OF_CONDUCT.md +0 -0
  59. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
  60. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
  61. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
  62. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
  63. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
  64. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/README.md +0 -0
  65. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
  66. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
  67. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/README.md +0 -0
  68. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/deploy.sh +0 -0
  69. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/images/banner.png +0 -0
  70. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/images/preview.gif +0 -0
  71. {babeldoc-0.1.6 → babeldoc-0.1.7}/docs/intro-to-pdf-object.md +0 -0
@@ -0,0 +1,85 @@
1
+ name: Bug Report
2
+ description: Create a report to help us improve
3
+ labels: ['bug']
4
+ body:
5
+ - type: checkboxes
6
+ id: checks
7
+ attributes:
8
+ label: Before you asking
9
+ options:
10
+ - label: I have searched the existing issues
11
+ required: true
12
+ - label: I spend at least 5 minutes for thinking and preparing
13
+ required: true
14
+ - label: I have carefully checked the issue, and it is unrelated to the network environment.
15
+ required: true
16
+ - type: markdown
17
+ attributes:
18
+ value: |
19
+ Thank you for using this project and providing feedback!
20
+ - type: textarea
21
+ id: environment
22
+ attributes:
23
+ label: Environment
24
+ description: |
25
+ examples:
26
+ - **OS**: Ubuntu 24.10
27
+ - **Python**: 3.12.0
28
+ - **BalbelDOC**: 1.9.0
29
+ value: |
30
+ - OS:
31
+ - Python:
32
+ - BalbelDOC:
33
+ render: markdown
34
+ validations:
35
+ required: false
36
+ - type: textarea
37
+ id: describe
38
+ attributes:
39
+ label: Describe the bug
40
+ description: A clear and concise description of what the bug is.
41
+ validations:
42
+ required: true
43
+ - type: textarea
44
+ id: reproduce
45
+ attributes:
46
+ label: To Reproduce
47
+ description: Steps to reproduce the behavior
48
+ value: |
49
+ 1. Go to '...'
50
+ 2. Click on '....'
51
+ 3. Scroll down to '....'
52
+ 4. See error
53
+ validations:
54
+ required: false
55
+ - type: textarea
56
+ id: expected
57
+ attributes:
58
+ label: Expected behavior
59
+ description: A clear and concise description of what you expected to happen.
60
+ validations:
61
+ required: false
62
+ - type: textarea
63
+ id: logs
64
+ attributes:
65
+ label: Relevant log output and screenshots
66
+ description: Please copy and paste any relevant log output and screenshots. This will be automatically formatted into code, so no need for backticks.
67
+ render: Text
68
+ validations:
69
+ required: false
70
+ - type: textarea
71
+ id: PDFfile
72
+ attributes:
73
+ label: Origin PDF file
74
+ description: |
75
+ if applicable, attach the input PDF file here.
76
+ validations:
77
+ required: false
78
+ - type: textarea
79
+ id: others
80
+ attributes:
81
+ label: Anything else?
82
+ description: |
83
+ Add any other context about the problem here.
84
+ validations:
85
+ required: false
@@ -0,0 +1,33 @@
1
+ name: Feature request
2
+ description: Suggest an idea for this project
3
+ labels: ['enhancement']
4
+ body:
5
+ - type: textarea
6
+ id: describe
7
+ attributes:
8
+ label: Is your feature request related to a problem?
9
+ description: A clear and concise description of what the problem is
10
+ placeholder: Ex. I'm always frustrated when ...
11
+ validations:
12
+ required: false
13
+ - type: textarea
14
+ id: solution
15
+ attributes:
16
+ label: Describe the solution you'd like
17
+ description: A clear and concise description of what you want to happen
18
+ validations:
19
+ required: false
20
+ - type: textarea
21
+ id:
22
+ attributes:
23
+ label: Describe alternatives you've considered
24
+ description: A clear and concise description of any alternative solutions or features you've considered.
25
+ validations:
26
+ required: false
27
+ - type: textarea
28
+ id: additional
29
+ attributes:
30
+ label: Additional context
31
+ description: Add any other projects about the feature request here.
32
+ validations:
33
+ required: false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BabelDOC
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Yet Another Document Translator
5
5
  Project-URL: Homepage, https://github.com/funstory-ai/BabelDOC
6
6
  Project-URL: Issues, https://github.com/funstory-ai/BabelDOC/issues
@@ -140,10 +140,14 @@ uv run babeldoc --bing --files example.pdf --files example2.pdf
140
140
  - `--short-line-split-factor`: Split threshold factor (default: 0.8). The actual threshold is the median length of all lines on the current page \* this factor
141
141
  - `--skip-clean`: Skip PDF cleaning step
142
142
  - `--dual-translate-first`: Put translated pages first in dual PDF mode (default: original pages first)
143
+ - `--disable-rich-text-translate`: Disable rich text translation (may help improve compatibility with some PDFs)
144
+ - `--enhance-compatibility`: Enable all compatibility enhancement options (equivalent to --skip-clean --dual-translate-first --disable-rich-text-translate)
143
145
 
144
146
  > [!TIP]
145
147
  > - Both `--skip-clean` and `--dual-translate-first` may help improve compatibility with some PDF readers
148
+ > - `--disable-rich-text-translate` can also help with compatibility by simplifying translation input
146
149
  > - However, using `--skip-clean` will result in larger file sizes
150
+ > - If you encounter any compatibility issues, try using `--enhance-compatibility` first
147
151
 
148
152
  ### Translation Service Options
149
153
 
@@ -167,10 +171,16 @@ uv run babeldoc --bing --files example.pdf --files example2.pdf
167
171
  - `--openai-base-url`: Base URL for OpenAI API
168
172
  - `--openai-api-key`: API key for OpenAI service
169
173
 
174
+ > [!TIP]
175
+ >
176
+ > 1. This tool supports any OpenAI-compatible API endpoints. Just set the correct base URL and API key. (e.g. `https://xxx.custom.xxx/v1`)
177
+ > 2. For local models like Ollama, you can use any value as the API key (e.g. `--openai-api-key a`).
178
+
170
179
  ### Output Control
171
180
 
172
181
  - `--output`, `-o`: Output directory for translated files. If not set, use current working directory.
173
182
  - `--debug`, `-d`: Enable debug logging level and export detailed intermediate results in `~/.cache/yadt/working`.
183
+ - `--report-interval`: Progress report interval in seconds (default: 0.1).
174
184
 
175
185
  ### Configuration File
176
186
 
@@ -108,10 +108,14 @@ uv run babeldoc --bing --files example.pdf --files example2.pdf
108
108
  - `--short-line-split-factor`: Split threshold factor (default: 0.8). The actual threshold is the median length of all lines on the current page \* this factor
109
109
  - `--skip-clean`: Skip PDF cleaning step
110
110
  - `--dual-translate-first`: Put translated pages first in dual PDF mode (default: original pages first)
111
+ - `--disable-rich-text-translate`: Disable rich text translation (may help improve compatibility with some PDFs)
112
+ - `--enhance-compatibility`: Enable all compatibility enhancement options (equivalent to --skip-clean --dual-translate-first --disable-rich-text-translate)
111
113
 
112
114
  > [!TIP]
113
115
  > - Both `--skip-clean` and `--dual-translate-first` may help improve compatibility with some PDF readers
116
+ > - `--disable-rich-text-translate` can also help with compatibility by simplifying translation input
114
117
  > - However, using `--skip-clean` will result in larger file sizes
118
+ > - If you encounter any compatibility issues, try using `--enhance-compatibility` first
115
119
 
116
120
  ### Translation Service Options
117
121
 
@@ -135,10 +139,16 @@ uv run babeldoc --bing --files example.pdf --files example2.pdf
135
139
  - `--openai-base-url`: Base URL for OpenAI API
136
140
  - `--openai-api-key`: API key for OpenAI service
137
141
 
142
+ > [!TIP]
143
+ >
144
+ > 1. This tool supports any OpenAI-compatible API endpoints. Just set the correct base URL and API key. (e.g. `https://xxx.custom.xxx/v1`)
145
+ > 2. For local models like Ollama, you can use any value as the API key (e.g. `--openai-api-key a`).
146
+
138
147
  ### Output Control
139
148
 
140
149
  - `--output`, `-o`: Output directory for translated files. If not set, use current working directory.
141
150
  - `--debug`, `-d`: Enable debug logging level and export detailed intermediate results in `~/.cache/yadt/working`.
151
+ - `--report-interval`: Progress report interval in seconds (default: 0.1).
142
152
 
143
153
  ### Configuration File
144
154
 
@@ -0,0 +1 @@
1
+ __version__ = "0.1.7"
@@ -14,7 +14,7 @@ logger = logging.getLogger(__name__)
14
14
 
15
15
 
16
16
  class PDFCreater:
17
- stage_name = "创建PDF文件"
17
+ stage_name = "Create PDF file"
18
18
 
19
19
  def __init__(
20
20
  self,
@@ -176,7 +176,8 @@ class PDFCreater:
176
176
  page_op = BitStream()
177
177
  # q {ops_base}Q 1 0 0 1 {x0} {y0} cm {ops_new}
178
178
  page_op.append(b"q ")
179
- page_op.append(base_op)
179
+ if base_op is not None:
180
+ page_op.append(base_op)
180
181
  page_op.append(b" Q ")
181
182
  page_op.append(
182
183
  f"q Q 1 0 0 1 {page.cropbox.box.x} {page.cropbox.box.y} cm \n".encode(),
@@ -375,7 +376,13 @@ class PDFCreater:
375
376
  dual = pymupdf.open(self.original_pdf_path)
376
377
  if translation_config.debug:
377
378
  translation_config.raise_if_cancelled()
378
- self.write_debug_info(dual, translation_config)
379
+ try:
380
+ self.write_debug_info(dual, translation_config)
381
+ except Exception:
382
+ logger.warning(
383
+ "Failed to write debug info to dual PDF",
384
+ exc_info=True,
385
+ )
379
386
  dual.insert_file(pdf)
380
387
  page_count = pdf.page_count
381
388
  for page_id in range(page_count):
@@ -17,7 +17,7 @@ logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
19
  class ILCreater:
20
- stage_name = "解析PDF并创建中间表示"
20
+ stage_name = "Parse PDF and Create Intermediate Representation"
21
21
 
22
22
  def __init__(self, translation_config: TranslationConfig):
23
23
  self.progress = None
@@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
11
11
 
12
12
 
13
13
  class AddDebugInformation:
14
- stage_name = "添加DEBUG信息"
14
+ stage_name = "Add Debug Information"
15
15
 
16
16
  def __init__(self, translation_config: TranslationConfig):
17
17
  self.translation_config = translation_config
@@ -112,7 +112,7 @@ class ParagraphTranslateTracker:
112
112
 
113
113
 
114
114
  class ILTranslator:
115
- stage_name = "翻译段落"
115
+ stage_name = "Translate Paragraphs"
116
116
 
117
117
  def __init__(
118
118
  self,
@@ -230,6 +230,7 @@ class ILTranslator:
230
230
  self,
231
231
  paragraph: PdfParagraph,
232
232
  page_font_map: dict[str, PdfFont] = None,
233
+ disable_rich_text_translate: bool | None = None,
233
234
  ):
234
235
  if not paragraph.pdf_paragraph_composition:
235
236
  return
@@ -256,6 +257,12 @@ class ILTranslator:
256
257
  )
257
258
  return None
258
259
 
260
+ # 如果没有指定 disable_rich_text_translate,使用配置中的值
261
+ if disable_rich_text_translate is None:
262
+ disable_rich_text_translate = (
263
+ self.translation_config.disable_rich_text_translate
264
+ )
265
+
259
266
  placeholder_id = 1
260
267
  placeholders = []
261
268
  chars = []
@@ -275,6 +282,11 @@ class ILTranslator:
275
282
  elif composition.pdf_character:
276
283
  chars.append(composition.pdf_character)
277
284
  elif composition.pdf_same_style_characters:
285
+ if disable_rich_text_translate:
286
+ # 如果禁用富文本翻译,直接添加字符
287
+ chars.extend(composition.pdf_same_style_characters.pdf_character)
288
+ continue
289
+
278
290
  fonta = self.font_mapper.map(
279
291
  page_font_map[
280
292
  composition.pdf_same_style_characters.pdf_style.font_id
@@ -330,6 +342,14 @@ class ILTranslator:
330
342
  )
331
343
  return None
332
344
 
345
+ # 如果占位符数量超过50,且未禁用富文本翻译,则递归调用并禁用富文本翻译
346
+ if len(placeholders) > 50 and not disable_rich_text_translate:
347
+ logger.warning(
348
+ f"Too many placeholders ({len(placeholders)}) in paragraph[{paragraph.debug_id}], "
349
+ "disabling rich text translation for this paragraph",
350
+ )
351
+ return self.get_translate_input(paragraph, page_font_map, True)
352
+
333
353
  text = get_char_unicode_string(chars)
334
354
  return self.TranslateInput(text, placeholders, paragraph.pdf_style)
335
355
 
@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
13
13
 
14
14
 
15
15
  class LayoutParser:
16
- stage_name = "解析页面布局"
16
+ stage_name = "Parse Page Layout"
17
17
 
18
18
  def __init__(self, translation_config: TranslationConfig):
19
19
  self.translation_config = translation_config
@@ -26,7 +26,7 @@ def generate_base58_id(length: int = 5) -> str:
26
26
 
27
27
 
28
28
  class ParagraphFinder:
29
- stage_name = "解析段落"
29
+ stage_name = "Parse Paragraphs"
30
30
 
31
31
  def __init__(self, translation_config: TranslationConfig):
32
32
  self.translation_config = translation_config
@@ -9,7 +9,7 @@ logger = logging.getLogger(__name__)
9
9
 
10
10
 
11
11
  class RemoveDescent:
12
- stage_name = "移除字体下沉"
12
+ stage_name = "Remove Char Descent"
13
13
 
14
14
  def __init__(self, translation_config: TranslationConfig):
15
15
  self.translation_config = translation_config
@@ -22,7 +22,7 @@ from babeldoc.translation_config import TranslationConfig
22
22
 
23
23
 
24
24
  class StylesAndFormulas:
25
- stage_name = "解析公式与样式"
25
+ stage_name = "Parse Formulas and Styles"
26
26
 
27
27
  def __init__(self, translation_config: TranslationConfig):
28
28
  self.translation_config = translation_config
@@ -355,7 +355,7 @@ class TypesettingUnit:
355
355
 
356
356
 
357
357
  class Typesetting:
358
- stage_name = "排版"
358
+ stage_name = "Typesetting"
359
359
 
360
360
  def __init__(self, translation_config: TranslationConfig):
361
361
  self.font_mapper = FontMapper(translation_config)
@@ -397,7 +397,7 @@ class Typesetting:
397
397
  font_size=6,
398
398
  graphic_state=il_version_1.GraphicState(),
399
399
  )
400
- text = "本文档由funstory.ai的开源PDF翻译库yadt(http://yadt.io)翻译,本仓库正在积极的建设当中,欢迎star和关注。"
400
+ text = "本文档由funstory.ai的开源PDF翻译库BabelDOC(http://yadt.io)翻译,本仓库正在积极的建设当中,欢迎star和关注。"
401
401
  if self.translation_config.debug:
402
402
  text += "\n 当前为DEBUG模式,将显示更多辅助信息。请注意,部分框的位置对应原文,但在译文中可能不正确。"
403
403
  page.pdf_paragraph.append(
@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
13
13
 
14
14
 
15
15
  class FontMapper:
16
- stage_name = "添加字体"
16
+ stage_name = "Add Fonts"
17
17
 
18
18
  def __init__(self, translation_config: TranslationConfig):
19
19
  self.font_names = [
@@ -287,6 +287,7 @@ async def async_translate(translation_config: TranslationConfig):
287
287
  finish_event=finish_event,
288
288
  cancel_event=cancel_event,
289
289
  loop=loop,
290
+ report_interval=translation_config.report_interval,
290
291
  ) as pm:
291
292
  future = loop.run_in_executor(None, do_translate, pm, translation_config)
292
293
  try:
@@ -20,7 +20,7 @@ from babeldoc.document_il.translator.translator import set_translate_rate_limite
20
20
  from babeldoc.translation_config import TranslationConfig
21
21
 
22
22
  logger = logging.getLogger(__name__)
23
- __version__ = "0.1.6"
23
+ __version__ = "0.1.7"
24
24
 
25
25
 
26
26
  def create_parser():
@@ -158,6 +158,24 @@ def create_parser():
158
158
  action="store_true",
159
159
  help="Put translated pages first in dual PDF mode",
160
160
  )
161
+ translation_params.add_argument(
162
+ "--disable-rich-text-translate",
163
+ default=False,
164
+ action="store_true",
165
+ help="Disable rich text translation (may help improve compatibility with some PDFs)",
166
+ )
167
+ translation_params.add_argument(
168
+ "--enhance-compatibility",
169
+ default=False,
170
+ action="store_true",
171
+ help="Enable all compatibility enhancement options (equivalent to --skip-clean --dual-translate-first --disable-rich-text-translate)",
172
+ )
173
+ translation_params.add_argument(
174
+ "--report-interval",
175
+ type=float,
176
+ default=0.1,
177
+ help="Progress report interval in seconds (default: 0.1)",
178
+ )
161
179
  service_params = translation_params.add_mutually_exclusive_group()
162
180
  service_params.add_argument(
163
181
  "--openai",
@@ -400,6 +418,9 @@ async def main():
400
418
  doc_layout_model=doc_layout_model,
401
419
  skip_clean=args.skip_clean,
402
420
  dual_translate_first=args.dual_translate_first,
421
+ disable_rich_text_translate=args.disable_rich_text_translate,
422
+ enhance_compatibility=args.enhance_compatibility,
423
+ report_interval=args.report_interval,
403
424
  )
404
425
 
405
426
  # Create progress handler
@@ -24,6 +24,7 @@ class ProgressMonitor:
24
24
  self.progress_change_callback = progress_change_callback
25
25
  self.finish_callback = finish_callback
26
26
  self.report_interval = report_interval
27
+ logger.debug(f"report_interval: {self.report_interval}")
27
28
  self.last_report_time = 0
28
29
  self.finish_stage_count = 0
29
30
  self.finish_event = finish_event
@@ -31,6 +32,18 @@ class ProgressMonitor:
31
32
  self.loop = loop
32
33
  if finish_event and not loop:
33
34
  raise ValueError("finish_event requires a loop")
35
+ if self.progress_change_callback:
36
+ self.progress_change_callback(
37
+ type="stage_summary",
38
+ stages=[
39
+ {
40
+ "name": name,
41
+ "percent": 1.0 / len(stages),
42
+ }
43
+ for name in stages
44
+ ],
45
+ )
46
+ self.lock = threading.Lock()
34
47
 
35
48
  def stage_start(self, stage_name: str, total: int):
36
49
  stage = self.stage[stage_name]
@@ -49,6 +62,7 @@ class ProgressMonitor:
49
62
  stage_current=0,
50
63
  stage_total=total,
51
64
  )
65
+ self.last_report_time = 0.0
52
66
  return stage
53
67
 
54
68
  def __enter__(self):
@@ -66,7 +80,7 @@ class ProgressMonitor:
66
80
  self.finish_callback(type="error", error=CancelledError)
67
81
 
68
82
  def stage_done(self, stage):
69
- self.last_report_time = 0
83
+ self.last_report_time = 0.0
70
84
  self.finish_stage_count += 1
71
85
  if (
72
86
  stage.current != stage.total
@@ -94,19 +108,20 @@ class ProgressMonitor:
94
108
  return progress
95
109
 
96
110
  def stage_update(self, stage, n: int):
97
- if (
98
- self.progress_change_callback
99
- and time.time() - self.last_report_time > self.report_interval
100
- ):
101
- self.progress_change_callback(
102
- type="progress_update",
103
- stage=stage.display_name,
104
- stage_progress=stage.current * 100 / stage.total,
105
- stage_current=stage.current,
106
- stage_total=stage.total,
107
- overall_progress=self.calculate_current_progress(stage),
108
- )
109
- self.last_report_time = time.time()
111
+ with self.lock:
112
+ report_time_delta = time.time() - self.last_report_time
113
+ if report_time_delta < self.report_interval:
114
+ return
115
+ if self.progress_change_callback:
116
+ self.progress_change_callback(
117
+ type="progress_update",
118
+ stage=stage.display_name,
119
+ stage_progress=stage.current * 100 / stage.total,
120
+ stage_current=stage.current,
121
+ stage_total=stage.total,
122
+ overall_progress=self.calculate_current_progress(stage),
123
+ )
124
+ self.last_report_time = time.time()
110
125
 
111
126
  def translate_done(self, translate_result):
112
127
  if self.finish_callback:
@@ -33,6 +33,9 @@ class TranslationConfig:
33
33
  doc_layout_model=None,
34
34
  skip_clean: bool = False,
35
35
  dual_translate_first: bool = False,
36
+ disable_rich_text_translate: bool = False, # 是否禁用富文本翻译
37
+ enhance_compatibility: bool = False, # 增强兼容性模式
38
+ report_interval: float = 0.1, # Progress report interval in seconds
36
39
  ):
37
40
  self.input_file = input_file
38
41
  self.translator = translator
@@ -51,8 +54,12 @@ class TranslationConfig:
51
54
  self.short_line_split_factor = short_line_split_factor
52
55
  self.use_rich_pbar = use_rich_pbar
53
56
  self.progress_monitor = progress_monitor
54
- self.skip_clean = skip_clean
55
- self.dual_translate_first = dual_translate_first
57
+ self.skip_clean = skip_clean or enhance_compatibility
58
+ self.dual_translate_first = dual_translate_first or enhance_compatibility
59
+ self.disable_rich_text_translate = (
60
+ disable_rich_text_translate or enhance_compatibility
61
+ )
62
+ self.report_interval = report_interval
56
63
  if progress_monitor:
57
64
  if progress_monitor.cancel_event is None:
58
65
  progress_monitor.cancel_event = threading.Event()
@@ -40,7 +40,7 @@ Please pay special attention to:
40
40
 
41
41
 
42
42
  1. Fork this repository and clone it locally.
43
- 2. Use `doc/deploy.sh` to set up the development environment.
43
+ 2. Use `doc/deploy.sh` to set up the development environment.
44
44
  3. Create a new branch and make code changes on that branch. `git checkout -b feature/<feature-name>`
45
45
  4. Perform development and ensure the code meets the requirements.
46
46
 
@@ -72,6 +72,8 @@ git commit -m "<semantic commit message>"
72
72
 
73
73
  - Use the `uv run yadt` command for development and testing.
74
74
 
75
+ - When you need print log, please use `log.debug()` to print info. **DO NOT USE `print()`**
76
+
75
77
  - Code formatting
76
78
 
77
79
  3. Dependency Updates
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "BabelDOC"
3
- version = "0.1.6"
3
+ version = "0.1.7"
4
4
  description = "Yet Another Document Translator"
5
5
  license = "AGPL-3.0"
6
6
  readme = "README.md"
@@ -117,7 +117,7 @@ dev = [
117
117
  ]
118
118
 
119
119
  [bumpver]
120
- current_version = "0.1.6"
120
+ current_version = "0.1.7"
121
121
  version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
122
122
 
123
123
  [bumpver.file_patterns]
@@ -38,7 +38,7 @@ wheels = [
38
38
 
39
39
  [[package]]
40
40
  name = "babeldoc"
41
- version = "0.1.6"
41
+ version = "0.1.7"
42
42
  source = { editable = "." }
43
43
  dependencies = [
44
44
  { name = "bitstring" },
@@ -1,34 +0,0 @@
1
- ---
2
- name: Bug report
3
- about: Create a report to help us improve
4
- title: ''
5
- labels: 'bug'
6
- assignees: ''
7
-
8
- ---
9
-
10
- **Describe the bug**
11
- A clear and concise description of what the bug is.
12
-
13
- **To Reproduce**
14
- Steps to reproduce the behavior:
15
- 1. Go to '...'
16
- 2. Click on '....'
17
- 3. Scroll down to '....'
18
- 4. See error
19
-
20
- **Expected behavior**
21
- A clear and concise description of what you expected to happen.
22
-
23
- **Screenshots**
24
- If applicable, add screenshots to help explain your problem.
25
-
26
- **Desktop (please complete the following information):**
27
- - OS: [e.g. macOS Sequoia 15.3, Windows 11]
28
- - Version [e.g. 0.1.0]
29
-
30
- **Input PDF file:**
31
- if applicable, attach the input PDF file here.
32
-
33
- **Additional context**
34
- Add any other context about the problem here.
@@ -1,20 +0,0 @@
1
- ---
2
- name: Feature request
3
- about: Suggest an idea for this project
4
- title: ''
5
- labels: 'enhancement'
6
- assignees: ''
7
-
8
- ---
9
-
10
- **Is your feature request related to a problem? Please describe.**
11
- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
-
13
- **Describe the solution you'd like**
14
- A clear and concise description of what you want to happen.
15
-
16
- **Describe alternatives you've considered**
17
- A clear and concise description of any alternative solutions or features you've considered.
18
-
19
- **Additional context**
20
- Add any other context or screenshots about the feature request here.
@@ -1 +0,0 @@
1
- __version__ = "0.1.6"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes