pdf2epub 0.1.1 → 0.1.3
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.
- package/README.md +35 -110
- package/package.json +9 -44
- package/pdf2epub.js +624 -0
- package/LICENSE +0 -22
- package/bin/pdf2epub.js +0 -14
- package/lib/cli.js +0 -134
- package/lib/paths.js +0 -44
- package/lib/python.js +0 -76
- package/lib/setup.js +0 -152
- package/vendor/pdf2epub/LICENSE +0 -9
- package/vendor/pdf2epub/README.md +0 -217
- package/vendor/pdf2epub/UPSTREAM.json +0 -8
- package/vendor/pdf2epub/main.py +0 -118
- package/vendor/pdf2epub/modules/__init__.py +0 -0
- package/vendor/pdf2epub/modules/mark2epub.py +0 -696
- package/vendor/pdf2epub/modules/pdf2md.py +0 -172
- package/vendor/pdf2epub/modules/postprocessing/__init__.py +0 -0
- package/vendor/pdf2epub/modules/postprocessing/prompt.txt +0 -41
- package/vendor/pdf2epub/modules/postprocessing/template.py +0 -177
- package/vendor/pdf2epub/requirements.txt +0 -8
package/README.md
CHANGED
|
@@ -1,130 +1,55 @@
|
|
|
1
|
-
# pdf2epub
|
|
1
|
+
# pdf2epub
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
from the command line with a single `npm install`.
|
|
5
|
-
|
|
6
|
-
pdf2epub converts PDF files to cleanly structured Markdown and EPUB using
|
|
7
|
-
[marker-pdf](https://github.com/datalab-to/marker) for AI layout detection,
|
|
8
|
-
OCR, table and image extraction. The upstream project is written in Python;
|
|
9
|
-
this package bundles a pinned copy of its source and takes care of creating a
|
|
10
|
-
private Python environment for it the first time you run it.
|
|
3
|
+
Convert a PDF into a reflowable EPUB 3 ebook that works on Kindle (via Send-to-Kindle / Calibre), Kobo, Apple Books and other readers.
|
|
11
4
|
|
|
12
5
|
## Install
|
|
13
6
|
|
|
14
7
|
```bash
|
|
15
|
-
npm install
|
|
8
|
+
npm install
|
|
16
9
|
```
|
|
17
10
|
|
|
18
|
-
Requirements:
|
|
19
|
-
|
|
20
|
-
- Node.js 18 or newer
|
|
21
|
-
- Either [uv](https://docs.astral.sh/uv/) (recommended; it fetches Python 3.13 by itself)
|
|
22
|
-
or Python 3.10–3.13 on your `PATH` (`python3.13`, `python3.12`, ...).
|
|
23
|
-
- Disk space and a network connection for the first run: PyTorch and marker-pdf
|
|
24
|
-
(several hundred MB) are installed once, and marker-pdf downloads its models
|
|
25
|
-
from Hugging Face the first time it converts a document.
|
|
26
|
-
|
|
27
11
|
## Usage
|
|
28
12
|
|
|
29
13
|
```bash
|
|
30
|
-
|
|
31
|
-
pdf2epub book.pdf
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
output_path Output directory (default: directory named after the PDF)
|
|
48
|
-
--max-pages INT Maximum number of pages to process
|
|
49
|
-
--start-page INT Page number to start from (requires --max-pages)
|
|
50
|
-
--skip-epub Only create Markdown; no interactive EPUB prompts
|
|
51
|
-
--skip-md Reuse existing Markdown, only build the EPUB
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
EPUB generation asks for metadata (title, author, language, ...) interactively,
|
|
55
|
-
so it needs a terminal. In scripts and CI use `--skip-epub`, or feed the answers
|
|
56
|
-
on stdin: seven metadata prompts (Enter keeps the default) followed by `n` to
|
|
57
|
-
skip the Markdown review step:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
printf 'My Title\nJane Doe\n\n\n\n\n\nn\n' | pdf2epub book.pdf out --skip-md
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Output layout:
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
output_directory/
|
|
67
|
-
└── document_name/
|
|
68
|
-
├── document_name.md
|
|
69
|
-
├── document_name.epub
|
|
70
|
-
├── document_name_metadata.json
|
|
71
|
-
└── images/
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Wrapper commands
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
pdf2epub setup [--force] # create (or recreate) the Python environment now
|
|
78
|
-
pdf2epub info # where things live, which Python, which upstream commit
|
|
79
|
-
pdf2epub clean # delete the Python environment
|
|
80
|
-
pdf2epub --version
|
|
81
|
-
pdf2epub help
|
|
82
|
-
pdf2epub -- --help # anything after "--" goes to upstream untouched
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Environment variables
|
|
86
|
-
|
|
87
|
-
| Variable | Purpose | Default |
|
|
88
|
-
| -------------------- | -------------------------------------------------------------------- | -------------- |
|
|
89
|
-
| `PDF2EPUB_HOME` | Directory holding the Python venv and install state | `~/.pdf2epub` |
|
|
90
|
-
| `PDF2EPUB_PYTHON` | Interpreter to use (a path, or a version like `3.12` when using uv) | auto-detected |
|
|
91
|
-
| `PDF2EPUB_INSTALLER` | `auto` (uv if present, else `venv` + `pip`) or `pip` | `auto` |
|
|
92
|
-
| `HF_HOME` | Hugging Face cache where marker-pdf stores its models | HF default |
|
|
93
|
-
| `TORCH_DEVICE` | Force a device for marker-pdf (`cpu`, `cuda`, `mps`) | auto |
|
|
14
|
+
node pdf2epub.js book.pdf # -> book.epub
|
|
15
|
+
node pdf2epub.js book.pdf -o out.epub -t "Title" -a "Author" -l vi
|
|
16
|
+
node pdf2epub.js book.pdf -c cover.jpg # embed a cover image
|
|
17
|
+
node pdf2epub.js book.pdf --split pages --pages-per-chapter 5
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Option | Description |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `-o, --output <file>` | Output path (default: input name with `.epub`) |
|
|
23
|
+
| `-t, --title <text>` | Override title (default: PDF metadata, then filename) |
|
|
24
|
+
| `-a, --author <text>` | Override author |
|
|
25
|
+
| `-l, --lang <code>` | Language code, e.g. `en`, `vi` (default `en`) |
|
|
26
|
+
| `-c, --cover <image>` | JPG/PNG cover image to embed |
|
|
27
|
+
| `--split <mode>` | `auto`, `outline` (PDF bookmarks), `headings` (font size), `pages` |
|
|
28
|
+
| `--pages-per-chapter <n>` | Pages per chapter in `pages` mode (default 10) |
|
|
29
|
+
| `--keep-headers` | Keep repeating page headers/footers and page numbers |
|
|
30
|
+
| `--font-scale <n>` | Heading detection threshold relative to body font (default 1.15) |
|
|
94
31
|
|
|
95
32
|
## How it works
|
|
96
33
|
|
|
97
|
-
1.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
3. Every invocation then runs `python main.py <your args>` inside that venv.
|
|
103
|
-
Upgrading the npm package to a version with different requirements or a new
|
|
104
|
-
upstream commit triggers a reinstall automatically.
|
|
34
|
+
1. Extracts positioned text from every page with `pdfjs-dist`.
|
|
35
|
+
2. Rebuilds lines and paragraphs from coordinates, joins wrapped lines and undoes end-of-line hyphenation.
|
|
36
|
+
3. Strips running headers, footers and page numbers that repeat across pages.
|
|
37
|
+
4. Detects headings by font size; splits chapters from PDF bookmarks when present.
|
|
38
|
+
5. Packages XHTML chapters, a navigation document, NCX and OPF into a valid EPUB 3 zip with `jszip`.
|
|
105
39
|
|
|
106
|
-
|
|
107
|
-
Linux/Windows and MPS on Apple Silicon. For ROCm or a specific CUDA build,
|
|
108
|
-
reinstall torch inside the venv (`pdf2epub info` shows its location), following
|
|
109
|
-
[pytorch.org/get-started/locally](https://pytorch.org/get-started/locally/).
|
|
40
|
+
## Telemetry
|
|
110
41
|
|
|
111
|
-
|
|
42
|
+
Telemetry is **off by default** — pdf2epub sends nothing unless you opt in. Installing the package sends nothing; there is no install script.
|
|
112
43
|
|
|
113
|
-
|
|
114
|
-
`transformers<5`. Published advisories for transformers 4.x concern loading
|
|
115
|
-
model files or remote code from untrusted sources; pdf2epub only loads the fixed
|
|
116
|
-
marker-pdf models from Hugging Face. Do not point it at untrusted model
|
|
117
|
-
repositories.
|
|
44
|
+
If you set `PDF2EPUB_TELEMETRY=1`, each run sends one ping so the author can see how often pdf2epub is used by AI coding agents (Claude Code, Cursor, Codex, ...) vs. people. Exactly these fields are sent, and nothing else:
|
|
118
45
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
npm test # fast unit tests (no Python required)
|
|
123
|
-
npm run test:e2e # also builds a real venv and runs upstream --help
|
|
124
|
-
npm run sync-upstream -- v1.1.0 # re-vendor a specific upstream ref
|
|
46
|
+
```json
|
|
47
|
+
{ "v": "0.1.3", "agent": "claude-code | cursor | ... | none", "node": "22.x", "os": "darwin" }
|
|
125
48
|
```
|
|
126
49
|
|
|
127
|
-
|
|
50
|
+
No file names, paths, PDF content, hostnames, user IDs — and no IP is stored with the stats. The agent name comes from environment variables the agent sets (e.g. `CLAUDECODE`). When enabled, each run prints a one-line notice to stderr; the request times out after 1.5 s and any failure is ignored.
|
|
51
|
+
|
|
52
|
+
## Limitations
|
|
128
53
|
|
|
129
|
-
|
|
130
|
-
|
|
54
|
+
- Scanned (image-only) PDFs have no text layer. Run OCR first, e.g. `ocrmypdf in.pdf out.pdf`.
|
|
55
|
+
- Images, tables and multi-column layouts are converted to plain text; figures are not embedded.
|
package/package.json
CHANGED
|
@@ -1,52 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf2epub",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"pdf",
|
|
7
|
-
"epub",
|
|
8
|
-
"markdown",
|
|
9
|
-
"pdf2epub",
|
|
10
|
-
"pdf-to-epub",
|
|
11
|
-
"marker-pdf",
|
|
12
|
-
"ocr",
|
|
13
|
-
"ebook",
|
|
14
|
-
"converter",
|
|
15
|
-
"cli"
|
|
16
|
-
],
|
|
17
|
-
"homepage": "https://github.com/overcuriousity/pdf2epub#readme",
|
|
18
|
-
"bugs": "https://github.com/overcuriousity/pdf2epub/issues",
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"author": "dalt4sec",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Convert PDF files to EPUB ebooks",
|
|
5
|
+
"type": "module",
|
|
21
6
|
"bin": {
|
|
22
|
-
"pdf2epub": "
|
|
7
|
+
"pdf2epub": "./pdf2epub.js"
|
|
23
8
|
},
|
|
24
|
-
"files": [
|
|
25
|
-
"bin",
|
|
26
|
-
"lib",
|
|
27
|
-
"vendor",
|
|
28
|
-
"!**/__pycache__",
|
|
29
|
-
"!**/*.pyc",
|
|
30
|
-
"README.md",
|
|
31
|
-
"LICENSE"
|
|
32
|
-
],
|
|
33
9
|
"scripts": {
|
|
34
|
-
"
|
|
35
|
-
"test:e2e": "PDF2EPUB_E2E=1 node --test \"test/*.test.js\"",
|
|
36
|
-
"sync-upstream": "node scripts/sync-upstream.js",
|
|
37
|
-
"prepublishOnly": "npm test"
|
|
38
|
-
},
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": ">=18"
|
|
10
|
+
"start": "node pdf2epub.js"
|
|
41
11
|
},
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"upstream": {
|
|
47
|
-
"repo": "overcuriousity/pdf2epub",
|
|
48
|
-
"ref": "v1.1.0",
|
|
49
|
-
"commit": "5eae669d1c897b4735f369fb2ff4086237db3a81"
|
|
50
|
-
}
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"jszip": "^3.10.1",
|
|
15
|
+
"pdfjs-dist": "^4.10.38"
|
|
51
16
|
}
|
|
52
17
|
}
|