Skip to content

How It Works

Retro-Jack edited this page Aug 6, 2026 · 1 revision

How It Works

Three steps, with a pause between each.

Step 1 — Copy to staging

PDFs are copied from INPUT_DIR to STAGING_DIR, preserving their paths relative to the input root, so a nested layout survives the trip. Name collisions are suffixed rather than overwritten: name(1).pdf, name(2).pdf, and so on.

Two cases skip the copy:

  • Input folder empty — whatever is already staged is converted instead.
  • Staging already holds PDFs — you're asked first, since the usual reason for a non-empty staging folder is an interrupted earlier run.

Files whose basename matches EXCLUDED_BASENAMES (e.g. sample.pdf) are never picked up.

Step 2 — Convert

One container per PDF. The important parts of how it's invoked:

Flag Why
--user $(id -u):$(id -g) Container writes as you, so the output tree isn't root-owned
-e HOME=/models Anything reaching for ~/.cache lands somewhere writable
-v STAGING:/data/input:ro Source tree is read-only, so nothing can be written beside the source
-v OUTPUT:/data/output The only writable mount
-v MODEL_CACHE:/models Models persist between runs
--memory, timeout Caps a runaway conversion locally

Skip detection

Before converting, the script looks for an existing result and skips the document if it finds one — *.epub in EPUB mode, *.md in Markdown-only mode, so switching modes converts again rather than falsely reporting the work as done.

It checks two candidate folders: the document's original name, and the name step 3 would have given it. Both have to be checked, because a document converted on an earlier run is now sitting under its tidied name — miss that and every subsequent run re-converts everything and then fails to rename the result, leaving two copies of each document.

When something goes wrong

A timeout, a non-zero exit, or a missing result folder each warn and move on to the next document; the batch is never aborted. The missing-folder case also logs what the output root actually contains, because the exact result path is inferred from pdf2epub's documentation rather than guaranteed.

Interrupting the script force-removes the running container and deletes the partially written result folder — the deletion is guarded so it can only ever remove a subdirectory of OUTPUT_DIR, never the root.

Step 3 — Tidy names

Runs only if something was actually converted this run. See Name Tidying.

Clone this wiki locally