On 03/03/2021 05:36, Kyle Meyer wrote:
Rodrigo Morales writes:

[...]
+ create a Org link to specific pages of a PDF and highlight a given
   string.

#+begin_src emacs-lisp :results silent
(setq org-file-apps
       '(("\\.pdf::\\([0-9]+\\)::\\([^:]+\\)\\'" . "zathura -P %1 -f %2 %s")))
#+end_src

The following link must open the PDF at a given page and highlight the
given string. However, I'm getting the following error (see the
=#+begin_example= block below.)

[[file:~/Downloads/grub.pdf::95::do]]

Correct link should be [[info:grub#true]] (a joke, at least a kind of).

Actually I never considered search string for highlighting of particular text, so thank you for the hint. Browsers could generate (mutually incompatible) link to particular rectangle. With xpopple (fork of old xpdf) it is possible to send command to select region.

However I think it is better to use logical links instead of page numbers:

   okular --find do ~/Downloads/grub.pdf'#true'
   xpdf ~/Downloads/grub.pdf +true

Unfortunately firefox replaces "#" to percent-encoded sequence in command line argument and could not find the file. It requires editing in address bar.

#+begin_example
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
   replace-match(nil t t "zathura -P 95 -f %2 
/home/username/Downloads/grub....")

I haven't looked at this closely or tried to trigger the error, but an
in-flight patch is touching this area
(<https://orgmode.org/list/87mtw8fupl....@kyleam.com>).  I've yet to
revisit it to address Maxim's helpful feedback, but I hope to soon and
will look at this error then too.

Kyle, your patch works for such handlers. This case is another argument to replace all substitutions in a single pass. Global state (match data) is the source of the problem.

I am attaching informal single-line patch for quick plumbing. Alternative is to use save-match-data around string-match inside the loop.
diff --git a/lisp/org.el b/lisp/org.el
index fd6226702..f45adb308 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -8757,8 +8757,8 @@ If the file does not exist, throw an error."
       (save-match-data
 	(let ((match-index 1)
 	      (number-of-groups (- (/ (length link-match-data) 2) 1)))
-	  (set-match-data link-match-data)
 	  (while (<= match-index number-of-groups)
+	    (set-match-data link-match-data)
 	    (let ((regex (concat "%" (number-to-string match-index)))
 		  (replace-with (match-string match-index dlink)))
 	      (while (string-match regex cmd)

Reply via email to