Paper Reader
A local web app to read PDF papers side-by-side with an automatic Chinese (or other-language) translation, powered by pdf2zh.
Features
- Side-by-side panes: original PDF on the left, translated PDF on the right, with synced scrolling.
- Clickable links: internal page jumps and external URLs both work in the rendered view.
- Auto-numbered table of contents: outline panel generated from the PDF's bookmark tree.
- Selectable text layer: copy text from both the original and translated panes.
- Bounded directory browser: serves only files under the configured directory; no path-traversal escapes.
Requirements
- Python >= 3.11
pdf2zh is installed automatically as a dependency.
Install
pipx install paper-reader # once published
# or from a local checkout:
pipx install .
After installing, run paper-reader doctor once to apply two colorspace bug-fix patches to the bundled pdf2zh/pdfminer (without them, color figures may render red). This is idempotent — safe to run repeatedly.
paper-reader doctor
Why is this needed? pdf2zh 1.9.11 (the current release) still ships both colorspace bugs. The
doctorcommand patches them in-place so you do not have to wait for an upstream fix.
Usage
paper-reader [DIR] [options]
- With no
DIR, Paper Reader serves the current working directory. paper-reader ~/papersserves that directory.- Open the URL printed on startup (default: http://127.0.0.1:8733).
- Pass
--opento have the browser open automatically.
Examples:
paper-reader # serve current directory
paper-reader ~/papers # serve ~/papers
paper-reader ~/papers --open # serve ~/papers and open browser
paper-reader --port 9000 # use a different port
Configuration
Settings are resolved in this order (highest priority first):
CLI flag > environment variable > config file > default
The config file location is ~/.config/paper-reader/config.toml (respects XDG_CONFIG_HOME).
| Option | CLI flag | Env var | Default |
|---|---|---|---|
| Browse directory | DIR (positional) |
PAPER_DIR |
current working directory |
| Port | --port |
PAPER_PORT |
8733 |
| Host | --host |
PAPER_HOST |
127.0.0.1 |
| Cache directory | --cache-dir |
PAPER_CACHE |
~/.cache/paper-reader (XDG_CACHE_HOME aware) |
| Source language | --from |
PAPER_FROM |
en |
| Target language | --to |
PAPER_TO |
zh |
| Translation engine | --engine |
PAPER_ENGINE |
google (choices: google, microsoft, mymemory) |
| Concurrency | --concurrency |
PAPER_CONCURRENCY |
3 |
| pdf2zh path | --pdf2zh |
PAPER_PDF2ZH |
auto-discovered |
| Open browser | --open |
(CLI only) | off |
| Config file path | --config |
(CLI only) | ~/.config/paper-reader/config.toml |
Example ~/.config/paper-reader/config.toml
port = 8733
host = "127.0.0.1"
engine = "google"
lang_from = "en"
lang_to = "zh"
concurrency = 4
cache_dir = "~/.cache/paper-reader"
How It Works
Flask serves a pdf.js frontend that renders two PDF panes side-by-side. Translation is performed per-page by invoking the external pdf2zh CLI as a subprocess; translated PDFs are cached so each page is only translated once.
License & Credits
This project is licensed under the MIT License (see LICENSE).
It invokes pdf2zh / PDFMathTranslate (AGPL-3.0) as a separate command-line program via subprocess. This is aggregation, not a derivative work — the Paper Reader source code remains MIT while pdf2zh's AGPL obligations remain with pdf2zh itself.
Metadata
Release files for paper-reader 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| paper_reader-0.1.0.tar.gz | 56.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| paper_reader-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.5 kB
Release files / paper_reader-0.1.0.tar.gz
| Download URL | paper_reader-0.1.0.tar.gz |
|---|---|
| Size | 56.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ce5073b3ca5d0ff4f4f2bc34cec058752267aafaba5f3ae563c08ec55853c3ab
|
|
BLAKE2b-256 checksum How to use checksums |
4d58d800fe99b5ab4e62e64e16585aa31cbcc164f0c1881467ab43580744c97e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / paper_reader-0.1.0-py3-none-any.whl
| Download URL | paper_reader-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8f1d94e75d9552a1b686be37a42040142400d20da1e3c70c842f220c05dbb3cf
|
|
BLAKE2b-256 checksum How to use checksums |
61bf5b21cc49c3a5e9192d14e34b6ff5da9c8b817dc32a3a54e63a59d406e76f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|