BabelDOC 0.1.6__py3-none-any.whl
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/__init__.py +1 -0
- babeldoc/asynchronize/__init__.py +51 -0
- babeldoc/const.py +7 -0
- babeldoc/converter.py +510 -0
- babeldoc/document_il/__init__.py +43 -0
- babeldoc/document_il/backend/__init__.py +0 -0
- babeldoc/document_il/backend/pdf_creater.py +402 -0
- babeldoc/document_il/frontend/__init__.py +0 -0
- babeldoc/document_il/frontend/il_creater.py +348 -0
- babeldoc/document_il/il_version_1.py +799 -0
- babeldoc/document_il/il_version_1.rnc +141 -0
- babeldoc/document_il/il_version_1.rng +390 -0
- babeldoc/document_il/il_version_1.xsd +235 -0
- babeldoc/document_il/midend/__init__.py +0 -0
- babeldoc/document_il/midend/add_debug_information.py +138 -0
- babeldoc/document_il/midend/il_translator.py +553 -0
- babeldoc/document_il/midend/layout_parser.py +180 -0
- babeldoc/document_il/midend/paragraph_finder.py +452 -0
- babeldoc/document_il/midend/remove_descent.py +168 -0
- babeldoc/document_il/midend/styles_and_formulas.py +701 -0
- babeldoc/document_il/midend/typesetting.py +761 -0
- babeldoc/document_il/translator/__init__.py +0 -0
- babeldoc/document_il/translator/cache.py +145 -0
- babeldoc/document_il/translator/translator.py +267 -0
- babeldoc/document_il/utils/fontmap.py +227 -0
- babeldoc/document_il/utils/layout_helper.py +467 -0
- babeldoc/document_il/utils/style_helper.py +86 -0
- babeldoc/document_il/xml_converter.py +51 -0
- babeldoc/docvision/README.md +0 -0
- babeldoc/docvision/__init__.py +0 -0
- babeldoc/docvision/doclayout.py +278 -0
- babeldoc/docvision/rpc_doclayout.py +162 -0
- babeldoc/high_level.py +468 -0
- babeldoc/main.py +466 -0
- babeldoc/pdfinterp.py +464 -0
- babeldoc/progress_monitor.py +146 -0
- babeldoc/translation_config.py +156 -0
- babeldoc-0.1.6.dist-info/METADATA +283 -0
- babeldoc-0.1.6.dist-info/RECORD +42 -0
- babeldoc-0.1.6.dist-info/WHEEL +4 -0
- babeldoc-0.1.6.dist-info/entry_points.txt +2 -0
- babeldoc-0.1.6.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import shutil
|
|
3
|
+
import tempfile
|
|
4
|
+
import threading
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from babeldoc.const import CACHE_FOLDER
|
|
8
|
+
from babeldoc.docvision.doclayout import DocLayoutModel
|
|
9
|
+
from babeldoc.progress_monitor import ProgressMonitor
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TranslationConfig:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
input_file: str,
|
|
16
|
+
translator,
|
|
17
|
+
lang_in: str,
|
|
18
|
+
lang_out: str,
|
|
19
|
+
font: str | None = None,
|
|
20
|
+
pages: str | None = None,
|
|
21
|
+
output_dir: str | None = None,
|
|
22
|
+
debug: bool = False,
|
|
23
|
+
working_dir: str | None = None,
|
|
24
|
+
no_dual: bool = False,
|
|
25
|
+
no_mono: bool = False,
|
|
26
|
+
formular_font_pattern: str | None = None,
|
|
27
|
+
formular_char_pattern: str | None = None,
|
|
28
|
+
qps: int = 1,
|
|
29
|
+
split_short_lines: bool = False, # 是否将比较短的行强制切分成不同段落,此功能可能会导致糟糕的排版&bug
|
|
30
|
+
short_line_split_factor: float = 0.8, # 切分阈值系数。实际阈值为当前页所有行长度中位数*此系数
|
|
31
|
+
use_rich_pbar: bool = True, # 是否使用 rich 进度条
|
|
32
|
+
progress_monitor: ProgressMonitor | None = None, # progress_monitor
|
|
33
|
+
doc_layout_model=None,
|
|
34
|
+
skip_clean: bool = False,
|
|
35
|
+
dual_translate_first: bool = False,
|
|
36
|
+
):
|
|
37
|
+
self.input_file = input_file
|
|
38
|
+
self.translator = translator
|
|
39
|
+
self.font = font
|
|
40
|
+
self.pages = pages
|
|
41
|
+
self.page_ranges = self._parse_pages(pages) if pages else None
|
|
42
|
+
self.debug = debug
|
|
43
|
+
self.lang_in = lang_in
|
|
44
|
+
self.lang_out = lang_out
|
|
45
|
+
self.no_dual = no_dual
|
|
46
|
+
self.no_mono = no_mono
|
|
47
|
+
self.formular_font_pattern = formular_font_pattern
|
|
48
|
+
self.formular_char_pattern = formular_char_pattern
|
|
49
|
+
self.qps = qps
|
|
50
|
+
self.split_short_lines = split_short_lines
|
|
51
|
+
self.short_line_split_factor = short_line_split_factor
|
|
52
|
+
self.use_rich_pbar = use_rich_pbar
|
|
53
|
+
self.progress_monitor = progress_monitor
|
|
54
|
+
self.skip_clean = skip_clean
|
|
55
|
+
self.dual_translate_first = dual_translate_first
|
|
56
|
+
if progress_monitor:
|
|
57
|
+
if progress_monitor.cancel_event is None:
|
|
58
|
+
progress_monitor.cancel_event = threading.Event()
|
|
59
|
+
if progress_monitor.finish_event is None:
|
|
60
|
+
progress_monitor.finish_event = threading.Event()
|
|
61
|
+
|
|
62
|
+
if working_dir is None:
|
|
63
|
+
if debug:
|
|
64
|
+
working_dir = (
|
|
65
|
+
Path(CACHE_FOLDER) / "working" / Path(input_file).name.split(".")[0]
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
working_dir = tempfile.mkdtemp()
|
|
69
|
+
self.working_dir = working_dir
|
|
70
|
+
self._is_temp_dir = not debug and working_dir.startswith(tempfile.gettempdir())
|
|
71
|
+
|
|
72
|
+
Path(working_dir).mkdir(parents=True, exist_ok=True)
|
|
73
|
+
|
|
74
|
+
if output_dir is None:
|
|
75
|
+
# output_dir = os.path.dirname(input_file)
|
|
76
|
+
output_dir = Path.cwd()
|
|
77
|
+
self.output_dir = output_dir
|
|
78
|
+
|
|
79
|
+
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
|
80
|
+
|
|
81
|
+
if doc_layout_model is None:
|
|
82
|
+
doc_layout_model = DocLayoutModel.load_available()
|
|
83
|
+
self.doc_layout_model = doc_layout_model
|
|
84
|
+
|
|
85
|
+
def get_output_file_path(self, filename):
|
|
86
|
+
return Path(self.output_dir) / filename
|
|
87
|
+
|
|
88
|
+
def get_working_file_path(self, filename):
|
|
89
|
+
return Path(self.working_dir) / filename
|
|
90
|
+
|
|
91
|
+
def _parse_pages(self, pages_str: str | None) -> list[tuple[int, int]] | None:
|
|
92
|
+
"""解析页码字符串,返回页码范围列表
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
pages_str: 形如 "1-,2,-3,4" 的页码字符串
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
包含 (start, end) 元组的列表,其中 -1 表示无限制
|
|
99
|
+
"""
|
|
100
|
+
if not pages_str:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
ranges = []
|
|
104
|
+
for part in pages_str.split(","):
|
|
105
|
+
part = part.strip()
|
|
106
|
+
if "-" in part:
|
|
107
|
+
start, end = part.split("-")
|
|
108
|
+
start = int(start) if start else 1
|
|
109
|
+
end = int(end) if end else -1
|
|
110
|
+
ranges.append((start, end))
|
|
111
|
+
else:
|
|
112
|
+
page = int(part)
|
|
113
|
+
ranges.append((page, page))
|
|
114
|
+
return ranges
|
|
115
|
+
|
|
116
|
+
def should_translate_page(self, page_number: int) -> bool:
|
|
117
|
+
"""判断指定页码是否需要翻译
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
page_number: 页码
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
是否需要翻译该页
|
|
124
|
+
"""
|
|
125
|
+
if not self.page_ranges:
|
|
126
|
+
return True
|
|
127
|
+
|
|
128
|
+
for start, end in self.page_ranges:
|
|
129
|
+
if start <= page_number and (end == -1 or page_number <= end):
|
|
130
|
+
return True
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
def raise_if_cancelled(self):
|
|
134
|
+
if self.progress_monitor:
|
|
135
|
+
self.progress_monitor.raise_if_cancelled()
|
|
136
|
+
|
|
137
|
+
def cancel_translation(self):
|
|
138
|
+
if self.progress_monitor:
|
|
139
|
+
self.progress_monitor.cancel()
|
|
140
|
+
|
|
141
|
+
def __del__(self):
|
|
142
|
+
"""Clean up temporary directory if it was created."""
|
|
143
|
+
if hasattr(self, "_is_temp_dir") and self._is_temp_dir:
|
|
144
|
+
with contextlib.suppress(Exception):
|
|
145
|
+
shutil.rmtree(self.working_dir, ignore_errors=True)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class TranslateResult:
|
|
149
|
+
original_pdf_path: str
|
|
150
|
+
total_seconds: float
|
|
151
|
+
mono_pdf_path: str | None
|
|
152
|
+
dual_pdf_path: str | None
|
|
153
|
+
|
|
154
|
+
def __init__(self, mono_pdf_path: str | None, dual_pdf_path: str | None):
|
|
155
|
+
self.mono_pdf_path = mono_pdf_path
|
|
156
|
+
self.dual_pdf_path = dual_pdf_path
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BabelDOC
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Summary: Yet Another Document Translator
|
|
5
|
+
Project-URL: Homepage, https://github.com/funstory-ai/BabelDOC
|
|
6
|
+
Project-URL: Issues, https://github.com/funstory-ai/BabelDOC/issues
|
|
7
|
+
License-Expression: AGPL-3.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: PDF
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: <3.13,>=3.10
|
|
13
|
+
Requires-Dist: bitstring>=4.3.0
|
|
14
|
+
Requires-Dist: configargparse>=1.7
|
|
15
|
+
Requires-Dist: httpx>=0.27.0
|
|
16
|
+
Requires-Dist: huggingface-hub>=0.27.0
|
|
17
|
+
Requires-Dist: msgpack>=1.1.0
|
|
18
|
+
Requires-Dist: numpy>=2.0.2
|
|
19
|
+
Requires-Dist: onnx>=1.17.0
|
|
20
|
+
Requires-Dist: onnxruntime>=1.16.1
|
|
21
|
+
Requires-Dist: openai>=1.59.3
|
|
22
|
+
Requires-Dist: opencv-python>=4.10.0.84
|
|
23
|
+
Requires-Dist: orjson>=3.10.14
|
|
24
|
+
Requires-Dist: pdfminer-six>=20240706
|
|
25
|
+
Requires-Dist: peewee>=3.17.8
|
|
26
|
+
Requires-Dist: pymupdf>=1.25.1
|
|
27
|
+
Requires-Dist: rich>=13.9.4
|
|
28
|
+
Requires-Dist: toml>=0.10.2
|
|
29
|
+
Requires-Dist: tqdm>=4.67.1
|
|
30
|
+
Requires-Dist: xsdata[cli,lxml,soap]>=24.12
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
<!-- # Yet Another Document Translator -->
|
|
34
|
+
|
|
35
|
+
<div align="center">
|
|
36
|
+
<img src="./docs/images/banner.png" width="320px" alt="YADT"/>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<h2 id="title">BabelDOC</h2>
|
|
40
|
+
|
|
41
|
+
<p>
|
|
42
|
+
<!-- PyPI -->
|
|
43
|
+
<a href="https://pypi.org/project/BabelDOC/">
|
|
44
|
+
<img src="https://img.shields.io/pypi/v/BabelDOC"></a>
|
|
45
|
+
<a href="https://pepy.tech/projects/BabelDOC">
|
|
46
|
+
<img src="https://static.pepy.tech/badge/BabelDOC"></a>
|
|
47
|
+
<!-- <a href="https://github.com/funstory-ai/BabelDOC/pulls">
|
|
48
|
+
<img src="https://img.shields.io/badge/contributions-welcome-green"></a> -->
|
|
49
|
+
<!-- License -->
|
|
50
|
+
<a href="./LICENSE">
|
|
51
|
+
<img src="https://img.shields.io/github/license/funstory-ai/BabelDOC"></a>
|
|
52
|
+
<a href="https://t.me/+Z9_SgnxmsmA5NzBl">
|
|
53
|
+
<img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat-squeare&logo=telegram&logoColor=white"></a>
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
PDF scientific paper translation and bilingual comparison library.
|
|
58
|
+
|
|
59
|
+
- Provides a simple [command line interface](#getting-started).
|
|
60
|
+
- Provides a [Python API](#python-api).
|
|
61
|
+
- Mainly designed to be embedded into other programs, but can also be used directly for simple translation tasks.
|
|
62
|
+
|
|
63
|
+
## Preview
|
|
64
|
+
|
|
65
|
+
<div align="center">
|
|
66
|
+
<img src="./docs/images/preview.gif" width="80%"/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
## Getting Started
|
|
70
|
+
|
|
71
|
+
### Install from PyPI
|
|
72
|
+
|
|
73
|
+
We recommend using the Tool feature of [uv](https://github.com/astral-sh/uv) to install yadt.
|
|
74
|
+
|
|
75
|
+
1. First, you need to refer to [uv installation](https://github.com/astral-sh/uv#installation) to install uv and set up the `PATH` environment variable as prompted.
|
|
76
|
+
|
|
77
|
+
2. Use the following command to install yadt:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
uv tool install --python 3.12 BabelDOC
|
|
81
|
+
|
|
82
|
+
babeldoc --help
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
3. Use the `babeldoc` command. For example:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
babeldoc --bing --files example.pdf
|
|
89
|
+
|
|
90
|
+
# multiple files
|
|
91
|
+
babeldoc --bing --files example1.pdf --files example2.pdf
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Install from Source
|
|
95
|
+
|
|
96
|
+
We still recommend using [uv](https://github.com/astral-sh/uv) to manage virtual environments.
|
|
97
|
+
|
|
98
|
+
1. First, you need to refer to [uv installation](https://github.com/astral-sh/uv#installation) to install uv and set up the `PATH` environment variable as prompted.
|
|
99
|
+
|
|
100
|
+
2. Use the following command to install yadt:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# clone the project
|
|
104
|
+
git clone https://github.com/funstory-ai/BabelDOC
|
|
105
|
+
|
|
106
|
+
# enter the project directory
|
|
107
|
+
cd BabelDOC
|
|
108
|
+
|
|
109
|
+
# install dependencies and run babeldoc
|
|
110
|
+
uv run babeldoc --help
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
3. Use the `uv run babeldoc` command. For example:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv run babeldoc --bing --files example.pdf
|
|
117
|
+
|
|
118
|
+
# multiple files
|
|
119
|
+
uv run babeldoc --bing --files example.pdf --files example2.pdf
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
> [!TIP]
|
|
123
|
+
> The absolute path is recommended.
|
|
124
|
+
|
|
125
|
+
## Advanced Options
|
|
126
|
+
|
|
127
|
+
### Language Options
|
|
128
|
+
|
|
129
|
+
- `--lang-in`, `-li`: Source language code (default: en)
|
|
130
|
+
- `--lang-out`, `-lo`: Target language code (default: zh)
|
|
131
|
+
|
|
132
|
+
> [!TIP]
|
|
133
|
+
> Currently, this project mainly focuses on English-to-Chinese translation, and other scenarios have not been tested yet.
|
|
134
|
+
|
|
135
|
+
### PDF Processing Options
|
|
136
|
+
|
|
137
|
+
- `--files`: One or more file paths to input PDF documents.
|
|
138
|
+
- `--pages`, `-p`: Specify pages to translate (e.g., "1,2,1-,-3,3-5"). If not set, translate all pages
|
|
139
|
+
- `--split-short-lines`: Force split short lines into different paragraphs (may cause poor typesetting & bugs)
|
|
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
|
+
- `--skip-clean`: Skip PDF cleaning step
|
|
142
|
+
- `--dual-translate-first`: Put translated pages first in dual PDF mode (default: original pages first)
|
|
143
|
+
|
|
144
|
+
> [!TIP]
|
|
145
|
+
> - Both `--skip-clean` and `--dual-translate-first` may help improve compatibility with some PDF readers
|
|
146
|
+
> - However, using `--skip-clean` will result in larger file sizes
|
|
147
|
+
|
|
148
|
+
### Translation Service Options
|
|
149
|
+
|
|
150
|
+
- `--qps`: QPS (Queries Per Second) limit for translation service (default: 4)
|
|
151
|
+
- `--ignore-cache`: Ignore translation cache and force retranslation
|
|
152
|
+
- `--no-dual`: Do not output bilingual PDF files
|
|
153
|
+
- `--no-mono`: Do not output monolingual PDF files
|
|
154
|
+
- `--openai`: Use OpenAI for translation (default: False)
|
|
155
|
+
- `--bing`: Use Bing for translation (default: False)
|
|
156
|
+
- `--google`: Use Google Translate for translation (default: False)
|
|
157
|
+
|
|
158
|
+
> [!TIP]
|
|
159
|
+
>
|
|
160
|
+
> 1. You must specify one translation service among `--openai`, `--bing`, `--google`.
|
|
161
|
+
> 2. It is recommended to use models with strong compatibility with OpenAI, such as: `glm-4-flash`, `deepseek-chat`, etc.
|
|
162
|
+
> 3. Currently, it has not been optimized for traditional translation engines like Bing/Google, it is recommended to use LLMs.
|
|
163
|
+
|
|
164
|
+
### OpenAI Specific Options
|
|
165
|
+
|
|
166
|
+
- `--openai-model`: OpenAI model to use (default: gpt-4o-mini)
|
|
167
|
+
- `--openai-base-url`: Base URL for OpenAI API
|
|
168
|
+
- `--openai-api-key`: API key for OpenAI service
|
|
169
|
+
|
|
170
|
+
### Output Control
|
|
171
|
+
|
|
172
|
+
- `--output`, `-o`: Output directory for translated files. If not set, use current working directory.
|
|
173
|
+
- `--debug`, `-d`: Enable debug logging level and export detailed intermediate results in `~/.cache/yadt/working`.
|
|
174
|
+
|
|
175
|
+
### Configuration File
|
|
176
|
+
|
|
177
|
+
- `--config`, `-c`: Configuration file path. Use the TOML format.
|
|
178
|
+
|
|
179
|
+
Example Configuration:
|
|
180
|
+
|
|
181
|
+
```toml
|
|
182
|
+
[babeldoc]
|
|
183
|
+
debug = true
|
|
184
|
+
lang-in = "en-US"
|
|
185
|
+
lang-out = "zh-CN"
|
|
186
|
+
qps = 20
|
|
187
|
+
# this is a comment
|
|
188
|
+
# pages = 4
|
|
189
|
+
openai = true
|
|
190
|
+
openai-model = "SOME_ALSOME_MODEL"
|
|
191
|
+
openai-base-url = "https://example.example/v1"
|
|
192
|
+
openai-api-key = "[KEY]"
|
|
193
|
+
# All other options can also be set in the configuration file.
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Python API
|
|
197
|
+
|
|
198
|
+
You can refer to the example in [main.py](https://github.com/funstory-ai/yadt/blob/main/babeldoc/main.py) to use BabelDOC's Python API.
|
|
199
|
+
|
|
200
|
+
Please note:
|
|
201
|
+
|
|
202
|
+
1. Make sure call `babeldoc.high_level.init()` before using the API
|
|
203
|
+
|
|
204
|
+
2. The current `TranslationConfig` does not fully validate input parameters, so you need to ensure the validity of input parameters
|
|
205
|
+
|
|
206
|
+
## Background
|
|
207
|
+
|
|
208
|
+
There are a lot projects and teams working on to make document editing and translating easier like:
|
|
209
|
+
|
|
210
|
+
- [mathpix](https://mathpix.com/)
|
|
211
|
+
- [Doc2X](https://doc2x.noedgeai.com/)
|
|
212
|
+
- [minerU](https://github.com/opendatalab/MinerU)
|
|
213
|
+
- [PDFMathTranslate](https://github.com/funstory-ai/yadt)
|
|
214
|
+
|
|
215
|
+
There are also some solutions to solve specific parts of the problem like:
|
|
216
|
+
|
|
217
|
+
- [layoutreader](https://github.com/microsoft/unilm/tree/master/layoutreader): the read order of the text block in a pdf
|
|
218
|
+
- [Surya](https://github.com/surya-is/surya): the structure of the pdf
|
|
219
|
+
|
|
220
|
+
This project hopes to promote a standard pipeline and interface to solve the problem.
|
|
221
|
+
|
|
222
|
+
In fact, there are two main stages of a PDF parser or translator:
|
|
223
|
+
|
|
224
|
+
- **Parsing**: A stage of parsing means to get the structure of the pdf such as text blocks, images, tables, etc.
|
|
225
|
+
- **Rendering**: A stage of rendering means to render the structure into a new pdf or other format.
|
|
226
|
+
|
|
227
|
+
For a service like mathpix, it will parse the pdf into a structure may be in a XML format, and then render them using a single column reader order as [layoutreader](https://github.com/microsoft/unilm/tree/master/layoutreader) does. The bad news is that the original structure lost.
|
|
228
|
+
|
|
229
|
+
Some people will use Adobe PDF Parser because it will generate a Word document and it keeps the original structure. But it is somewhat expensive.
|
|
230
|
+
And you know, a pdf or word document is not a good format for reading in mobile devices.
|
|
231
|
+
|
|
232
|
+
We offer an intermediate representation of the results from parser and can be rendered into a new pdf or other format. The pipeline is also a plugin-based system which everybody can add their new model, ocr, renderer, etc.
|
|
233
|
+
|
|
234
|
+
## Roadmap
|
|
235
|
+
|
|
236
|
+
- [ ] Add line support
|
|
237
|
+
- [ ] Add table support
|
|
238
|
+
- [ ] Add cross-page/cross-column paragraph support
|
|
239
|
+
- [ ] More advanced typesetting features
|
|
240
|
+
- [ ] Outline support
|
|
241
|
+
- [ ] ...
|
|
242
|
+
|
|
243
|
+
Our first 1.0 version goal is to finish a translation from [PDF Reference, Version 1.7](https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf) to the following language version:
|
|
244
|
+
|
|
245
|
+
- Simplified Chinese
|
|
246
|
+
- Traditional Chinese
|
|
247
|
+
- Japanese
|
|
248
|
+
- Spanish
|
|
249
|
+
|
|
250
|
+
And meet the following requirements:
|
|
251
|
+
|
|
252
|
+
- layout error less than 1%
|
|
253
|
+
- content loss less than 1%
|
|
254
|
+
|
|
255
|
+
## Known Issues
|
|
256
|
+
|
|
257
|
+
1. Parsing errors in the author and reference sections; they get merged into one paragraph after translation.
|
|
258
|
+
2. Lines are not supported.
|
|
259
|
+
3. Does not support drop caps.
|
|
260
|
+
|
|
261
|
+
## How to Contribute
|
|
262
|
+
|
|
263
|
+
We encourage you to contribute to YADT! Please check out the [CONTRIBUTING](https://github.com/funstory-ai/yadt/blob/main/docs/CONTRIBUTING.md) guide.
|
|
264
|
+
|
|
265
|
+
Everyone interacting in YADT and its sub-projects' codebases, issue trackers, chat rooms, and mailing lists is expected to follow the YADT [Code of Conduct](https://github.com/funstory-ai/yadt/blob/main/docs/CODE_OF_CONDUCT.md).
|
|
266
|
+
|
|
267
|
+
## Acknowledgements
|
|
268
|
+
|
|
269
|
+
- [PDFMathTranslate](https://github.com/Byaidu/PDFMathTranslate)
|
|
270
|
+
- [DocLayout-YOLO](https://github.com/opendatalab/DocLayout-YOLO)
|
|
271
|
+
- [pdfminer](https://github.com/pdfminer/pdfminer.six)
|
|
272
|
+
- [PyMuPDF](https://github.com/pymupdf/PyMuPDF)
|
|
273
|
+
- [Asynchronize](https://github.com/multimeric/Asynchronize/tree/master?tab=readme-ov-file)
|
|
274
|
+
|
|
275
|
+
<h2 id="star_hist">Star History</h2>
|
|
276
|
+
|
|
277
|
+
<a href="https://star-history.com/#funstory-ai/babeldoc&Date">
|
|
278
|
+
<picture>
|
|
279
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date&theme=dark" />
|
|
280
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date" />
|
|
281
|
+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date"/>
|
|
282
|
+
</picture>
|
|
283
|
+
</a>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
babeldoc/__init__.py,sha256=n3oM6B_EMz93NsTI18NNZd-jKFcUPzUkbIKj5VFK5ok,22
|
|
2
|
+
babeldoc/const.py,sha256=u247IzFnLn3tb7W7XmXY8rFv5jIe66s2xZDc8CuEKlk,149
|
|
3
|
+
babeldoc/converter.py,sha256=vVS6pOfYU1is2googvbc-VMyNYZTvj16edizgA_Bwwc,24391
|
|
4
|
+
babeldoc/high_level.py,sha256=WqUvNb09f1_zmuG7CUhDQAllmHueq8YGg1_jGTMhMAA,17121
|
|
5
|
+
babeldoc/main.py,sha256=EHhPhsPnzIPgnozgetVpJEjCUTae8glZ0XcawkAjPNg,14936
|
|
6
|
+
babeldoc/pdfinterp.py,sha256=vXcfJ6FsFEFg9jNTK8UA96V3_pOp-BOI1j2TyT3zGGQ,18713
|
|
7
|
+
babeldoc/progress_monitor.py,sha256=NE70TTBPlk9gQV6TIu88SQiKr_HR-bx3jbUoqF0wxWQ,4890
|
|
8
|
+
babeldoc/translation_config.py,sha256=0yIostif5zTZ8w7ACl65Vw40R4R9tyXWwS19kur2XNU,5412
|
|
9
|
+
babeldoc/asynchronize/__init__.py,sha256=W7KpbxIjg-AZ3epqOgjbs4uolW3RmzdqSiVIZbQxr0M,1802
|
|
10
|
+
babeldoc/document_il/__init__.py,sha256=QGzQfV-GqFU3FWstqHP5okNTKf4JaW6TJBDXmS1xWLw,1569
|
|
11
|
+
babeldoc/document_il/il_version_1.py,sha256=q8TD8h0dNsCFs2oRqrrmiydyFIUL84pveMAm2zcj0nY,16809
|
|
12
|
+
babeldoc/document_il/il_version_1.rnc,sha256=Al2lgyQC1idvaRJnLeIAD7261F9ZrWrrt5_qEZOI9Sc,3603
|
|
13
|
+
babeldoc/document_il/il_version_1.rng,sha256=xaGtcT7ch6JdZQ-o9ZNqP0Zl6BKqUDZCbYbWnq0RrJ8,9809
|
|
14
|
+
babeldoc/document_il/il_version_1.xsd,sha256=yaVEsJohd4JjzIYOiWvFlQRooNRnpPISpyXaGai1QJI,8644
|
|
15
|
+
babeldoc/document_il/xml_converter.py,sha256=7safmkEMU1FyAZwC36a6bRgz6--Ptu0UxjXBxhGzFSw,1775
|
|
16
|
+
babeldoc/document_il/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
babeldoc/document_il/backend/pdf_creater.py,sha256=_AQJsIIDHIznaxubfFEw_P2u8sw6p0BpFzhVsS4kbwc,16893
|
|
18
|
+
babeldoc/document_il/frontend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
babeldoc/document_il/frontend/il_creater.py,sha256=GCvnHVZspFsPlQNmTTwqbnXqm1qi-RyTfJl8OHU5VoY,12530
|
|
20
|
+
babeldoc/document_il/midend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
babeldoc/document_il/midend/add_debug_information.py,sha256=SYgmSMGxWYaSWc_hoS1Zk1aO4MIOIdxEep9rqrr7JGg,4789
|
|
22
|
+
babeldoc/document_il/midend/il_translator.py,sha256=vW9hud3h0bIpNtecpmD_Yw8DgIxPOQaGU56klRU4K5Q,20418
|
|
23
|
+
babeldoc/document_il/midend/layout_parser.py,sha256=rZRX-wl_EG4bet-pivuztu3VaDrYzo08cfQhblRGgIg,6808
|
|
24
|
+
babeldoc/document_il/midend/paragraph_finder.py,sha256=e09R94obb6HO6C603AQnEYZpGndCF8vZG-1LMbwsU8w,16850
|
|
25
|
+
babeldoc/document_il/midend/remove_descent.py,sha256=K2PHPsISTvmU1vW-8Jzhrzc_kNiHl8GmZfToEbBU2O8,6809
|
|
26
|
+
babeldoc/document_il/midend/styles_and_formulas.py,sha256=eK2Me4oSP7EQL-Vg8MDBs3ODJE0XL0xSsm8MHMF_PxM,28367
|
|
27
|
+
babeldoc/document_il/midend/typesetting.py,sha256=ECVlixb7Hj3jLAxx5jSAa7Kwlz1xuBCumfajuHZtB1I,26486
|
|
28
|
+
babeldoc/document_il/translator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
babeldoc/document_il/translator/cache.py,sha256=HIVj3Ec7WEmckUF8ELW6lFjfF42HAPiX3FfMt5OzpEs,4304
|
|
30
|
+
babeldoc/document_il/translator/translator.py,sha256=TcQJboMDU94uRQ-PnutulJCxk0hqpM418t4WKXWQdOo,9232
|
|
31
|
+
babeldoc/document_il/utils/fontmap.py,sha256=Z7D4uIY3Fd0jgYZXS32St8BkOn1WYOWNj976kuStBJI,9055
|
|
32
|
+
babeldoc/document_il/utils/layout_helper.py,sha256=MEe2oVGFdjP2N5VelIUZYF5UFA9pcll9YvlUlPrRK9c,16778
|
|
33
|
+
babeldoc/document_il/utils/style_helper.py,sha256=AHQnTd6O1JZyy4auNgTDxabynxX7p_H8rMf26Jt4PiY,2764
|
|
34
|
+
babeldoc/docvision/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
+
babeldoc/docvision/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
babeldoc/docvision/doclayout.py,sha256=54xLHL6qsUJ9CsbOr0DaIQRQjEWn0eahXpU4NLYxYH8,9008
|
|
37
|
+
babeldoc/docvision/rpc_doclayout.py,sha256=RsycJnpb850-T0_787qVC7ObS1NGApbMMOj82mlzEW4,5098
|
|
38
|
+
babeldoc-0.1.6.dist-info/METADATA,sha256=m8Vs6O7qxcMzZjzYxuSlaqeHWcRvw-xCAyt4vKxNYYo,10388
|
|
39
|
+
babeldoc-0.1.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
40
|
+
babeldoc-0.1.6.dist-info/entry_points.txt,sha256=65vKshdSbjvg1dh1fDsdNwtluWZB54OB6hXH9NihWuE,47
|
|
41
|
+
babeldoc-0.1.6.dist-info/licenses/LICENSE,sha256=AJcaDjGuPz-cOS67fE_68gL7xlKbqWFWBYfhdMCaXsQ,34515
|
|
42
|
+
babeldoc-0.1.6.dist-info/RECORD,,
|