kindle-pdf-cropper 0.1.0__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 (24) hide show
  1. kindle_pdf_cropper-0.1.0/LICENSE +21 -0
  2. kindle_pdf_cropper-0.1.0/PKG-INFO +145 -0
  3. kindle_pdf_cropper-0.1.0/README.md +112 -0
  4. kindle_pdf_cropper-0.1.0/pyproject.toml +54 -0
  5. kindle_pdf_cropper-0.1.0/setup.cfg +4 -0
  6. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/__init__.py +3 -0
  7. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/analysis.py +723 -0
  8. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/cli.py +128 -0
  9. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/config.py +87 -0
  10. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/model.py +76 -0
  11. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/output_epub.py +340 -0
  12. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/output_pdf.py +65 -0
  13. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper/pipeline.py +97 -0
  14. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/PKG-INFO +145 -0
  15. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/SOURCES.txt +22 -0
  16. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/dependency_links.txt +1 -0
  17. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/entry_points.txt +2 -0
  18. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/requires.txt +6 -0
  19. kindle_pdf_cropper-0.1.0/src/kindle_pdf_cropper.egg-info/top_level.txt +1 -0
  20. kindle_pdf_cropper-0.1.0/tests/test_analysis.py +92 -0
  21. kindle_pdf_cropper-0.1.0/tests/test_cli.py +41 -0
  22. kindle_pdf_cropper-0.1.0/tests/test_epub.py +94 -0
  23. kindle_pdf_cropper-0.1.0/tests/test_pdf_output.py +74 -0
  24. kindle_pdf_cropper-0.1.0/tests/test_split.py +146 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kindle-pdf-cropper contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.4
