Turn long foreign-language PDFs into page-aware reading notes.
No cloud lock-in. No extra translation subscription. Use the AI you already pay for.
OpenLongPDF Translator is a local-first workflow for reading long foreign-language PDFs with the AI tool you already use. It extracts text from text-layer PDFs, keeps page numbers, splits long documents into translation packs, gives you a local browser GUI for ChatGPT Web/App workflows, captures ChatGPT replies through a visible user-started helper, imports translated chunks, and assembles Markdown and HTML reading notes. A paid OpenAI-compatible API mode is available, but the primary route does not require API keys.
pip install -e .For development with uv:
uv run openlongpdf --helpopenlongpdf run book.pdf --target-language Japaneserun prepares the PDF, calculates a conservative safe pack size, generates prompt packs, and starts the local GUI.
In the GUI:
- Install the Chrome extension once from
extension/if you have not already. - Click
Start ChatGPT Translation. - Confirm once in the OpenLongPDF panel on ChatGPT.
After that one-time consent, the helper sends each remaining pack, waits for ChatGPT to finish, captures the new assistant response from the visible page, posts it to the local GUI, imports the marked translated chunks, and runs assemble when all packs are imported.
This route uses your existing ChatGPT Plus/Pro browser session. OpenLongPDF does not store credentials, cookies, access tokens, or session data.
openlongpdf prepare book.pdf --pages-per-chunk 10 --target-language Japanese
openlongpdf gui book_openlongpdfThe GUI opens a local browser page where you can:
- generate multi-chunk packs,
- copy a pack to the clipboard,
- install a ChatGPT-side Chrome extension helper,
- send one queued pack, or auto-send/capture/import/assemble remaining queued packs from the ChatGPT page,
- see pack progress: pending, sent, imported, and failed,
- retry a failed pack or reset assist state,
- paste/import responses manually if automatic capture fails,
- assemble the final reading notes manually.
The GUI does not store ChatGPT credentials, cookies, access tokens, or session data. Browser Assist is optional and visible: it runs only after you open ChatGPT through the local GUI or fallback bookmarklet and confirm the auto session. Browser Assist still does not store credentials, cookies, tokens, or session data. It may stop if ChatGPT changes its page structure.
openlongpdf prepare book.pdf --pages-per-chunk 10
openlongpdf queue book_openlongpdf --write
openlongpdf pack-plan book_openlongpdf
openlongpdf pack book_openlongpdf --auto
openlongpdf copy-pack book_openlongpdf pack_001 --open chatgpt
# Paste/send the copied pack text in ChatGPT, then save the answer.
openlongpdf import book_openlongpdf book_openlongpdf/output/pack_responses/pack_001_response.md
openlongpdf status book_openlongpdf
openlongpdf assemble book_openlongpdfThis creates:
source_chunks/prompts/translated_chunks/output/packs/output/pack_responses/output/reading_note.mdoutput/index.htmlstatus.jsonmanifest.md
Pack-based paste assistance is the first-class long-document workflow:
openlongpdf prepare book.pdfopenlongpdf queue book_openlongpdf --writeopenlongpdf pack-plan book_openlongpdfopenlongpdf pack book_openlongpdf --auto- Review
output/translation_packs.mdto see every pack file and response save path. openlongpdf copy-pack book_openlongpdf pack_NNN --open chatgpt- Paste/send the copied pack text in ChatGPT, Claude, Gemini, DeepL, or another translator.
- Save each translated answer to the suggested
output/pack_responses/pack_NNN_response.mdpath. openlongpdf import book_openlongpdf book_openlongpdf/output/pack_responses/pack_NNN_response.md- Repeat by pack until
openlongpdf status book_openlongpdfshows no remaining chunks. openlongpdf assemble book_openlongpdf
For long documents, inspect the whole queue first:
openlongpdf queue book_openlongpdf
openlongpdf queue book_openlongpdf --write
openlongpdf queue book_openlongpdf --allcopy-pack ... --open chatgpt copies a full prompt pack and opens ChatGPT. next --copy --open chatgpt does the same for one-chunk fallback. On WSL/Linux, clipboard support prefers PowerShell Set-Clipboard before clip.exe so non-ASCII text such as Cyrillic, Japanese, and accented Latin characters survives the Windows clipboard boundary. On macOS, OpenLongPDF uses pbcopy/pbpaste for clipboard access and open for browser launching when available. The WSL Unicode-safe guidance remains unchanged. Browser opening tries cmd.exe /c start, wslview, xdg-open, and other safe local openers. If those tools are unavailable, OpenLongPDF prints paths and errors without storing credentials or scraping websites.
queue lists every remaining prompt file and the matching translated chunk target. --write creates output/translation_queue.md as a checklist so a 30+ chunk workload is visible before you start copying prompts.
For long PDFs where the safe pack size is small, use the GUI's Browser Assist to avoid copy/paste round trips:
openlongpdf gui book_openlongpdfIn the local GUI:
- Generate packs.
- Install the Chrome extension once:
- open
chrome://extensions - enable Developer mode
- choose
Load unpacked - select this repository's
extension/directory
- open
- Open
Browser Assist. - Click
Start Translation In ChatGPT. - Use
Send next packfor one pack, orAuto translate allfor the full remaining queue.
If installing the extension is not possible, Browser Assist also keeps an advanced bookmarklet fallback. The fallback has the same automation logic, but it is harder to explain to non-technical users.
The helper fetches queued pack text from the local GUI, records the current assistant-message state, fills the ChatGPT composer, clicks send, waits for the response to finish, extracts the newly visible assistant response, and posts it to POST /assist/import-response on the local GUI. The GUI saves the raw response under output/pack_responses/, imports marked translated chunk blocks into translated_chunks/, updates output/assist_state.json, and runs assemble automatically after all packs are imported.
Automatic capture uses fallback DOM selectors including [data-message-author-role="assistant"], article, .markdown, and text fallback. This is intentionally a visible browser helper, not ChatGPT scraping in the background. ChatGPT DOM changes can break capture. If capture or import fails, the GUI marks the pack as failed, stores the failed response as output/pack_responses/<pack>_failed_response.md when available, and shows the failed pack/error so you can retry from the GUI.
output/assist_state.json tracks each pack as:
pendingsendingsentimportedfailed
On resume, imported packs are skipped. Failed packs stop auto-run until you use Retry failed pack or Reset assist state in the GUI.
If a WSL path contains spaces or non-ASCII characters, prefer command variables or tab completion instead of retyping the path. For example:
WIN_HOME="$(wslpath "$(powershell.exe -NoProfile -Command '[Environment]::GetFolderPath("UserProfile")' | tr -d '\r')")"
PROJECT="$(find "$WIN_HOME/Downloads" -maxdepth 1 -type d -name '*openlongpdf' | head -n 1)"
openlongpdf pack-plan "$PROJECT"
openlongpdf pack "$PROJECT" --autoFor one-chunk-at-a-time fallback:
openlongpdf next book_openlongpdf --copy --open chatgpt
# Paste/send the prompt, copy the translated answer, then:
openlongpdf paste book_openlongpdfFor long PDFs, generate fewer larger prompt files:
openlongpdf pack-plan book_openlongpdf
openlongpdf pack book_openlongpdf --autopack-plan measures the remaining chunks and recommends a conservative pack size for ChatGPT-style web/app output. pack --auto uses that recommendation. The defaults keep each pack near or below 40,000 prompt characters and 40,000 source characters, because output truncation is usually the limiting factor. You can still override the result:
openlongpdf pack book_openlongpdf --chunks-per-pack 3This writes the pack index and prompt files, and the index suggests response save paths:
output/translation_packs.mdoutput/packs/pack_001.mdoutput/packs/pack_002.mdoutput/pack_responses/pack_001_response.mdas the suggested save path for the translated answer
Copy a pack to the clipboard with:
openlongpdf copy-pack book_openlongpdf pack_001 --open chatgptDo not use cat output/packs/pack_001.md | clip.exe on WSL for Cyrillic or other non-ASCII documents; it can produce mojibake. Use copy-pack, which uses the Unicode-safe clipboard route when PowerShell is available.
Each pack asks the translator to return marked blocks:
--- BEGIN TRANSLATED CHUNK chunk_001 ---
translated notes
--- END TRANSLATED CHUNK chunk_001 ---
After saving a translator response, import all translated chunks in that response at once:
openlongpdf import book_openlongpdf book_openlongpdf/output/pack_responses/pack_001_response.mdimport refuses to overwrite existing translated chunks unless --overwrite is provided. This keeps manual ChatGPT/DeepL-style workflows explicit while avoiding one command per chunk.
For users with API access:
export OPENAI_API_KEY=...
openlongpdf prepare book.pdf --pages-per-chunk 10 --target-language Japanese
openlongpdf translate book_openlongpdf --model your-paid-model
# Review the planned chunk count and prompt size, then run:
openlongpdf translate book_openlongpdf --model your-paid-model --yes
openlongpdf assemble book_openlongpdftranslate sends each missing chunk to an OpenAI-compatible /chat/completions API, saves every response immediately into translated_chunks/, and skips chunks that are already translated. It refuses to call the paid API until --yes is provided. By default it reads the API key from OPENAI_API_KEY; use --api-key-env and --base-url for another compatible provider.
ChatGPT Plus/Pro website subscriptions are not API credentials. The primary Browser Assist route uses your logged-in ChatGPT browser session and does not need an API key. The separate translate command requires a provider API key and may incur API charges.
OpenLongPDF is not a translation model and is not a cloud translation service. It does not implement OCR, a hosted web app, a native app, user accounts, billing, cloud storage, or PDF regeneration. It does not store credentials, cookies, access tokens, or session data.
API-based auto-translation uses provider API keys from environment variables. Browser Assist is a visible user-started helper for an already logged-in ChatGPT tab; it does not authenticate against ChatGPT Web accounts or reuse browser subscriptions as API credentials.
Only process documents you have the right to read or use. Do not publish translated copyrighted works without permission. Public demos and tests should use public-domain or synthetic documents, not copyrighted translated books.
- OCR for scanned PDFs
- Token-aware chunking
- Glossary support
- Provider-specific cost estimates
- Better HTML reader