pdf2epub 0.1.2 → 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 CHANGED
@@ -1,141 +1,55 @@
1
- # pdf2epub (npm)
1
+ # pdf2epub
2
2
 
3
- Install and run [overcuriousity/pdf2epub](https://github.com/overcuriousity/pdf2epub)
4
- from the command line with a single `npm i pdf2epub`.
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 i pdf2epub
16
- npx pdf2epub --version
8
+ npm install
17
9
  ```
18
10
 
19
- This adds `pdf2epub` to your project; run it with `npx pdf2epub ...` or from an
20
- npm script. (A global install with `npm i -g pdf2epub` gives you a plain
21
- `pdf2epub` command instead.)
22
-
23
- Requirements:
24
-
25
- - Node.js 18 or newer
26
- - Either [uv](https://docs.astral.sh/uv/) (recommended; it fetches Python 3.13 by itself)
27
- or Python 3.10–3.13 on your `PATH` (`python3.13`, `python3.12`, ...).
28
- - Disk space and a network connection for the first run: PyTorch and marker-pdf
29
- (several hundred MB) are installed once, and marker-pdf downloads its models
30
- from Hugging Face the first time it converts a document.
31
-
32
11
  ## Usage
33
12
 
34
13
  ```bash
35
- # Convert one PDF -> ./book/book.md + ./book/book.epub
36
- npx pdf2epub book.pdf
37
-
38
- # Convert every PDF in a directory into an output directory
39
- npx pdf2epub ./papers ./converted
40
-
41
- # Markdown only (no interactive prompts)
42
- npx pdf2epub thesis.pdf --skip-epub
43
-
44
- # A page range
45
- npx pdf2epub book.pdf --start-page 10 --max-pages 50
46
- ```
47
-
48
- Or as an npm script in `package.json`:
49
-
50
- ```json
51
- { "scripts": { "convert": "pdf2epub ./input ./output --skip-epub" } }
52
- ```
53
-
54
- All arguments are passed straight through to upstream's `main.py`:
55
-
56
- ```
57
- input_path PDF file or directory (default: ./input/*.pdf)
58
- output_path Output directory (default: directory named after the PDF)
59
- --max-pages INT Maximum number of pages to process
60
- --start-page INT Page number to start from (requires --max-pages)
61
- --skip-epub Only create Markdown; no interactive EPUB prompts
62
- --skip-md Reuse existing Markdown, only build the EPUB
63
- ```
64
-
65
- EPUB generation asks for metadata (title, author, language, ...) interactively,
66
- so it needs a terminal. In scripts and CI use `--skip-epub`, or feed the answers
67
- on stdin: seven metadata prompts (Enter keeps the default) followed by `n` to
68
- skip the Markdown review step:
69
-
70
- ```bash
71
- printf 'My Title\nJane Doe\n\n\n\n\n\nn\n' | npx pdf2epub book.pdf out --skip-md
72
- ```
73
-
74
- Output layout:
75
-
76
- ```
77
- output_directory/
78
- └── document_name/
79
- ├── document_name.md
80
- ├── document_name.epub
81
- ├── document_name_metadata.json
82
- └── images/
83
- ```
84
-
85
- ### Wrapper commands
86
-
87
- ```bash
88
- npx pdf2epub setup [--force] # create (or recreate) the Python environment now
89
- npx pdf2epub info # where things live, which Python, which upstream commit
90
- npx pdf2epub clean # delete the Python environment
91
- npx pdf2epub --version
92
- npx pdf2epub help
93
- npx pdf2epub -- --help # anything after "--" goes to upstream untouched
94
- ```
95
-
96
- ### Environment variables
97
-
98
- | Variable | Purpose | Default |
99
- | -------------------- | -------------------------------------------------------------------- | -------------- |
100
- | `PDF2EPUB_HOME` | Directory holding the Python venv and install state | `~/.pdf2epub` |
101
- | `PDF2EPUB_PYTHON` | Interpreter to use (a path, or a version like `3.12` when using uv) | auto-detected |
102
- | `PDF2EPUB_INSTALLER` | `auto` (uv if present, else `venv` + `pip`) or `pip` | `auto` |
103
- | `HF_HOME` | Hugging Face cache where marker-pdf stores its models | HF default |
104
- | `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) |
105
31
 
106
32
  ## How it works
107
33
 
108
- 1. `npm i pdf2epub` installs a small Node CLI plus the upstream Python
109
- source pinned to a specific commit (see `vendor/pdf2epub/UPSTREAM.json`).
110
- 2. On first use (or `npx pdf2epub setup`) the CLI creates a virtual environment in
111
- `PDF2EPUB_HOME` with uv or `python -m venv` and installs upstream's
112
- `requirements.txt` (marker-pdf, transformers, PyTorch, ...).
113
- 3. Every invocation then runs `python main.py <your args>` inside that venv.
114
- Upgrading the npm package to a version with different requirements or a new
115
- 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`.
116
39
 
117
- GPU acceleration follows upstream: the default PyTorch wheel supports CUDA on
118
- Linux/Windows and MPS on Apple Silicon. For ROCm or a specific CUDA build,
119
- reinstall torch inside the venv (`npx pdf2epub info` shows its location), following
120
- [pytorch.org/get-started/locally](https://pytorch.org/get-started/locally/).
40
+ ## Telemetry
121
41
 
122
- ## Security notes
42
+ Telemetry is **off by default** — pdf2epub sends nothing unless you opt in. Installing the package sends nothing; there is no install script.
123
43
 
124
- Upstream pins `transformers==4.57.6` because `marker-pdf 1.10.2` requires
125
- `transformers<5`. Published advisories for transformers 4.x concern loading
126
- model files or remote code from untrusted sources; pdf2epub only loads the fixed
127
- marker-pdf models from Hugging Face. Do not point it at untrusted model
128
- 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:
129
45
 
130
- ## Development
131
-
132
- ```bash
133
- npm test # fast unit tests (no Python required)
134
- npm run test:e2e # also builds a real venv and runs upstream --help
135
- 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" }
136
48
  ```
137
49
 
138
- ## License
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
139
53
 
140
- MIT. The bundled pdf2epub source is © overcuriousity, MIT licensed
141
- (`vendor/pdf2epub/LICENSE`).
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.2",
4
- "description": "CLI wrapper that installs and runs overcuriousity/pdf2epub: convert PDF files to structured Markdown and EPUB with AI layout detection (marker-pdf). Bootstraps its own Python environment on first run.",
5
- "keywords": [
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": "bin/pdf2epub.js"
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
- "test": "node --test \"test/*.test.js\"",
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
- "publishConfig": {
43
- "access": "public"
44
- },
45
- "pdf2epub": {
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
  }