BabelDOC 0.3.30__tar.gz → 0.3.32__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 (107) hide show
  1. {babeldoc-0.3.30 → babeldoc-0.3.32}/PKG-INFO +3 -1
  2. {babeldoc-0.3.30 → babeldoc-0.3.32}/README.md +2 -0
  3. babeldoc-0.3.32/babeldoc/__init__.py +1 -0
  4. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/const.py +1 -1
  5. babeldoc-0.3.32/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +8 -0
  6. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/backend/pdf_creater.py +1 -1
  7. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/detect_scanned_file.py +1 -1
  8. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/il_translator_llm_only.py +3 -0
  9. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/paragraph_finder.py +22 -0
  10. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/styles_and_formulas.py +4 -4
  11. babeldoc-0.3.32/babeldoc/document_il/utils/paragraph_helper.py +36 -0
  12. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/high_level.py +13 -0
  13. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/main.py +1 -1
  14. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/pdfinterp.py +41 -1
  15. babeldoc-0.3.32/docs/supported_languages.md +140 -0
  16. {babeldoc-0.3.30 → babeldoc-0.3.32}/mkdocs.yml +1 -0
  17. {babeldoc-0.3.30 → babeldoc-0.3.32}/pyproject.toml +2 -2
  18. {babeldoc-0.3.30 → babeldoc-0.3.32}/uv.lock +1 -1
  19. babeldoc-0.3.30/babeldoc/__init__.py +0 -1
  20. babeldoc-0.3.30/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +0 -3
  21. {babeldoc-0.3.30 → babeldoc-0.3.32}/.cursorignore +0 -0
  22. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
  23. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
  24. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/PULL_REQUEST_TEMPLATE/pr_form.yml +0 -0
  25. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/dependabot.yml +0 -0
  26. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/labels.yml +0 -0
  27. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/release-drafter.yml +0 -0
  28. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/codeql.yml +0 -0
  29. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/docs.yml +0 -0
  30. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/labeler.yml +0 -0
  31. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/lint.yml +0 -0
  32. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/pr-lint.yml +0 -0
  33. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/publish-to-pypi.yml +0 -0
  34. {babeldoc-0.3.30 → babeldoc-0.3.32}/.github/workflows/test.yml +0 -0
  35. {babeldoc-0.3.30 → babeldoc-0.3.32}/.gitignore +0 -0
  36. {babeldoc-0.3.30 → babeldoc-0.3.32}/.pre-commit-config.yaml +0 -0
  37. {babeldoc-0.3.30 → babeldoc-0.3.32}/LICENSE +0 -0
  38. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/assets/assets.py +0 -0
  39. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/assets/embedding_assets_metadata.py +0 -0
  40. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/asynchronize/__init__.py +0 -0
  41. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/converter.py +0 -0
  42. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/__init__.py +0 -0
  43. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/backend/__init__.py +0 -0
  44. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/frontend/__init__.py +0 -0
  45. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/frontend/il_creater.py +0 -0
  46. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/il_version_1.py +0 -0
  47. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/il_version_1.rnc +0 -0
  48. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/il_version_1.rng +0 -0
  49. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/il_version_1.xsd +0 -0
  50. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/__init__.py +0 -0
  51. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/add_debug_information.py +0 -0
  52. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/il_translator.py +0 -0
  53. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/layout_parser.py +0 -0
  54. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/remove_descent.py +0 -0
  55. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/table_parser.py +0 -0
  56. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/midend/typesetting.py +0 -0
  57. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/translator/__init__.py +0 -0
  58. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/translator/cache.py +0 -0
  59. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/translator/translator.py +0 -0
  60. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/atomic_integer.py +0 -0
  61. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/fontmap.py +0 -0
  62. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/layout_helper.py +0 -0
  63. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/priority_thread_pool_executor.py +0 -0
  64. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/style_helper.py +0 -0
  65. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/utils/zstd_helper.py +0 -0
  66. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/document_il/xml_converter.py +0 -0
  67. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/docvision/README.md +0 -0
  68. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/docvision/__init__.py +0 -0
  69. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/docvision/doclayout.py +0 -0
  70. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/docvision/rpc_doclayout.py +0 -0
  71. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/docvision/table_detection/rapidocr.py +0 -0
  72. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/format/office/__init__.py +0 -0
  73. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/progress_monitor.py +0 -0
  74. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/result_merger.py +0 -0
  75. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/split_manager.py +0 -0
  76. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/tools/generate_font_metadata.py +0 -0
  77. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/tools/italic_assistance.py +0 -0
  78. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/tools/italic_recognize_tool.py +0 -0
  79. {babeldoc-0.3.30 → babeldoc-0.3.32}/babeldoc/translation_config.py +0 -0
  80. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/CODE_OF_CONDUCT.md +0 -0
  81. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/CONTRIBUTING.md +0 -0
  82. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/CONTRIBUTOR_REWARD.md +0 -0
  83. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
  84. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
  85. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
  86. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
  87. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
  88. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/README.md +0 -0
  89. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
  90. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
  91. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/README.md +0 -0
  92. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/deploy.sh +0 -0
  93. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-banner.png +0 -0
  94. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
  95. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
  96. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
  97. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
  98. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-big-logo.png +0 -0
  99. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-contributor_reward_example.png +0 -0
  100. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-preview.gif +0 -0
  101. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
  102. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
  103. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/images/babeldoc-small-logo.png +0 -0
  104. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/index.md +0 -0
  105. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/intro-to-pdf-object.md +0 -0
  106. {babeldoc-0.3.30 → babeldoc-0.3.32}/docs/requirements.txt +0 -0
  107. {babeldoc-0.3.30 → babeldoc-0.3.32}/tests/test_translation_config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BabelDOC
