mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-11-26 07:33:39 +00:00
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>>
This commit is contained in:
parent
237c65b1f7
commit
803d76825a
@ -1927,12 +1927,16 @@ keywords.
|
||||
|
||||
Assume point is at the beginning of the snippet."
|
||||
(save-excursion
|
||||
(looking-at "@\\([-A-Za-z0-9]+\\){")
|
||||
(looking-at "<\\([-A-Za-z0-9]+\\)@")
|
||||
(let* ((begin (point))
|
||||
(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"))
|
||||
(end (point)))
|
||||
`(export-snippet
|
||||
@ -1945,7 +1949,7 @@ Assume point is at the beginning of the snippet."
|
||||
(defun org-element-export-snippet-interpreter (export-snippet contents)
|
||||
"Interpret EXPORT-SNIPPET object as Org syntax.
|
||||
CONTENTS is nil."
|
||||
(format "@%s{%s}"
|
||||
(format "<%s@%s>"
|
||||
(org-element-property :back-end 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."
|
||||
(save-excursion
|
||||
(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
|
||||
|
@ -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
|
||||
|
||||
(ert-deftest test-org-element/block-switches ()
|
||||
@ -210,8 +138,21 @@ Return interpreted string."
|
||||
(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 ()
|
||||
"Test footnote-reference parsing."
|
||||
@ -267,7 +208,76 @@ Return interpreted string."
|
||||
(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
|
||||
|
||||
(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 ()
|
||||
"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 ()
|
||||
"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 ()
|
||||
"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 ()
|
||||
"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\nTwo spaces\n Three spaces"))))
|
||||
|
||||
|
||||
|
||||
;;;; Navigation tools.
|
||||
;;; Test Navigation Tools.
|
||||
|
||||
(ert-deftest test-org-element/forward-element ()
|
||||
"Test `org-element-forward' specifications."
|
||||
|
Loading…
Reference in New Issue
Block a user