Skip to main content

unmark

Remove pen/pencil markings from a PDF - fully offline. No AI, no network. Your files never leave your machine.

pip install unmark
unmark erase "marked.pdf"            # -> "marked clean.pdf"

erase - the main feature

Strips the markings and hands back a clean PDF. It picks the right path automatically:

  • Digital annotations (marks added in GoodNotes / Preview / Adobe, etc.) → deleted losslessly; the original page is restored exactly, text stays text.
  • Marks baked into a scan → colour ink (red/blue/green pen) is removed by channel-dominance detection that leaves the printed text untouched. Options: --pencil (light-grey graphite), --lines (experimental underline erase).
unmark erase "scan.pdf" out.pdf --pencil     # also remove light pencil
unmark erase "scan.pdf" --sat 10             # remove more colour (may leave less)
unmark erase "notes.pdf" --lossless          # PNG pages instead of JPEG

What erase can and can't do (honest)

mark result
digital annotation ✅ removed perfectly (lossless)
red / blue / green pen ✅ removed; text preserved
light-grey pencil ⚙️ removed with --pencil
dark pen / heavy pencil at the same tone as the print ❌ cannot be removed offline - it carries no colour or brightness difference from the real letters. Only AI or manual erasing gets those.

reflow - experimental

⚠️ Experimental. reflow OCRs the printed text (offline, via RapidOCR) and re-typesets a fresh PDF. On clean, single-column papers it's decent. On dense, two-column, or heavily marked papers it is unreliable - it misreads circled option markers, over-splits questions, and leftover dark handwriting bleeds into the text. Always proofread. Offline OCR simply can't match a vision model on messy scans; that's a hard ceiling, not a bug.

pip install "unmark[ocr]"                     # adds the offline OCR engine
unmark reflow "scan.pdf" --columns 1          # single-column works best
unmark reflow "scan.pdf" --pages 1-4          # limit to some pages

How it works

erase: PyMuPDF renders each page → numpy colour/pencil masking → repackaged as a compact greyscale PDF (or the annotation layer is simply deleted). reflow: colour-clean → split columns → RapidOCR → parse → re-typeset (Story API).

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unmark-0.1.0.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unmark-0.1.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file unmark-0.1.0.tar.gz.

File metadata

  • Download URL: unmark-0.1.0.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for unmark-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d007c8e511bd23a1f132662a99d5ed1a92c1b5c79e77897c5bc9e3b36b995c03
MD5 8fbb1efa6f34a9084da6fe0248bbe0cf
BLAKE2b-256 e4dcf37b022aa8ece0524ebbdf8e0cc612a7edce76c8868f7e26023de9939960

See more details on using hashes here.

File details

Details for the file unmark-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: unmark-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for unmark-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 33bbbbdab49517ddf068b3613e7c75e853f32a109f445896f5076b74136c7226
MD5 8bce2f105721a58f0857e444c4446300
BLAKE2b-256 fa44186f10efa9aafaf852dcaaed35b0062b706a65d3c6b0f7f237444ea81bc2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page