org-element: Only allow plain links in links
authorNicolas Goaziou <n.goaziou@gmail.com>
Mon, 25 Feb 2013 20:32:15 +0000 (25 21:32 +0100)
committerNicolas Goaziou <n.goaziou@gmail.com>
Mon, 25 Feb 2013 21:16:01 +0000 (25 22:16 +0100)
* lisp/org-element.el (org-element-all-successors): Add `plain-link'
  successor.
(org-element-object-restrictions): Remove `link' within `link'.  Allow
`plain-link' instead.
(org-element-plain-link-successor): New function.
* testing/lisp/test-org-element.el: Add test.

Plain links within links are needed for the following kind of syntax:

  [[http://orgmode.org][file:unicorn.png]]

No other link type is allowed within links.

lisp/org-element.el
testing/lisp/test-org-element.el

index 1c9ee9f..fb12b41 100644 (file)
@@ -186,7 +186,7 @@ is not sufficient to know if point is at a paragraph ending.  See
 
 (defconst org-element-all-successors
   '(export-snippet footnote-reference inline-babel-call inline-src-block
-                  latex-or-entity line-break link macro radio-target
+                  latex-or-entity line-break link macro plain-link radio-target
                   statistics-cookie sub/superscript table-cell target
                   text-markup timestamp)
   "Complete list of successors.")
@@ -198,7 +198,6 @@ is not sufficient to know if point is at a paragraph ending.  See
     (verbatim . text-markup) (entity . latex-or-entity)
     (latex-fragment . latex-or-entity))
   "Alist of translations between object type and successor name.
-
 Sharing the same successor comes handy when, for example, the
 regexp matching one object can also match the other object.")
 
@@ -315,8 +314,8 @@ a secondary string.")
          link macro radio-target sub/superscript target text-markup)
     (keyword inline-babel-call inline-src-block latex-or-entity link macro
             sub/superscript text-markup timestamp)
-    (link export-snippet inline-babel-call inline-src-block latex-or-entity link
-         sub/superscript text-markup)
+    (link export-snippet inline-babel-call inline-src-block latex-or-entity
+         plain-link sub/superscript text-markup)
     (paragraph export-snippet footnote-reference inline-babel-call
               inline-src-block latex-or-entity line-break link macro
               radio-target statistics-cookie sub/superscript target text-markup
@@ -3101,6 +3100,16 @@ beginning position."
       (when (re-search-forward link-regexp limit t)
        (cons 'link (match-beginning 0))))))
 
+(defun org-element-plain-link-successor (limit)
+  "Search for the next plain link object.
+
+LIMIT bounds the search.
+
+Return value is a cons cell whose CAR is `link' and CDR is
+beginning position."
+  (and (save-excursion (re-search-forward org-plain-link-re limit t))
+       (cons 'link (match-beginning 0))))
+
 
 ;;;; Macro
 
index 5a08b9e..cfb66e8 100644 (file)
@@ -1193,7 +1193,7 @@ e^{i\\pi}+1=0
 
 (ert-deftest test-org-element/link-parser ()
   "Test `link' parser."
-  ;; 1. Radio target.
+  ;; Radio target.
   (should
    (equal
     "radio"
@@ -1201,18 +1201,18 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map
-       (let ((org-target-link-regexp "radio")) (org-element-parse-buffer))
-       'link 'identity nil t)))))
-  ;; 2. Standard link.
+          (let ((org-target-link-regexp "radio")) (org-element-parse-buffer))
+          'link 'identity nil t)))))
+  ;; Standard link.
   ;;
