pdf-misc.el (11828B)
1 ;;; pdf-misc.el --- Miscellaneous commands for PDF buffer. -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2013, 2014 Andreas Politz 4 5 ;; Author: Andreas Politz <politza@fh-trier.de> 6 ;; Keywords: files, multimedia 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 ;; 23 24 25 (require 'pdf-view) 26 (require 'pdf-util) 27 (require 'imenu) 28 29 30 31 ;;; Code: 32 33 (defvar pdf-misc-minor-mode-map 34 (let ((map (make-sparse-keymap))) 35 (define-key map (kbd "I") 'pdf-misc-display-metadata) 36 (define-key map (kbd "C-c C-p") 'pdf-misc-print-document) 37 map) 38 "Keymap used in `pdf-misc-minor-mode'.") 39 40 ;;;###autoload 41 (define-minor-mode pdf-misc-minor-mode 42 "FIXME: Not documented." 43 :group 'pdf-misc) 44 45 ;;;###autoload 46 (define-minor-mode pdf-misc-size-indication-minor-mode 47 "Provide a working size indication in the mode-line." 48 :group 'pdf-misc 49 (pdf-util-assert-pdf-buffer) 50 (cond 51 (pdf-misc-size-indication-minor-mode 52 (unless (assq 'pdf-misc-size-indication-minor-mode 53 mode-line-position) 54 (setq mode-line-position 55 `((pdf-misc-size-indication-minor-mode 56 (:eval (pdf-misc-size-indication))) 57 ,@mode-line-position)))) 58 (t 59 (setq mode-line-position 60 (cl-remove 'pdf-misc-size-indication-minor-mode 61 mode-line-position :key 'car-safe))))) 62 63 (defun pdf-misc-size-indication () 64 "Return size indication string for the mode-line." 65 (let ((top (= (window-vscroll nil t) 0)) 66 (bot (>= (+ (- (nth 3 (window-inside-pixel-edges)) 67 (nth 1 (window-inside-pixel-edges))) 68 (window-vscroll nil t)) 69 (cdr (pdf-view-image-size t))))) 70 (cond 71 ((and top bot) " All") 72 (top " Top") 73 (bot " Bot") 74 (t (format 75 " %d%%%%" 76 (ceiling 77 (* 100 (/ (float (window-vscroll nil t)) 78 (cdr (pdf-view-image-size t)))))))))) 79 80 (defvar pdf-misc-menu-bar-minor-mode-map (make-sparse-keymap) 81 "The keymap used in `pdf-misc-menu-bar-minor-mode'.") 82 83 (easy-menu-define nil pdf-misc-menu-bar-minor-mode-map 84 "Menu for PDF Tools." 85 `("PDF Tools" 86 ["Go Backward" pdf-history-backward 87 :visible (bound-and-true-p pdf-history-minor-mode) 88 :active (and (bound-and-true-p pdf-history-minor-mode) 89 (not (pdf-history-end-of-history-p)))] 90 ["Go Forward" pdf-history-forward 91 :visible (bound-and-true-p pdf-history-minor-mode) 92 :active (not (pdf-history-end-of-history-p))] 93 ["--" nil 94 :visible (derived-mode-p 'pdf-virtual-view-mode)] 95 ["Next file" pdf-virtual-buffer-forward-file 96 :visible (derived-mode-p 'pdf-virtual-view-mode) 97 :active (pdf-virtual-document-next-file 98 (pdf-view-current-page))] 99 ["Previous file" pdf-virtual-buffer-backward-file 100 :visible (derived-mode-p 'pdf-virtual-view-mode) 101 :active (not (eq 1 (pdf-view-current-page)))] 102 ["--" nil 103 :visible (bound-and-true-p pdf-history-minor-mode)] 104 ["Add text annotation" pdf-annot-mouse-add-text-annotation 105 :visible (bound-and-true-p pdf-annot-minor-mode) 106 :keys "\\[pdf-annot-add-text-annotation]"] 107 ("Add markup annotation" 108 :active (pdf-view-active-region-p) 109 :visible (and (bound-and-true-p pdf-annot-minor-mode) 110 (pdf-info-markup-annotations-p)) 111 ["highlight" pdf-annot-add-highlight-markup-annotation] 112 ["squiggly" pdf-annot-add-squiggly-markup-annotation] 113 ["underline" pdf-annot-add-underline-markup-annotation] 114 ["strikeout" pdf-annot-add-strikeout-markup-annotation]) 115 ["--" nil :visible (bound-and-true-p pdf-annot-minor-mode)] 116 ["Display Annotations" pdf-annot-list-annotations 117 :help "List all annotations" 118 :visible (bound-and-true-p pdf-annot-minor-mode)] 119 ["Display Attachments" pdf-annot-attachment-dired 120 :help "Display attachments in a dired buffer" 121 :visible (featurep 'pdf-annot)] 122 ["Display Metadata" pdf-misc-display-metadata 123 :help "Display information about the document" 124 :visible (featurep 'pdf-misc)] 125 ["Display Outline" pdf-outline 126 :help "Display documents outline" 127 :visible (featurep 'pdf-outline)] 128 "--" 129 ("Render Options" 130 ["Printed Mode" (lambda () 131 (interactive) 132 (pdf-view-printer-minor-mode 'toggle)) 133 :style toggle 134 :selected pdf-view-printer-minor-mode 135 :help "Display the PDF as it would be printed."] 136 ["Midnight Mode" (lambda () 137 (interactive) 138 (pdf-view-midnight-minor-mode 'toggle)) 139 :style toggle 140 :selected pdf-view-midnight-minor-mode 141 :help "Apply a color-filter appropriate for past midnight reading."]) 142 "--" 143 ["Copy region" pdf-view-kill-ring-save 144 :keys "\\[kill-ring-save]" 145 :active (pdf-view-active-region-p)] 146 ("Selection style" 147 ["Glyph" (pdf-view-set-selection-style 'glyph) 148 :style radio 149 :selected (eq pdf-view-selection-style 'glyph) 150 :help "When dragging the mouse, select individual characters."] 151 ["Word" (pdf-view-set-selection-style 'word) 152 :style radio 153 :selected (eq pdf-view-selection-style 'word) 154 :help "When dragging the mouse, select entire words."] 155 ["Line" (pdf-view-set-selection-style 'line) 156 :style radio 157 :selected (eq pdf-view-selection-style 'line) 158 :help "When dragging the mouse, select entire lines."]) 159 "--" 160 ["Isearch document" isearch-forward 161 :visible (bound-and-true-p pdf-isearch-minor-mode)] 162 ["Occur document" pdf-occur 163 :visible (featurep 'pdf-occur)] 164 "--" 165 ["Locate TeX source" pdf-sync-backward-search-mouse 166 :visible (and (featurep 'pdf-sync) 167 (equal last-command-event 168 last-nonmenu-event))] 169 ["--" nil :visible (and (featurep 'pdf-sync) 170 (equal last-command-event 171 last-nonmenu-event))] 172 ["Print" pdf-misc-print-document 173 :active (and (pdf-view-buffer-file-name) 174 (file-readable-p (pdf-view-buffer-file-name)))] 175 ["Create image" pdf-view-extract-region-image 176 :help "Create an image of the page or the selected region(s)."] 177 ["Create virtual PDF" pdf-virtual-buffer-create 178 :help "Create a PDF containing all documents in this directory." 179 :visible (bound-and-true-p pdf-virtual-global-minor-mode)] 180 "--" 181 ["Revert buffer" pdf-view-revert-buffer 182 :visible (pdf-info-writable-annotations-p)] 183 "--" 184 ["Customize" pdf-tools-customize])) 185 186 ;;;###autoload 187 (define-minor-mode pdf-misc-menu-bar-minor-mode 188 "Display a PDF Tools menu in the menu-bar." 189 :group 'pdf-misc 190 (pdf-util-assert-pdf-buffer)) 191 192 (defvar pdf-misc-context-menu-minor-mode-map 193 (let ((kmap (make-sparse-keymap))) 194 (define-key kmap [down-mouse-3] 'pdf-misc-popup-context-menu) 195 kmap)) 196 197 ;;;###autoload 198 (define-minor-mode pdf-misc-context-menu-minor-mode 199 "Provide a right-click context menu in PDF buffers. 200 201 \\{pdf-misc-context-menu-minor-mode-map}" 202 :group 'pdf-misc 203 (pdf-util-assert-pdf-buffer)) 204 205 (defun pdf-misc-popup-context-menu (_event) 206 "Popup a context menu at position." 207 (interactive "@e") 208 (popup-menu 209 (cons 'keymap 210 (cddr (or (lookup-key pdf-misc-menu-bar-minor-mode-map 211 [menu-bar PDF\ Tools]) 212 (lookup-key pdf-misc-menu-bar-minor-mode-map 213 [menu-bar pdf\ tools])))))) 214 215 (defun pdf-misc-display-metadata () 216 "Display all available metadata in a separate buffer." 217 (interactive) 218 (pdf-util-assert-pdf-buffer) 219 (let* ((buffer (current-buffer)) 220 (md (pdf-info-metadata))) 221 (with-current-buffer (get-buffer-create "*PDF-Metadata*") 222 (let* ((inhibit-read-only t) 223 (pad (apply' max (mapcar (lambda (d) 224 (length (symbol-name (car d)))) 225 md))) 226 (fmt (format "%%%ds:%%s\n" pad))) 227 (erase-buffer) 228 (setq header-line-format (buffer-name buffer) 229 buffer-read-only t) 230 (font-lock-mode 1) 231 (font-lock-add-keywords nil 232 '(("^ *\\(\\(?:\\w\\|-\\)+\\):" 233 (1 font-lock-keyword-face)))) 234 (dolist (d md) 235 (let ((key (car d)) 236 (val (cdr d))) 237 (cl-case key 238 (keywords 239 (setq val (mapconcat 'identity val ", ")))) 240 (let ((beg (+ (length (symbol-name key)) (point) 1)) 241 (fill-prefix 242 (make-string (1+ pad) ?\s))) 243 (insert (format fmt key val)) 244 (fill-region beg (point) ))))) 245 (goto-char 1) 246 (display-buffer (current-buffer))) 247 md)) 248 249 (defgroup pdf-misc nil 250 "Miscellaneous options for PDF documents." 251 :group 'pdf-tools) 252 253 (define-obsolete-variable-alias 'pdf-misc-print-programm 254 'pdf-misc-print-program-executable "1.0") 255 (defcustom pdf-misc-print-program-executable nil 256 "The program used for printing. 257 258 It is called with one argument, the PDF file." 259 :group 'pdf-misc 260 :type 'file) 261 262 (define-obsolete-variable-alias 'pdf-misc-print-programm-args 263 'pdf-misc-print-program-args "1.0") 264 (defcustom pdf-misc-print-program-args nil 265 "List of additional arguments passed to `pdf-misc-print-program'." 266 :group 'pdf-misc 267 :type '(repeat string)) 268 269 (define-obsolete-function-alias 'pdf-misc-print-programm 270 'pdf-misc-print-program "1.0") 271 (defun pdf-misc-print-program (&optional interactive-p) 272 "Return the program used to print PDFs (if the executable is installed). 273 274 If INTERACTIVE-P is non-nil, ask the user for which program to 275 use when printing the PDF. Optionally, save the choice" 276 (or (and pdf-misc-print-program-executable 277 (executable-find pdf-misc-print-program-executable)) 278 (when interactive-p 279 (let* ((default (car (delq nil (mapcar 280 'executable-find 281 '("gtklp" "xpp" "gpr"))))) 282 buffer-file-name 283 (program 284 (expand-file-name 285 (read-file-name 286 "Print with: " default nil t nil 'file-executable-p)))) 287 (when (and program 288 (executable-find program)) 289 (when (y-or-n-p "Save choice using customize? ") 290 (customize-save-variable 291 'pdf-misc-print-program-executable program)) 292 (setq pdf-misc-print-program-executable program)))))) 293 294 (defun pdf-misc-print-document (filename &optional interactive-p) 295 "Print the PDF doc FILENAME. 296 297 `pdf-misc-print-program' handles the print program, which see for 298 definition of INTERACTIVE-P." 299 (interactive 300 (list (pdf-view-buffer-file-name) t)) 301 (cl-check-type filename (and string (satisfies file-readable-p))) 302 (let ((program (pdf-misc-print-program interactive-p)) 303 (args (append pdf-misc-print-program-args (list filename)))) 304 (unless program 305 (error "No print program available")) 306 (apply #'start-process "printing" nil program args) 307 (message "Print job started: %s %s" 308 program (mapconcat #'identity args " ")))) 309 310 311 (provide 'pdf-misc) 312 313 ;;; pdf-misc.el ends here