2
+ Name: kindle-pdf-cropper
3
+ Version: 0.1.0
4
+ Summary: Auto-crop PDF margins / headers / footers and optionally split pages into Kindle-friendly landscape pages (PDF or EPUB output)
5
+ Author: ygnid
6
+ Maintainer: ygnid
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/ygnid/kindle-pdf-cropper
9
+ Project-URL: Repository, https://github.com/ygnid/kindle-pdf-cropper
10
+ Project-URL: Documentation, https://github.com/ygnid/kindle-pdf-cropper/blob/main/README.md
11
+ Keywords: pdf,kindle,crop,epub,ebook,margins,header,footer,ebook-reader
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Text Processing
23
+ Classifier: Topic :: Text Processing :: Markup :: HTML
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: pymupdf<3,>=1.26.4
28
+ Requires-Dist: numpy>=1.24
29
+ Requires-Dist: pillow>=9.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # kindle-pdf-cropper
35
+
36
+ 自动剪裁 PDF 四周白边与页眉/页脚、为 Kindle 生成阅读优化 PDF/EPUB 的命令行工具。
37
+
38
+ - 剪掉每页四周白边 + 页眉/页脚 + 页码,只保留正文内容;
39
+ - 可选 `--split`:把每页**上下切成两页**,输出**横版**页面,Kindle 横屏阅读字号接近翻倍;
40
+ - **默认(自适应切分)**:不指定重叠参数时,程序自动把切线放在**两行文字之间的空白处**——
41
+ 文字型 PDF 用文本行 bbox 找行间空隙,扫描型 PDF 用图像识别算法找两行之间的空白带——
42
+ 因此**不会切断任何一行**,也不需要重叠区域;
43
+ - 也可以显式指定 `--split-overlap-*` 恢复"中线切分 + 两页重叠"的旧模式;
44
+ - **自适应**文字型与扫描图片型 PDF;输出结果保持原样——文字仍是文字、
45
+ 扫描图仍是扫描图,**文字/公式/表格的排版完全不变**,只做整页剪裁与切分;
46
+ - 输出 **PDF**(文字/矢量/图片保真)或 **EPUB**(固定版式,排版不重排)。
47
+
48
+ 技术选型调研见 [docs/research.md](docs/research.md),算法设计见 [docs/design.md](docs/design.md)。
49
+
50
+ ## 安装
51
+
52
+ 要求 Python ≥ 3.10。
53
+
54
+ ```bash
55
+ cd kindle-pdf-cropper
56
+ python -m venv .venv
57
+ .venv\Scripts\activate # Windows
58
+ # source .venv/bin/activate # Linux / macOS
59
+ pip install -e .
60
+ ```
61
+
62
+ ## 快速开始
63
+
64
+ ```bash
65
+ # 只裁白边和页眉页脚,输出 PDF(默认)
66
+ kindle-crop 书.pdf
67
+
68
+ # 裁切 + 上下切分成横版两页(自适应:切线自动落在两行文字之间的空白处,不切行)
69
+ kindle-crop 书.pdf --split -o out/书_横版
70
+
71
+ # 旧模式:中线切分 + 两页重叠(需要指定重叠参数)
72
+ kindle-crop 书.pdf --split --split-overlap-pt 20 -o out/书_横版
73
+
74
+ # 同时输出 PDF 和 EPUB(自动:文字页=SVG,扫描页=位图)
75
+ kindle-crop 书.pdf --format both -o out/书
76
+
77
+ # 扫描件:调大安全边距、提高 EPUB 位图质量
78
+ kindle-crop 扫描.pdf --padding 10 --epub-dpi 220 --format epub
79
+
80
+ # 调试:把每页的分析叠加图(裁剪框/页眉页脚带/切分框)导出成 PNG
81
+ kindle-crop 书.pdf --debug-dir debug
82
+ ```
83
+
84
+ ## 常用参数
85
+
86
+ | 参数 | 默认 | 说明 |
87
+ | --- | --- | --- |
88
+ | `--format pdf\|epub\|both` | `pdf` | 输出格式 |
89
+ | `--split` | 关 | 每页上下切成两页横版 |
90
+ | `--split-overlap-pt` | —(自适应) | 指定后启用"中线切分+重叠":两页最小重叠(点) |
91
+ | `--split-overlap-ratio` | —(自适应) | 指定后启用"中线切分+重叠":重叠 = max(比例×裁剪高, 最小点数) |
92
+ | `--padding` | `6` | 内容框外保留的安全边距(点) |
93
+ | `--no-header-footer` | 关 | 只裁边距,不删除页眉/页脚/页码 |
94
+ | `--epub-mode image\|svg\|auto` | `auto` | 文字页→SVG,扫描页→位图 |
95
+ | `--epub-dpi` | `200` | EPUB 位图分辨率 |
96
+ | `--epub-image-format jpeg\|png` | `jpeg` | EPUB 位图格式 |
97
+ | `--analysis-dpi` | `144` | 分析用渲染分辨率 |
98
+ | `--debug-dir DIR` | — | 导出每页分析叠加图 |
99
+ | `-o PATH` | 输入名+`_cropped` | 输出路径(`both` 时自动补 `.pdf`/`.epub`) |
100
+
101
+ ## 自适应切分说明(--split)
102
+
103
+ 不指定 `--split-overlap-*` 时,切分线按如下方式自动确定:
104
+
105
+ 1. **文字型 PDF**:取裁剪区内所有文本行 bbox,找出相邻两行之间宽度足够的空白间隙
106
+ (≥ 0.4 × 中位行高),选择**离页面垂直中线最近**的间隙,把切线放在该间隙正中
107
+ ——上一行完整保留在上半页,下一行完整保留在下半页,中间无重叠也不丢内容;
108
+ 2. **扫描型 PDF**:用图像识别算法对裁剪区做**行投影**,找到连续"无墨水行"的空白带
109
+ (行与行之间的空白),取离中线最近的空白带,把切线放在空白带正中;
110
+ 3. 若页面附近不存在可用的空白带(例如旋转 90° 的扫描页、文字带接近满页),
111
+ 退化为在中线处切分,保证上下两页尺寸均衡。
112
+
113
+ 指定 `--split-overlap-*` 后恢复旧模式:在中线切分,两页保留
114
+ `max(比例×裁剪高, 最小点数)` 的重叠,保证中线附近的一行不会显示不全。
115
+
116
+ ## 输出说明
117
+
118
+ - **PDF 输出**:每个输出页的页面尺寸就是裁剪后的尺寸(物理裁剪,而非仅改 CropBox,
119
+ 任何阅读器都稳定显示);文字保持可选中的文字,表格线/公式等矢量、嵌入字体原样保留;
120
+ 目录与元数据保留。
121
+ - **EPUB 输出**:EPUB 是流式重排容器,若要保持排版不变只能用**固定版式**:
122
+ 每页钉死一个 viewport。
123
+ - 文字页 → 内联 **SVG**(文字仍为文字,矢量图形保留);
124
+ - 扫描页 → 整页 **JPEG/PNG 位图**;
125
+ - 若你的阅读器对 SVG/固定版式支持不佳(如部分 Kindle 固件),请用
126
+ `--epub-mode image` 或直接使用 PDF 输出。
127
+
128
+ ## 示例文件
129
+
130
+ `examples/` 下有生成的样例(文字型、扫描型、旋转扫描型):
131
+ 运行 `python tests/make_samples.py text examples/sample_text.pdf` 等重新生成。
132
+
133
+ ## 开发与测试
134
+
135
+ ```bash
136
+ pip install -e .[dev]
137
+ python -m pytest
138
+ ```
139
+
140
+ 测试覆盖:边距/页眉页脚分析、扫描与旋转页、PDF 输出文字保真、切分重叠、
141
+ 自适应切分(文字行间 / 扫描空白带 / 旋转页退避)、EPUB 结构与内容校验、CLI 端到端。
142
+
143
+ ## 许可
144
+
145
+ MIT,见 [LICENSE](LICENSE)。
@@ -0,0 +1,112 @@
1
+ # kindle-pdf-cropper
2
+
3
+ 自动剪裁 PDF 四周白边与页眉/页脚、为 Kindle 生成阅读优化 PDF/EPUB 的命令行工具。
4
+
5
+ - 剪掉每页四周白边 + 页眉/页脚 + 页码,只保留正文内容;
6
+ - 可选 `--split`:把每页**上下切成两页**,输出**横版**页面,Kindle 横屏阅读字号接近翻倍;
7
+ - **默认(自适应切分)**:不指定重叠参数时,程序自动把切线放在**两行文字之间的空白处**——
8
+ 文字型 PDF 用文本行 bbox 找行间空隙,扫描型 PDF 用图像识别算法找两行之间的空白带——
9
+ 因此**不会切断任何一行**,也不需要重叠区域;
10
+ - 也可以显式指定 `--split-overlap-*` 恢复"中线切分 + 两页重叠"的旧模式;
11
+ - **自适应**文字型与扫描图片型 PDF;输出结果保持原样——文字仍是文字、
12
+ 扫描图仍是扫描图,**文字/公式/表格的排版完全不变**,只做整页剪裁与切分;
13
+ - 输出 **PDF**(文字/矢量/图片保真)或 **EPUB**(固定版式,排版不重排)。
14
+
15
+ 技术选型调研见 [docs/research.md](docs/research.md),算法设计见 [docs/design.md](docs/design.md)。
16
+
17
+ ## 安装
18
+
19
+ 要求 Python ≥ 3.10。
20
+
21
+ ```bash
22
+ cd kindle-pdf-cropper
23
+ python -m venv .venv
24
+ .venv\Scripts\activate # Windows
25
+ # source .venv/bin/activate # Linux / macOS
26
+ pip install -e .
27
+ ```
28
+
29
+ ## 快速开始
30
+
31
+ ```bash
32
+ # 只裁白边和页眉页脚,输出 PDF(默认)
33
+ kindle-crop 书.pdf
34
+
35
+ # 裁切 + 上下切分成横版两页(自适应:切线自动落在两行文字之间的空白处,不切行)
36
+ kindle-crop 书.pdf --split -o out/书_横版
37
+
38
+ # 旧模式:中线切分 + 两页重叠(需要指定重叠参数)
39
+ kindle-crop 书.pdf --split --split-overlap-pt 20 -o out/书_横版
40
+
41
+ # 同时输出 PDF 和 EPUB(自动:文字页=SVG,扫描页=位图)
42
+ kindle-crop 书.pdf --format both -o out/书
43
+
44
+ # 扫描件:调大安全边距、提高 EPUB 位图质量
45
+ kindle-crop 扫描.pdf --padding 10 --epub-dpi 220 --format epub
46
+
47
+ # 调试:把每页的分析叠加图(裁剪框/页眉页脚带/切分框)导出成 PNG
48
+ kindle-crop 书.pdf --debug-dir debug
49
+ ```
50
+
51
+ ## 常用参数
52
+
53
+ | 参数 | 默认 | 说明 |
54
+ | --- | --- | --- |
55
+ | `--format pdf\|epub\|both` | `pdf` | 输出格式 |
56
+ | `--split` | 关 | 每页上下切成两页横版 |
57
+ | `--split-overlap-pt` | —(自适应) | 指定后启用"中线切分+重叠":两页最小重叠(点) |
58
+ | `--split-overlap-ratio` | —(自适应) | 指定后启用"中线切分+重叠":重叠 = max(比例×裁剪高, 最小点数) |
59
+ | `--padding` | `6` | 内容框外保留的安全边距(点) |
60
+ | `--no-header-footer` | 关 | 只裁边距,不删除页眉/页脚/页码 |
61
+ | `--epub-mode image\|svg\|auto` | `auto` | 文字页→SVG,扫描页→位图 |
62
+ | `--epub-dpi` | `200` | EPUB 位图分辨率 |
63
+ | `--epub-image-format jpeg\|png` | `jpeg` | EPUB 位图格式 |
64
+ | `--analysis-dpi` | `144` | 分析用渲染分辨率 |
65
+ | `--debug-dir DIR` | — | 导出每页分析叠加图 |
66
+ | `-o PATH` | 输入名+`_cropped` | 输出路径(`both` 时自动补 `.pdf`/`.epub`) |
67
+
68
+ ## 自适应切分说明(--split)
69
+
70
+ 不指定 `--split-overlap-*` 时,切分线按如下方式自动确定:
71
+
72
+ 1. **文字型 PDF**:取裁剪区内所有文本行 bbox,找出相邻两行之间宽度足够的空白间隙
73
+ (≥ 0.4 × 中位行高),选择**离页面垂直中线最近**的间隙,把切线放在该间隙正中
74
+ ——上一行完整保留在上半页,下一行完整保留在下半页,中间无重叠也不丢内容;
75
+ 2. **扫描型 PDF**:用图像识别算法对裁剪区做**行投影**,找到连续"无墨水行"的空白带
76
+ (行与行之间的空白),取离中线最近的空白带,把切线放在空白带正中;
77
+ 3. 若页面附近不存在可用的空白带(例如旋转 90° 的扫描页、文字带接近满页),
78
+ 退化为在中线处切分,保证上下两页尺寸均衡。
79
+
80
+ 指定 `--split-overlap-*` 后恢复旧模式:在中线切分,两页保留
81
+ `max(比例×裁剪高, 最小点数)` 的重叠,保证中线附近的一行不会显示不全。
82
+
83
+ ## 输出说明
84
+
85
+ - **PDF 输出**:每个输出页的页面尺寸就是裁剪后的尺寸(物理裁剪,而非仅改 CropBox,
86
+ 任何阅读器都稳定显示);文字保持可选中的文字,表格线/公式等矢量、嵌入字体原样保留;
87
+ 目录与元数据保留。
88
+ - **EPUB 输出**:EPUB 是流式重排容器,若要保持排版不变只能用**固定版式**:
89
+ 每页钉死一个 viewport。
90
+ - 文字页 → 内联 **SVG**(文字仍为文字,矢量图形保留);
91
+ - 扫描页 → 整页 **JPEG/PNG 位图**;
92
+ - 若你的阅读器对 SVG/固定版式支持不佳(如部分 Kindle 固件),请用
93
+ `--epub-mode image` 或直接使用 PDF 输出。
94
+
95
+ ## 示例文件
96
+
97
+ `examples/` 下有生成的样例(文字型、扫描型、旋转扫描型):
98
+ 运行 `python tests/make_samples.py text examples/sample_text.pdf` 等重新生成。
99
+
100
+ ## 开发与测试
101
+
102
+ ```bash
103
+ pip install -e .[dev]
104
+ python -m pytest
105
+ ```
106
+
107
+ 测试覆盖:边距/页眉页脚分析、扫描与旋转页、PDF 输出文字保真、切分重叠、
108
+ 自适应切分(文字行间 / 扫描空白带 / 旋转页退避)、EPUB 结构与内容校验、CLI 端到端。
109
+
110
+ ## 许可
111
+
112
+ MIT,见 [LICENSE](LICENSE)。
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "kindle-pdf-cropper"
7
+ version = "0.1.0"
8
+ description = "Auto-crop PDF margins / headers / footers and optionally split pages into Kindle-friendly landscape pages (PDF or EPUB output)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "ygnid" }]
14
+ maintainers = [{ name = "ygnid" }]
15
+ keywords = ["pdf", "kindle", "crop", "epub", "ebook", "margins", "header", "footer", "ebook-reader"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Intended Audience :: End Users/Desktop",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3.14",
27
+ "Topic :: Text Processing",
28
+ "Topic :: Text Processing :: Markup :: HTML",
29
+ ]
30
+ dependencies = [
31
+ "pymupdf>=1.26.4,<3",
32
+ "numpy>=1.24",
33
+ "pillow>=9.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = ["pytest>=7"]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/ygnid/kindle-pdf-cropper"
41
+ Repository = "https://github.com/ygnid/kindle-pdf-cropper"
42
+ Documentation = "https://github.com/ygnid/kindle-pdf-cropper/blob/main/README.md"
43
+
44
+ [project.scripts]
45
+ kindle-crop = "kindle_pdf_cropper.cli:main"
46
+
47
+ [tool.setuptools.packages.find]
48
+ where = ["src"]
49
+
50
+ [tool.setuptools]
51
+ include-package-data = true
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """kindle-pdf-cropper: auto-crop PDF margins / headers / footers for Kindle."""
2
+
3
+ __version__ = "0.1.0"