Function: org-link-expand-abbrev

org-link-expand-abbrev is a byte-compiled function defined in ol.el.gz.

Signature

(org-link-expand-abbrev LINK)

Documentation

Replace link abbreviations in LINK string.

Abbreviations are defined in org-link-abbrev-alist.

Source Code

;; Defined in /usr/src/emacs/lisp/org/ol.el.gz
(defun org-link-expand-abbrev (link)
  "Replace link abbreviations in LINK string.
Abbreviations are defined in `org-link-abbrev-alist'."
  (if (not (string-match "^\\([^:]*\\)\\(::?\\(.*\\)\\)?$" link)) link
    (let* ((key (match-string 1 link))
	   (as (or (assoc key org-link-abbrev-alist-local)
		   (assoc key org-link-abbrev-alist)))
	   (tag (and (match-end 2) (match-string 3 link)))
	   rpl)
      (if (not as)
	  link
	(setq rpl (cdr as))
        (cl-macrolet
            ((eval-or-disable (&rest body)
               "Run BODY and disable AS abbrev if it errs."
               `(condition-case err
                    (progn ,@body)
                  (error
                   (org-display-warning
                    (format "Disabling link abbrev %s <- %s after expansion failure: %S"
                            rpl link (error-message-string err)))
                   (setq org-link-abbrev-alist-local (delete as org-link-abbrev-alist-local)
                         org-link-abbrev-alist (delete as org-link-abbrev-alist))
                   link))))
          ;; Drop any potentially dangerous text properties like
          ;; `modification-hooks' that may be used as an attack vector.
          (substring-no-properties
           (cond
            ((symbolp rpl)
             (eval-or-disable
              (let ((expanded (funcall rpl tag)))
                (unless (stringp expanded)
                  (error "%s did not return a string: %S" rpl expanded))
                expanded)))
            ((string-match "%(\\([^)]+\\))" rpl)
             (let ((rpl-fun-symbol (intern-soft (match-string 1 rpl))))
               ;; Using `unsafep-function' is not quite enough because
               ;; Emacs considers functions like `getenv' safe, while
               ;; they can potentially be used to expose private system
               ;; data to attacker if abbreviated link is clicked.
               (if (or (eq t (get rpl-fun-symbol 'org-link-abbrev-safe))
                       (eq t (get rpl-fun-symbol 'pure)))
                   (eval-or-disable
                    (replace-match
                     (save-match-data
                       (funcall rpl-fun-symbol tag))
                     t t rpl))
                 (org-display-warning
                  (format "Disabling unsafe link abbrev: %s
You may mark function safe via (put '%s 'org-link-abbrev-safe t)"
                          rpl (match-string 1 rpl)))
                 (setq org-link-abbrev-alist-local (delete as org-link-abbrev-alist-local)
                       org-link-abbrev-alist (delete as org-link-abbrev-alist))
                 link
                 )))
            ((string-match "%s" rpl) (replace-match (or tag "") t t rpl))
            ((string-match "%h" rpl)
             (replace-match (url-hexify-string (or tag "")) t t rpl))
            (t (concat rpl tag)))))))))