BabelDOC 0.2.31__tar.gz → 0.2.33__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.
- {babeldoc-0.2.31 → babeldoc-0.2.33}/PKG-INFO +4 -1
- {babeldoc-0.2.31 → babeldoc-0.2.33}/README.md +3 -0
- babeldoc-0.2.33/babeldoc/__init__.py +1 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/const.py +1 -1
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/styles_and_formulas.py +2 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/high_level.py +27 -20
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/main.py +8 -1
- babeldoc-0.2.33/babeldoc/tools/italic_assistance.py +205 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/translation_config.py +2 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/pyproject.toml +2 -2
- {babeldoc-0.2.31 → babeldoc-0.2.33}/uv.lock +1 -1
- babeldoc-0.2.31/babeldoc/__init__.py +0 -1
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.cursorignore +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/dependabot.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/labels.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/release-drafter.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/workflows/codeql.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/workflows/docs.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/workflows/labeler.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/workflows/publish-to-pypi.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.github/workflows/test.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.gitignore +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/.pre-commit-config.yaml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/LICENSE +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/assets/assets.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/assets/embedding_assets_metadata.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/asynchronize/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/converter.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/backend/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/backend/pdf_creater.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/frontend/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/frontend/il_creater.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/il_version_1.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/il_version_1.rnc +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/il_version_1.rng +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/il_version_1.xsd +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/add_debug_information.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/detect_scanned_file.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/il_translator.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/il_translator_llm_only.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/layout_parser.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/paragraph_finder.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/remove_descent.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/table_parser.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/midend/typesetting.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/translator/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/translator/cache.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/translator/translator.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/atomic_integer.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/fontmap.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/layout_helper.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/priority_thread_pool_executor.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/style_helper.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/xml_converter.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/docvision/README.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/docvision/__init__.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/docvision/doclayout.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/docvision/rpc_doclayout.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/docvision/table_detection/rapidocr.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/pdfinterp.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/progress_monitor.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/result_merger.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/split_manager.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/tools/generate_font_metadata.py +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/CODE_OF_CONDUCT.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/CONTRIBUTING.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/CONTRIBUTOR_REWARD.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/README.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/README.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/deploy.sh +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-banner.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-contributor_reward_example.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-preview.gif +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-small-logo.png +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/index.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/intro-to-pdf-object.md +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/docs/requirements.txt +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/mkdocs.yml +0 -0
- {babeldoc-0.2.31 → babeldoc-0.2.33}/tests/test_translation_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: BabelDOC
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.33
|
|
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
|
|
@@ -187,6 +187,7 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
187
187
|
- `--max-pages-per-part`: Maximum number of pages per part for split translation. If not set, no splitting will be performed.
|
|
188
188
|
- `--no-watermark`: [DEPRECATED] Use --watermark-output-mode=no_watermark instead.
|
|
189
189
|
- `--translate-table-text`: Translate table text (experimental, default: False)
|
|
190
|
+
- `--skip-scanned-detection`: Skip scanned document detection (default: False). When using split translation, only the first part performs detection if not skipped.
|
|
190
191
|
|
|
191
192
|
> [!TIP]
|
|
192
193
|
> - Both `--skip-clean` and `--dual-translate-first` may help improve compatibility with some PDF readers
|
|
@@ -194,6 +195,7 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
194
195
|
> - However, using `--skip-clean` will result in larger file sizes
|
|
195
196
|
> - If you encounter any compatibility issues, try using `--enhance-compatibility` first
|
|
196
197
|
> - Use `--max-pages-per-part` for large documents to split them into smaller parts for translation and automatically merge them back.
|
|
198
|
+
> - Use `--skip-scanned-detection` to speed up processing when you know your document is not a scanned PDF.
|
|
197
199
|
|
|
198
200
|
### Translation Service Options
|
|
199
201
|
|
|
@@ -268,6 +270,7 @@ use-alternating-pages-dual = false
|
|
|
268
270
|
watermark-output-mode = "watermarked" # Choices: "watermarked", "no_watermark", "both"
|
|
269
271
|
max-pages-per-part = 50 # Automatically split the document for translation and merge it back.
|
|
270
272
|
# no-watermark = false # DEPRECATED: Use watermark-output-mode instead
|
|
273
|
+
skip-scanned-detection = false # Skip scanned document detection for faster processing
|
|
271
274
|
|
|
272
275
|
# Translation service
|
|
273
276
|
openai = true
|
|
@@ -141,6 +141,7 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
141
141
|
- `--max-pages-per-part`: Maximum number of pages per part for split translation. If not set, no splitting will be performed.
|
|
142
142
|
- `--no-watermark`: [DEPRECATED] Use --watermark-output-mode=no_watermark instead.
|
|
143
143
|
- `--translate-table-text`: Translate table text (experimental, default: False)
|
|
144
|
+
- `--skip-scanned-detection`: Skip scanned document detection (default: False). When using split translation, only the first part performs detection if not skipped.
|
|
144
145
|
|
|
145
146
|
> [!TIP]
|
|
146
147
|
> - Both `--skip-clean` and `--dual-translate-first` may help improve compatibility with some PDF readers
|
|
@@ -148,6 +149,7 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
148
149
|
> - However, using `--skip-clean` will result in larger file sizes
|
|
149
150
|
> - If you encounter any compatibility issues, try using `--enhance-compatibility` first
|
|
150
151
|
> - Use `--max-pages-per-part` for large documents to split them into smaller parts for translation and automatically merge them back.
|
|
152
|
+
> - Use `--skip-scanned-detection` to speed up processing when you know your document is not a scanned PDF.
|
|
151
153
|
|
|
152
154
|
### Translation Service Options
|
|
153
155
|
|
|
@@ -222,6 +224,7 @@ use-alternating-pages-dual = false
|
|
|
222
224
|
watermark-output-mode = "watermarked" # Choices: "watermarked", "no_watermark", "both"
|
|
223
225
|
max-pages-per-part = 50 # Automatically split the document for translation and merge it back.
|
|
224
226
|
# no-watermark = false # DEPRECATED: Use watermark-output-mode instead
|
|
227
|
+
skip-scanned-detection = false # Skip scanned document detection for faster processing
|
|
225
228
|
|
|
226
229
|
# Translation service
|
|
227
230
|
openai = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.33"
|
|
@@ -49,19 +49,19 @@ from babeldoc.translation_config import WatermarkOutputMode
|
|
|
49
49
|
logger = logging.getLogger(__name__)
|
|
50
50
|
|
|
51
51
|
TRANSLATE_STAGES = [
|
|
52
|
-
(ILCreater.stage_name,
|
|
53
|
-
(DetectScannedFile.stage_name,
|
|
54
|
-
(LayoutParser.stage_name,
|
|
55
|
-
(TableParser.stage_name, 0
|
|
56
|
-
(ParagraphFinder.stage_name,
|
|
57
|
-
(StylesAndFormulas.stage_name, 1.
|
|
52
|
+
(ILCreater.stage_name, 14.12), # Parse PDF and Create IR
|
|
53
|
+
(DetectScannedFile.stage_name, 2.45), # DetectScannedFile
|
|
54
|
+
(LayoutParser.stage_name, 14.03), # Parse Page Layout
|
|
55
|
+
(TableParser.stage_name, 1.0), # Parse Table
|
|
56
|
+
(ParagraphFinder.stage_name, 6.26), # Parse Paragraphs
|
|
57
|
+
(StylesAndFormulas.stage_name, 1.66), # Parse Formulas and Styles
|
|
58
58
|
# (RemoveDescent.stage_name, 0.15), # Remove Char Descent
|
|
59
|
-
(ILTranslator.stage_name,
|
|
60
|
-
(Typesetting.stage_name,
|
|
61
|
-
(FontMapper.stage_name, 0.
|
|
62
|
-
(PDFCreater.stage_name, 1.
|
|
63
|
-
(SUBSET_FONT_STAGE_NAME,
|
|
64
|
-
(SAVE_PDF_STAGE_NAME,
|
|
59
|
+
(ILTranslator.stage_name, 46.96), # Translate Paragraphs
|
|
60
|
+
(Typesetting.stage_name, 4.71), # Typesetting
|
|
61
|
+
(FontMapper.stage_name, 0.61), # Add Fonts
|
|
62
|
+
(PDFCreater.stage_name, 1.96), # Generate drawing instructions
|
|
63
|
+
(SUBSET_FONT_STAGE_NAME, 0.92), # Subset font
|
|
64
|
+
(SAVE_PDF_STAGE_NAME, 6.34), # Save PDF
|
|
65
65
|
]
|
|
66
66
|
|
|
67
67
|
resfont_map = {
|
|
@@ -431,6 +431,10 @@ def do_translate(
|
|
|
431
431
|
(x, x) for x in should_translate_pages
|
|
432
432
|
]
|
|
433
433
|
|
|
434
|
+
# Only first part should do scanned detection if enabled
|
|
435
|
+
if i > 0:
|
|
436
|
+
part_config.skip_scanned_detection = True
|
|
437
|
+
|
|
434
438
|
part_config.working_dir = (
|
|
435
439
|
translation_config.get_part_working_dir(i)
|
|
436
440
|
)
|
|
@@ -576,14 +580,17 @@ def _do_translate_single(
|
|
|
576
580
|
# [Previous implementation of do_translate continues here]
|
|
577
581
|
|
|
578
582
|
# 检测是否为扫描文件
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
583
|
+
if translation_config.skip_scanned_detection:
|
|
584
|
+
logger.debug("skipping scanned file detection")
|
|
585
|
+
else:
|
|
586
|
+
logger.debug("start detect scanned file")
|
|
587
|
+
DetectScannedFile(translation_config).process(docs)
|
|
588
|
+
logger.debug("finish detect scanned file")
|
|
589
|
+
if translation_config.debug:
|
|
590
|
+
xml_converter.write_json(
|
|
591
|
+
docs,
|
|
592
|
+
translation_config.get_working_file_path("detect_scanned_file.json"),
|
|
593
|
+
)
|
|
587
594
|
|
|
588
595
|
# Generate layouts for all pages
|
|
589
596
|
logger.debug("start generating layouts")
|
|
@@ -23,7 +23,7 @@ from babeldoc.translation_config import TranslationConfig
|
|
|
23
23
|
from babeldoc.translation_config import WatermarkOutputMode
|
|
24
24
|
|
|
25
25
|
logger = logging.getLogger(__name__)
|
|
26
|
-
__version__ = "0.2.
|
|
26
|
+
__version__ = "0.2.33"
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def create_parser():
|
|
@@ -204,6 +204,12 @@ def create_parser():
|
|
|
204
204
|
default=False,
|
|
205
205
|
help="Show character box (debug only)",
|
|
206
206
|
)
|
|
207
|
+
translation_group.add_argument(
|
|
208
|
+
"--skip-scanned-detection",
|
|
209
|
+
action="store_true",
|
|
210
|
+
default=False,
|
|
211
|
+
help="Skip scanned document detection (speeds up processing for non-scanned documents)",
|
|
212
|
+
)
|
|
207
213
|
# service option argument group
|
|
208
214
|
service_group = translation_group.add_mutually_exclusive_group()
|
|
209
215
|
service_group.add_argument(
|
|
@@ -370,6 +376,7 @@ async def main():
|
|
|
370
376
|
split_strategy=split_strategy,
|
|
371
377
|
table_model=table_model,
|
|
372
378
|
show_char_box=args.show_char_box,
|
|
379
|
+
skip_scanned_detection=args.skip_scanned_detection,
|
|
373
380
|
)
|
|
374
381
|
|
|
375
382
|
# Create progress handler
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import orjson
|
|
7
|
+
from babeldoc.const import CACHE_FOLDER
|
|
8
|
+
|
|
9
|
+
WORKING_FOLDER = Path(CACHE_FOLDER) / "working"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def find_latest_il_json() -> Path | None:
|
|
13
|
+
"""
|
|
14
|
+
Find the latest il_translated.json file in ~/.cache/babeldoc/ subdirectories.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Path to the most recently modified il_translated.json file, or None if not found.
|
|
18
|
+
"""
|
|
19
|
+
base_dir = Path(WORKING_FOLDER)
|
|
20
|
+
json_files = list(base_dir.glob("*/il_translated.json"))
|
|
21
|
+
|
|
22
|
+
if not json_files:
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
# Sort by modification time (newest first)
|
|
26
|
+
json_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
|
|
27
|
+
return json_files[0]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def extract_fonts_from_paragraph(
|
|
31
|
+
paragraph: dict, page_font_map: dict[str, tuple[str, str]]
|
|
32
|
+
) -> set[tuple[str, str]]:
|
|
33
|
+
"""
|
|
34
|
+
Extract all font_ids and names used in a paragraph.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
paragraph: The paragraph dictionary
|
|
38
|
+
page_font_map: Dictionary mapping font_id to (font_id, name) tuples
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Set of (font_id, name) tuples
|
|
42
|
+
"""
|
|
43
|
+
fonts = set()
|
|
44
|
+
|
|
45
|
+
# Check if paragraph has a pdfStyle with font_id
|
|
46
|
+
if (
|
|
47
|
+
"pdf_style" in paragraph
|
|
48
|
+
and paragraph["pdf_style"]
|
|
49
|
+
and "font_id" in paragraph["pdf_style"]
|
|
50
|
+
):
|
|
51
|
+
font_id = paragraph["pdf_style"]["font_id"]
|
|
52
|
+
if font_id in page_font_map:
|
|
53
|
+
fonts.add(page_font_map[font_id])
|
|
54
|
+
|
|
55
|
+
# Process paragraph compositions if present
|
|
56
|
+
if "pdf_paragraph_composition" in paragraph:
|
|
57
|
+
for comp in paragraph["pdf_paragraph_composition"]:
|
|
58
|
+
# Check different composition types that might contain font information
|
|
59
|
+
|
|
60
|
+
# Direct pdfCharacter in composition
|
|
61
|
+
if "pdf_character" in comp and comp["pdf_character"]:
|
|
62
|
+
char = comp["pdf_character"]
|
|
63
|
+
if "pdf_style" in char and "font_id" in char["pdf_style"]:
|
|
64
|
+
font_id = char["pdf_style"]["font_id"]
|
|
65
|
+
if font_id in page_font_map:
|
|
66
|
+
fonts.add(page_font_map[font_id])
|
|
67
|
+
|
|
68
|
+
# PdfLine in composition
|
|
69
|
+
elif "pdf_line" in comp and comp["pdf_line"]:
|
|
70
|
+
line = comp["pdf_line"]
|
|
71
|
+
if "pdf_character" in line:
|
|
72
|
+
for char in line["pdf_character"]:
|
|
73
|
+
if "pdf_style" in char and "font_id" in char["pdf_style"]:
|
|
74
|
+
font_id = char["pdf_style"]["font_id"]
|
|
75
|
+
if font_id in page_font_map:
|
|
76
|
+
fonts.add(page_font_map[font_id])
|
|
77
|
+
|
|
78
|
+
# PdfFormula in composition
|
|
79
|
+
elif "pdf_formula" in comp and comp["pdf_formula"]:
|
|
80
|
+
formula = comp["pdf_formula"]
|
|
81
|
+
if "pdf_character" in formula:
|
|
82
|
+
for char in formula["pdf_character"]:
|
|
83
|
+
if "pdf_style" in char and "font_id" in char["pdf_style"]:
|
|
84
|
+
font_id = char["pdf_style"]["font_id"]
|
|
85
|
+
if font_id in page_font_map:
|
|
86
|
+
fonts.add(page_font_map[font_id])
|
|
87
|
+
|
|
88
|
+
# PdfSameStyleCharacters in composition
|
|
89
|
+
elif (
|
|
90
|
+
"pdf_same_style_characters" in comp
|
|
91
|
+
and comp["pdf_same_style_characters"]
|
|
92
|
+
):
|
|
93
|
+
same_style = comp["pdf_same_style_characters"]
|
|
94
|
+
if "pdf_style" in same_style and "font_id" in same_style["pdf_style"]:
|
|
95
|
+
font_id = same_style["pdf_style"]["font_id"]
|
|
96
|
+
if font_id in page_font_map:
|
|
97
|
+
fonts.add(page_font_map[font_id])
|
|
98
|
+
|
|
99
|
+
# PdfSameStyleUnicodeCharacters in composition
|
|
100
|
+
elif (
|
|
101
|
+
"pdf_same_style_unicode_characters" in comp
|
|
102
|
+
and comp["pdf_same_style_unicode_characters"]
|
|
103
|
+
):
|
|
104
|
+
same_style_unicode = comp["pdf_same_style_unicode_characters"]
|
|
105
|
+
if (
|
|
106
|
+
"pdf_style" in same_style_unicode
|
|
107
|
+
and "font_id" in same_style_unicode["pdf_style"]
|
|
108
|
+
):
|
|
109
|
+
font_id = same_style_unicode["pdf_style"]["font_id"]
|
|
110
|
+
if font_id in page_font_map:
|
|
111
|
+
fonts.add(page_font_map[font_id])
|
|
112
|
+
|
|
113
|
+
return fonts
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def find_fonts_by_debug_id(json_path: Path, debug_id_regex: str) -> dict[str, str]:
|
|
117
|
+
"""
|
|
118
|
+
Find all fonts used in paragraphs with matching debug_id.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
json_path: Path to the il_translated.json file
|
|
122
|
+
debug_id_regex: Regular expression to match debug_id values
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Dictionary mapping font_ids to font names
|
|
126
|
+
"""
|
|
127
|
+
# Load and parse JSON
|
|
128
|
+
with json_path.open("rb") as f:
|
|
129
|
+
doc_data = orjson.loads(f.read())
|
|
130
|
+
|
|
131
|
+
# Compile regex pattern (case insensitive)
|
|
132
|
+
pattern = re.compile(debug_id_regex.strip(" \"'"), re.IGNORECASE)
|
|
133
|
+
|
|
134
|
+
# Set to collect all found font information
|
|
135
|
+
found_fonts = set()
|
|
136
|
+
|
|
137
|
+
# Process each page
|
|
138
|
+
for page in doc_data.get("page", []):
|
|
139
|
+
# Create a mapping of font_id to (font_id, name) tuples for this page
|
|
140
|
+
page_font_map = {}
|
|
141
|
+
for font in page.get("pdf_font", []):
|
|
142
|
+
if "font_id" in font and "name" in font:
|
|
143
|
+
page_font_map[font["font_id"]] = (font["font_id"], font["name"])
|
|
144
|
+
|
|
145
|
+
# Check each paragraph
|
|
146
|
+
for paragraph in page.get("pdf_paragraph", []):
|
|
147
|
+
# Check if paragraph has debug_id and if it matches the pattern
|
|
148
|
+
debug_id = paragraph.get("debug_id")
|
|
149
|
+
if debug_id and pattern.search(debug_id):
|
|
150
|
+
# Get all fonts used in this paragraph
|
|
151
|
+
paragraph_fonts = extract_fonts_from_paragraph(paragraph, page_font_map)
|
|
152
|
+
found_fonts.update(paragraph_fonts)
|
|
153
|
+
|
|
154
|
+
# Convert set of tuples to dictionary
|
|
155
|
+
return dict(found_fonts)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def main():
|
|
159
|
+
parser = argparse.ArgumentParser(
|
|
160
|
+
description="Extract fonts from paragraphs with matching debug_id"
|
|
161
|
+
)
|
|
162
|
+
parser.add_argument(
|
|
163
|
+
"debug_id_regex", nargs="+", help="Regular expression to match debug_id values"
|
|
164
|
+
)
|
|
165
|
+
parser.add_argument(
|
|
166
|
+
"--json-path",
|
|
167
|
+
help="Path to il_translated.json (if not provided, will use the latest file)",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
args = parser.parse_args()
|
|
171
|
+
|
|
172
|
+
# Determine JSON file path
|
|
173
|
+
json_path = None
|
|
174
|
+
if args.json_path:
|
|
175
|
+
json_path = Path(args.json_path)
|
|
176
|
+
if not json_path.exists():
|
|
177
|
+
print(f"Error: File not found: {json_path}")
|
|
178
|
+
return 1
|
|
179
|
+
else:
|
|
180
|
+
json_path = find_latest_il_json()
|
|
181
|
+
if not json_path:
|
|
182
|
+
print("Error: Could not find any il_translated.json file")
|
|
183
|
+
return 1
|
|
184
|
+
|
|
185
|
+
print(f"Using JSON file: {json_path}")
|
|
186
|
+
|
|
187
|
+
# Find fonts matching the debug_id pattern
|
|
188
|
+
fonts = find_fonts_by_debug_id(json_path, "|".join(args.debug_id_regex))
|
|
189
|
+
|
|
190
|
+
# Output the results
|
|
191
|
+
if fonts:
|
|
192
|
+
print(
|
|
193
|
+
f"Found {len(fonts)} fonts in paragraphs matching debug_id pattern: {args.debug_id_regex}"
|
|
194
|
+
)
|
|
195
|
+
print(json.dumps(fonts, indent=2, ensure_ascii=False))
|
|
196
|
+
else:
|
|
197
|
+
print(
|
|
198
|
+
f"No fonts found for paragraphs matching debug_id pattern: {args.debug_id_regex}"
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return 0
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if __name__ == "__main__":
|
|
205
|
+
exit(main())
|
|
@@ -67,6 +67,7 @@ class TranslationConfig:
|
|
|
67
67
|
split_strategy: BaseSplitStrategy | None = None,
|
|
68
68
|
table_model=None,
|
|
69
69
|
show_char_box: bool = False,
|
|
70
|
+
skip_scanned_detection: bool = False,
|
|
70
71
|
):
|
|
71
72
|
self.translator = translator
|
|
72
73
|
|
|
@@ -97,6 +98,7 @@ class TranslationConfig:
|
|
|
97
98
|
self.doc_layout_model = doc_layout_model
|
|
98
99
|
|
|
99
100
|
self.skip_clean = skip_clean or enhance_compatibility
|
|
101
|
+
self.skip_scanned_detection = skip_scanned_detection
|
|
100
102
|
|
|
101
103
|
self.dual_translate_first = dual_translate_first or enhance_compatibility
|
|
102
104
|
self.disable_rich_text_translate = (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "BabelDOC"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.33"
|
|
4
4
|
description = "Yet Another Document Translator"
|
|
5
5
|
license = "AGPL-3.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -148,7 +148,7 @@ pythonpath = [".", "src"]
|
|
|
148
148
|
testpaths = ["tests"]
|
|
149
149
|
|
|
150
150
|
[bumpver]
|
|
151
|
-
current_version = "0.2.
|
|
151
|
+
current_version = "0.2.33"
|
|
152
152
|
version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
|
|
153
153
|
|
|
154
154
|
[bumpver.file_patterns]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.31"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/babeldoc_exception/BabelDOCException.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/babeldoc/document_il/utils/priority_thread_pool_executor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-with-transparent-background.png
RENAMED
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-big-logo-with-transparent-background.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-small-logo-with-transparent-background.png
RENAMED
|
File without changes
|
{babeldoc-0.2.31 → babeldoc-0.2.33}/docs/images/babeldoc-small-logo-with-transparent-background.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|