Function: org-element-link-parser

org-element-link-parser is a byte-compiled function defined in org-element.el.gz.

Signature

(org-element-link-parser)

Documentation

Parse link at point, if any.

When at a link, return a list whose car is link and cdr a plist with :type, :path, :format, :raw-link, :application,
:search-option, :begin, :end, :contents-begin,
:contents-end and :post-blank as keywords. Otherwise, return
nil.

Assume point is at the beginning of the link.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-element.el.gz
;;;; Link

(defun org-element-link-parser ()
  "Parse link at point, if any.

When at a link, return a list whose car is `link' and cdr a plist
with `:type', `:path', `:format', `:raw-link', `:application',
`:search-option', `:begin', `:end', `:contents-begin',
`:contents-end' and `:post-blank' as keywords.  Otherwise, return
nil.

Assume point is at the beginning of the link."
  (catch 'no-object
    (let ((begin (point))
	  end contents-begin contents-end link-end post-blank path type format
	  raw-link search-option application)
      (cond
       ;; Type 1: Text targeted from a radio target.
       ((and org-target-link-regexp
	     (save-excursion (or (bolp) (backward-char))
			     (looking-at org-target-link-regexp)))
	(setq type "radio")
	(setq format 'plain)
	(setq link-end (match-end 1))
	(setq path (match-string-no-properties 1))
	(setq contents-begin (match-beginning 1))
	(setq contents-end (match-end 1)))
       ;; Type 2: Standard link, i.e. [[https://orgmode.org][website]]
       ((looking-at org-link-bracket-re)
	(setq format 'bracket)
	(setq contents-begin (match-beginning 2))
	(setq contents-end (match-end 2))
	(setq link-end (match-end 0))
	;; RAW-LINK is the original link.  Decode any encoding.
	;; Expand any abbreviation in it.
	;;
	;; Also treat any newline character and associated
	;; indentation as a single space character.  This is not
	;; compatible with RFC 3986, which requires to ignore
	;; them altogether.  However, doing so would require
	;; users to encode spaces on the fly when writing links
	;; (e.g., insert [[shell:ls%20*.org]] instead of
	;; [[shell:ls *.org]], which defeats Org's focus on
	;; simplicity.
	(setq raw-link (org-link-expand-abbrev
			(org-link-unescape
			 (replace-regexp-in-string
			  "[ \t]*\n[ \t]*" " "
			  (match-string-no-properties 1)))))
	;; Determine TYPE of link and set PATH accordingly.  According
	;; to RFC 3986, remove whitespaces from URI in external links.
	;; In internal ones, treat indentation as a single space.
	(cond
	 ;; File type.
	 ((or (file-name-absolute-p raw-link)
	      (string-match "\\`\\.\\.?/" raw-link))
	  (setq type "file")
	  (setq path raw-link))
	 ;; Explicit type (http, irc, bbdb...).
	 ((string-match org-link-types-re raw-link)
	  (setq type (match-string 1 raw-link))
	  (setq path (substring raw-link (match-end 0))))
	 ;; Code-ref type: PATH is the name of the reference.
	 ((and (string-match-p "\\`(" raw-link)
	       (string-match-p ")\\'" raw-link))
	  (setq type "coderef")
	  (setq path (substring raw-link 1 -1)))
	 ;; Custom-id type: PATH is the name of the custom id.
	 ((= (string-to-char raw-link) ?#)
	  (setq type "custom-id")
	  (setq path (substring raw-link 1)))
	 ;; Fuzzy type: Internal link either matches a target, an
	 ;; headline name or nothing.  PATH is the target or
	 ;; headline's name.
	 (t
	  (setq type "fuzzy")
	  (setq path raw-link))))
       ;; Type 3: Plain link, e.g., https://orgmode.org
       ((looking-at org-link-plain-re)
	(setq format 'plain)
	(setq raw-link (match-string-no-properties 0))
	(setq type (match-string-no-properties 1))
	(setq link-end (match-end 0))
	(setq path (match-string-no-properties 2)))
       ;; Type 4: Angular link, e.g., <https://orgmode.org>.  Unlike to
       ;; bracket links, follow RFC 3986 and remove any extra
       ;; whitespace in URI.
       ((looking-at org-link-angle-re)
	(setq format 'angle)
	(setq type (match-string-no-properties 1))
	(setq link-end (match-end 0))
	(setq raw-link
	      (buffer-substring-no-properties
	       (match-beginning 1) (match-end 2)))
	(setq path (replace-regexp-in-string
		    "[ \t]*\n[ \t]*" "" (match-string-no-properties 2))))
       (t (throw 'no-object nil)))
      ;; In any case, deduce end point after trailing white space from
      ;; LINK-END variable.
      (save-excursion
	(setq post-blank
	      (progn (goto-char link-end) (skip-chars-forward " \t")))
	(setq end (point)))
      ;; Special "file"-type link processing.  Extract opening
      ;; application and search option, if any.  Also normalize URI.
      (when (string-match "\\`file\\(?:\\+\\(.+\\)\\)?\\'" type)
	(setq application (match-string 1 type))
	(setq type "file")
	(when (string-match "::\\(.*\\)\\'" path)
	  (setq search-option (match-string 1 path))
	  (setq path (replace-match "" nil nil path)))
	(setq path (replace-regexp-in-string "\\`///*\\(.:\\)?/" "\\1/" path)))
      ;; Translate link, if `org-link-translation-function' is set.
      (let ((trans (and (functionp org-link-translation-function)
			(funcall org-link-translation-function type path))))
	(when trans
	  (setq type (car trans))
	  (setq path (cdr trans))))
      (list 'link
	    (list :type type
		  :path path
		  :format format
		  :raw-link (or raw-link path)
		  :application application
		  :search-option search-option
		  :begin begin
		  :end end
		  :contents-begin contents-begin
		  :contents-end contents-end
		  :post-blank post-blank)))))