BabelDOC 0.3.40__tar.gz → 0.3.41__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.3.40 → babeldoc-0.3.41}/PKG-INFO +1 -1
- babeldoc-0.3.41/babeldoc/__init__.py +1 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/const.py +1 -1
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/il_translator.py +83 -26
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/il_translator_llm_only.py +43 -16
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/translator/translator.py +6 -3
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/main.py +1 -1
- {babeldoc-0.3.40 → babeldoc-0.3.41}/pyproject.toml +2 -2
- {babeldoc-0.3.40 → babeldoc-0.3.41}/uv.lock +1 -1
- babeldoc-0.3.40/babeldoc/__init__.py +0 -1
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.cursorignore +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/PULL_REQUEST_TEMPLATE/pr_form.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/dependabot.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/labels.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/release-drafter.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/codeql.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/docs.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/labeler.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/lint.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/pr-lint.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/publish-to-pypi.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.github/workflows/test.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.gitignore +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/.pre-commit-config.yaml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/LICENSE +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/README.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/assets/assets.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/assets/embedding_assets_metadata.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/asynchronize/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/converter.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/backend/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/backend/pdf_creater.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/frontend/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/frontend/il_creater.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/il_version_1.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/il_version_1.rnc +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/il_version_1.rng +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/il_version_1.xsd +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/add_debug_information.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/detect_scanned_file.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/layout_parser.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/paragraph_finder.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/remove_descent.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/styles_and_formulas.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/table_parser.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/midend/typesetting.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/translator/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/translator/cache.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/atomic_integer.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/fontmap.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/layout_helper.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/paragraph_helper.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/priority_thread_pool_executor.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/style_helper.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/utils/zstd_helper.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/document_il/xml_converter.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/docvision/README.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/docvision/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/docvision/doclayout.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/docvision/rpc_doclayout.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/docvision/table_detection/rapidocr.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/format/office/__init__.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/high_level.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/pdfinterp.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/progress_monitor.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/result_merger.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/split_manager.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/tools/generate_font_metadata.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/tools/italic_assistance.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/tools/italic_recognize_tool.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/babeldoc/translation_config.py +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/CODE_OF_CONDUCT.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/CONTRIBUTING.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/CONTRIBUTOR_REWARD.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/README.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/README.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/deploy.sh +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-banner.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-contributor_reward_example.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-preview.gif +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-small-logo.png +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/index.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/intro-to-pdf-object.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/requirements.txt +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/docs/supported_languages.md +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/mkdocs.yml +0 -0
- {babeldoc-0.3.40 → babeldoc-0.3.41}/tests/test_translation_config.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.41"
|
|
@@ -39,18 +39,29 @@ class RichTextPlaceholder:
|
|
|
39
39
|
composition: PdfSameStyleCharacters,
|
|
40
40
|
left_placeholder: str,
|
|
41
41
|
right_placeholder: str,
|
|
42
|
+
left_regex_pattern: str = None,
|
|
43
|
+
right_regex_pattern: str = None,
|
|
42
44
|
):
|
|
43
45
|
self.id = placeholder_id
|
|
44
46
|
self.composition = composition
|
|
45
47
|
self.left_placeholder = left_placeholder
|
|
46
48
|
self.right_placeholder = right_placeholder
|
|
49
|
+
self.left_regex_pattern = left_regex_pattern
|
|
50
|
+
self.right_regex_pattern = right_regex_pattern
|
|
47
51
|
|
|
48
52
|
|
|
49
53
|
class FormulaPlaceholder:
|
|
50
|
-
def __init__(
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
placeholder_id: int,
|
|
57
|
+
formula: PdfFormula,
|
|
58
|
+
placeholder: str,
|
|
59
|
+
regex_pattern: str,
|
|
60
|
+
):
|
|
51
61
|
self.id = placeholder_id
|
|
52
62
|
self.formula = formula
|
|
53
63
|
self.placeholder = placeholder
|
|
64
|
+
self.regex_pattern = regex_pattern
|
|
54
65
|
|
|
55
66
|
|
|
56
67
|
class PbarContext:
|
|
@@ -328,10 +339,14 @@ class ILTranslator:
|
|
|
328
339
|
paragraph: PdfParagraph,
|
|
329
340
|
):
|
|
330
341
|
placeholder = self.translate_engine.get_formular_placeholder(formula_id)
|
|
342
|
+
if isinstance(placeholder, tuple):
|
|
343
|
+
placeholder, regex_pattern = placeholder
|
|
344
|
+
else:
|
|
345
|
+
regex_pattern = re.escape(placeholder)
|
|
331
346
|
if placeholder in paragraph.unicode:
|
|
332
347
|
return self.create_formula_placeholder(formula, formula_id + 1, paragraph)
|
|
333
348
|
|
|
334
|
-
return FormulaPlaceholder(formula_id, formula, placeholder)
|
|
349
|
+
return FormulaPlaceholder(formula_id, formula, placeholder, regex_pattern)
|
|
335
350
|
|
|
336
351
|
def create_rich_text_placeholder(
|
|
337
352
|
self,
|
|
@@ -345,6 +360,14 @@ class ILTranslator:
|
|
|
345
360
|
right_placeholder = self.translate_engine.get_rich_text_right_placeholder(
|
|
346
361
|
composition_id,
|
|
347
362
|
)
|
|
363
|
+
if isinstance(left_placeholder, tuple):
|
|
364
|
+
left_placeholder, left_placeholder_regex_pattern = left_placeholder
|
|
365
|
+
else:
|
|
366
|
+
left_placeholder_regex_pattern = re.escape(left_placeholder)
|
|
367
|
+
if isinstance(right_placeholder, tuple):
|
|
368
|
+
right_placeholder, right_placeholder_regex_pattern = right_placeholder
|
|
369
|
+
else:
|
|
370
|
+
right_placeholder_regex_pattern = re.escape(right_placeholder)
|
|
348
371
|
if (
|
|
349
372
|
left_placeholder in paragraph.unicode
|
|
350
373
|
or right_placeholder in paragraph.unicode
|
|
@@ -360,6 +383,8 @@ class ILTranslator:
|
|
|
360
383
|
composition,
|
|
361
384
|
left_placeholder,
|
|
362
385
|
right_placeholder,
|
|
386
|
+
left_placeholder_regex_pattern,
|
|
387
|
+
right_placeholder_regex_pattern,
|
|
363
388
|
)
|
|
364
389
|
|
|
365
390
|
def get_translate_input(
|
|
@@ -550,13 +575,14 @@ class ILTranslator:
|
|
|
550
575
|
for placeholder in input_text.placeholders:
|
|
551
576
|
if isinstance(placeholder, FormulaPlaceholder):
|
|
552
577
|
# 转义特殊字符
|
|
553
|
-
pattern = re.escape(placeholder.placeholder)
|
|
578
|
+
# pattern = re.escape(placeholder.placeholder)
|
|
579
|
+
pattern = placeholder.regex_pattern
|
|
554
580
|
patterns.append(f"({pattern})")
|
|
555
581
|
placeholder_patterns.append(f"({pattern})")
|
|
556
582
|
placeholder_map[placeholder.placeholder] = placeholder
|
|
557
583
|
else:
|
|
558
|
-
left =
|
|
559
|
-
right =
|
|
584
|
+
left = placeholder.left_regex_pattern
|
|
585
|
+
right = placeholder.right_regex_pattern
|
|
560
586
|
patterns.append(f"({left}.*?{right})")
|
|
561
587
|
placeholder_patterns.append(f"({left})")
|
|
562
588
|
placeholder_patterns.append(f"({right})")
|
|
@@ -569,6 +595,8 @@ class ILTranslator:
|
|
|
569
595
|
if all_match:
|
|
570
596
|
if llm_translate_tracker:
|
|
571
597
|
llm_translate_tracker.set_placeholder_full_match()
|
|
598
|
+
else:
|
|
599
|
+
logger.debug(f"Failed to match all placeholder for {input_text.unicode}")
|
|
572
600
|
# 合并所有模式
|
|
573
601
|
combined_pattern = "|".join(patterns)
|
|
574
602
|
combined_placeholder_pattern = "|".join(placeholder_patterns)
|
|
@@ -618,13 +646,12 @@ class ILTranslator:
|
|
|
618
646
|
p
|
|
619
647
|
for p in input_text.placeholders
|
|
620
648
|
if not isinstance(p, FormulaPlaceholder)
|
|
621
|
-
and
|
|
649
|
+
and re.match(f"^{p.left_regex_pattern}", matched_text)
|
|
622
650
|
)
|
|
623
|
-
text =
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
]
|
|
651
|
+
text = re.match(
|
|
652
|
+
f"^{placeholder.left_regex_pattern}(.+){placeholder.right_regex_pattern}$",
|
|
653
|
+
matched_text,
|
|
654
|
+
).group(1)
|
|
628
655
|
|
|
629
656
|
if isinstance(
|
|
630
657
|
placeholder.composition,
|
|
@@ -738,39 +765,69 @@ class ILTranslator:
|
|
|
738
765
|
llm_input = [self.translation_config.custom_system_prompt]
|
|
739
766
|
else:
|
|
740
767
|
llm_input = [
|
|
741
|
-
"You are a professional
|
|
768
|
+
f"You are a professional and reliable machine translation engine responsible for translating the input text into {self.translation_config.lang_out}."
|
|
742
769
|
]
|
|
770
|
+
llm_hint = []
|
|
743
771
|
|
|
744
772
|
if title_paragraph:
|
|
745
|
-
|
|
773
|
+
llm_hint.append(
|
|
746
774
|
f"The first title in the full text: {title_paragraph.unicode}"
|
|
747
775
|
)
|
|
748
776
|
if (
|
|
749
777
|
local_title_paragraph
|
|
750
778
|
and local_title_paragraph.debug_id != title_paragraph.debug_id
|
|
751
779
|
):
|
|
752
|
-
|
|
780
|
+
llm_hint.append(
|
|
753
781
|
f"The most similar title in the full text: {local_title_paragraph.unicode}"
|
|
754
782
|
)
|
|
755
|
-
# Create a structured prompt template for LLM translation
|
|
756
|
-
llm_input.append(
|
|
757
|
-
f'Please do not translate style tags like "{self.translate_engine.get_rich_text_left_placeholder(1)}xxx{self.translate_engine.get_rich_text_right_placeholder(2)}"!'
|
|
758
|
-
)
|
|
759
783
|
|
|
760
|
-
llm_input.append(
|
|
761
|
-
f'Please do not translate formula placeholders like "{self.translate_engine.get_formular_placeholder(3)}"!'
|
|
762
|
-
)
|
|
763
784
|
if self.translation_config.add_formula_placehold_hint:
|
|
764
785
|
placeholders_hint = translate_input.get_placeholders_hint()
|
|
765
786
|
if placeholders_hint:
|
|
766
|
-
|
|
787
|
+
llm_hint.append(
|
|
767
788
|
f"This is the formula placeholder hint: \n{placeholders_hint}"
|
|
768
789
|
)
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
790
|
+
|
|
791
|
+
if llm_hint:
|
|
792
|
+
llm_input.append(
|
|
793
|
+
"When translating, please refer to the following information to improve translation quality:"
|
|
794
|
+
)
|
|
795
|
+
for i, line in enumerate(llm_hint):
|
|
796
|
+
llm_input.append(f"{i}. {line}")
|
|
797
|
+
llm_input.append("When translating, please follow the following rules:")
|
|
798
|
+
|
|
799
|
+
rich_text_left_placeholder = (
|
|
800
|
+
self.translate_engine.get_rich_text_left_placeholder(1)
|
|
801
|
+
)
|
|
802
|
+
if isinstance(rich_text_left_placeholder, tuple):
|
|
803
|
+
rich_text_left_placeholder = rich_text_left_placeholder[0]
|
|
804
|
+
rich_text_right_placeholder = (
|
|
805
|
+
self.translate_engine.get_rich_text_right_placeholder(2)
|
|
806
|
+
)
|
|
807
|
+
if isinstance(rich_text_right_placeholder, tuple):
|
|
808
|
+
rich_text_right_placeholder = rich_text_right_placeholder[0]
|
|
809
|
+
|
|
810
|
+
# Create a structured prompt template for LLM translation
|
|
811
|
+
llm_input.append(
|
|
812
|
+
f'1. Do not translate style tags, such as "{rich_text_left_placeholder}xxx{rich_text_right_placeholder}"!'
|
|
813
|
+
)
|
|
814
|
+
|
|
815
|
+
formula_placeholder = self.translate_engine.get_formular_placeholder(3)
|
|
816
|
+
if isinstance(formula_placeholder, tuple):
|
|
817
|
+
formula_placeholder = formula_placeholder[0]
|
|
818
|
+
|
|
819
|
+
llm_input.append(
|
|
820
|
+
f'2. Do not translate formula placeholders, such as "{formula_placeholder}". The system will automatically replace the placeholders with the corresponding formulas.'
|
|
821
|
+
)
|
|
822
|
+
llm_input.append(
|
|
823
|
+
"3. If there is no need to translate (such as proper nouns, codes, etc.), then return the original text."
|
|
824
|
+
)
|
|
825
|
+
llm_input.append(
|
|
826
|
+
"4. Only output the translation result without explanations and annotations."
|
|
827
|
+
)
|
|
828
|
+
llm_input.append(f"5. Translate text into {self.translation_config.lang_out}.")
|
|
772
829
|
prompt_template = f"""
|
|
773
|
-
|
|
830
|
+
Now, please carefully read the following text to be translated and directly output your translation.\n\n{text}
|
|
774
831
|
|
|
775
832
|
"""
|
|
776
833
|
llm_input.append(prompt_template)
|
|
@@ -177,7 +177,7 @@ class ILTranslatorLLMOnly:
|
|
|
177
177
|
copy.deepcopy(paragraph)
|
|
178
178
|
)
|
|
179
179
|
|
|
180
|
-
if total_token_count >
|
|
180
|
+
if total_token_count > 200 or len(paragraphs) > 10:
|
|
181
181
|
executor.submit(
|
|
182
182
|
self.translate_paragraph,
|
|
183
183
|
BatchParagraph(paragraphs, tracker),
|
|
@@ -265,24 +265,57 @@ class ILTranslatorLLMOnly:
|
|
|
265
265
|
llm_input = [self.translation_config.custom_system_prompt]
|
|
266
266
|
else:
|
|
267
267
|
llm_input = [
|
|
268
|
-
"You are a professional
|
|
268
|
+
f"You are a professional and reliable machine translation engine responsible for translating the input text into {self.translation_config.lang_out}."
|
|
269
269
|
]
|
|
270
270
|
|
|
271
|
+
llm_hint = []
|
|
271
272
|
if title_paragraph:
|
|
272
|
-
|
|
273
|
+
llm_hint.append(
|
|
273
274
|
f"The first title in the full text: {title_paragraph.unicode}"
|
|
274
275
|
)
|
|
275
276
|
if (
|
|
276
277
|
local_title_paragraph
|
|
277
278
|
and local_title_paragraph.debug_id != title_paragraph.debug_id
|
|
278
279
|
):
|
|
279
|
-
|
|
280
|
+
llm_hint.append(
|
|
280
281
|
f"The most similar title in the full text: {local_title_paragraph.unicode}"
|
|
281
282
|
)
|
|
283
|
+
|
|
284
|
+
if llm_hint:
|
|
285
|
+
llm_input.append(
|
|
286
|
+
"When translating, please refer to the following information to improve translation quality:"
|
|
287
|
+
)
|
|
288
|
+
for i, line in enumerate(llm_hint):
|
|
289
|
+
llm_input.append(f"{i}. {line}")
|
|
290
|
+
llm_input.append("When translating, please follow the following rules:")
|
|
291
|
+
# Create a structured prompt template for LLM translation
|
|
292
|
+
rich_text_left_placeholder = (
|
|
293
|
+
self.translate_engine.get_rich_text_left_placeholder(1)
|
|
294
|
+
)
|
|
295
|
+
if isinstance(rich_text_left_placeholder, tuple):
|
|
296
|
+
rich_text_left_placeholder = rich_text_left_placeholder[0]
|
|
297
|
+
rich_text_right_placeholder = (
|
|
298
|
+
self.translate_engine.get_rich_text_right_placeholder(2)
|
|
299
|
+
)
|
|
300
|
+
if isinstance(rich_text_right_placeholder, tuple):
|
|
301
|
+
rich_text_right_placeholder = rich_text_right_placeholder[0]
|
|
302
|
+
llm_input.append(
|
|
303
|
+
f'1. Do not translate style tags, such as "{rich_text_left_placeholder}xxx{rich_text_right_placeholder}"!'
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
formula_placeholder = self.translate_engine.get_formular_placeholder(3)
|
|
307
|
+
if isinstance(formula_placeholder, tuple):
|
|
308
|
+
formula_placeholder = formula_placeholder[0]
|
|
309
|
+
llm_input.append(
|
|
310
|
+
f'2. Do not translate formula placeholders, such as "{formula_placeholder}". The system will automatically replace the placeholders with the corresponding formulas.'
|
|
311
|
+
)
|
|
312
|
+
llm_input.append(
|
|
313
|
+
"3. If there is no need to translate (such as proper nouns, codes, etc.), then return the original text."
|
|
314
|
+
)
|
|
282
315
|
# Create a structured prompt template for LLM translation
|
|
283
316
|
prompt_template = (
|
|
284
317
|
f"""
|
|
285
|
-
You will be given a JSON formatted input containing entries with "id" and "input" fields.
|
|
318
|
+
4. You will be given a JSON formatted input containing entries with "id" and "input" fields.
|
|
286
319
|
|
|
287
320
|
For each entry in the JSON, translate the contents of the "input" field into {self.translation_config.lang_out}.
|
|
288
321
|
Write the translation back into the "output" field for that entry.
|
|
@@ -318,16 +351,6 @@ class ILTranslatorLLMOnly:
|
|
|
318
351
|
"""
|
|
319
352
|
)
|
|
320
353
|
llm_input.append(prompt_template)
|
|
321
|
-
llm_input.append(
|
|
322
|
-
f'Please do not translate style tags like "{self.translate_engine.get_rich_text_left_placeholder(1)}xxx{self.translate_engine.get_rich_text_right_placeholder(2)}"!'
|
|
323
|
-
)
|
|
324
|
-
llm_input.append(
|
|
325
|
-
f'Please do not translate formula placeholders like "{self.translate_engine.get_formular_placeholder(3)}"!'
|
|
326
|
-
)
|
|
327
|
-
if self.translation_config.add_formula_placehold_hint:
|
|
328
|
-
llm_input.append(
|
|
329
|
-
"The system will automatically replace placeholders with corresponding formulas, please do not translate the placeholders!"
|
|
330
|
-
)
|
|
331
354
|
llm_input.append(
|
|
332
355
|
f"""Here is the input:
|
|
333
356
|
|
|
@@ -350,7 +373,10 @@ class ILTranslatorLLMOnly:
|
|
|
350
373
|
|
|
351
374
|
parsed_output = json.loads(llm_output)
|
|
352
375
|
|
|
353
|
-
translation_results = {
|
|
376
|
+
translation_results = {
|
|
377
|
+
item["id"]: item.get("output", item.get("input"))
|
|
378
|
+
for item in parsed_output
|
|
379
|
+
}
|
|
354
380
|
|
|
355
381
|
if len(translation_results) != len(inputs):
|
|
356
382
|
raise Exception(
|
|
@@ -446,6 +472,7 @@ class ILTranslatorLLMOnly:
|
|
|
446
472
|
logger.warning(error_message)
|
|
447
473
|
for llm_translate_tracker in llm_translate_trackers:
|
|
448
474
|
llm_translate_tracker.set_error_message(error_message)
|
|
475
|
+
llm_translate_tracker.set_fallback_to_translate()
|
|
449
476
|
if not should_translate_paragraph:
|
|
450
477
|
should_translate_paragraph = list(
|
|
451
478
|
range(len(batch_paragraph.paragraphs))
|
|
@@ -277,11 +277,14 @@ class OpenAITranslator(BaseTranslator):
|
|
|
277
277
|
logger.exception("Error updating token count")
|
|
278
278
|
|
|
279
279
|
def get_formular_placeholder(self, placeholder_id: int):
|
|
280
|
-
return "{v" + str(placeholder_id) + "}"
|
|
280
|
+
return "{v" + str(placeholder_id) + "}", f"{{\\s*v\\s*{placeholder_id}\\s*}}"
|
|
281
281
|
return "{{" + str(placeholder_id) + "}}"
|
|
282
282
|
|
|
283
283
|
def get_rich_text_left_placeholder(self, placeholder_id: int):
|
|
284
|
-
return
|
|
284
|
+
return (
|
|
285
|
+
f"<style id='{placeholder_id}'>",
|
|
286
|
+
f"<\\s*style\\s*id\\s*=\\s*'\\s*{placeholder_id}\\s*'\\s*>",
|
|
287
|
+
)
|
|
285
288
|
|
|
286
289
|
def get_rich_text_right_placeholder(self, placeholder_id: int):
|
|
287
|
-
return "</style>"
|
|
290
|
+
return "</style>", r"<\s*\/\s*style\s*>"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "BabelDOC"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.41"
|
|
4
4
|
description = "Yet Another Document Translator"
|
|
5
5
|
license = "AGPL-3.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -150,7 +150,7 @@ pythonpath = [".", "src"]
|
|
|
150
150
|
testpaths = ["tests"]
|
|
151
151
|
|
|
152
152
|
[bumpver]
|
|
153
|
-
current_version = "0.3.
|
|
153
|
+
current_version = "0.3.41"
|
|
154
154
|
version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
|
|
155
155
|
|
|
156
156
|
[bumpver.file_patterns]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.40"
|
|
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.3.40 → babeldoc-0.3.41}/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
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/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.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-with-transparent-background.png
RENAMED
|
File without changes
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-big-logo-with-transparent-background.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/docs/images/babeldoc-small-logo-with-transparent-background.png
RENAMED
|
File without changes
|
{babeldoc-0.3.40 → babeldoc-0.3.41}/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
|
|
File without changes
|