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 new syntax node of link type containing
:type, :type-explicit-p, :path, :format, :raw-link,
:application, :search-option, :begin, :end, :contents-begin,
:contents-end and :post-blank as properties. 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 new syntax node of `link' type containing
`:type', `:type-explicit-p', `:path', `:format', `:raw-link',
`:application', `:search-option', `:begin', `:end', `:contents-begin',
`:contents-end' and `:post-blank' as properties. 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
(explicit-type-p nil))
(cond
;; Type 1: Text targeted from a radio target.
((and org-target-link-regexp
(save-excursion (or (bolp) (backward-char))
(if org-target-link-regexps
(org--re-list-looking-at org-target-link-regexps)
(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 ignoring
;; 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-p "\\`\\.\\.?/" 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-no-properties 1 raw-link))
(setq explicit-type-p t)
(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 explicit-type-p t)
(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 explicit-type-p t)
(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-no-properties 1 type))
(setq type "file")
(when (string-match "::\\(.*\\)\\'" path)
(setq search-option (match-string-no-properties 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 explicit-type-p t)
(setq path (cdr trans))))
(org-element-create
'link
(list :type (org-element--get-cached-string type)
:type-explicit-p explicit-type-p
: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)))))