blob: 8b27c381f7486961004e510f70225ba90247072c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
;; jao-doc-view-imenu.el --- old docview/imenu -*- lexical-binding: t; -*-
;; Copyright (C) 2022 jao
;; Author: jao <mail@jao.io>
;; Keywords:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Old code that made its way into emacs 29. It defines imenu entries for
;; docview.
;;; Code:
(defvar jao-pdf--outline-rx
"[^\t]+\\(\t+\\)\"\\(.+\\)\"\t#\\(?:page=\\)?\\([0-9]+\\)")
(defun jao-pdf-outline (&optional file-name)
"Return an alist describing the given FILE-NAME (or current if nil).
The result is cached as a local buffer variable."
(let* ((outline nil)
(fn (or file-name (buffer-file-name)))
(fn (shell-quote-argument (expand-file-name fn))))
(with-temp-buffer
(insert (shell-command-to-string (format "mutool show %s outline" fn)))
(goto-char (point-min))
(while (re-search-forward jao-pdf--outline-rx nil t)
(push `((level . ,(length (match-string 1)))
(title . ,(match-string 2))
(page . ,(string-to-number (match-string 3))))
outline)))
(setq jao-pdf--outline (nreverse outline))))
(defun jao-pdf-imenu--index (items act)
(let ((level (alist-get 'level (car items)))
(index nil))
(while (and (car items) (<= level (alist-get 'level (car items))))
(let-alist (car items)
(let ((title (format "%s%s (%s)" "" .title .page)))
(if (> .level level)
(let ((sub (jao-pdf-imenu--index items act))
(fst (car index)))
(setq index (cdr index))
(push (cons (car fst) (cons fst (car sub))) index)
(setq items (cdr sub)))
(push `(,title 0 ,act ,.page) index)
(setq items (cdr items))))))
(cons (nreverse index) items)))
(defun jao-pdf-imenu-index (&optional goto-page-fn file-name)
"Create an imenu index using `jao-pdf-outline'."
(let* ((goto (or goto-page-fn 'doc-view-goto-page))
(act (lambda (_name _pos page) (funcall goto page)))
(items (jao-pdf-outline file-name)))
(car (jao-pdf-imenu--index items act))))
(defun jao-pdf-set-up-imenu ()
(setq-local imenu-create-index-function #'jao-pdf-imenu-index
imenu-submenus-on-top nil
imenu-sort-function nil)
(imenu-add-to-menubar "Outline"))
|