Browse Source

org-element: Change to export-snippet syntax

* contrib/lisp/org-element.el (org-element-export-snippet-parser):
  Change syntax from @back-end{contents} to <back-end@contents>.
(org-element-export-snippet-successor): Use new syntax
* testing/lisp/test-org-element.el: Add test.

This change is required as curly braces conflict with LaTeX syntax
when trying to break a command in two parts.  On the other hand, HTML
tags can be broken easily in two.  More explicitely, both the
following constructs are possible now:

  <latex@\textsc{>Name<latex@}> and <html@<b>>
Nicolas Goaziou 13 years ago
parent
commit
803d76825a
2 changed files with 186 additions and 167 deletions
  1. 17 9
      contrib/lisp/org-element.el
  2. 169 158
      testing/lisp/test-org-element.el

+ 17 - 9
contrib/lisp/org-element.el

@@ -1927,12 +1927,16 @@ keywords.
 
 
 Assume point is at the beginning of the snippet."
 Assume point is at the beginning of the snippet."
   (save-excursion
   (save-excursion
-    (looking-at "@\\([-A-Za-z0-9]+\\){")
+    (looking-at "<\\([-A-Za-z0-9]+\\)@")
     (let* ((begin (point))
     (let* ((begin (point))
 	   (back-end (org-match-string-no-properties 1))
 	   (back-end (org-match-string-no-properties 1))
-	   (before-blank (progn (goto-char (scan-sexps (1- (match-end 0)) 1))))
-	   (value (buffer-substring-no-properties
-		   (match-end 0) (1- before-blank)))
+	   (inner-begin (match-end 0))
+	   (inner-end
+	    (let ((count 1))
+	      (while (and (> count 0) (re-search-forward "[<>]" nil t))
+		(if (equal (match-string 0) "<") (incf count) (decf count)))
+	      (1- (point))))
+	   (value (buffer-substring-no-properties inner-begin inner-end))
 	   (post-blank (skip-chars-forward " \t"))
 	   (post-blank (skip-chars-forward " \t"))
 	   (end (point)))
 	   (end (point)))
       `(export-snippet
       `(export-snippet
@@ -1945,7 +1949,7 @@ Assume point is at the beginning of the snippet."
 (defun org-element-export-snippet-interpreter (export-snippet contents)
 (defun org-element-export-snippet-interpreter (export-snippet contents)
   "Interpret EXPORT-SNIPPET object as Org syntax.
   "Interpret EXPORT-SNIPPET object as Org syntax.
 CONTENTS is nil."
 CONTENTS is nil."
-  (format "@%s{%s}"
+  (format "<%s@%s>"
 	  (org-element-property :back-end export-snippet)
 	  (org-element-property :back-end export-snippet)
 	  (org-element-property :value export-snippet)))
 	  (org-element-property :value export-snippet)))
 
 
@@ -1958,10 +1962,14 @@ Return value is a cons cell whose CAR is `export-snippet' CDR is
 its beginning position."
 its beginning position."
   (save-excursion
   (save-excursion
     (catch 'exit
     (catch 'exit
-      (while (re-search-forward "@[-A-Za-z0-9]+{" limit t)
-	(when (let ((end (ignore-errors (scan-sexps (1- (point)) 1))))
-		(and end (eq (char-before end) ?})))
-	  (throw 'exit (cons 'export-snippet (match-beginning 0))))))))
+      (while (re-search-forward "<[-A-Za-z0-9]+@" limit t)
+	(save-excursion
+	  (let ((beg (match-beginning 0))
+		(count 1))
+	    (while (re-search-forward "[<>]" limit t)
+	      (if (equal (match-string 0) "<") (incf count) (decf count))
+	      (when (zerop count)
+		(throw 'exit (cons 'export-snippet beg))))))))))
 
 
 
 
 ;;;; Footnote Reference
 ;;;; Footnote Reference

+ 169 - 158
testing/lisp/test-org-element.el

@@ -34,80 +34,8 @@ Return interpreted string."
 
 
 
 
 
 
-;;; Tests:
+;;; Test Parsers
 
 
-
-;;;; Headlines
-
-(ert-deftest test-org-element/headline-quote-keyword ()
-  "Test QUOTE keyword recognition."
-  ;; Reference test.
-  (org-test-with-temp-text "* Headline"
-    (let ((org-quote-string "QUOTE"))
-      (should-not (org-element-property :quotedp (org-element-at-point)))))
-  ;; Standard position.
-  (org-test-with-temp-text "* QUOTE Headline"
-    (let ((org-quote-string "QUOTE"))
-      (let ((headline (org-element-at-point)))
-	(should (org-element-property :quotedp headline))
-	;; Test removal from raw value.
-	(should (equal (org-element-property :raw-value headline) "Headline"))))
-    ;; Case sensitivity.
-    (let ((org-quote-string "Quote"))
-      (should-not (org-element-property :quotedp (org-element-at-point)))))
-  ;; With another keyword.
-  (org-test-with-temp-text "* TODO QUOTE Headline"
-    (let ((org-quote-string "QUOTE")
-	  (org-todo-keywords '((sequence "TODO" "DONE"))))
-      (should (org-element-property :quotedp (org-element-at-point))))))
-
-(ert-deftest test-org-element/headline-comment-keyword ()
-  "Test COMMENT keyword recognition."
-  ;; Reference test.
-  (org-test-with-temp-text "* Headline"
-    (let ((org-comment-string "COMMENT"))
-      (should-not (org-element-property :commentedp (org-element-at-point)))))
-  ;; Standard position.
-  (org-test-with-temp-text "* COMMENT Headline"
-    (let ((org-comment-string "COMMENT"))
-      (let ((headline (org-element-at-point)))
-	(should (org-element-property :commentedp headline))
-	;; Test removal from raw value.
-	(should (equal (org-element-property :raw-value headline) "Headline"))))
-    ;; Case sensitivity.
-    (let ((org-comment-string "Comment"))
-      (should-not (org-element-property :commentedp (org-element-at-point)))))
-  ;; With another keyword.
-  (org-test-with-temp-text "* TODO COMMENT Headline"
-    (let ((org-comment-string "COMMENT")
-	  (org-todo-keywords '((sequence "TODO" "DONE"))))
-      (should (org-element-property :commentedp (org-element-at-point))))))
-
-(ert-deftest test-org-element/headline-archive-tag ()
-  "Test ARCHIVE tag recognition."
-  ;; Reference test.
-  (org-test-with-temp-text "* Headline"
-    (let ((org-archive-tag "ARCHIVE"))
-      (should-not (org-element-property :archivedp (org-element-at-point)))))
-  ;; Single tag.
-  (org-test-with-temp-text "* Headline :ARCHIVE:"
-    (let ((org-archive-tag "ARCHIVE"))
-      (let ((headline (org-element-at-point)))
-	(should (org-element-property :archivedp headline))
-	;; Test tag removal.
-	(should-not (org-element-property :tags headline))))
-    (let ((org-archive-tag "Archive"))
-      (should-not (org-element-property :archivedp (org-element-at-point)))))
-  ;; Multiple tags.
-  (org-test-with-temp-text "* Headline :test:ARCHIVE:"
-    (let ((org-archive-tag "ARCHIVE"))
-      (let ((headline (org-element-at-point)))
-	(should (org-element-property :archivedp headline))
-	;; Test tag removal.
-	(should (equal (org-element-property :tags headline) ":test:"))))))
-
-
-
 ;;;; Example-blocks and Src-blocks
 ;;;; Example-blocks and Src-blocks
 
 
 (ert-deftest test-org-element/block-switches ()
 (ert-deftest test-org-element/block-switches ()
@@ -210,8 +138,21 @@ Return interpreted string."
 	 (equal (org-element-property :label-fmt element) "[ref:%s]"))))))
 	 (equal (org-element-property :label-fmt element) "[ref:%s]"))))))
 
 
 
 
-
-;;;; Footnotes references and definitions
+;;;; Export snippets
+
+(ert-deftest test-org-element/export-snippet ()
+  "Test export-snippet parsing."
+  (should
+   (equal
+    (org-test-with-temp-text "<back-end@contents>"
+      (org-element-map
+       (org-element-parse-buffer) 'export-snippet 'identity nil t))
+    '(export-snippet
+      (:back-end "back-end"
+		 :value "contents" :begin 1 :end 20 :post-blank 0)))))
+
+
+;;;; Footnotes references
 
 
 (ert-deftest test-org-element/footnote-reference ()
 (ert-deftest test-org-element/footnote-reference ()
   "Test footnote-reference parsing."
   "Test footnote-reference parsing."
@@ -267,7 +208,76 @@ Return interpreted string."
       (org-element-parse-buffer) 'footnote-reference 'identity))))
       (org-element-parse-buffer) 'footnote-reference 'identity))))
 
 
 
 
-
+;;;; Headlines
+
+(ert-deftest test-org-element/headline-quote-keyword ()
+  "Test QUOTE keyword recognition."
+  ;; Reference test.
+  (org-test-with-temp-text "* Headline"
+    (let ((org-quote-string "QUOTE"))
+      (should-not (org-element-property :quotedp (org-element-at-point)))))
+  ;; Standard position.
+  (org-test-with-temp-text "* QUOTE Headline"
+    (let ((org-quote-string "QUOTE"))
+      (let ((headline (org-element-at-point)))
+	(should (org-element-property :quotedp headline))
+	;; Test removal from raw value.
+	(should (equal (org-element-property :raw-value headline) "Headline"))))
+    ;; Case sensitivity.
+    (let ((org-quote-string "Quote"))
+      (should-not (org-element-property :quotedp (org-element-at-point)))))
+  ;; With another keyword.
+  (org-test-with-temp-text "* TODO QUOTE Headline"
+    (let ((org-quote-string "QUOTE")
+	  (org-todo-keywords '((sequence "TODO" "DONE"))))
+      (should (org-element-property :quotedp (org-element-at-point))))))
+
+(ert-deftest test-org-element/headline-comment-keyword ()
+  "Test COMMENT keyword recognition."
+  ;; Reference test.
+  (org-test-with-temp-text "* Headline"
+    (let ((org-comment-string "COMMENT"))
+      (should-not (org-element-property :commentedp (org-element-at-point)))))
+  ;; Standard position.
+  (org-test-with-temp-text "* COMMENT Headline"
+    (let ((org-comment-string "COMMENT"))
+      (let ((headline (org-element-at-point)))
+	(should (org-element-property :commentedp headline))
+	;; Test removal from raw value.
+	(should (equal (org-element-property :raw-value headline) "Headline"))))
+    ;; Case sensitivity.
+    (let ((org-comment-string "Comment"))
+      (should-not (org-element-property :commentedp (org-element-at-point)))))
+  ;; With another keyword.
+  (org-test-with-temp-text "* TODO COMMENT Headline"
+    (let ((org-comment-string "COMMENT")
+	  (org-todo-keywords '((sequence "TODO" "DONE"))))
+      (should (org-element-property :commentedp (org-element-at-point))))))
+
+(ert-deftest test-org-element/headline-archive-tag ()
+  "Test ARCHIVE tag recognition."
+  ;; Reference test.
+  (org-test-with-temp-text "* Headline"
+    (let ((org-archive-tag "ARCHIVE"))
+      (should-not (org-element-property :archivedp (org-element-at-point)))))
+  ;; Single tag.
+  (org-test-with-temp-text "* Headline :ARCHIVE:"
+    (let ((org-archive-tag "ARCHIVE"))
+      (let ((headline (org-element-at-point)))
+	(should (org-element-property :archivedp headline))
+	;; Test tag removal.
+	(should-not (org-element-property :tags headline))))
+    (let ((org-archive-tag "Archive"))
+      (should-not (org-element-property :archivedp (org-element-at-point)))))
+  ;; Multiple tags.
+  (org-test-with-temp-text "* Headline :test:ARCHIVE:"
+    (let ((org-archive-tag "ARCHIVE"))
+      (let ((headline (org-element-at-point)))
+	(should (org-element-property :archivedp headline))
+	;; Test tag removal.
+	(should (equal (org-element-property :tags headline) ":test:"))))))
+
+
 ;;;; Verse blocks
 ;;;; Verse blocks
 
 
 (ert-deftest test-org-element/verse-block ()
 (ert-deftest test-org-element/verse-block ()
@@ -306,84 +316,7 @@ Return interpreted string."
 
 
 
 
 
 
-;;;; Granularity
-
-(ert-deftest test-org-element/granularity ()
-  "Test granularity impact on buffer parsing."
-  (org-test-with-temp-text "
-* Head 1
-** Head 2
-#+BEGIN_CENTER
-Centered paragraph.
-#+END_CENTER
-Paragraph \\alpha."
-    ;; 1.1. Granularity set to `headline' should parse every headline
-    ;;      in buffer, and only them.
-    (let ((tree (org-element-parse-buffer 'headline)))
-      (should (= 2 (length (org-element-map tree 'headline 'identity))))
-      (should-not (org-element-map tree 'paragraph 'identity)))
-    ;; 1.2. Granularity set to `greater-element' should not enter
-    ;;      greater elements excepted headlines and sections.
-    (let ((tree (org-element-parse-buffer 'greater-element)))
-      (should (= 1 (length (org-element-map tree 'center-block 'identity))))
-      (should (= 1 (length (org-element-map tree 'paragraph 'identity))))
-      (should-not (org-element-map tree 'entity 'identity)))
-    ;; 1.3. Granularity set to `element' should enter every
-    ;;      greater-element.
-    (let ((tree (org-element-parse-buffer 'element)))
-      (should (= 2 (length (org-element-map tree 'paragraph 'identity))))
-      (should-not (org-element-map tree 'entity 'identity)))
-    ;; 1.4. Granularity set to `object' can see everything.
-    (let ((tree (org-element-parse-buffer 'object)))
-      (should (= 1 (length (org-element-map tree 'entity 'identity)))))))
-
-(ert-deftest test-org-element/secondary-string-parsing ()
-  "Test if granularity correctly toggles secondary strings parsing."
-  ;; 1. With a granularity bigger than `object', no secondary string
-  ;;    should be parsed.
-  ;;
-  ;; 1.1. Test with `headline' type.
-  (org-test-with-temp-text "* Headline"
-    (let ((headline
-	   (org-element-map (org-element-parse-buffer 'headline) 'headline
-			    'identity
-			    nil
-			    'first-match)))
-      (should (stringp (org-element-property :title headline)))))
-  ;; 1.2. Test with `item' type.
-  (org-test-with-temp-text "* Headline\n- tag :: item"
-    (let ((item (org-element-map (org-element-parse-buffer 'element)
-				 'item
-				 'identity
-				 nil
-				 'first-match)))
-      (should (stringp (org-element-property :tag item)))))
-  ;; 1.3. Test with `inlinetask' type, if avalaible.
-  (when (featurep 'org-inlinetask)
-    (let ((org-inlinetask-min-level 15))
-      (org-test-with-temp-text "*************** Inlinetask"
-	(let ((inlinetask (org-element-map (org-element-parse-buffer 'element)
-					   'inlinetask
-					   'identity
-					   nil
-					   'first-match)))
-	  (should (stringp (org-element-property :title inlinetask)))))))
-  ;; 2. With a default granularity, secondary strings should be
-  ;;    parsed.
-  (org-test-with-temp-text "* Headline"
-    (let ((headline
-	   (org-element-map (org-element-parse-buffer) 'headline
-			    'identity
-			    nil
-			    'first-match)))
-      (should (listp (org-element-property :title headline)))))
-  ;; 3. `org-element-at-point' should never parse a secondary string.
-  (org-test-with-temp-text "* Headline"
-    (should (stringp (org-element-property :title (org-element-at-point))))))
-
-
-
-;;;; Interpretation.
+;;; Test Interpreters.
 
 
 (ert-deftest test-org-element/interpret-affiliated-keywords ()
 (ert-deftest test-org-element/interpret-affiliated-keywords ()
   "Test if affiliated keywords are correctly interpreted."
   "Test if affiliated keywords are correctly interpreted."
@@ -697,8 +630,8 @@ CLOSED: <2012-01-01> DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
 
 
 (ert-deftest test-org-element/export-snippet-interpreter ()
 (ert-deftest test-org-element/export-snippet-interpreter ()
   "Test export snippet interpreter."
   "Test export snippet interpreter."
-  (should (equal (org-test-parse-and-interpret "@back-end{test}")
-		 "@back-end{test}\n")))
+  (should (equal (org-test-parse-and-interpret "<back-end@contents>")
+		 "<back-end@contents>\n")))
 
 
 (ert-deftest test-org-element/footnote-reference-interpreter ()
 (ert-deftest test-org-element/footnote-reference-interpreter ()
   "Test footnote reference interpreter."
   "Test footnote reference interpreter."
@@ -844,7 +777,84 @@ CLOSED: <2012-01-01> DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
 
 
 
 
 
 
-;;;; Normalize contents
+;;; Test Granularity
+
+(ert-deftest test-org-element/granularity ()
+  "Test granularity impact on buffer parsing."
+  (org-test-with-temp-text "
+* Head 1
+** Head 2
+#+BEGIN_CENTER
+Centered paragraph.
+#+END_CENTER
+Paragraph \\alpha."
+    ;; 1.1. Granularity set to `headline' should parse every headline
+    ;;      in buffer, and only them.
+    (let ((tree (org-element-parse-buffer 'headline)))
+      (should (= 2 (length (org-element-map tree 'headline 'identity))))
+      (should-not (org-element-map tree 'paragraph 'identity)))
+    ;; 1.2. Granularity set to `greater-element' should not enter
+    ;;      greater elements excepted headlines and sections.
+    (let ((tree (org-element-parse-buffer 'greater-element)))
+      (should (= 1 (length (org-element-map tree 'center-block 'identity))))
+      (should (= 1 (length (org-element-map tree 'paragraph 'identity))))
+      (should-not (org-element-map tree 'entity 'identity)))
+    ;; 1.3. Granularity set to `element' should enter every
+    ;;      greater-element.
+    (let ((tree (org-element-parse-buffer 'element)))
+      (should (= 2 (length (org-element-map tree 'paragraph 'identity))))
+      (should-not (org-element-map tree 'entity 'identity)))
+    ;; 1.4. Granularity set to `object' can see everything.
+    (let ((tree (org-element-parse-buffer 'object)))
+      (should (= 1 (length (org-element-map tree 'entity 'identity)))))))
+
+(ert-deftest test-org-element/secondary-string-parsing ()
+  "Test if granularity correctly toggles secondary strings parsing."
+  ;; 1. With a granularity bigger than `object', no secondary string
+  ;;    should be parsed.
+  ;;
+  ;; 1.1. Test with `headline' type.
+  (org-test-with-temp-text "* Headline"
+    (let ((headline
+	   (org-element-map (org-element-parse-buffer 'headline) 'headline
+			    'identity
+			    nil
+			    'first-match)))
+      (should (stringp (org-element-property :title headline)))))
+  ;; 1.2. Test with `item' type.
+  (org-test-with-temp-text "* Headline\n- tag :: item"
+    (let ((item (org-element-map (org-element-parse-buffer 'element)
+				 'item
+				 'identity
+				 nil
+				 'first-match)))
+      (should (stringp (org-element-property :tag item)))))
+  ;; 1.3. Test with `inlinetask' type, if avalaible.
+  (when (featurep 'org-inlinetask)
+    (let ((org-inlinetask-min-level 15))
+      (org-test-with-temp-text "*************** Inlinetask"
+	(let ((inlinetask (org-element-map (org-element-parse-buffer 'element)
+					   'inlinetask
+					   'identity
+					   nil
+					   'first-match)))
+	  (should (stringp (org-element-property :title inlinetask)))))))
+  ;; 2. With a default granularity, secondary strings should be
+  ;;    parsed.
+  (org-test-with-temp-text "* Headline"
+    (let ((headline
+	   (org-element-map (org-element-parse-buffer) 'headline
+			    'identity
+			    nil
+			    'first-match)))
+      (should (listp (org-element-property :title headline)))))
+  ;; 3. `org-element-at-point' should never parse a secondary string.
+  (org-test-with-temp-text "* Headline"
+    (should (stringp (org-element-property :title (org-element-at-point))))))
+
+
+
+;;; Test Normalize Contents
 
 
 (ert-deftest test-org-element/normalize-contents ()
 (ert-deftest test-org-element/normalize-contents ()
   "Test `org-element-normalize-contents' specifications."
   "Test `org-element-normalize-contents' specifications."
@@ -882,8 +892,9 @@ CLOSED: <2012-01-01> DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
      '(paragraph nil "No space\n  Two spaces\n   Three spaces") t)
      '(paragraph nil "No space\n  Two spaces\n   Three spaces") t)
     '(paragraph nil "No space\nTwo spaces\n Three spaces"))))
     '(paragraph nil "No space\nTwo spaces\n Three spaces"))))
 
 
+
 
 
-;;;; Navigation tools.
+;;; Test Navigation Tools.
 
 
 (ert-deftest test-org-element/forward-element ()
 (ert-deftest test-org-element/forward-element ()
   "Test `org-element-forward' specifications."
   "Test `org-element-forward' specifications."