diff --git a/contrib/lisp/org-e-ascii.el b/contrib/lisp/org-e-ascii.el index 8654df553..f4f6fa249 100644 --- a/contrib/lisp/org-e-ascii.el +++ b/contrib/lisp/org-e-ascii.el @@ -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") diff --git a/contrib/lisp/org-e-html.el b/contrib/lisp/org-e-html.el index a887cffcb..a724df125 100644 --- a/contrib/lisp/org-e-html.el +++ b/contrib/lisp/org-e-html.el @@ -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 "%s" - (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 "%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")) diff --git a/contrib/lisp/org-e-latex.el b/contrib/lisp/org-e-latex.el index c14d6a40d..07917ad31 100644 --- a/contrib/lisp/org-e-latex.el +++ b/contrib/lisp/org-e-latex.el @@ -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")) diff --git a/contrib/lisp/org-e-odt.el b/contrib/lisp/org-e-odt.el index 433b535a0..12f81d6df 100644 --- a/contrib/lisp/org-e-odt.el +++ b/contrib/lisp/org-e-odt.el @@ -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")) diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el index 5ac00e2fa..8a104d261 100644 --- a/contrib/lisp/org-export.el +++ b/contrib/lisp/org-export.el @@ -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 diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el index 910eaddcc..5075c87ac 100644 --- a/testing/lisp/test-org-export.el +++ b/testing/lisp/test-org-export.el @@ -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" + (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" + (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