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