3
- Version: 0.3.30
3
+ Version: 0.3.32
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
@@ -88,6 +88,8 @@ PDF scientific paper translation and bilingual comparison library.
88
88
  - Provides a [Python API](#python-api).
89
89
  - Mainly designed to be embedded into other programs, but can also be used directly for simple translation tasks.
90
90
 
91
+ [Supported Language](https://funstory-ai.github.io/BabelDOC/supported_languages/)
92
+
91
93
  ## Preview
92
94
 
93
95
  <div align="center">
@@ -39,6 +39,8 @@ PDF scientific paper translation and bilingual comparison library.
39
39
  - Provides a [Python API](#python-api).
40
40
  - Mainly designed to be embedded into other programs, but can also be used directly for simple translation tasks.
41
41
 
42
+ [Supported Language](https://funstory-ai.github.io/BabelDOC/supported_languages/)
43
+
42
44
  ## Preview
43
45
 
44
46
  <div align="center">
@@ -0,0 +1 @@
1
+ __version__ = "0.3.32"
@@ -3,7 +3,7 @@ import shutil
3
3
  import subprocess
4
4
  from pathlib import Path
5
5
 
6
- __version__ = "0.3.30"
6
+ __version__ = "0.3.32"
7
7
 
8
8
  CACHE_FOLDER = Path.home() / ".cache" / "babeldoc"
9
9
 
@@ -0,0 +1,8 @@
1
+ class ScannedPDFError(Exception):
2
+ def __init__(self, message):
3
+ super().__init__(message)
4
+
5
+
6
+ class ExtractTextError(Exception):
7
+ def __init__(self, message):
8
+ super().__init__(message)
@@ -782,7 +782,7 @@ class PDFCreater:
782
782
  try:
783
783
  doc.xref_set_key(doc[pageno].xref, name, box)
784
784
  except Exception:
785
- logger.error(f"Error restoring media box {name} from PDF")
785
+ logger.debug(f"Error restoring media box {name} from PDF")
786
786
 
787
787
  def write(
788
788
  self, translation_config: TranslationConfig, check_font_exists: bool = False
@@ -130,4 +130,4 @@ class DetectScannedFile:
130
130
  )[:, :, ::-1]
131
131
  before_page_image = cv2.cvtColor(before_page_image, cv2.COLOR_RGB2GRAY)
132
132
  after_page_image = cv2.cvtColor(after_page_image, cv2.COLOR_RGB2GRAY)
133
- return structural_similarity(before_page_image, after_page_image) > 0.9
133
+ return structural_similarity(before_page_image, after_page_image) > 0.98
@@ -16,6 +16,7 @@ from babeldoc.document_il.midend.il_translator import ILTranslator
16
16
  from babeldoc.document_il.midend.il_translator import PageTranslateTracker
17
17
  from babeldoc.document_il.translator.translator import BaseTranslator
18
18
  from babeldoc.document_il.utils.fontmap import FontMapper
19
+ from babeldoc.document_il.utils.paragraph_helper import is_cid_paragraph
19
20
  from babeldoc.document_il.utils.priority_thread_pool_executor import (
20
21
  PriorityThreadPoolExecutor,
21
22
  )
@@ -162,6 +163,8 @@ class ILTranslatorLLMOnly:
162
163
  for paragraph in page.pdf_paragraph:
163
164
  if paragraph.debug_id is None or paragraph.unicode is None:
164
165
  continue
166
+ if is_cid_paragraph(paragraph):
167
+ continue
165
168
  # self.translate_paragraph(paragraph, pbar,tracker.new_paragraph(), page_font_map, page_xobj_font_map)
166
169
  total_token_count += self.calc_token_count(paragraph.unicode)
167
170
  paragraphs.append(paragraph)
@@ -3,16 +3,19 @@ import random
3
3
  import re
4
4
 
5
5
  from babeldoc.document_il import Box
6
+ from babeldoc.document_il import Document
6
7
  from babeldoc.document_il import Page
7
8
  from babeldoc.document_il import PdfCharacter
8
9
  from babeldoc.document_il import PdfLine
9
10
  from babeldoc.document_il import PdfParagraph
10
11
  from babeldoc.document_il import PdfParagraphComposition
11
12
  from babeldoc.document_il import PdfRectangle
13
+ from babeldoc.document_il.babeldoc_exception.BabelDOCException import ExtractTextError
12
14
  from babeldoc.document_il.utils.layout_helper import Layout
13
15
  from babeldoc.document_il.utils.layout_helper import add_space_dummy_chars
14
16
  from babeldoc.document_il.utils.layout_helper import get_char_unicode_string
15
17
  from babeldoc.document_il.utils.layout_helper import is_bullet_point
18
+ from babeldoc.document_il.utils.paragraph_helper import is_cid_paragraph
16
19
  from babeldoc.document_il.utils.style_helper import WHITE
17
20
  from babeldoc.translation_config import TranslationConfig
18
21
 
@@ -132,6 +135,25 @@ class ParagraphFinder:
132
135
  self.process_page(page)
133
136
  pbar.advance()
134
137
 
138
+ total_paragraph_count = 0
139
+ for page in document.page:
140
+ total_paragraph_count += len(page.pdf_paragraph)
141
+ if total_paragraph_count == 0:
142
+ raise ExtractTextError("The document contains no paragraphs.")
143
+
144
+ if self.check_cid_paragraph(document):
145
+ raise ExtractTextError("The document contains too many CID paragraphs.")
146
+
147
+ def check_cid_paragraph(self, doc: Document):
148
+ cid_para_count = 0
149
+ para_total = 0
150
+ for page in doc.page:
151
+ para_total += len(page.pdf_paragraph)
152
+ for para in page.pdf_paragraph:
153
+ if is_cid_paragraph(para):
154
+ cid_para_count += 1
155
+ return cid_para_count / para_total > 0.8
156
+
135
157
  def bbox_overlap(self, bbox1: Box, bbox2: Box) -> bool:
136
158
  return (
137
159
  bbox1.x < bbox2.x2
@@ -529,10 +529,10 @@ class StylesAndFormulas:
529
529
  pattern_text = (
530
530
  r"^("
531
531
  r"|Cambria.*"
532
- r"|EUAlbertina.+"
533
- r"|NimbusRomNo9L.+"
534
- r"|GlosaMath.+"
535
- r"|URWPalladioL.+"
532
+ r"|EUAlbertina.*"
533
+ r"|NimbusRomNo9L.*"
534
+ r"|GlosaMath.*"
535
+ r"|URWPalladioL.*"
536
536
  r"|CMSS.+"
537
537
  r"|Arial.*"
538
538
  r"|TimesNewRoman.*"
@@ -0,0 +1,36 @@
1
+ import logging
2
+ import re
3
+
4
+ from babeldoc.document_il import il_version_1
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ def is_cid_paragraph(paragraph: il_version_1.PdfParagraph):
10
+ chars: list[il_version_1.PdfCharacter] = []
11
+ for composition in paragraph.pdf_paragraph_composition:
12
+ if composition.pdf_line:
13
+ chars.extend(composition.pdf_line.pdf_character)
14
+ elif composition.pdf_same_style_characters:
15
+ chars.extend(composition.pdf_same_style_characters.pdf_character)
16
+ elif composition.pdf_same_style_unicode_characters:
17
+ continue
18
+ # chars.extend(composition.pdf_same_style_unicode_characters.unicode)
19
+ elif composition.pdf_formula:
20
+ chars.extend(composition.pdf_formula.pdf_character)
21
+ elif composition.pdf_character:
22
+ chars.append(composition.pdf_character)
23
+ else:
24
+ logger.error(
25
+ f"Unknown composition type. "
26
+ f"Composition: {composition}. "
27
+ f"Paragraph: {paragraph}. ",
28
+ )
29
+ continue
30
+
31
+ cid_count = 0
32
+ for char in chars:
33
+ if re.match(r"^\(cid:\d+\)$", char.char_unicode):
34
+ cid_count += 1
35
+
36
+ return cid_count > len(chars) * 0.8
@@ -5,6 +5,7 @@ import io
5
5
  import logging
6
6
  import pathlib
7
7
  import shutil
8
+ import struct
8
9
  import threading
9
10
  import time
10
11
  from asyncio import CancelledError
@@ -13,6 +14,7 @@ from typing import Any
13
14
  from typing import BinaryIO
14
15
 
15
16
  import pymupdf
17
+ from pdfminer.cmapdb import IdentityCMap
16
18
  from pdfminer.pdfdocument import PDFDocument
17
19
  from pdfminer.pdfinterp import PDFResourceManager
18
20
  from pdfminer.pdfpage import PDFPage
@@ -49,6 +51,17 @@ from babeldoc.translation_config import TranslateResult
49
51
  from babeldoc.translation_config import TranslationConfig
50
52
  from babeldoc.translation_config import WatermarkOutputMode
51
53
 
54
+
55
+ def decode(_, code: bytes) -> tuple[int, ...]:
56
+ n = len(code) // 2
57
+ if n:
58
+ return struct.unpack_from(f">{n}H", code)
59
+ else:
60
+ return ()
61
+
62
+
63
+ IdentityCMap.decode = decode
64
+
52
65
  logger = logging.getLogger(__name__)
53
66
 
54
67
  TRANSLATE_STAGES = [
@@ -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.3.30"
26
+ __version__ = "0.3.32"
27
27
 
28
28
 
29
29
  def create_parser():
@@ -19,12 +19,15 @@ from pdfminer.pdfinterp import PDFPageInterpreter
19
19
  from pdfminer.pdfinterp import PDFResourceManager
20
20
  from pdfminer.pdfinterp import PDFStackT
21
21
  from pdfminer.pdfpage import PDFPage
22
+ from pdfminer.pdftypes import LITERALS_ASCII85_DECODE
22
23
  from pdfminer.pdftypes import PDFObjRef
24
+ from pdfminer.pdftypes import PDFStream
23
25
  from pdfminer.pdftypes import dict_value
24
26
  from pdfminer.pdftypes import list_value
25
27
  from pdfminer.pdftypes import resolve1
26
28
  from pdfminer.pdftypes import stream_value
27
29
  from pdfminer.psexceptions import PSEOF
30
+ from pdfminer.psexceptions import PSTypeError
28
31
  from pdfminer.psparser import PSKeyword
29
32
  from pdfminer.psparser import PSLiteral
30
33
  from pdfminer.psparser import keyword_name
@@ -33,6 +36,7 @@ from pdfminer.utils import MATRIX_IDENTITY
33
36
  from pdfminer.utils import Matrix
34
37
  from pdfminer.utils import Rect
35
38
  from pdfminer.utils import apply_matrix_pt
39
+ from pdfminer.utils import choplist
36
40
  from pdfminer.utils import mult_matrix
37
41
 
38
42
  from babeldoc.document_il.frontend.il_creater import ILCreater
@@ -47,6 +51,42 @@ def safe_float(o: Any) -> float | None:
47
51
  return None
48
52
 
49
53
 
54
+ class PDFContentParserEx(PDFContentParser):
55
+ def __init__(self, streams: Sequence[object]) -> None:
56
+ super().__init__(streams)
57
+
58
+ def do_keyword(self, pos: int, token: PSKeyword) -> None:
59
+ if token is self.KEYWORD_BI:
60
+ # inline image within a content stream
61
+ self.start_type(pos, "inline")
62
+ elif token is self.KEYWORD_ID:
63
+ try:
64
+ (_, objs) = self.end_type("inline")
65
+ if len(objs) % 2 != 0:
66
+ error_msg = f"Invalid dictionary construct: {objs!r}"
67
+ raise PSTypeError(error_msg)
68
+ d = {literal_name(k): resolve1(v) for (k, v) in choplist(2, objs)}
69
+ eos = b"EI"
70
+ filter_ = d.get("F", None)
71
+ if filter_:
72
+ if isinstance(filter_, PSLiteral):
73
+ filter_ = [filter_]
74
+ if filter_[0] in LITERALS_ASCII85_DECODE:
75
+ eos = b"~>"
76
+ (pos, data) = self.get_inline_data(pos + len(b"ID "), target=eos)
77
+ if eos != b"EI": # it may be necessary for decoding
78
+ data += eos
79
+ obj = PDFStream(d, data)
80
+ self.push((pos, obj))
81
+ if eos == b"EI": # otherwise it is still in the stream
82
+ self.push((pos, self.KEYWORD_EI))
83
+ except PSTypeError:
84
+ if settings.STRICT:
85
+ raise
86
+ else:
87
+ self.push((pos, token))
88
+
89
+
50
90
  class PDFPageInterpreterEx(PDFPageInterpreter):
51
91
  """Processor for the content of a PDF page
52
92
 
@@ -409,7 +449,7 @@ class PDFPageInterpreterEx(PDFPageInterpreter):
409
449
  self.il_creater.on_new_stream()
410
450
  # 重载返回指令流
411
451
  try:
412
- parser = PDFContentParser([stream])
452
+ parser = PDFContentParserEx([stream])
413
453
  except PSEOF:
414
454
  # empty page
415
455
  return
@@ -0,0 +1,140 @@
1
+ # Supported Languages
2
+
3
+ For languages in the table below that do not rely on ligature support, BabelDOC provides good support. For languages that partially rely on ligatures, BabelDOC's translation results can generally meet self-reading needs. For languages that completely rely on ligatures (such as some Indian languages), BabelDOC does not currently support them.
4
+
5
+ We are working hard to develop support for ligatures as soon as possible.
6
+
7
+ | Language | Language Code | Ligature Dependency |
8
+ | :------------------- | :------------ | :------------------ |
9
+ | Simplified Chinese | zh-CN | None |
10
+ | Traditional Chinese | zh-TW | None |
11
+ | Japanese | JP | None |
12
+ | Korean | KR | None |
13
+ | Polish | PL | Partial |
14
+ | Russian | RU | None |
15
+ | Spanish | es | None |
16
+ | Portuguese | pt | None |
17
+ | French | fr | Partial |
18
+ | Malay | ms | None |
19
+ | Indonesian | id | None |
20
+ | Turkmen | tk | None |
21
+ | Filipino (Tagalog) | tl | None |
22
+ | Vietnamese | vi | None |
23
+ | Azerbaijani | az | None |
24
+ | Kazakh (Latin) | kk | None |
25
+ | Kazakh (Cyrillic) | kk | None |
26
+ | German | de | None |
27
+ | Dutch | nl | None |
28
+ | Irish | ga | None |
29
+ | Italian | it | None |
30
+ | Greek | el | None |
31
+ | Swedish | sv | None |
32
+ | Danish | da | None |
33
+ | Norwegian | no | None |
34
+ | Icelandic | is | None |
35
+ | Finnish | fi | None |
36
+ | Ukrainian | uk | None |
37
+ | Czech | cs | None |
38
+ | Romanian | ro | None |
39
+ | Hungarian | hu | None |
40
+ | Slovak | sk | None |
41
+ | Croatian | hr | None |
42
+ | Estonian | et | None |
43
+ | Latvian | lv | None |
44
+ | Lithuanian | lt | None |
45
+ | Belarusian | be | None |
46
+ | Macedonian | mk | None |
47
+ | Albanian | sq | None |
48
+ | Serbian (Cyrillic) | sr | Partial |
49
+ | Serbian (Latin) | sr | Partial |
50
+ | Slovenian | sl | None |
51
+ | Catalan | ca | None |
52
+ | Bulgarian | bg | None |
53
+ | Maltese | mt | None |
54
+ | Swahili | sw | None |
55
+ | Amharic | am | None |
56
+ | Oromo | om | None |
57
+ | Tigrinya | ti | None |
58
+ | Haitian Creole | ht | None |
59
+ | Latin | la | None |
60
+ | Lao | lo | None |
61
+ | Malayalam | ml | None |
62
+ | Gujarati | gu | None |
63
+ | Thai | th | None |
64
+ | Burmese | my | Partial |
65
+ | Tamil | ta | None |
66
+ | Telugu | te | None |
67
+ | Oriya | or | Partial |
68
+ | Armenian | hy | None |
69
+ | Mongolian (Cyrillic) | mn | None |
70
+ | Georgian | ka | None |
71
+ | Khmer | km | None |
72
+ | Bosnian | bs | None |
73
+ | Luxembourgish | lb | None |
74
+ | Moldovan | ro | None |
75
+ | Moldovan (Cyrillic) | ro | None |
76
+ | Romansh | rm | None |
77
+ | Turkish | tr | None |
78
+ | Sinhala | si | None |
79
+ | Uzbek | uz | None |
80
+ | Kyrgyz | ky | None |
81
+ | Tajik | tg | None |
82
+ | Abkhazian | ab | None |
83
+ | Afar | aa | None |
84
+ | Afrikaans | af | None |
85
+ | Akan | ak | None |
86
+ | Aragonese | an | None |
87
+ | Avaric | av | None |
88
+ | Avestan | ae | None |
89
+ | Ewe | ee | None |
90
+ | Aymara | ay | None |
91
+ | Ojibwa | oj | None |
92
+ | Occitan | oc | None |
93
+ | Oriya | or | None |
94
+ | Ossetian | os | None |
95
+ | Pali | pi | None |
96
+ | Bashkir | ba | None |
97
+ | Basque | eu | None |
98
+ | Bambara | bm | None |
99
+ | Breton | br | None |
100
+ | Chamorro | ch | None |
101
+ | Chechen | ce | None |
102
+ | Chuvash | cv | None |
103
+ | Tswana | tn | None |
104
+ | Divehi | dv | None |
105
+ | Ndebele, South | nr | None |
106
+ | Ndonga | ng | None |
107
+ | Faroese | fo | None |
108
+ | Fijian | fj | None |
109
+ | Frisian, Western | fy | None |
110
+ | Fulah | ff | None |
111
+ | Ganda | lg | None |
112
+ | Kongo | kg | None |
113
+ | Kalaallisut | kl | None |
114
+ | Church Slavic | cu | None |
115
+ | Guarani | gn | None |
116
+ | Interlingua | ia | None |
117
+ | Hausa | ha | None |
118
+ | Herero | hz | None |
119
+ | Kikuyu | ki | None |
120
+ | Rundi | rn | None |
121
+ | Kinyarwanda | rw | None |
122
+ | Kirghiz | ky | None |
123
+ | Galician | gl | None |
124
+ | Kanuri | kr | None |
125
+ | Cornish | kw | None |
126
+ | Komi | kv | None |
127
+ | Xhosa | xh | None |
128
+ | Corsican | co | None |
129
+ | Cree | cr | None |
130
+ | Croatian | hr | None |
131
+ | Quechua | qu | None |
132
+ | Kurdish (Latin) | ku | None |
133
+ | Kuanyama | kj | None |
134
+ | Limburgan | li | None |
135
+ | Lingala | ln | None |
136
+ | Manx | gv | None |
137
+ | Malagasy | mg | None |
138
+ | Marshallese | mh | None |
139
+ | Maori | mi | None |
140
+
@@ -132,6 +132,7 @@ not_in_nav: |
132
132
  # Page tree
133
133
  nav:
134
134
  - Home: index.md
135
+ - Supported languages: supported_languages.md
135
136
  - API:
136
137
  - Async Translation API: ImplementationDetails/AsyncTranslate/AsyncTranslate.md
137
138
  - Implementation Details:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "BabelDOC"
3
- version = "0.3.30"
3
+ version = "0.3.32"
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.30"
153
+ current_version = "0.3.32"
154
154
  version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
155
155
 
156
156
  [bumpver.file_patterns]
@@ -48,7 +48,7 @@ wheels = [
48
48
 
49
49
  [[package]]
50
50
  name = "babeldoc"
51
- version = "0.3.30"
51
+ version = "0.3.32"
52
52
  source = { editable = "." }
53
53
  dependencies = [
54
54
  { name = "bitstring" },
@@ -1 +0,0 @@
1
- __version__ = "0.3.30"
@@ -1,3 +0,0 @@
1
- class ScannedPDFError(Exception):
2
- def __init__(self, message):
3
- super().__init__(message)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes