Skip to content

About

Extracts highlights, underlines, and notes from a folder of PDFs into a single org-mode file, using pdfannots. Runs automatically via a launchd LaunchAgent whenever the folder changes, with incremental caching, logging, and macOS notifications via terminal-notifier. Works with Preview, pdf-tools, and other annotation sources.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pdf-highlights-to-org

Extracts highlights, underlines, and typed notes from a folder of PDFs into a single org-mode file, automatically, whenever a file in that folder changes.

Why

Apple Books does not reliably expose PDF annotations for export — they live in an internal cache, not in the PDF file or its own annotation database. This tool instead reads the PDF's own annotation objects directly, so it works regardless of which app you used to annotate (Preview on macOS/iOS, pdf-tools in Emacs via poppler, etc.).

How it works

  • pdfannots (MIT, pdfminer.six) does the actual extraction — it recovers the highlighted/underlined text from the annotation's coordinates, since plain highlights don't store their own text.
  • pdf-highlights-to-org.py wraps it: scans a folder, keeps an incremental cache (only reprocesses changed files), writes one org file, logs every run, and sends a macOS notification at the end.
  • A launchd LaunchAgent watches the folder and reruns the script on every change.

Annotation types covered: Highlight, Underline (Preview classifies plain highlighting under this type, not Highlight), Squiggly, StrikeOut, Text (standalone note), FreeText. Both the highlighted text and any attached typed comment are captured separately.

Install

pip3 install pdfannots --break-system-packages
brew install terminal-notifier

Setup

  1. pdf-highlights-to-org.py and update-pdf-highlights-org.sh live in this folder — edit PDF_DIR and ORG_OUT in the latter to match your own setup.
  2. Copy com.example.pdfhighlights.plist to ~/Library/LaunchAgents/, rename it, and replace every YOUR_USERNAME placeholder with your actual paths (launchd plists can't use $HOME).
  3. chmod +x update-pdf-highlights-org.sh
  4. launchctl load ~/Library/LaunchAgents/<your-renamed>.plist

Notifications

Uses terminal-notifier rather than osascript -e 'display notification': the latter is silently dropped by macOS when invoked from a background process with no real Script Editor in the foreground (confirmed against ~/Library/Group Containers/group.com.apple.usernoted/db2/db — such notifications are recorded with presented=0). In System Settings → Notifications, set terminal-notifier's alert style to Banners (auto-dismisses but stays in Notification Center history) rather than Alerts.

Known limitations

  • EPUB files are out of scope (pdfannots only reads PDF).
  • Structurally corrupted PDFs (missing /Root, truncated files, etc.) are logged as errors and skipped, not repaired.
  • iCloud "placeholder" files not yet downloaded locally are not handled explicitly.
  • Large/complex PDFs are capped at a 120s timeout per file.
  • The generated org file is fully regenerated on every run — don't hand-edit it.

License

MIT for this glue code. pdfannots and terminal-notifier are separate MIT-licensed projects, installed via pip/brew, not vendored here.

About

Extracts highlights, underlines, and notes from a folder of PDFs into a single org-mode file, using pdfannots. Runs automatically via a launchd LaunchAgent whenever the folder changes, with incremental caching, logging, and macOS notifications via terminal-notifier. Works with Preview, pdf-tools, and other annotation sources.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages