* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view @ 2024-09-28 15:10 Visuwesh 2024-09-28 15:42 ` Eli Zaretskii 0 siblings, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-09-28 15:10 UTC (permalink / raw) To: 73530 [-- Attachment #1: Type: text/plain, Size: 694 bytes --] Tags: patch Attached patch adds a function to create imenu index for Djvu files using djvused. If you do not have a Djvu file available, I can point to a file from libgen that can be used as a test file. In GNU Emacs 31.0.50 (build 7, x86_64-pc-linux-gnu, X toolkit, cairo version 1.18.0, Xaw scroll bars) of 2024-09-09 built on astatine Repository revision: 7d7aa65f63db78c5732f1580213fc3767b767a4a Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12101011 System Description: Debian GNU/Linux trixie/sid Configured using: 'configure --with-sound=alsa --with-x-toolkit=lucid --without-xaw3d --without-gconf --without-libsystemd --with-cairo' [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-imenu-index-function-for-Djvu-files-in-doc-view.patch --] [-- Type: text/patch, Size: 6720 bytes --] From 27174371d677f0e79f2291ce3f2849838a28ca0e Mon Sep 17 00:00:00 2001 From: Visuwesh <visuweshm@gmail.com> Date: Sat, 28 Sep 2024 20:37:50 +0530 Subject: [PATCH] Add imenu index function for Djvu files in doc-view * lisp/doc-view.el (doc-view-imenu-enabled): Tweak the default value to check for 'djvused'. (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-imenu-index, doc-view-imenu-setup): Use new function instead. * doc/emacs/misc.texi (DocView Navigation): Mention index creation using 'djvused' too. * etc/NEWS: Announce the change. --- doc/emacs/misc.texi | 16 ++++++------ etc/NEWS | 5 ++++ lisp/doc-view.el | 60 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index e19e554fb26..eee6f08ef3b 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -584,14 +584,14 @@ DocView Navigation @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}. + When the @command{mutool} or the @command{djvused} 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 the required program 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}. @findex doc-view-page-to-register @findex doc-view-jump-to-register diff --git a/etc/NEWS b/etc/NEWS index 607665a71bb..162af7b3e43 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -268,6 +268,11 @@ Docview can store current page to buffer local registers with the new command 'doc-view-page-to-register' (bound to 'm'), and later 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. + ** Tramp +++ diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 395993e6263..d461b606ce6 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -216,10 +216,13 @@ doc-view-mupdf-use-svg :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-imenu-enabled (and (or (executable-find "mutool") + (executable-find "djvused")) + t) + "Whether to generate an imenu outline when available. +This uses \"mutool\" for PDF files and \"djvused\" for Djvu files." :type 'boolean - :version "29.1") + :version "31.1") (defcustom doc-view-imenu-title-format "%t (%p)" "Format spec for imenu's display of section titles from docview documents. @@ -2004,6 +2007,41 @@ doc-view--imenu-subtree (setq outline (cdr outline)))))) (cons (nreverse index) outline))) +(defun doc-view--djvu-outline (&optional file-name) + "Return a list describing the outline of FILE-NAME. +If FILE-NAME is nil, use the current file. + +For the format, see `doc-view--pdf-outline'." + (unless file-name (setq file-name (buffer-file-name))) + (with-temp-buffer + (call-process "djvused" nil (current-buffer) nil + "-e" "print-outline" file-name) + (goto-char (point-min)) + (when (eobp) + (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. If nil, then 1 is +used." + (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-index (&optional file-name goto-page-fn) "Create an imenu index using \"mutool\" to extract its outline. @@ -2012,16 +2050,28 @@ doc-view-imenu-index 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)))) + (outline (or doc-view--outline (doc-view--outline file-name)))) (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))) + (pcase doc-view-doc-type + ('djvu + (when (executable-find "djvused") + (doc-view--djvu-outline file-name))) + (_ + (when (executable-find "mutool") + (doc-view--pdf-outline file-name))))) + (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)) + doc-view--outline (doc-view--outline)) (when doc-view--outline (imenu-add-to-menubar "Outline")))) ;;;; User interface commands and the mode -- 2.45.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 15:10 bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view Visuwesh @ 2024-09-28 15:42 ` Eli Zaretskii 2024-09-28 17:02 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Eli Zaretskii @ 2024-09-28 15:42 UTC (permalink / raw) To: Visuwesh, Tassilo Horn; +Cc: 73530 > From: Visuwesh <visuweshm@gmail.com> > Date: Sat, 28 Sep 2024 20:40:54 +0530 > > > Attached patch adds a function to create imenu index for Djvu files > using djvused. If you do not have a Djvu file available, I can point to > a file from libgen that can be used as a test file. Thanks, but can we please not hard-code names of programs, and instead use variables that can be adjusted by users? I know that "mutool" was hard-coded, but adding more hard-coded programs sounds too much. Adding Tassilo to the discussion. > + When the @command{mutool} or the @command{djvused} 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 the required program 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}. This is misleading, I think: it leaves the impression that the two tools are interchangeable, where in reality each one supports different format of files. The text should say explicitly that one is for PDF, the other for Djvu. > -(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t) > - "Whether to generate an imenu outline when \"mutool\" is available." > +(defcustom doc-view-imenu-enabled (and (or (executable-find "mutool") > + (executable-find "djvused")) > + t) > + "Whether to generate an imenu outline when available. "When available" sounds awkward. "When possible", perhaps? Also, "generate imenu outline" is too general. Don't forget that the first line of a doc string is shown by apropos commands, and so should speak for itself. I would say Whether to generate imenu outline for PDF and DJVU files. The "when available" part is unnecessary, because Emacs checks for availability, and the user can override that. > +Optional argument LEVEL is the current heading level. If nil, then 1 is > +used." Optional argument LEVEL is the current heading level, which defaults to 1. > +(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." Since FILE-NAME can be omitted, it is better to use our usual style: If FILE-NAME is nil or omitted, it defaults to the current buffer's file name. > + (unless file-name (setq file-name (buffer-file-name))) > + (pcase doc-view-doc-type > + ('djvu > + (when (executable-find "djvused") > + (doc-view--djvu-outline file-name))) > + (_ > + (when (executable-find "mutool") > + (doc-view--pdf-outline file-name))))) We already tested that the relevant tool is available, so why test that here again? Thanks. ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 15:42 ` Eli Zaretskii @ 2024-09-28 17:02 ` Tassilo Horn 2024-09-28 17:35 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-28 17:02 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 73530, Visuwesh Eli Zaretskii <eliz@gnu.org> writes: >> Attached patch adds a function to create imenu index for Djvu files >> using djvused. If you do not have a Djvu file available, I can point >> to a file from libgen that can be used as a test file. > > Thanks, but can we please not hard-code names of programs, and instead > use variables that can be adjusted by users? I know that "mutool" was > hard-coded, but adding more hard-coded programs sounds too much. That would be good, yes. > Adding Tassilo to the discussion. > >> + When the @command{mutool} or the @command{djvused} 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 the required program 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}. > > This is misleading, I think: it leaves the impression that the two > tools are interchangeable, where in reality each one supports > different format of files. The text should say explicitly that one is > for PDF, the other for Djvu. Indeed. And while we are here: doesn anyone know why we have an option to disable imenu support? I see that we have that since Jose contributed the initial imenu support but why? I can't see any harm done if it was always enabled and would give a user-error like "For imenu support for XXX files, program YYY has to be installed" or something when invoking imenu. And why someone might want to disable it even if the required program is available is beyond my imagination. I mean, if you don't want to use imenu, then just don't invoke it... >> -(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t) >> - "Whether to generate an imenu outline when \"mutool\" is available." >> +(defcustom doc-view-imenu-enabled (and (or (executable-find "mutool") >> + (executable-find "djvused")) >> + t) >> + "Whether to generate an imenu outline when available. > > "When available" sounds awkward. "When possible", perhaps? > > Also, "generate imenu outline" is too general. Don't forget that the > first line of a doc string is shown by apropos commands, and so should > speak for itself. I would say > > Whether to generate imenu outline for PDF and DJVU files. > > The "when available" part is unnecessary, because Emacs checks for > availability, and the user can override that. Well, if we must keep this defcustom, then it should probably allow enabling/disabling the feature for each file type separately, i.e., its value should be a set (pdf djvu). Bye, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 17:02 ` Tassilo Horn @ 2024-09-28 17:35 ` Visuwesh 2024-09-28 17:53 ` Eli Zaretskii 2024-09-28 18:11 ` Tassilo Horn 0 siblings, 2 replies; 24+ messages in thread From: Visuwesh @ 2024-09-28 17:35 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, 73530 [சனி செப்டம்பர் 28, 2024] Tassilo Horn wrote: > Eli Zaretskii <eliz@gnu.org> writes: > >>> Attached patch adds a function to create imenu index for Djvu files >>> using djvused. If you do not have a Djvu file available, I can point >>> to a file from libgen that can be used as a test file. >> >> Thanks, but can we please not hard-code names of programs, and instead >> use variables that can be adjusted by users? I know that "mutool" was >> hard-coded, but adding more hard-coded programs sounds too much. > > That would be good, yes. Will do. >> Adding Tassilo to the discussion. >> >>> + When the @command{mutool} or the @command{djvused} 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 the required program 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}. >> >> This is misleading, I think: it leaves the impression that the two >> tools are interchangeable, where in reality each one supports >> different format of files. The text should say explicitly that one is >> for PDF, the other for Djvu. OK, will rewrite. > Indeed. And while we are here: doesn anyone know why we have an option > to disable imenu support? I see that we have that since Jose > contributed the initial imenu support but why? I can't see any harm > done if it was always enabled and would give a user-error like "For > imenu support for XXX files, program YYY has to be installed" or > something when invoking imenu. And why someone might want to disable it > even if the required program is available is beyond my imagination. I > mean, if you don't want to use imenu, then just don't invoke it... I was wondering the same thing, especially since the cost of making the imenu index is not that high. >>> -(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t) >>> - "Whether to generate an imenu outline when \"mutool\" is available." >>> +(defcustom doc-view-imenu-enabled (and (or (executable-find "mutool") >>> + (executable-find "djvused")) >>> + t) >>> + "Whether to generate an imenu outline when available. >> >> "When available" sounds awkward. "When possible", perhaps? >> >> Also, "generate imenu outline" is too general. Don't forget that the >> first line of a doc string is shown by apropos commands, and so should >> speak for itself. I would say >> >> Whether to generate imenu outline for PDF and DJVU files. >> >> The "when available" part is unnecessary, because Emacs checks for >> availability, and the user can override that. > > Well, if we must keep this defcustom, then it should probably allow > enabling/disabling the feature for each file type separately, i.e., its > value should be a set (pdf djvu). That would make sense. I was wondering if we should create separate defcustom for each program but this is a better approach. [ BTW, is it "DJVU" or "Djvu"? The comments in doc-view.el uses the latter AFAICT. ] > Bye, > Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 17:35 ` Visuwesh @ 2024-09-28 17:53 ` Eli Zaretskii 2024-09-28 18:11 ` Tassilo Horn 1 sibling, 0 replies; 24+ messages in thread From: Eli Zaretskii @ 2024-09-28 17:53 UTC (permalink / raw) To: Visuwesh; +Cc: 73530, tsdh > From: Visuwesh <visuweshm@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org>, 73530@debbugs.gnu.org > Date: Sat, 28 Sep 2024 23:05:33 +0530 > > [ BTW, is it "DJVU" or "Djvu"? The comments in doc-view.el uses the > latter AFAICT. ] I think it's actually DjVu. ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 17:35 ` Visuwesh 2024-09-28 17:53 ` Eli Zaretskii @ 2024-09-28 18:11 ` Tassilo Horn 2024-09-28 19:03 ` jao 1 sibling, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-28 18:11 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, 73530, Jose A. Ortega Ruiz Visuwesh <visuweshm@gmail.com> writes: >>> doc-view-imenu-enabled >> >> Indeed. And while we are here: doesn anyone know why we have an >> option to disable imenu support? I see that we have that since Jose >> contributed the initial imenu support but why? I can't see any harm >> done if it was always enabled and would give a user-error like "For >> imenu support for XXX files, program YYY has to be installed" or >> something when invoking imenu. And why someone might want to disable >> it even if the required program is available is beyond my >> imagination. I mean, if you don't want to use imenu, then just don't >> invoke it... > > I was wondering the same thing, especially since the cost of making the > imenu index is not that high. So lets ask Jose (added to Cc). Bye, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 18:11 ` Tassilo Horn @ 2024-09-28 19:03 ` jao 2024-09-28 19:15 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: jao @ 2024-09-28 19:03 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, 73530, Visuwesh On Sat, Sep 28 2024, Tassilo Horn wrote: > Visuwesh <visuweshm@gmail.com> writes: > >>>> doc-view-imenu-enabled >>> >>> Indeed. And while we are here: doesn anyone know why we have an >>> option to disable imenu support? I see that we have that since Jose >>> contributed the initial imenu support but why? I can't see any harm >>> done if it was always enabled and would give a user-error like "For >>> imenu support for XXX files, program YYY has to be installed" or >>> something when invoking imenu. And why someone might want to disable >>> it even if the required program is available is beyond my >>> imagination. I mean, if you don't want to use imenu, then just don't >>> invoke it... >> >> I was wondering the same thing, especially since the cost of making the >> imenu index is not that high. > > So lets ask Jose (added to Cc). If I recall correctly, that flag is there to save CPU cycles in case users of doc-view are not interested in imenu. The PDF's outline is scanned using mutool when doc-view-mode is activated if doc-view-imenu-enabled is true, and for big files that can take a second or two. I am not sure why I didn't delay creation of the index, but it's probably because there are menu entries to create and I didn't bother to investigate deeper. Also, because I didn't want to see a pause the first time imenu was invoked on a PDF. Admittedly, most of the time the pause is small enough to make all of the above moot. Cheers, jao -- Many people take no care of their money till they come nearly to the end of it, and others do just the same with their time. -Johann Wolfgang von Goethe (1749-1832) ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 19:03 ` jao @ 2024-09-28 19:15 ` Tassilo Horn 2024-09-28 19:50 ` Jose A. Ortega Ruiz 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-28 19:15 UTC (permalink / raw) To: jao; +Cc: Eli Zaretskii, 73530, Visuwesh jao <jao@gnu.org> writes: >>>>> doc-view-imenu-enabled > > If I recall correctly, that flag is there to save CPU cycles in case > users of doc-view are not interested in imenu. > > The PDF's outline is scanned using mutool when doc-view-mode is > activated if doc-view-imenu-enabled is true, and for big files that > can take a second or two. > > I am not sure why I didn't delay creation of the index, but it's > probably because there are menu entries to create and I didn't bother > to investigate deeper. Also, because I didn't want to see a pause the > first time imenu was invoked on a PDF. Thanks for explaining! > Admittedly, most of the time the pause is small enough to make all of > the above moot. I think I'd prefer to delay the creation of the index until imenu is invoked the first time and get rid of doc-view-imenu-enabled. If we really wanted to and the requirements are met, we could also run the index creation in an idle-timer. Probably not by default but maybe by adding and documenting a function one could add to doc-view-mode-hook for that purpose. Bye, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 19:15 ` Tassilo Horn @ 2024-09-28 19:50 ` Jose A. Ortega Ruiz 2024-09-29 14:03 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Jose A. Ortega Ruiz @ 2024-09-28 19:50 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, 73530, Visuwesh On Sat, Sep 28 2024, Tassilo Horn wrote: [...] > I think I'd prefer to delay the creation of the index until imenu is > invoked the first time and get rid of doc-view-imenu-enabled. If we > really wanted to and the requirements are met, we could also run the > index creation in an idle-timer. Probably not by default but maybe by > adding and documenting a function one could add to doc-view-mode-hook > for that purpose. FWIW, I'd keep doc-view-imenu-enabled, and use it to control the creation of the idle timer. The latter sounds like the right solution to avoid delays, and the former a much simpler strategy than asking users to configure hooks. I also very much like the idea of being able to tell emacs not to call executables in my path and create other processes behind my back. Personally, I find that ability reason enough to keep the flag, delays or not, and, now that i think of it, that was perhaps the main reason I introduced doc-view-imenu-enabled. Unconditionally spawning external processes doesn't feel right to me. Just my 2c, jao -- I took a speed reading course and read War and Peace in twenty minutes. It involves Russia. -Woody Allen ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-28 19:50 ` Jose A. Ortega Ruiz @ 2024-09-29 14:03 ` Tassilo Horn 2024-09-29 14:34 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-29 14:03 UTC (permalink / raw) To: Jose A. Ortega Ruiz; +Cc: Eli Zaretskii, 73530, Visuwesh "Jose A. Ortega Ruiz" <jao@gnu.org> writes: >> I think I'd prefer to delay the creation of the index until imenu is >> invoked the first time and get rid of doc-view-imenu-enabled. If we >> really wanted to and the requirements are met, we could also run the >> index creation in an idle-timer. Probably not by default but maybe by >> adding and documenting a function one could add to doc-view-mode-hook >> for that purpose. > > FWIW, I'd keep doc-view-imenu-enabled, and use it to control the > creation of the idle timer. The latter sounds like the right solution > to avoid delays, and the former a much simpler strategy than asking > users to configure hooks. Also fine with me. Visuwesh, would you like to proceed in that direction? Thanks, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-29 14:03 ` Tassilo Horn @ 2024-09-29 14:34 ` Visuwesh 2024-09-29 16:20 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-09-29 14:34 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [ஞாயிறு செப்டம்பர் 29, 2024] Tassilo Horn wrote: > "Jose A. Ortega Ruiz" <jao@gnu.org> writes: > >>> I think I'd prefer to delay the creation of the index until imenu is >>> invoked the first time and get rid of doc-view-imenu-enabled. If we >>> really wanted to and the requirements are met, we could also run the >>> index creation in an idle-timer. Probably not by default but maybe by >>> adding and documenting a function one could add to doc-view-mode-hook >>> for that purpose. >> >> FWIW, I'd keep doc-view-imenu-enabled, and use it to control the >> creation of the idle timer. The latter sounds like the right solution >> to avoid delays, and the former a much simpler strategy than asking >> users to configure hooks. > > Also fine with me. Visuwesh, would you like to proceed in that > direction? Is an idle timer necessary? Imenu calls the index function only when it finds that the index hasn't been created yet so we can rely on that mechanism instead. This would be simpler than using an idle timer. WDYT? > Thanks, > Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-29 14:34 ` Visuwesh @ 2024-09-29 16:20 ` Tassilo Horn 2024-09-29 16:38 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-29 16:20 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Visuwesh <visuweshm@gmail.com> writes: >>> FWIW, I'd keep doc-view-imenu-enabled, and use it to control the >>> creation of the idle timer. The latter sounds like the right >>> solution to avoid delays, and the former a much simpler strategy >>> than asking users to configure hooks. >> >> Also fine with me. Visuwesh, would you like to proceed in that >> direction? > > Is an idle timer necessary? I don't know yet. Jose said the index building could take a little while. > Imenu calls the index function only when it finds that the index > hasn't been created yet so we can rely on that mechanism instead. > This would be simpler than using an idle timer. WDYT? Then let's do it the simple way and then test how long the index building actually takes on reasonable large PDFs/DjVu files. Thanks, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-29 16:20 ` Tassilo Horn @ 2024-09-29 16:38 ` Visuwesh 2024-09-29 17:15 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-09-29 16:38 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [ஞாயிறு செப்டம்பர் 29, 2024] Tassilo Horn wrote: >> Imenu calls the index function only when it finds that the index >> hasn't been created yet so we can rely on that mechanism instead. >> This would be simpler than using an idle timer. WDYT? > > Then let's do it the simple way and then test how long the index > building actually takes on reasonable large PDFs/DjVu files. OK, I will send an updated patch in a few days. ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-29 16:38 ` Visuwesh @ 2024-09-29 17:15 ` Tassilo Horn 2024-09-30 17:29 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-09-29 17:15 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Am So, 29. Sep 2024, um 18:38, schrieb Visuwesh: > [ஞாயிறு செப்டம்பர் 29, 2024] Tassilo Horn wrote: > >>> Imenu calls the index function only when it finds that the index >>> hasn't been created yet so we can rely on that mechanism instead. >>> This would be simpler than using an idle timer. WDYT? >> >> Then let's do it the simple way and then test how long the index >> building actually takes on reasonable large PDFs/DjVu files. > > OK, I will send an updated patch in a few days. Great, thank you! Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-29 17:15 ` Tassilo Horn @ 2024-09-30 17:29 ` Visuwesh 2024-10-02 6:42 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-09-30 17:29 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [-- Attachment #1: Type: text/plain, Size: 684 bytes --] [ஞாயிறு செப்டம்பர் 29, 2024] Tassilo Horn wrote: > Am So, 29. Sep 2024, um 18:38, schrieb Visuwesh: >> [ஞாயிறு செப்டம்பர் 29, 2024] Tassilo Horn wrote: >> >>>> Imenu calls the index function only when it finds that the index >>>> hasn't been created yet so we can rely on that mechanism instead. >>>> This would be simpler than using an idle timer. WDYT? >>> >>> Then let's do it the simple way and then test how long the index >>> building actually takes on reasonable large PDFs/DjVu files. >> >> OK, I will send an updated patch in a few days. > > Great, thank you! Please review the attached. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-imenu-index-function-for-Djvu-files-in-doc-view.patch --] [-- Type: text/x-diff, Size: 9434 bytes --] From 8ccfe9440363569d6624153177d724bbcf2a122f Mon Sep 17 00:00:00 2001 From: Visuwesh <visuweshm@gmail.com> Date: Sat, 28 Sep 2024 20:37:50 +0530 Subject: [PATCH] Add imenu index function for Djvu files in doc-view * lisp/doc-view.el (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) --- doc/emacs/misc.texi | 15 +++---- etc/NEWS | 7 ++++ lisp/doc-view.el | 99 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index e19e554fb26..332d5b1468f 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -581,17 +581,14 @@ DocView Navigation 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}. + 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}. @findex doc-view-page-to-register @findex doc-view-jump-to-register diff --git a/etc/NEWS b/etc/NEWS index 607665a71bb..b6035e13639 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -268,6 +268,13 @@ Docview can store current page to buffer local registers with the new command 'doc-view-page-to-register' (bound to 'm'), and later 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 +++ diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 395993e6263..1c8bcaee2f1 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -29,6 +29,8 @@ ;; and OXPS documents require `mutool' which comes with mupdf ;; (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 files when available. ;;; Commentary: @@ -216,10 +218,23 @@ doc-view-mupdf-use-svg :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. @@ -1953,7 +1968,9 @@ doc-view--outline-rx "[^\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. @@ -1968,6 +1985,7 @@ doc-view--pdf-outline (fn (expand-file-name fn))) (with-temp-buffer (unless (eql 0 (call-process "mutool" 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) @@ -1978,6 +1996,42 @@ doc-view--pdf-outline 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. @@ -2010,19 +2064,36 @@ doc-view-imenu-index 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 -- 2.45.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-09-30 17:29 ` Visuwesh @ 2024-10-02 6:42 ` Tassilo Horn 2024-10-02 8:19 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-10-02 6:42 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Visuwesh <visuweshm@gmail.com> writes: Hi Visuwesh, [Sorry if this message appears twice but it seems to have bounced yesterday.] > Please review the attached. First of all, the patch doesn't apply on master's NEWS and misc.texi here. If I exclude those, the changes to doc-view.el can be applied. Unfortunately, I didn't find a PDF nor DjVu document on my computer where an index can be built. I have the relevant tools installed but get the message that no index can be built for that document and doc-view--outline becomes 'unavailable. I've tried various PDFs generated by LaTeX with many section, subsections, etc. For DjVu, my sample size is 1, and that's a presentation, so at least here I'm not sure if there should be an index available... That said, I haven't used the imenu feature before so I can't say if it ever worked for me... > diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi > index e19e554fb26..332d5b1468f 100644 > --- a/doc/emacs/misc.texi > +++ b/doc/emacs/misc.texi > @@ -581,17 +581,14 @@ DocView Navigation > 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}. > + DocView can generate an outline menu for PDF and Djvu documents using Didn't Eli say the official spelling was DjVu? That's at least the spelling that the djvused man pages also uses and they should know. > +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}. I guess you should mention the new defcustom doc-view-djvused-program here, too. > +(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") Ah, I thought our last agreement was that we keep that variable (as suggested by Jose) as it is used right now but make it possible to have a value that tells to index only PDF or DjVu documents. Well, I actually have no strong opinion here. Technically, I like your approach better because of its simplicity. I would like to test with some larger documents to see how long index building takes, though. Anyhow, please write a complete sentence in the deprecation, so a dot at the end. And remove the comma. Bye, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-02 6:42 ` Tassilo Horn @ 2024-10-02 8:19 ` Visuwesh 2024-10-02 14:53 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-10-02 8:19 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [-- Attachment #1: Type: text/plain, Size: 6924 bytes --] [புதன் அக்டோபர் 02, 2024] Tassilo Horn wrote: > Visuwesh <visuweshm@gmail.com> writes: > > Hi Visuwesh, > > [Sorry if this message appears twice but it seems to have bounced > yesterday.] [ I did not get the previous mail FYI. ] >> Please review the attached. > > First of all, the patch doesn't apply on master's NEWS and misc.texi > here. If I exclude those, the changes to doc-view.el can be applied. Oops, I suppose I can no longer be lazy about pulling from remote anymore. > Unfortunately, I didn't find a PDF nor DjVu document on my computer > where an index can be built. I have the relevant tools installed but > get the message that no index can be built for that document and > doc-view--outline becomes 'unavailable. > > I've tried various PDFs generated by LaTeX with many section, > subsections, etc. The PDF generated by LaTeX can have a wildly different outline than matched by doc-view's regexp: % mutool show test.pdf outline | "Text" #nameddest=section.1 | "Annotations" #nameddest=section.2 | "Links" #nameddest=section.3 | "Attachments" #nameddest=section.4 + "Outline" #nameddest=section.5 + "subsection" #nameddest=subsection.5.1 | "subsubsection" #nameddest=subsubsection.5.1.1 Compare it with: % mutool show atkins_physical_chemistry.pdf outline | "Cover" #page=1&view=Fit | "PREFACE" #page=7&view=Fit | "USING THE BOOK" #page=8&view=Fit | "ABOUT THE AUTHORS" #page=12&view=Fit | "ACKNOWLEDGEMENTS" #page=13&view=Fit | "BRIEF CONTENTS" #page=15&view=Fit | "FULL CONTENTS" #page=17&view=Fit | "CONVENTIONS" #page=27&view=Fit | "LIST OF TABLES" #page=28&view=Fit ... > For DjVu, my sample size is 1, and that's a presentation, so at least > here I'm not sure if there should be an index available... I will send the link to the DjVu file that I wrote the feature for off-list. I will send a link to a PDF file too. > That said, I haven't used the imenu feature before so I can't say if it > ever worked for me... > >> diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi >> index e19e554fb26..332d5b1468f 100644 >> --- a/doc/emacs/misc.texi >> +++ b/doc/emacs/misc.texi >> @@ -581,17 +581,14 @@ DocView Navigation >> 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}. >> + DocView can generate an outline menu for PDF and Djvu documents using > > Didn't Eli say the official spelling was DjVu? That's at least the > spelling that the djvused man pages also uses and they should know. Fixed. >> +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}. > > I guess you should mention the new defcustom doc-view-djvused-program > here, too. Done. On this note, should we use doc-view-pdfdraw-program in place of mutool in doc-view--pdf-outline? >> +(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") > > Ah, I thought our last agreement was that we keep that variable (as > suggested by Jose) as it is used right now but make it possible to have > a value that tells to index only PDF or DjVu documents. Ahh, I misunderstood the suggestion. > Well, I actually have no strong opinion here. Technically, I like your > approach better because of its simplicity. I would like to test with > some larger documents to see how long index building takes, though. I tried the function with a large PDF file: % time mutool show atkins_physical_chemistry.pdf outline >/dev/null 0m00.32s real 0m00.30s user 0m00.02s system % time mutool show atkins_physical_chemistry.pdf outline >/dev/null 0m00.30s real 0m00.26s user 0m00.03s system % mutool show atkins_physical_chemistry.pdf outline |wc -l 925 % du -h atkins_physical_chemistry.pdf 97M atkins_physical_chemistry.pdf (benchmark-run 10 (doc-view--pdf-outline "~/doc/uni/refb/atkins_physical_chemistry.pdf")) ;; => (3.0118861719999996 0 0.0) (benchmark-run 1 (doc-view--pdf-outline "~/doc/uni/refb/atkins_physical_chemistry.pdf")) ;; => (0.306343039 0 0.0) which honestly isn't that long a time to wait for the first time you say M-g i. Now for the DjVu file that I was testing on: % time djvused -e print-outline Solid_State_Physics_Ashcroft.djvu >/dev/null 0m00.24s real 0m00.23s user 0m00.01s system % djvused -e print-outline Solid_State_Physics_Ashcroft.djvu |wc -l 115 % du -sh Solid_State_Physics_Ashcroft.djvu 83M Solid_State_Physics_Ashcroft.djvu (benchmark-run 10 (doc-view--djvu-outline "~/tmp/Solid_State_Physics_Ashcroft.djvu")) ;; => (2.2234427809999997 0 0.0) (benchmark-run 1 (doc-view--djvu-outline "~/tmp/Solid_State_Physics_Ashcroft.djvu")) ;; => (0.239040117 0 0.0) IIRC, there's a djvu file somewhere stashed in my home directory that had an index. I can benchmark making the index for that file too if you want. For my init.el which has a (length imenu--index-alist) = 852, (benchmark-run 10 (setq imenu--index-alist nil) (imenu--make-index-alist)) ;; => (7.113529254 0 0.0) with REPETITIONS=1, I get (0.854962398 0 0.0). In conclusion, the waiting time is barely an inconvenience. > Anyhow, please write a complete sentence in the deprecation, so a dot at > the end. And remove the comma. Done. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-imenu-index-function-for-DjVu-files-in-doc-view.patch --] [-- Type: text/x-diff, Size: 9829 bytes --] From 54c6050fa054dfb23b9f73c46661bfb8c69cc931 Mon Sep 17 00:00:00 2001 From: Visuwesh <visuweshm@gmail.com> Date: Wed, 2 Oct 2024 13:48:25 +0530 Subject: [PATCH] Add imenu index function for DjVu files in doc-view * lisp/doc-view.el (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) --- doc/emacs/misc.texi | 18 ++++---- etc/NEWS | 7 +++ lisp/doc-view.el | 101 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 102 insertions(+), 24 deletions(-) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index b074eb034b2..7b11a829b0b 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -581,17 +581,17 @@ DocView Navigation 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 diff --git a/etc/NEWS b/etc/NEWS index abe316547aa..bbcef80b762 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -351,6 +351,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 +++ diff --git a/lisp/doc-view.el b/lisp/doc-view.el index e79295a8b01..6aa90926465 100644 --- a/lisp/doc-view.el +++ b/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: @@ -216,10 +218,23 @@ doc-view-mupdf-use-svg :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 @@ doc-view--outline-rx "[^\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. @@ -1973,6 +1990,7 @@ doc-view--pdf-outline (fn (expand-file-name fn))) (with-temp-buffer (unless (eql 0 (call-process "mutool" 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 +2001,42 @@ doc-view--pdf-outline 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 +2069,36 @@ doc-view-imenu-index 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 -- 2.45.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-02 8:19 ` Visuwesh @ 2024-10-02 14:53 ` Tassilo Horn 2024-10-03 8:03 ` Tassilo Horn 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-10-02 14:53 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Visuwesh <visuweshm@gmail.com> writes: >> Unfortunately, I didn't find a PDF nor DjVu document on my computer >> where an index can be built. I have the relevant tools installed but >> get the message that no index can be built for that document and >> doc-view--outline becomes 'unavailable. >> >> I've tried various PDFs generated by LaTeX with many section, >> subsections, etc. > > The PDF generated by LaTeX can have a wildly different outline than > matched by doc-view's regexp: > > % mutool show test.pdf outline > | "Text" #nameddest=section.1 > | "Annotations" #nameddest=section.2 > > Compare it with: > > % mutool show atkins_physical_chemistry.pdf outline > | "Cover" #page=1&view=Fit > | "PREFACE" #page=7&view=Fit > | "USING THE BOOK" #page=8&view=Fit Ok, I see. All my LaTeX PDFs have #nameddest=section.x values instead of #page=X values, so that's the reason they don't work. It would be good if we could mention that it won't work because there are no page references in the outline in the error message. >> For DjVu, my sample size is 1, and that's a presentation, so at least >> here I'm not sure if there should be an index available... > > I will send the link to the DjVu file that I wrote the feature for > off-list. I will send a link to a PDF file too. Thanks, will try with those two files. > On this note, should we use doc-view-pdfdraw-program in place of mutool > in doc-view--pdf-outline? Yes, but only if the older names pdfdraw and mudraw already had the "show <file> outline" feature. >> Well, I actually have no strong opinion here. Technically, I like >> your approach better because of its simplicity. I would like to test >> with some larger documents to see how long index building takes, >> though. > > I tried the function with a large PDF file: Will try with the large two you've linked later. Thanks, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-02 14:53 ` Tassilo Horn @ 2024-10-03 8:03 ` Tassilo Horn 2024-10-03 11:10 ` Visuwesh 2024-10-03 14:51 ` Visuwesh 0 siblings, 2 replies; 24+ messages in thread From: Tassilo Horn @ 2024-10-03 8:03 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Tassilo Horn <tsdh@gnu.org> writes: Hi again, >> The PDF generated by LaTeX can have a wildly different outline than >> matched by doc-view's regexp: >> >> % mutool show test.pdf outline >> | "Text" #nameddest=section.1 >> | "Annotations" #nameddest=section.2 >> >> Compare it with: >> >> % mutool show atkins_physical_chemistry.pdf outline >> | "Cover" #page=1&view=Fit >> | "PREFACE" #page=7&view=Fit >> | "USING THE BOOK" #page=8&view=Fit > > Ok, I see. All my LaTeX PDFs have #nameddest=section.x values instead > of #page=X values, so that's the reason they don't work. It would be > good if we could mention that it won't work because there are no page > references in the outline in the error message. Would you mind doing that in a new version of the patch? And I wonder if it mutool could spit out page references in addition to the nameddest references. Do you know if there's a technical limitation or if it's just not implemented? Sadly, their communication platform seems to be Discord where I didn't want to register an account to ask. They seem to use the ghostscript bugzilla, so one could create a ticket there... If nobody else here in the discussion already has an account there, I wouldn't mind creating ony myself and asking. >>> For DjVu, my sample size is 1, and that's a presentation, so at least >>> here I'm not sure if there should be an index available... >> >> I will send the link to the DjVu file that I wrote the feature for >> off-list. I will send a link to a PDF file too. > > Thanks, will try with those two files. I did so now and it is blazingly fast for those 80+mb PDF/DjVu files even on my almost 10 years old laptop, so I'd say your simpler approach is the right choice. >> On this note, should we use doc-view-pdfdraw-program in place of >> mutool in doc-view--pdf-outline? > > Yes, but only if the older names pdfdraw and mudraw already had the > "show <file> outline" feature. I revert the "but only if" part. If mupdf is old and comes with, e.g., the pdfdraw executable, chances are almost zero that mutool is installed, too. And if it is, then we should prefer it anywhere. So I think the way to go is to (executable-find "mutool") in doc-view-pdfdraw-program first so that it takes precedence and use doc-view-pdfdraw-program in doc-view--pdf-outline. >>> Well, I actually have no strong opinion here. Technically, I like >>> your approach better because of its simplicity. I would like to test >>> with some larger documents to see how long index building takes, >>> though. >> >> I tried the function with a large PDF file: > > Will try with the large two you've linked later. As said above, it's more than fast enough, so let's take your approach. Thanks, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-03 8:03 ` Tassilo Horn @ 2024-10-03 11:10 ` Visuwesh 2024-10-03 12:11 ` Tassilo Horn 2024-10-03 14:51 ` Visuwesh 1 sibling, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-10-03 11:10 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [வியாழன் அக்டோபர் 03, 2024] Tassilo Horn wrote: > Tassilo Horn <tsdh@gnu.org> writes: > > Hi again, > >>> The PDF generated by LaTeX can have a wildly different outline than >>> matched by doc-view's regexp: >>> >>> % mutool show test.pdf outline >>> | "Text" #nameddest=section.1 >>> | "Annotations" #nameddest=section.2 >>> >>> Compare it with: >>> >>> % mutool show atkins_physical_chemistry.pdf outline >>> | "Cover" #page=1&view=Fit >>> | "PREFACE" #page=7&view=Fit >>> | "USING THE BOOK" #page=8&view=Fit >> >> Ok, I see. All my LaTeX PDFs have #nameddest=section.x values instead >> of #page=X values, so that's the reason they don't work. It would be >> good if we could mention that it won't work because there are no page >> references in the outline in the error message. > > Would you mind doing that in a new version of the patch? > > And I wonder if it mutool could spit out page references in addition to > the nameddest references. Do you know if there's a technical limitation > or if it's just not implemented? Unfortunately, I have no idea. I actually don't use doc-view for PDF files, only for docx and DjVu. > Sadly, their communication platform seems to be Discord where I didn't > want to register an account to ask. They seem to use the ghostscript > bugzilla, so one could create a ticket there... If nobody else here in > the discussion already has an account there, I wouldn't mind creating > ony myself and asking. If I cannot find anything in the man page, I can ask in their Discord. I do have an account lying around, I can at least put it to good use. Can this be done in another patch later on? I am not sure if I will get the time soon to follow up on this part of the problem. It would be cleaner if we open another bug report to track this too. >>>> For DjVu, my sample size is 1, and that's a presentation, so at least >>>> here I'm not sure if there should be an index available... >>> >>> I will send the link to the DjVu file that I wrote the feature for >>> off-list. I will send a link to a PDF file too. >> >> Thanks, will try with those two files. > > I did so now and it is blazingly fast for those 80+mb PDF/DjVu files > even on my almost 10 years old laptop, so I'd say your simpler approach > is the right choice. > >>> On this note, should we use doc-view-pdfdraw-program in place of >>> mutool in doc-view--pdf-outline? >> >> Yes, but only if the older names pdfdraw and mudraw already had the >> "show <file> outline" feature. > > I revert the "but only if" part. If mupdf is old and comes with, e.g., > the pdfdraw executable, chances are almost zero that mutool is > installed, too. And if it is, then we should prefer it anywhere. So I > think the way to go is to (executable-find "mutool") in > doc-view-pdfdraw-program first so that it takes precedence and use > doc-view-pdfdraw-program in doc-view--pdf-outline. OK, I will post a patch if you're okay with opening another bug report for the nameddest PDF thingy. >>>> Well, I actually have no strong opinion here. Technically, I like >>>> your approach better because of its simplicity. I would like to test >>>> with some larger documents to see how long index building takes, >>>> though. >>> >>> I tried the function with a large PDF file: >> >> Will try with the large two you've linked later. > > As said above, it's more than fast enough, so let's take your approach. Great, thank you for taking the time to test the patch. ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-03 11:10 ` Visuwesh @ 2024-10-03 12:11 ` Tassilo Horn 0 siblings, 0 replies; 24+ messages in thread From: Tassilo Horn @ 2024-10-03 12:11 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 Hi again, of course we should do the nameddest thing in another patch. No reason to put this one on hold. Thanks, Tassilo Am Do, 3. Okt 2024, um 13:10, schrieb Visuwesh: > [வியாழன் அக்டோபர் 03, 2024] Tassilo Horn wrote: > >> Tassilo Horn <tsdh@gnu.org> writes: >> >> Hi again, >> >>>> The PDF generated by LaTeX can have a wildly different outline than >>>> matched by doc-view's regexp: >>>> >>>> % mutool show test.pdf outline >>>> | "Text" #nameddest=section.1 >>>> | "Annotations" #nameddest=section.2 >>>> >>>> Compare it with: >>>> >>>> % mutool show atkins_physical_chemistry.pdf outline >>>> | "Cover" #page=1&view=Fit >>>> | "PREFACE" #page=7&view=Fit >>>> | "USING THE BOOK" #page=8&view=Fit >>> >>> Ok, I see. All my LaTeX PDFs have #nameddest=section.x values instead >>> of #page=X values, so that's the reason they don't work. It would be >>> good if we could mention that it won't work because there are no page >>> references in the outline in the error message. >> >> Would you mind doing that in a new version of the patch? >> >> And I wonder if it mutool could spit out page references in addition to >> the nameddest references. Do you know if there's a technical limitation >> or if it's just not implemented? > > Unfortunately, I have no idea. I actually don't use doc-view for PDF > files, only for docx and DjVu. > >> Sadly, their communication platform seems to be Discord where I didn't >> want to register an account to ask. They seem to use the ghostscript >> bugzilla, so one could create a ticket there... If nobody else here in >> the discussion already has an account there, I wouldn't mind creating >> ony myself and asking. > > If I cannot find anything in the man page, I can ask in their Discord. > I do have an account lying around, I can at least put it to good use. > > Can this be done in another patch later on? I am not sure if I will get > the time soon to follow up on this part of the problem. It would be > cleaner if we open another bug report to track this too. > >>>>> For DjVu, my sample size is 1, and that's a presentation, so at least >>>>> here I'm not sure if there should be an index available... >>>> >>>> I will send the link to the DjVu file that I wrote the feature for >>>> off-list. I will send a link to a PDF file too. >>> >>> Thanks, will try with those two files. >> >> I did so now and it is blazingly fast for those 80+mb PDF/DjVu files >> even on my almost 10 years old laptop, so I'd say your simpler approach >> is the right choice. >> >>>> On this note, should we use doc-view-pdfdraw-program in place of >>>> mutool in doc-view--pdf-outline? >>> >>> Yes, but only if the older names pdfdraw and mudraw already had the >>> "show <file> outline" feature. >> >> I revert the "but only if" part. If mupdf is old and comes with, e.g., >> the pdfdraw executable, chances are almost zero that mutool is >> installed, too. And if it is, then we should prefer it anywhere. So I >> think the way to go is to (executable-find "mutool") in >> doc-view-pdfdraw-program first so that it takes precedence and use >> doc-view-pdfdraw-program in doc-view--pdf-outline. > > OK, I will post a patch if you're okay with opening another bug report > for the nameddest PDF thingy. > >>>>> Well, I actually have no strong opinion here. Technically, I like >>>>> your approach better because of its simplicity. I would like to test >>>>> with some larger documents to see how long index building takes, >>>>> though. >>>> >>>> I tried the function with a large PDF file: >>> >>> Will try with the large two you've linked later. >> >> As said above, it's more than fast enough, so let's take your approach. > > Great, thank you for taking the time to test the patch. ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-03 8:03 ` Tassilo Horn 2024-10-03 11:10 ` Visuwesh @ 2024-10-03 14:51 ` Visuwesh 2024-10-04 5:31 ` Tassilo Horn 1 sibling, 1 reply; 24+ messages in thread From: Visuwesh @ 2024-10-03 14:51 UTC (permalink / raw) To: Tassilo Horn; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530 [-- Attachment #1: Type: text/plain, Size: 1680 bytes --] [வியாழன் அக்டோபர் 03, 2024] Tassilo Horn wrote: >>>> For DjVu, my sample size is 1, and that's a presentation, so at least >>>> here I'm not sure if there should be an index available... >>> >>> I will send the link to the DjVu file that I wrote the feature for >>> off-list. I will send a link to a PDF file too. >> >> Thanks, will try with those two files. > > I did so now and it is blazingly fast for those 80+mb PDF/DjVu files > even on my almost 10 years old laptop, so I'd say your simpler approach > is the right choice. > >>> On this note, should we use doc-view-pdfdraw-program in place of >>> mutool in doc-view--pdf-outline? >> >> Yes, but only if the older names pdfdraw and mudraw already had the >> "show <file> outline" feature. > > I revert the "but only if" part. If mupdf is old and comes with, e.g., > the pdfdraw executable, chances are almost zero that mutool is > installed, too. And if it is, then we should prefer it anywhere. So I > think the way to go is to (executable-find "mutool") in > doc-view-pdfdraw-program first so that it takes precedence and use > doc-view-pdfdraw-program in doc-view--pdf-outline. > >>>> Well, I actually have no strong opinion here. Technically, I like >>>> your approach better because of its simplicity. I would like to test >>>> with some larger documents to see how long index building takes, >>>> though. >>> >>> I tried the function with a large PDF file: >> >> Will try with the large two you've linked later. > > As said above, it's more than fast enough, so let's take your approach. I have now attached a patch with the above change. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-imenu-index-function-for-DjVu-files-in-doc-view.patch --] [-- Type: text/x-diff, Size: 10574 bytes --] From 441f0e9339a853ac011d08c8754fc5c9217d146f Mon Sep 17 00:00:00 2001 From: Visuwesh <visuweshm@gmail.com> Date: Wed, 2 Oct 2024 13:48:25 +0530 Subject: [PATCH] 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) --- doc/emacs/misc.texi | 18 ++++---- etc/NEWS | 7 +++ lisp/doc-view.el | 108 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 27 deletions(-) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index b074eb034b2..7b11a829b0b 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -581,17 +581,17 @@ DocView Navigation 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 diff --git a/etc/NEWS b/etc/NEWS index abe316547aa..bbcef80b762 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -351,6 +351,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 +++ diff --git a/lisp/doc-view.el b/lisp/doc-view.el index e79295a8b01..3683f1f60d4 100644 --- a/lisp/doc-view.el +++ b/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 @@ doc-view-ghostscript-program (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 @@ doc-view-mupdf-use-svg :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 @@ doc-view--outline-rx "[^\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 @@ doc-view--pdf-outline (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 @@ doc-view--pdf-outline 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 @@ doc-view-imenu-index 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 -- 2.45.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-03 14:51 ` Visuwesh @ 2024-10-04 5:31 ` Tassilo Horn 2024-10-04 7:31 ` Visuwesh 0 siblings, 1 reply; 24+ messages in thread From: Tassilo Horn @ 2024-10-04 5:31 UTC (permalink / raw) To: Visuwesh; +Cc: Eli Zaretskii, Jose A. Ortega Ruiz, 73530-done Visuwesh <visuweshm@gmail.com> writes: >> As said above, it's more than fast enough, so let's take your approach. > > I have now attached a patch with the above change. Applied and pushed to master. I'm closing this issue. Thanks a lot, Tassilo ^ permalink raw reply [flat|nested] 24+ messages in thread
* bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view 2024-10-04 5:31 ` Tassilo Horn @ 2024-10-04 7:31 ` Visuwesh 0 siblings, 0 replies; 24+ messages in thread From: Visuwesh @ 2024-10-04 7:31 UTC (permalink / raw) To: 73530; +Cc: tsdh [வெள்ளி அக்டோபர் 04, 2024] Tassilo Horn wrote: > Visuwesh <visuweshm@gmail.com> writes: > >>> As said above, it's more than fast enough, so let's take your approach. >> >> I have now attached a patch with the above change. > > Applied and pushed to master. I'm closing this issue. Great, thank you! ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2024-10-04 7:31 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-09-28 15:10 bug#73530: [PATCH] Add imenu index function for Djvu files in doc-view Visuwesh 2024-09-28 15:42 ` Eli Zaretskii 2024-09-28 17:02 ` Tassilo Horn 2024-09-28 17:35 ` Visuwesh 2024-09-28 17:53 ` Eli Zaretskii 2024-09-28 18:11 ` Tassilo Horn 2024-09-28 19:03 ` jao 2024-09-28 19:15 ` Tassilo Horn 2024-09-28 19:50 ` Jose A. Ortega Ruiz 2024-09-29 14:03 ` Tassilo Horn 2024-09-29 14:34 ` Visuwesh 2024-09-29 16:20 ` Tassilo Horn 2024-09-29 16:38 ` Visuwesh 2024-09-29 17:15 ` Tassilo Horn 2024-09-30 17:29 ` Visuwesh 2024-10-02 6:42 ` Tassilo Horn 2024-10-02 8:19 ` Visuwesh 2024-10-02 14:53 ` Tassilo Horn 2024-10-03 8:03 ` Tassilo Horn 2024-10-03 11:10 ` Visuwesh 2024-10-03 12:11 ` Tassilo Horn 2024-10-03 14:51 ` Visuwesh 2024-10-04 5:31 ` Tassilo Horn 2024-10-04 7:31 ` Visuwesh
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).