org-export: Implement `org-export-resolve-radio-link'

* contrib/lisp/org-export.el (org-export-resolve-coderef): New function.
* contrib/lisp/org-e-ascii.el (org-e-ascii-link): Use new function.
* contrib/lisp/org-e-html.el (org-e-html-link): Use new function.
* contrib/lisp/org-e-latex.el (org-e-latex-link): Use new function.
* contrib/lisp/org-e-odt.el (org-e-odt-link): Use new function.
* testing/lisp/test-org-export.el: Add tests.
This commit is contained in:
Nicolas Goaziou 2012-05-18 11:20:00 +02:00
parent e1eb6a4af2
commit 51472b4d33
6 changed files with 81 additions and 60 deletions

View File

@ -61,7 +61,7 @@
(declare-function org-export-resolve-coderef "org-export" (ref info))
(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
(declare-function org-export-resolve-id-link "org-export" (link info))
(declare-function org-export-resolve-ref-link "org-export" (link info))
(declare-function org-export-resolve-radio-link "org-export" (link info))
(declare-function
org-export-to-file "org-export"
(backend file &optional subtreep visible-only body-only ext-plist))
@ -1451,11 +1451,9 @@ INFO is a plist holding contextual information."
;; Do not apply a special syntax on radio links. Though, parse
;; and transcode path to have a proper display of contents.
((string= type "radio")
(org-export-data
(org-element-parse-secondary-string
(org-element-property :path link)
(cdr (assq 'radio-target org-element-object-restrictions)))
info))
(let ((destination (org-export-resolve-radio-link link info)))
(when destination
(org-export-data (org-element-contents destination) info))))
;; Do not apply a special syntax on fuzzy links pointing to
;; targets.
((string= type "fuzzy")

View File

@ -44,10 +44,6 @@
(declare-function org-element-get-property "org-element" (property element))
(declare-function org-element-normalize-string "org-element" (s))
(declare-function org-element-parse-secondary-string
"org-element" (string restriction &optional buffer))
(defvar org-element-string-restrictions)
(defvar org-element-object-restrictions)
(declare-function org-export-data "org-export" (data info))
(declare-function org-export-directory "org-export" (type plist))
@ -71,6 +67,7 @@
"org-export" (extension &optional subtreep pub-dir))
(declare-function org-export-resolve-coderef "org-export" (ref info))
(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
(declare-function org-export-resolve-radio-link "org-export" (link info))
(declare-function org-export-solidify-link-text "org-export" (s))
(declare-function
org-export-to-buffer "org-export"
@ -2479,12 +2476,11 @@ INFO is a plist holding contextual information. See
;; link. Path is parsed and transcoded in order to have a proper
;; display of the contents.
((string= type "radio")
(format "<a href=\"#%s\">%s</a>"
(org-export-solidify-link-text path)
(org-export-data
(org-element-parse-secondary-string
path (org-element-restriction 'radio-target))
info)))
(let ((destination (org-export-resolve-radio-link link info)))
(when destination
(format "<a href=\"#%s\">%s</a>"
(org-export-solidify-link-text path)
(org-export-data (org-element-contents destination) info)))))
;; Links pointing to an headline: Find destination and build
;; appropriate referencing command.
((member type '("custom-id" "fuzzy" "id"))

View File

@ -42,10 +42,6 @@
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-normalize-string "org-element" (s))
(declare-function org-element-parse-secondary-string
"org-element" (string restriction &optional buffer))
(defvar org-element-string-restrictions)
(defvar org-element-object-restrictions)
(declare-function org-export-data "org-export" (data info))
(declare-function org-export-directory "org-export" (type plist))
@ -71,6 +67,7 @@
"org-export" (extension &optional subtreep pub-dir))
(declare-function org-export-resolve-coderef "org-export" (ref info))
(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
(declare-function org-export-resolve-radio-link "org-export" (link info))
(declare-function org-export-solidify-link-text "org-export" (s))
(declare-function
org-export-to-buffer "org-export"
@ -1587,12 +1584,11 @@ INFO is a plist holding contextual information. See
;; link. Path is parsed and transcoded in order to have a proper
;; display of the contents.
((string= type "radio")
(format "\\hyperref[%s]{%s}"
(org-export-solidify-link-text path)
(org-export-data
(org-element-parse-secondary-string
path (cdr (assq 'radio-target org-element-object-restrictions)))
info)))
(let ((destination (org-export-resolve-radio-link link info)))
(when destination
(format "\\hyperref[%s]{%s}"
(org-export-solidify-link-text path)
(org-export-data (org-element-contents destination) info)))))
;; Links pointing to an headline: Find destination and build
;; appropriate referencing command.
((member type '("custom-id" "fuzzy" "id"))

View File

@ -1428,10 +1428,6 @@ formula file."
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-normalize-string "org-element" (s))
(declare-function org-element-parse-secondary-string
"org-element" (string restriction &optional buffer))
(defvar org-element-string-restrictions)
(defvar org-element-object-restrictions)
(declare-function org-export-data "org-export" (data info))
(declare-function org-export-directory "org-export" (type plist))
@ -1456,6 +1452,7 @@ formula file."
"org-export" (extension &optional subtreep pub-dir))
(declare-function org-export-resolve-coderef "org-export" (ref info))
(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
(declare-function org-export-resolve-radio-link "org-export" (link info))
(declare-function org-export-solidify-link-text "org-export" (s))
(declare-function
org-export-to-buffer "org-export"
@ -3619,12 +3616,11 @@ INFO is a plist holding contextual information. See
;; link. Path is parsed and transcoded in order to have a proper
;; display of the contents.
((string= type "radio")
(org-e-odt-format-internal-link
(org-export-data
(org-element-parse-secondary-string
path (org-element-restriction 'radio-target))
info)
(org-export-solidify-link-text path)))
(let ((destination (org-export-resolve-radio-link link info)))
(when destination
(org-e-odt-format-internal-link
(org-export-data (org-element-contents destination) info)
(org-export-solidify-link-text path)))))
;; Links pointing to an headline: Find destination and build
;; appropriate referencing command.
((member type '("custom-id" "fuzzy" "id"))

View File

@ -2891,6 +2891,34 @@ This only applies to links without a description."
(org-element-property :path link))))
rules))))
(defun org-export-resolve-coderef (ref info)
"Resolve a code reference REF.
INFO is a plist used as a communication channel.
Return associated line number in source code, or REF itself,
depending on src-block or example element's switches."
(org-element-map
(plist-get info :parse-tree) '(example-block src-block)
(lambda (el)
(with-temp-buffer
(insert (org-trim (org-element-property :value el)))
(let* ((label-fmt (regexp-quote
(or (org-element-property :label-fmt el)
org-coderef-label-format)))
(ref-re
(format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
(replace-regexp-in-string "%s" ref label-fmt nil t))))
;; Element containing REF is found. Resolve it to either
;; a label or a line number, as needed.
(when (re-search-backward ref-re nil t)
(cond
((org-element-property :use-labels el) ref)
((eq (org-element-property :number-lines el) 'continued)
(+ (org-export-get-loc el info) (line-number-at-pos)))
(t (line-number-at-pos)))))))
info 'first-match))
(defun org-export-resolve-fuzzy-link (link info)
"Return LINK destination.
@ -2975,33 +3003,19 @@ is either \"id\" or \"custom-id\"."
headline))
info 'first-match)))
(defun org-export-resolve-coderef (ref info)
"Resolve a code reference REF.
(defun org-export-resolve-radio-link (link info)
"Return radio-target object referenced as LINK destination.
INFO is a plist used as a communication channel.
Return associated line number in source code, or REF itself,
depending on src-block or example element's switches."
(org-element-map
(plist-get info :parse-tree) '(example-block src-block)
(lambda (el)
(with-temp-buffer
(insert (org-trim (org-element-property :value el)))
(let* ((label-fmt (regexp-quote
(or (org-element-property :label-fmt el)
org-coderef-label-format)))
(ref-re
(format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
(replace-regexp-in-string "%s" ref label-fmt nil t))))
;; Element containing REF is found. Resolve it to either
;; a label or a line number, as needed.
(when (re-search-backward ref-re nil t)
(cond
((org-element-property :use-labels el) ref)
((eq (org-element-property :number-lines el) 'continued)
(+ (org-export-get-loc el info) (line-number-at-pos)))
(t (line-number-at-pos)))))))
info 'first-match))
Return value can be a radio-target object or nil. Assume LINK
has type \"radio\"."
(let ((path (org-element-property :path link)))
(org-element-map
(plist-get info :parse-tree) 'radio-target
(lambda (radio)
(when (equal (org-element-property :value radio) path) radio))
info 'first-match)))
;;;; For Macros

View File

@ -637,6 +637,27 @@ Another text. (ref:text)
(should (equal (org-export-resolve-coderef "text" `(:parse-tree ,tree))
"text"))))))
(ert-deftest test-org-export/resolve-radio-link ()
"Test `org-export-resolve-radio-link' specifications."
;; Standard test.
(org-test-with-temp-text "<<<radio>>> radio"
(org-update-radio-target-regexp)
(should
(let* ((tree (org-element-parse-buffer))
(info `(:parse-tree ,tree)))
(org-export-resolve-radio-link
(org-element-map tree 'link 'identity info t)
info))))
;; Radio target with objects.
(org-test-with-temp-text "<<<radio \\alpha>>> radio \\alpha"
(org-update-radio-target-regexp)
(should
(let* ((tree (org-element-parse-buffer))
(info `(:parse-tree ,tree)))
(org-export-resolve-radio-link
(org-element-map tree 'link 'identity info t)
info)))))
;;; Src-block and example-block