Add imenu index function for DjVu files in doc-view
* lisp/doc-view.el (doc-view-pdfdraw-program): Prefer mutool over other names. (doc-view-imenu-enabled): Tweak the default value to check for 'djvused', and make it obsolete. (doc-view--djvu-outline, doc-view--parse-djvu-outline): Add new functions to return imenu index for a Djvu file. (doc-view--outline): Add new function to create the imenu index depending on the file type. (doc-view--outline): Document new possible variable value. (doc-view-imenu-index): Use the above function instead. (doc-view-imenu-setup): Try to create the imenu index unconditionally. * doc/emacs/misc.texi (DocView Navigation): Mention index creation using 'djvused' too. * etc/NEWS: Announce the change. (Bug#73530)
This commit is contained in:
parent
5e0935d991
commit
d6dd71cd56
3 changed files with 106 additions and 27 deletions
|
@ -581,17 +581,17 @@ you instead want the image to be re-rendered at the new size, set
|
|||
default size for DocView, customize the variable
|
||||
@code{doc-view-resolution}.
|
||||
|
||||
@vindex doc-view-imenu-enabled
|
||||
@vindex doc-view-imenu-flatten
|
||||
@vindex doc-view-imenu-format
|
||||
When the @command{mutool} program is available, DocView will use it
|
||||
to generate entries for an outline menu, making it accessible via the
|
||||
@code{imenu} facility (@pxref{Imenu}). To disable this functionality
|
||||
even when @command{mutool} can be found on your system, customize the
|
||||
variable @code{doc-view-imenu-enabled} to the @code{nil} value. You
|
||||
can further customize how @code{imenu} items are formatted and
|
||||
displayed using the variables @code{doc-view-imenu-format} and
|
||||
@code{doc-view-imenu-flatten}.
|
||||
@vindex doc-view-djvused-program
|
||||
DocView can generate an outline menu for PDF and DjVu documents using
|
||||
the @command{mutool} and the @command{djvused} programs respectively
|
||||
when they are available. This is made accessible via the @code{imenu}
|
||||
facility (@pxref{Imenu}). You can customize how @code{imenu} items are
|
||||
formatted and displayed using the variables @code{doc-view-imenu-format}
|
||||
and @code{doc-view-imenu-flatten}. The filename of the
|
||||
@command{djvused} program can be customized by changing the
|
||||
@code{doc-view-djvused-program} user option.
|
||||
|
||||
@cindex registers, in DocView mode
|
||||
@findex doc-view-page-to-register
|
||||
|
|
7
etc/NEWS
7
etc/NEWS
|
@ -364,6 +364,13 @@ Docview can store current page to buffer-local registers with the new
|
|||
command 'doc-view-page-to-register' (bound to 'm'), and later the stored
|
||||
page can be restored with 'doc-view-jump-to-register' (bound to ''').
|
||||
|
||||
+++
|
||||
*** Docview can generate imenu index for DjVu files.
|
||||
When the 'djvused' program is available, Docview can now generate imenu
|
||||
index for DjVu files from its outline.
|
||||
The name of the 'djvused' program can be customized by changing the user
|
||||
option 'doc-view-djvused-program'.
|
||||
|
||||
** Tramp
|
||||
|
||||
+++
|
||||
|
|
108
lisp/doc-view.el
108
lisp/doc-view.el
|
@ -27,8 +27,10 @@
|
|||
;; `pdftotext', which comes with xpdf (https://www.foolabs.com/xpdf/)
|
||||
;; or poppler (https://poppler.freedesktop.org/). EPUB, CBZ, FB2, XPS
|
||||
;; and OXPS documents require `mutool' which comes with mupdf
|
||||
;; (https://mupdf.com/index.html). Djvu documents require `ddjvu'
|
||||
;; (https://mupdf.com/index.html). DjVu documents require `ddjvu'
|
||||
;; (from DjVuLibre). ODF files require `soffice' (from LibreOffice).
|
||||
;; `djvused' (from DjVuLibre) can be optionally used to generate imenu
|
||||
;; outline for DjVu documents when available.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
|
@ -185,13 +187,13 @@ are available (see Info node `(emacs)Document View')."
|
|||
|
||||
(defcustom doc-view-pdfdraw-program
|
||||
(cond
|
||||
((executable-find "mutool") "mutool")
|
||||
((executable-find "pdfdraw") "pdfdraw")
|
||||
((executable-find "mudraw") "mudraw")
|
||||
((executable-find "mutool") "mutool")
|
||||
(t "mudraw"))
|
||||
"Name of MuPDF's program to convert PDF files to PNG."
|
||||
:type 'file
|
||||
:version "24.4")
|
||||
:version "31.1")
|
||||
|
||||
(defcustom doc-view-pdftotext-program-args '("-raw")
|
||||
"Parameters to give to the pdftotext command."
|
||||
|
@ -216,10 +218,23 @@ are available (see Info node `(emacs)Document View')."
|
|||
:type 'boolean
|
||||
:version "30.1")
|
||||
|
||||
(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t)
|
||||
"Whether to generate an imenu outline when \"mutool\" is available."
|
||||
(defcustom doc-view-djvused-program (and (executable-find "djvused")
|
||||
"djvused")
|
||||
"Name of \"djvused\" program to generate imenu outline for DjVu files.
|
||||
This is part of DjVuLibre."
|
||||
:type 'file
|
||||
:version "31.1")
|
||||
|
||||
(defcustom doc-view-imenu-enabled (and (or (executable-find "mutool")
|
||||
(executable-find "djvused"))
|
||||
t)
|
||||
"Whether to generate imenu outline for PDF and DjVu files.
|
||||
This uses \"mutool\" for PDF files and \"djvused\" for DjVu files."
|
||||
:type 'boolean
|
||||
:version "29.1")
|
||||
:version "31.1")
|
||||
(make-obsolete-variable 'doc-view-imenu-enabled
|
||||
"Imenu index is generated unconditionally when available."
|
||||
"31.1")
|
||||
|
||||
(defcustom doc-view-imenu-title-format "%t (%p)"
|
||||
"Format spec for imenu's display of section titles from docview documents.
|
||||
|
@ -1958,7 +1973,9 @@ the document text."
|
|||
"[^\t]+\\(\t+\\)\"\\(.+\\)\"\t#\\(?:page=\\)?\\([0-9]+\\)")
|
||||
|
||||
(defvar-local doc-view--outline nil
|
||||
"Cached PDF outline, so that it is only computed once per document.")
|
||||
"Cached PDF outline, so that it is only computed once per document.
|
||||
It can be the symbol `unavailable' to indicate that outline is
|
||||
unavailable for the document.")
|
||||
|
||||
(defun doc-view--pdf-outline (&optional file-name)
|
||||
"Return a list describing the outline of FILE-NAME.
|
||||
|
@ -1972,7 +1989,9 @@ structure is extracted by `doc-view--imenu-subtree'."
|
|||
(let ((outline nil)
|
||||
(fn (expand-file-name fn)))
|
||||
(with-temp-buffer
|
||||
(unless (eql 0 (call-process "mutool" nil (current-buffer) nil "show" fn "outline"))
|
||||
(unless (eql 0 (call-process doc-view-pdfdraw-program nil
|
||||
(current-buffer) nil "show" fn "outline"))
|
||||
(setq doc-view--outline 'unavailable)
|
||||
(imenu-unavailable-error "Unable to create imenu index using `mutool'"))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward doc-view--outline-rx nil t)
|
||||
|
@ -1983,6 +2002,42 @@ structure is extracted by `doc-view--imenu-subtree'."
|
|||
outline)))
|
||||
(nreverse outline)))))
|
||||
|
||||
(defun doc-view--djvu-outline (&optional file-name)
|
||||
"Return a list describing the outline of FILE-NAME.
|
||||
If FILE-NAME is nil or omitted, it defaults to the current buffer's file
|
||||
name.
|
||||
|
||||
For the format, see `doc-view--pdf-outline'."
|
||||
(unless file-name (setq file-name (buffer-file-name)))
|
||||
(with-temp-buffer
|
||||
(call-process doc-view-djvused-program nil (current-buffer) nil
|
||||
"-e" "print-outline" file-name)
|
||||
(goto-char (point-min))
|
||||
(when (eobp)
|
||||
(setq doc-view--outline 'unavailable)
|
||||
(imenu-unavailable-error "Unable to create imenu index using `djvused'"))
|
||||
(nreverse (doc-view--parse-djvu-outline (read (current-buffer))))))
|
||||
|
||||
(defun doc-view--parse-djvu-outline (bookmark &optional level)
|
||||
"Return a list describing the djvu outline from BOOKMARK.
|
||||
Optional argument LEVEL is the current heading level, which defaults to 1."
|
||||
(unless level (setq level 1))
|
||||
(let ((res))
|
||||
(unless (eq (car bookmark) 'bookmarks)
|
||||
(user-error "Unknown outline type: %S" (car bookmark)))
|
||||
(pcase-dolist (`(,title ,page . ,rest) (cdr bookmark))
|
||||
(push `((level . ,level)
|
||||
(title . ,title)
|
||||
(page . ,(string-to-number (string-remove-prefix "#" page))))
|
||||
res)
|
||||
(when (and rest (listp (car rest)))
|
||||
(setq res (append
|
||||
(doc-view--parse-djvu-outline
|
||||
(cons 'bookmarks rest)
|
||||
(+ level 1))
|
||||
res))))
|
||||
res))
|
||||
|
||||
(defun doc-view--imenu-subtree (outline act)
|
||||
"Construct a tree of imenu items for the given outline list and action.
|
||||
|
||||
|
@ -2015,19 +2070,36 @@ entries at an upper level."
|
|||
For extensibility, callers can specify a FILE-NAME to indicate
|
||||
the buffer other than the current buffer, and a jumping function
|
||||
GOTO-PAGE-FN other than `doc-view-goto-page'."
|
||||
(let* ((goto (or goto-page-fn 'doc-view-goto-page))
|
||||
(act (lambda (_name _pos page) (funcall goto page)))
|
||||
(outline (or doc-view--outline (doc-view--pdf-outline file-name))))
|
||||
(car (doc-view--imenu-subtree outline act))))
|
||||
(unless doc-view--outline
|
||||
(setq doc-view--outline (doc-view--outline file-name)))
|
||||
(unless (eq doc-view--outline 'unavailable)
|
||||
(let* ((goto (or goto-page-fn #'doc-view-goto-page))
|
||||
(act (lambda (_name _pos page) (funcall goto page)))
|
||||
(outline doc-view--outline))
|
||||
(car (doc-view--imenu-subtree outline act)))))
|
||||
|
||||
(defun doc-view--outline (&optional file-name)
|
||||
"Return the outline for the file FILE-NAME.
|
||||
If FILE-NAME is nil, use the current file instead."
|
||||
(unless file-name (setq file-name (buffer-file-name)))
|
||||
(let ((outline
|
||||
(pcase doc-view-doc-type
|
||||
('djvu
|
||||
(when doc-view-djvused-program
|
||||
(doc-view--djvu-outline file-name)))
|
||||
(_
|
||||
(doc-view--pdf-outline file-name)))))
|
||||
(when outline (imenu-add-to-menubar "Outline"))
|
||||
;; When the outline could not be made due to unavailability of the
|
||||
;; required program, or its absency from the document, return
|
||||
;; 'unavailable'.
|
||||
(or outline 'unavailable)))
|
||||
|
||||
(defun doc-view-imenu-setup ()
|
||||
"Set up local state in the current buffer for imenu, if needed."
|
||||
(when doc-view-imenu-enabled
|
||||
(setq-local imenu-create-index-function #'doc-view-imenu-index
|
||||
imenu-submenus-on-top nil
|
||||
imenu-sort-function nil
|
||||
doc-view--outline (doc-view--pdf-outline))
|
||||
(when doc-view--outline (imenu-add-to-menubar "Outline"))))
|
||||
(setq-local imenu-create-index-function #'doc-view-imenu-index
|
||||
imenu-submenus-on-top nil
|
||||
imenu-sort-function nil))
|
||||
|
||||
;;;; User interface commands and the mode
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue