diff options
Diffstat (limited to 'lib/doc/jao-doc-view.el')
| -rw-r--r-- | lib/doc/jao-doc-view.el | 157 | 
1 files changed, 90 insertions, 67 deletions
| diff --git a/lib/doc/jao-doc-view.el b/lib/doc/jao-doc-view.el index 5060452..af87c9e 100644 --- a/lib/doc/jao-doc-view.el +++ b/lib/doc/jao-doc-view.el @@ -1,6 +1,6 @@ -;; jao-doc-view.el -- Remembering visited documents +;; jao-doc-view.el -- Remembering visited documents -*- lexical-binding: t; -*- -;; Copyright (c) 2013, 2015, 2017, 2018, 2019 Jose Antonio Ortega Ruiz +;; Copyright (c) 2013, 2015, 2017, 2018, 2019, 2021 Jose Antonio Ortega Ruiz  ;; This file is free software; you can redistribute it and/or modify  ;; it under the terms of the GNU General Public License as published by @@ -20,14 +20,16 @@  ;;; Comentary: -;; Some utilities to keep track of visited documents and the last -;; visited page. +;; Some utilities to keep track of visited documents and their structure.  ;;; Code: -(defvar jao-doc-view-bmk-file "~/.emacs.d/doc-view-bmk") + +;;; Session + +(require 'doc-view) +  (defvar jao-doc-view-session-file "~/.emacs.d/doc-view-session") -(defvar jao-doc-view--current-bmks nil)  (defun jao-doc-view--read-file (file)    (let ((buff (find-file-noselect file))) @@ -42,65 +44,10 @@      (insert (format "%S" value))      (save-buffer))) -(defun jao-doc-view--read-bmks () -  (let ((bmks (jao-doc-view--read-file jao-doc-view-bmk-file))) -    (if (hash-table-p bmks) bmks (make-hash-table :test 'equal)))) - -(defun jao-doc-view--current-bmks () -  (or jao-doc-view--current-bmks -      (setq jao-doc-view--current-bmks (jao-doc-view--read-bmks)))) - -(defun jao-doc-view-purge-bmks () -  (interactive) -  (when jao-doc-view--current-bmks -    (maphash (lambda (k v) -               (when (or (not k) (= 1 v) (not (file-exists-p k))) -                 (remhash k jao-doc-view--current-bmks))) -             jao-doc-view--current-bmks))) - -(defun jao-doc-view-goto-bmk () -  (interactive) -  (when (eq major-mode 'pdf-view-mode) -    (let* ((bmks (jao-doc-view--current-bmks)) -           (fname (buffer-file-name)) -           (p (when fname (gethash (expand-file-name fname) bmks 1)))) -      (when (and (numberp p) (> p 1)) -        (message "Found bookmark at page %d" p) -        (ignore-errors (pdf-view-goto-page p)))))) - -(defun jao-doc-view-open (file) -  (let* ((buffs (buffer-list)) -         (b (catch 'done -              (while buffs -                (when (string-equal (buffer-file-name (car buffs)) file) -                  (throw 'done (car buffs))) -                (setq buffs (cdr buffs)))))) -    (if b -        (pop-to-buffer b) -      (when (file-exists-p file) (find-file file))))) -  (defun jao-doc-view-session (&optional file)    (let ((file (or file jao-doc-view-session-file)))      (jao-doc-view--read-file file))) -(defun jao-doc-view-load-session (&optional file) -  (interactive) -  (let ((docs (jao-doc-view-session file))) -    (when (not (listp docs)) (error "Empty session")) -    (dolist (d docs) (other-window 1) (jao-doc-view-open d)))) - -(defun jao-doc-view--save-bmks () -  (jao-doc-view-purge-bmks) -  (jao-doc-view--save-to-file jao-doc-view-bmk-file -                              (jao-doc-view--current-bmks))) - -(defun jao-doc-view--save-bmk (&rest ignored) -  (when (eq major-mode 'pdf-view-mode) -    (ignore-errors -      (puthash (buffer-file-name) -               (max (pdf-view-current-page) 1) -               (jao-doc-view--current-bmks))))) -  (defun jao-doc-view-save-session (&optional skip-current)    (interactive)    (let ((docs '()) @@ -109,15 +56,12 @@        (with-current-buffer b          (when (and (equalp major-mode 'pdf-view-mode)                     (not (equalp cb b))) -          (jao-doc-view--save-bmk)            (add-to-list 'docs (buffer-file-name))))) -    (jao-doc-view--save-bmks)      (when (> (length docs) 0)        (jao-doc-view--save-to-file jao-doc-view-session-file docs))))  (defun jao-doc-view--save-session-1 () -  (when (equalp major-mode 'pdf-view-mode) -    (jao-doc-view-purge-bmks) +  (when (derived-mode-p 'pdf-view-mode 'doc-view-mode)      (jao-doc-view-save-session t)))  (defvar jao-doc-session-timer nil) @@ -141,9 +85,88 @@                               t                               'jao-doc-view--save-session))) + +;;; PDF info + +(defvar-local jao--pdf-outline nil) + +(defmacro jao-doc-view--pdf-call (a b &rest args) +  `(cond ((derived-mode-p 'pdf-view-mode) (,a ,@args)) +         ((derived-mode-p 'doc-view-mode) (,b ,@args)))) + +(defun jao-doc-view-is-pdf (file) (string-match-p ".*\\.pdf$" file)) + +(defun jao-doc-view-title (&optional fname) +  (let ((base (file-name-base (or fname (buffer-file-name))))) +    (capitalize (replace-regexp-in-string "-" " " base)))) + +(defun jao-doc-view-title->file (title) +  (concat (mapconcat 'downcase (split-string title nil t) "-") ".pdf")) + +(defun jao-doc-view-current-page () +  (jao-doc-view--pdf-call pdf-view-current-page doc-view-current-page)) + +(defun jao-doc-view-goto-page (page &optional height) +  (when page +    (jao-doc-view--pdf-call pdf-view-goto-page doc-view-goto-page page)) +  (when (and height (derived-mode-p 'pdf-view-mode)) +    (image-set-window-vscroll +     (round (/ (* height (cdr (pdf-view-image-size))) (frame-char-height)))))) + +(defun jao-doc-view-pdf-outline () +  (if (derived-mode-p 'pdf-view-mode) +      (pdf-info-outline) +    (let ((outline nil) +          (fn (shell-quote-argument (buffer-file-name)))) +      (with-temp-buffer +        (insert (shell-command-to-string (format "mutool show %s outline" fn))) +        (goto-char (point-min)) +        (while (re-search-forward ".+\\(\t+\\)\"\\(.+\\)\"\t#\\([0-9]+\\)," nil t) +          (push `((level . ,(length (match-string 1))) +                  (title . ,(match-string 2)) +                  (page . ,(string-to-number (match-string 3)))) +                outline))) +      (nreverse outline)))) + +(defun jao-doc-view-section-title (&optional page) +  (when (not jao--pdf-outline) +    (setq-local jao--pdf-outline (jao-doc-view-pdf-outline))) +  (let ((page (or page (jao-doc-view-current-page))) +        (outline jao--pdf-outline) +        (cur-page 0) +        (cur-title (jao-doc-view-title))) +    (while (and (car outline) (< cur-page page)) +      (setq cur-page (cdr (assoc 'page (car outline)))) +      (when (<= cur-page page) +        (setq cur-title (cdr (assoc 'title (car outline))))) +      (setq outline (cdr outline))) +    (replace-regexp-in-string "[[:blank:]]+" " " cur-title))) + + +;;; imenu +(defun jao-doc-view--enable-imenu () +  (setq-local imenu-create-index-function #'jao-doc-view--imenu-create-index) +  (imenu-add-to-menubar "PDF outline")) + +(defun jao-doc-view--imenu-create-index () +  (let (index) +    (dolist (item (or jao--pdf-outline +                      (setq jao--pdf-outline (jao-doc-view-pdf-outline)))) +      (let-alist item +        (let* ((lvl (make-string (max 0 (1- .level)) ?.)) +               (title (format "%s%s (%s)" lvl .title .page))) +          (push `(,title 0 jao-doc-view--go ,item) index)))) +    (nreverse index))) + +(defun jao-doc-view--go (&rest args) +  (when-let (item (car (last args))) +    (let-alist item (jao-doc-view-goto-page .page)))) + + +;; install +;;;###autoload  (defun jao-doc-view-install () -  (jao-doc-view--current-bmks) -  (add-hook 'kill-buffer-hook 'jao-doc-view--save-bmk) +  (add-hook 'doc-view-mode-hook #'jao-doc-view--enable-imenu)    (add-hook 'kill-buffer-hook 'jao-doc-view--save-session-1 t)    (add-hook 'kill-emacs-hook 'jao-doc-view-save-session)    (jao-doc-view-start-session-timer)) | 
