Browse Source

org-element: Only allow plain links in links

* 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.
Nicolas Goaziou 12 years ago
parent
commit
7cd6fdcd34
2 changed files with 48 additions and 36 deletions
  1. 13 4
      lisp/org-element.el
  2. 35 32
      testing/lisp/test-org-element.el

+ 13 - 4
lisp/org-element.el

@@ -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
 

+ 35 - 32
testing/lisp/test-org-element.el

@@ -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