-  ;; 2.1. With description.
+  ;; ... with description.
   (should
    (equal
     '("Orgmode.org")
     (org-test-with-temp-text "[[http://orgmode.org][Orgmode.org]]"
       (org-element-contents
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.2. Without description.
+  ;; ... without description.
   (should
    (equal
     "http"
@@ -1220,7 +1220,7 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.3. With expansion.
+  ;; ... with expansion.
   (should
    (equal
     "//orgmode.org/worg"
@@ -1229,7 +1229,7 @@ e^{i\\pi}+1=0
        (org-element-property
         :path
         (org-element-map (org-element-parse-buffer) 'link 'identity nil t))))))
-  ;; 2.4. With translation.
+  ;; ... with translation.
   (should
    (equal
     "127.0.0.1"
@@ -1238,9 +1238,9 @@ e^{i\\pi}+1=0
        (let ((org-link-translation-function 'link-translate))
          (org-element-property
           :path
-          (org-element-map
-           (org-element-parse-buffer) 'link 'identity nil t)))))))
-  ;; 2.5. Id link.
+          (org-element-map (org-element-parse-buffer) 'link
+            'identity nil t)))))))
+  ;; ... id link.
   (should
    (equal
     "id"
@@ -1248,7 +1248,7 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.6. Custom-id link.
+  ;; ... custom-id link.
   (should
    (equal
     "custom-id"
@@ -1256,7 +1256,7 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.7 Coderef link.
+  ;; ... coderef link.
   (should
    (equal
     "coderef"
@@ -1264,7 +1264,7 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.8 Fuzzy link.
+  ;; ... fuzzy link.
   (should
    (equal
     "fuzzy"
@@ -1272,31 +1272,29 @@ e^{i\\pi}+1=0
       (org-element-property
        :type
        (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))))
-  ;; 2.9 File-type link with search option.
+  ;; ... file-type link with search option.
   (should
    (equal
     '(("file" "projects.org" "*task title"))
     (org-test-with-temp-text "[[file:projects.org::*task title]]"
-      (org-element-map
-       (org-element-parse-buffer) 'link
-       (lambda (l) (list (org-element-property :type l)
-                   (org-element-property :path l)
-                   (org-element-property :search-option l)))))))
-  ;; 2.10 File-type link with application.
+      (org-element-map (org-element-parse-buffer) 'link
+       (lambda (l) (list (org-element-property :type l)
+                    (org-element-property :path l)
+                    (org-element-property :search-option l)))))))
+  ;; ... file-type link with application.
   (should
    (equal
     '(("file" "projects.org" "docview"))
     (org-test-with-temp-text "[[docview:projects.org]]"
-      (org-element-map
-       (org-element-parse-buffer) 'link
-       (lambda (l) (list (org-element-property :type l)
-                   (org-element-property :path l)
-                   (org-element-property :application l)))))))
-  ;; 3. Plain link.
+      (org-element-map (org-element-parse-buffer) 'link
+       (lambda (l) (list (org-element-property :type l)
+                    (org-element-property :path l)
+                    (org-element-property :application l)))))))
+  ;; Plain link.
   (should
    (org-test-with-temp-text "A link: http://orgmode.org"
      (org-element-map (org-element-parse-buffer) 'link 'identity)))
-  ;; 4. Angular link.
+  ;; Angular link.
   (should
    (org-test-with-temp-text "A link: <http://orgmode.org>"
      (org-element-map (org-element-parse-buffer) 'link 'identity nil t)))
@@ -1314,10 +1312,15 @@ e^{i\\pi}+1=0
          (org-test-with-temp-text
              "#+LINK: orgmode http://www.orgmode.org/\n* H [[orgmode:#docs]]"
            (progn (org-mode-restart)
-                  (org-element-map
-                   (org-element-parse-buffer) 'link
-                   (lambda (link) (org-element-property :type link))
-                   nil t nil t))))))
+                  (org-element-map (org-element-parse-buffer) 'link
+                    (lambda (link) (org-element-property :type link))
+                    nil t nil t)))))
+  ;; Plain links are allowed as description of regular links.
+  (should
+   (equal "file"
+         (org-test-with-temp-text "[[http://orgmode.org][file:unicorn.jpg]]"
+           (search-forward "file:")
+           (org-element-property :type (org-element-context))))))
 
 
 ;;;; Macro