Subject: Re: bug#73638: 31.0.50; doc-view: imenu index cannot be made for LaTeX PDFs

From: Tassilo Horn <[email-masked]>
Date: Mon, 07 Oct 2024 09:02:31 +0200

Visuwesh <[email-masked]> writes:

Hi!

>> I don't do that very frequently.  I think it would be simpler if we
>> skip the sentinel and instead use some :buffer " *mutool-run-result*"
>> with make-process and just read from there after the
>> accept-process-output loop.
>
> That was a serious brainfart, indeed.  I've went with your approach in
> the attached, please review.
>
> @@ -1986,21 +1998,25 @@ doc-view--pdf-outline
>  structure is extracted by `doc-view--imenu-subtree'."
>    (let ((fn (or file-name (buffer-file-name))))
>      (when fn
> -      (let ((outline nil)
> -            (fn (expand-file-name fn)))
> -        (with-temp-buffer
> -          (unless (eql 0 (call-process doc-view-pdfdraw-program nil
> -                                       (current-buffer) nil "show" fn "outline"))
> +      (with-temp-buffer
> +        (let ((proc (make-process
> +                     :name "doc-view-pdf-outline"
> +                     :command (list "mutool" "run")
> +                     :buffer (current-buffer))))
> +          (process-send-string proc (format doc-view--mutool-pdf-outline-script
> +                                            (expand-file-name fn)))
> +          ;; Need to send this twice for some reason...
> +          (process-send-eof)
> +          (process-send-eof)
> +          (while (accept-process-output proc))
> +          (unless (eq (process-status proc) 'exit)
>              (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)
> -            (push `((level . ,(length (match-string 1)))
> -                    (title . ,(replace-regexp-in-string "\\\\[rt]" " "
> -                                                        (match-string 2)))
> -                    (page . ,(string-to-number (match-string 3))))
> -                  outline)))
> -        (nreverse outline)))))
> +          (search-forward "BEGIN")

If the script fails for some reason, there will be no BEGIN and we let a
search-failed error bubble up.  So I'd put it in the condition-case and
handle it like the end-of-file error.  Or simply provide the NOERROR
search-forward arg.

> +          (condition-case nil
> +              (read (current-buffer))
> +            (end-of-file nil)))))))

Maybe it would also a good idea to use a :stderr buffer with
make-process and put its contents into the imenu-unavailable-error.
That way, chances are better we get the reason for failure delivered in
bug reports.

Otherwise, it all looks good to me. :-)

Thanks,
  Tassilo