1

In my LaTeX code I have strings like:

\arXivid{1602.00735}

that create, in the generated PDF file, a link to, e.g. https://arxiv.org/abs/1602.00735.

I'd like to have the string \arXivid{1602.00735} clickable, like urls in goto-address-mode, opening the relative url in the browser.

How can I do it? Do I need to use a text-property?

I don't really need to fontify the string like goto-address-mode does.

3
  • Can we eliminate the PDF from the equation and just make the \arXivid{1602.00735} clickable? Also, are you seeking to incorporate this behavior into the AUCTeX library such that the text-properties are automatically laid; e.g., as font-lock does its thing?
    – lawlist
    Jan 29 at 22:27
  • The PDF stuff is only the explanation of what the LaTeX code does. It doesn't matter. I just need the string to be clickable and pointing to the correct url. Jan 29 at 22:30
  • Have a look at org-set-font-lock-defaults and see how the links are activated as part of font-lock ... You may wish to do something similar with the AUCTeX or other similar library that you are using to fontify the buffer text. The answer to this question, however, is non-trivial (in my opinion) but nevertheless completely doable.
    – lawlist
    Jan 29 at 22:36
3

The standard way to define clickable text is explained in the manual.

  • put an appropriate face, e.g. link and the text property keymap on the link text.
  • bind the follow-link event in that keymap to a function, e.g. arXivid-follow, that transforms the text into a link
  • the function gets an event that leads you to the click position where you can extract the id and transform it into a link
  • follow the link with browse-url

As lawlist indicated in his comment, you can let font-lock find and propertize the link text in the buffer.

The following code defines a minor mode arXivid-mode that adds the required keyword to font-lock-keywords.

(defun arXivid-link-at-point (&optional point)
  "Return \\arXivid{ID} link at POINT or nil if there is none."
  (save-excursion
    (when point
      (goto-char point))
    (skip-chars-backward "^[:space:]\\\\")
    (and
     (eq (char-before) ?\\)
     (looking-at "arXivid{\\([0-9.]+\\)}")
     (concat "https://arxiv.org/abs/" (match-string 1)))))

(defun arXivid-follow (event)
  "Follow \\arXivid{ID} links."
  (interactive "e")
  (let ((window (posn-window (event-end event)))
        (pos (posn-point (event-end event)))
    link)
    (if (not (windowp window))
        (error "Something is very wrong..."))
    (with-current-buffer (window-buffer window)
      (goto-char pos)
      (let ((link (arXivid-link-at-point)))
    (when link
      (browse-url link))))))

(defvar arXivid-keymap
  (let ((map (make-sparse-keymap)))
    (define-key map [follow-link] #'arXivid-follow)
    map)
  "Keymap for \\arXivid{ID} links.")

(defvar arXivid-keywords
  '(("\\\\arXivid{\\([0-9.]+\\)}"
     (0 `(face
      link
      keymap
      ,arXivid-keymap)
    prepend)))
  "Additional font lock keywords for `arXivid-mode'.")

(define-minor-mode arXivid-mode
  "Minor mode making \\arXivid{ID} clickable."
  :lighter " arX"
  (if arXivid-mode
      (font-lock-add-keywords
       nil
       arXivid-keywords
       t)
    (font-lock-remove-keywords
     nil
     arXivid-keywords))
  (font-lock-flush)
  (font-lock-ensure))
8
  • It works. I'll try to add the follow link with a shortcut (C.c RET) feature, like in goto-address-mode, by myself. Thank you . Jan 30 at 10:17
  • Is event in arXivid-follow a mouse click by default? Can I change it to allow follow-lin also by typing (C-c RET)? Jan 30 at 11:26
  • 1
    Evaluating (info "(elisp) Input Events") should tell you all you need to know about events.
    – NickD
    Jan 30 at 12:32
  • I tried: (defvar arXivid-keymap (let ((map (make-sparse-keymap))) (define-key map [follow-link] #'arXivid-follow) (define-key map (kbd "C-c RET") #'arXivid-follow) map) "Keymap for \\arXivid{ID} links.") but I get: Wrong type argument: commandp, arXivid-follow Jan 30 at 15:56
  • Yes, that's a bug in @Tobias's code I think: it needs to be made interactive: just add (interactive) at the beginning of arXivid-follow and see whether that works.
    – NickD
    Jan 30 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.