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

From: Visuwesh <[email-masked]>
Date: Mon, 07 Oct 2024 14:56:16 +0530

[திங்கள் அக்டோபர் 07, 2024] Tassilo Horn wrote:

> 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.

Ahh, the intention of the condition-case below was to handle this case.
Thanks for catching my mistake, it is a common error of mine to forget
the NOERROR argument.

>> +          (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.

I do not think it is worth the trouble since only syntax errors are
likely to surface up in stderr which would be very unlikely.  If the PDF
file does not have an outline, there would be nothing printed by our
script so end-of-file error should catch that case.  

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

If you are okay with leaving out the stderr case, I will send a patch
with a non-nil NOERROR argument to the quoted search-forward form.