My PDF Tools Settings
;; -*- lexical-binding: t; -*-
;; Install and Settings
(pdf-tools-install)
(pdf-loader-install)
(define-key pdf-view-mode-map (kbd "g") nil)
(define-key pdf-view-mode-map (kbd "g g") 'pdf-view-first-page)
(define-key pdf-view-mode-map (kbd "G") 'pdf-view-last-page)
(define-key pdf-view-mode-map (kbd "e") 'pdf-view-goto-page)
;; (define-key pdf-view-mode-map (kbd "r") 'pdf-view-revert-buffer)
;; (define-key pdf-view-mode-map (kbd "a") 'pdf-annot-add-text-annotation)
(define-key pdf-view-mode-map (kbd "d") 'pdf-annot-delete)
(define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation)
(define-key pdf-view-mode-map (kbd "~") 'pdf-annot-add-squiggly-markup-annotation)
(define-key pdf-view-mode-map (kbd "u") 'pdf-annot-add-underline-markup-annotation)
(define-key pdf-view-mode-map (kbd "s") 'pdf-annot-add-strikeout-markup-annotation)
; Remember all my pdf passwords permanently
(setq epdfinfo-cache-passwords t)
(setopt pdf-view-continuous nil)
;; Change the Zoom increments
;; (setq pdf-view-resize-factor 1.1) 10% increments
;; (setq pdf-view-resize-factor 1.05) ; 5% increments
;;;;;;;;;;;;;;;;
;; Fix for pdf-tools annotation editing bug
(defun pdf-annot-edit-contents-commit-with-retry ()
"Save annotation with automatic retry on 'No such annotation' error."
(interactive)
(condition-case err
;; Try the normal save first
(pdf-annot-edit-contents-finalize t)
(error
(if (string-match-p "No such annotation" (error-message-string err))
(progn
(message "Annotation ID became stale, refreshing buffer...")
;; Revert the PDF buffer to refresh annotation IDs
(with-current-buffer (pdf-annot-get-buffer pdf-annot-edit-contents--annotation)
(revert-buffer t t))
(sit-for 0.5) ; Brief pause for buffer refresh
;; Try to find the annotation again and save
(condition-case err2
(progn
(pdf-annot-edit-contents-finalize t)
(message "Annotation saved after buffer refresh"))
(error
(message "Failed to save annotation: %s" (error-message-string err2))
(when (y-or-n-p "Keep edit buffer open? ")
(pdf-annot-edit-contents-finalize nil)))))
;; For other errors, just show the message
(error "Failed to save annotation: %s" (error-message-string err))))))
;; Fix for annotation deletion with stale IDs
(defun pdf-annot-delete-with-retry (a)
"Delete annotation with automatic retry on 'No such annotation' error."
(interactive
(list (pdf-annot-read-annotation
"Click on the annotation you wish to delete")))
(condition-case err
;; Try normal deletion first
(progn
(with-current-buffer (pdf-annot-get-buffer a)
(pdf-info-delannot (pdf-annot-get-id a))
(set-buffer-modified-p t)
(pdf-annot-run-modified-hooks :delete a))
(when (called-interactively-p 'any)
(message "Annotation deleted")))
(error
(if (string-match-p "No such annotation" (error-message-string err))
(progn
(message "Annotation ID became stale, refreshing buffer...")
;; Revert the PDF buffer to refresh annotation IDs
(with-current-buffer (pdf-annot-get-buffer a)
(revert-buffer t t))
(sit-for 0.5)
;; Try to find and delete the annotation by position
(let* ((page (pdf-annot-get a 'page))
(edges (pdf-annot-get a 'edges))
(buffer (pdf-annot-get-buffer a))
(found-annot nil))
(with-current-buffer buffer
(let ((current-annots (pdf-annot-getannots page nil buffer)))
(catch 'found
(dolist (annot current-annots)
(when (equal (pdf-annot-get annot 'edges) edges)
(setq found-annot annot)
(throw 'found annot)))))
(if found-annot
(progn
(pdf-info-delannot (pdf-annot-get-id found-annot))
(set-buffer-modified-p t)
(pdf-annot-run-modified-hooks :delete found-annot)
(message "Annotation deleted after buffer refresh"))
(message "Could not find annotation to delete - it may have already been removed")))))
;; For other errors, just propagate them
(error "Failed to delete annotation: %s" (error-message-string err))))))
;; Cursor positioning fix for annotation editing
(defun pdf-annot-edit-contents-position-cursor ()
"Position cursor at end of annotation content when editing starts."
(when (and (bound-and-true-p pdf-annot-edit-contents-minor-mode)
pdf-annot-edit-contents--annotation)
(goto-char (point-max))))
;; Add hook to position cursor at end when edit buffer is set up
(advice-add 'pdf-annot-edit-contents-noselect :after
(lambda (&rest _args)
(with-current-buffer (get-buffer-create
(format "*Edit Annotation %s*"
(buffer-name (pdf-annot-get-buffer pdf-annot-edit-contents--annotation))))
(goto-char (point-max)))))
;; Override both functions
(advice-add 'pdf-annot-edit-contents-commit :override
#'pdf-annot-edit-contents-commit-with-retry)
(advice-add 'pdf-annot-delete :override
#'pdf-annot-delete-with-retry)
;; Remove any previous advice
(advice-remove 'pdf-annot-edit-contents-save-annotation
#'pdf-annot-edit-contents-save-annotation-fixed)
;; (message "PDF-tools annotation fix loaded. Will auto-retry on 'No such annotation' errors for both editing and deletion. Cursor will be positioned at end of text when editing.")
;;;;;;;;;;;;;;;;
;; (add-hook 'pdf-view-mode-hook (lambda () (pdf-view-midnight-minor-mode)))
;; (setq pdf-view-midnight-colors '("#d0d0d0" . "#222222"))
;; ;; (setq pdf-view-midnight-colors '("#ffffff" . "#000000"))
;;;;;;;;;;;;;;;;
;; Save the last place in my PDF
(require 'saveplace-pdf-view) ; requires saveplace-pdf-view
(save-place-mode 1)
;;;;;;;;;;;;;;;;
;; Fix PDF text selection visibility:
;; Some PDFs use the '3 Tr' rendering mode (invisible text) to hide
;; text, often for accessibility or anti-copying purposes. This script:
;;
;; 1. Converts the PDF to QDF format using `qpdf` so it's editable.
;; 2. Replaces '3 Tr' with '0 Tr' (normal fill text mode).
;; 3. Prepends '0 g' and '0 0 0 rg' to ensure black stroke and fill color,
;; avoiding faint or invisible text caused by inherited color states.
;; 4. Reloads the buffer so changes take effect in Emacs.
;;
;; Result: hidden or copy-resistant text becomes visible and selectable
;; in Emacs' PDF viewer, with readable black fill color.
;; sudo apt-get install qpdf
(defun my-fix-pdf-selection ()
"Fix PDF so invisible text (3 Tr) becomes visible with black fill."
(interactive)
(let ((pdf-file (buffer-file-name)))
(unless (string-equal (file-name-extension pdf-file) "pdf")
(error "Not a PDF file"))
;; Step 1: Convert to QDF format
(message "Converting PDF to QDF format...")
(shell-command (format "qpdf --qdf --object-streams=disable --replace-input '%s'" pdf-file))
;; Step 2: Fix rendering mode and force black color
(message "Fixing text rendering modes and setting black fill color...")
(with-temp-buffer
(insert-file-contents-literally pdf-file)
(let ((replacements 0))
(goto-char (point-min))
(while (re-search-forward "3 Tr" nil t)
(replace-match "0 g\n0 0 0 rg\n0 Tr" nil nil) ; Add black stroking and nonstroking fill
(setq replacements (1+ replacements)))
(message "Made %d replacements of '3 Tr' with black-filled '0 Tr'" replacements)
(write-region (point-min) (point-max) pdf-file nil 'silent)))
;; Step 3: Reload PDF
(revert-buffer t t t)
(message "PDF transparency fix applied successfully!")))
(provide 'pdf-tools-settings-fixes)