0

Here I found a solution on how to copy an URL from an org-link.

When applied to these two org-link:

[[https://emacs.stackexchange.com/][Emacs StackExchange]]
[[./path/file.org][An org file]]

It will respectively copy these strings:

https://emacs.stackexchange.com/
file:./path/file.org

I would have liked to have the two following strings copied instead:

https://emacs.stackexchange.com/
./path/

How could I achieve this?

UPDATE:

As I didn't make explicit the solution I was referring to in the first line of the question, here it is:

(defun farynaio/org-link-copy (&optional arg)
  "Extract URL from org-mode link and add it to kill ring."
  (interactive "P")
  (let* ((link (org-element-lineage (org-element-context) '(link) t))
          (type (org-element-property :type link))
          (url (org-element-property :path link))
          (url (concat type ":" url)))
    (kill-new url)
    (message (concat "Copied URL: " url))))

(define-key org-mode-map (kbd "C-x C-l") 'farynaio/org-link-copy)
NickD
  • 27,023
  • 3
  • 23
  • 42
crocefisso
  • 1,141
  • 7
  • 15

1 Answers1

1

Modify the yank handler in the answer you linked to as follows:

(defun my-yank-org-link (text)
  (if (derived-mode-p 'org-mode)
      (insert text)
    (string-match org-bracket-link-regexp text)
    (insert (my-mangle-url (substring text (match-beginning 1) (match-end 1))))))

(defun my-mangle-url (urlstr)
   (let ((url (url-generic-parse-url urlstr)))
     (if (not (equal (url-type url) "file"))
        urlstr
       (file-name-directory (url-filename url)))))

You will need to load the url-parse library before using the my-mangle-url function.

There are various ill-defined situations (e.g. if the filename is a directory, do you want to leave it alone or do you want to get the containing directory? The implementation does the latter. There may be problems with junk after the filename, although the line number spec file:./path/foo.org::3 works). I am also not convinced of the usefulness of it, but you can try it out and see.

EDIT: I assumed that the OP wanted to use the accepted answer in the linked question, but that is not the case.

Nevertheless, whatever the way one obtains the URL string out of the Org mode link, all one has to do is apply the my-mangle-url function to it (after fixing the bugs in that function :-) ) resulting in the modified output the OP wants:

(my-mangle-url "https://emacs.stackexchange.com/") ==> "https://emacs.stackexchange.com/"
(my-mangle-url "file:./path/foo.org::3") ==> "./path/"

Then it is just a matter of modifying @Navidot's answer e.g. to pass the modified string to kill-new:

   ...
   (kill-new (my-mangle-url url))
   ...
NickD
  • 27,023
  • 3
  • 23
  • 42
  • Thanks! I'm not able to make your code work but I'm trying to understand it so I could modify it. Isn't there a missing parenthesis at the end? About its usefulness, it is to easily produce `p` (see https://emacs.stackexchange.com/questions/75298/how-to-create-an-org-link-pointing-to-an-org-file-by-automatically-following-a , the question you commented yesterday) when pointing on an `org-link` from my index. About my answer to this previous question, the code I put works, but I wonder if it is well written... – crocefisso Jan 11 '23 at 16:50
  • 1
    I didn't try it out, assuming that the accepted answer to the [linked question](https://emacs.stackexchange.com/questions/3981/how-to-copy-links-out-of-org-mode) was the behavior you wanted, except for the "file" case which is the only thing I modified. I'll try it out when I get a chance and update the answer appropriately. – NickD Jan 11 '23 at 17:04
  • Oh I understand. Actually, I didn't try the accepted answer I tried Navidot's answer (second answer in points) which was more recent and seemed simpler. – crocefisso Jan 11 '23 at 17:12
  • See the edited answer (and note that there were three bugs (!) in `my-mangle-url` - I should never post without testing...) – NickD Jan 11 '23 at 17:49
  • Thank you NickD! It works perfectly! – crocefisso Jan 11 '23 at 17:58