Function: org-odt-link

org-odt-link is a byte-compiled function defined in ox-odt.el.gz.

Signature

(org-odt-link LINK DESC INFO)

Documentation

Transcode a LINK object from Org to ODT.

DESC is the description part of the link, or the empty string. INFO is a plist holding contextual information. See org-export-data.

Source Code

;; Defined in /usr/src/emacs/lisp/org/ox-odt.el.gz
(defun org-odt-link (link desc info)
  "Transcode a LINK object from Org to ODT.

DESC is the description part of the link, or the empty string.
INFO is a plist holding contextual information.  See
`org-export-data'."
  (let* ((type (org-element-property :type link))
	 (raw-path (org-element-property :path link))
	 ;; Ensure DESC really exists, or set it to nil.
	 (desc (and (not (string= desc "")) desc))
	 (imagep (org-export-inline-image-p
		  link (plist-get info :odt-inline-image-rules)))
	 (path (cond
		((string= type "file")
                 (let ((path-uri (org-export-file-uri raw-path)))
                   (if (string-prefix-p "file://" path-uri)
                       path-uri
                     ;; Otherwise, it is a relative path.
                     ;; OpenOffice treats base directory inside the odt
                     ;; archive.  The directory containing the odt file
                     ;; is "../".
                     (concat "../" path-uri))))
		(t (concat type ":" raw-path))))
	 ;; Convert & to & for correct XML representation
	 (path (replace-regexp-in-string "&" "&" path))
         (raw-path (replace-regexp-in-string "&" "&" raw-path)))
    (cond
     ;; Link type is handled by a special function.
     ((org-export-custom-protocol-maybe link desc 'odt info))
     ;; Image file.
     ((and (not desc) imagep) (org-odt-link--inline-image link info))
     ;; Formula file.
     ((and (not desc)
	   (org-export-inline-image-p
	    link (plist-get info :odt-inline-formula-rules)))
      (org-odt-link--inline-formula link info))
     ;; Radio target: Transcode target's contents and use them as
     ;; link's description.
     ((string= type "radio")
      (let ((destination (org-export-resolve-radio-link link info)))
	(if (not destination) desc
	  (format
	   "<text:bookmark-ref text:reference-format=\"text\" text:ref-name=\"OrgXref.%s\">%s</text:bookmark-ref>"
	   (org-export-get-reference destination info)
	   desc))))
     ;; Links pointing to a headline: Find destination and build
     ;; appropriate referencing command.
     ((member type '("custom-id" "fuzzy" "id"))
      (let ((destination (if (string= type "fuzzy")
			     (org-export-resolve-fuzzy-link link info)
			   (org-export-resolve-id-link link info))))
	(cl-case (org-element-type destination)
	  ;; Fuzzy link points to a headline.  If there's
	  ;; a description, create a hyperlink.  Otherwise, try to
	  ;; provide a meaningful description.
	  (headline
	   (if (not desc) (org-odt-link--infer-description destination info)
	     (let ((label
		    (or (and (string= type "custom-id")
			     (org-element-property :CUSTOM_ID destination))
			(org-export-get-reference destination info))))
	       (format
		"<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
		label desc))))
	  ;; Fuzzy link points to a target.  If there's a description,
	  ;; create a hyperlink.  Otherwise, try to provide
	  ;; a meaningful description.
	  (target
	   (format "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
		   (org-export-get-reference destination info)
		   (or desc (org-export-get-ordinal destination info))))
          ;; Link to a file, corresponding to string return value of
          ;; `org-export-resolve-id-link'.  Export it is file link.
          (plain-text
           (let ((file-link (org-element-copy link)))
             (org-element-put-property file-link :type "file")
             (org-element-put-property file-link :path destination)
             (org-element-put-property
              file-link
              :raw-link (format "file:%s" destination))
             (org-odt-link file-link desc info)))
	  ;; Fuzzy link points to some element (e.g., an inline image,
	  ;; a math formula or a table).
	  (otherwise
	   (let ((label-reference
		  (ignore-errors
		    (org-odt-format-label destination info 'reference))))
	     (cond
	      ((not label-reference)
	       (org-odt-link--infer-description destination info))
	      ;; LINK has no description.  Create
	      ;; a cross-reference showing entity's sequence
	      ;; number.
	      ((not desc) label-reference)
	      ;; LINK has description.  Insert a hyperlink with
	      ;; user-provided description.
	      (t
	       (format
		"<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
		(org-export-get-reference destination info)
		desc))))))))
     ;; Coderef: replace link with the reference name or the
     ;; equivalent line number.
     ((string= type "coderef")
      (let* ((line-no (format "%d" (org-export-resolve-coderef raw-path info)))
	     (href (concat "coderef-" raw-path)))
	(format
	 (org-export-get-coderef-format raw-path desc)
	 (format
	  "<text:bookmark-ref text:reference-format=\"number\" text:ref-name=\"OrgXref.%s\">%s</text:bookmark-ref>"
	  href line-no))))
     ;; External link with a description part.
     ((and path desc)
      (let ((link-contents (org-element-contents link)))
	;; Check if description is a link to an inline image.
	(if (and (not (cdr link-contents))
		 (let ((desc-element (car link-contents)))
		   (and (org-element-type-p desc-element 'link)
			(org-export-inline-image-p
			 desc-element
			 (plist-get info :odt-inline-image-rules)))))
	    ;; Format link as a clickable image.
	    (format "\n<draw:a xlink:type=\"simple\" xlink:href=\"%s\">\n%s\n</draw:a>"
		    path desc)
	  ;; Otherwise, format it as a regular link.
	  (format "<text:a xlink:type=\"simple\" xlink:href=\"%s\">%s</text:a>"
		  path desc))))
     ;; External link without a description part.
     (path
      (format "<text:a xlink:type=\"simple\" xlink:href=\"%s\">%s</text:a>"
	      path path))
     ;; No path, only description.  Try to do something useful.
     (t (format "<text:span text:style-name=\"%s\">%s</text:span>"
		"Emphasis" desc)))))