diff --git a/lisp/org-element.el b/lisp/org-element.el index dea1ff750..b7cdc4428 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1738,22 +1738,40 @@ Assume point is at the beginning of the paragraph." (end-of-line) (re-search-forward org-element-paragraph-separate limit 'm) (while (and (/= (point) limit) - (cond ((and (looking-at "[ \t]*:\\S-") - (not (looking-at org-drawer-regexp)))) - ((not (looking-at "[ \t]*#\\S-")) nil) - ((looking-at "[ \t]*\\+BEGIN:? ") - (not (save-excursion - (re-search-forward - "^[ \t]*\\+END:" limit t)))) - ((looking-at "[ \t]*\\+BEGIN_\\(\\S-+\\)") - (not (save-excursion - (re-search-forward - (concat "^[ \t]*\\+END_" - (match-string 1)) - limit t)))) - ((not (looking-at "[ \t]*#\\+\\S-+:"))))) - (when (re-search-forward org-element-paragraph-separate limit 'm) - (goto-char (match-beginning 0)))) + (cond + ;; Skip non-existent or incomplete drawer. + ((save-excursion + (beginning-of-line) + (and (looking-at "[ \t]*:\\S-") + (or (not (looking-at org-drawer-regexp)) + (not (save-excursion + (re-search-forward + "^[ \t]*:END:" limit t))))))) + ;; Stop at comments. + ((save-excursion + (beginning-of-line) + (not (looking-at "[ \t]*#\\S-"))) nil) + ;; Skip incomplete dynamic blocks. + ((save-excursion + (beginning-of-line) + (looking-at "[ \t]*#\\+BEGIN: ")) + (not (save-excursion + (re-search-forward + "^[ \t]*\\+END:" limit t)))) + ;; Skip incomplete blocks. + ((save-excursion + (beginning-of-line) + (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)")) + (not (save-excursion + (re-search-forward + (concat "^[ \t]*#\\+END_" + (match-string 1)) + limit t)))) + ;; Skip ill-formed keywords. + ((not (save-excursion + (beginning-of-line) + (looking-at "[ \t]*#\\+\\S-+:")))))) + (re-search-forward org-element-paragraph-separate limit 'm)) (if (eobp) (point) (goto-char (line-beginning-position))))) (contents-end (progn (skip-chars-backward " \r\t\n" contents-begin) (forward-line) diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index ae9043fe8..df719b78c 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -1144,10 +1144,34 @@ e^{i\\pi}+1=0 (org-element-parse-buffer) 'paragraph (lambda (p) (char-after (org-element-property :end p))) nil t)))) - ;; Keywords without colons are treated as plain text. + ;; Include ill-formed Keywords. (should (org-test-with-temp-text "#+wrong_keyword something" - (org-element-map (org-element-parse-buffer) 'paragraph 'identity)))) + (org-element-map (org-element-parse-buffer) 'paragraph 'identity))) + ;; Include incomplete-drawers. + (should + (let ((org-drawers '("TEST"))) + (org-test-with-temp-text ":TEST:\nParagraph" + (let ((elem (org-element-at-point))) + (and (eq (org-element-type elem) 'paragraph) + (= (point-max) (org-element-property :end elem))))))) + ;; Include non-existent drawers. + (should + (let ((org-drawers '("TEST"))) + (org-test-with-temp-text ":NONAME:" + (org-element-map (org-element-parse-buffer) 'paragraph 'identity)))) + ;; Include incomplete blocks. + (should + (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph" + (let ((elem (org-element-at-point))) + (and (eq (org-element-type elem) 'paragraph) + (= (point-max) (org-element-property :end elem)))))) + ;; Include incomplete dynamic blocks. + (should + (org-test-with-temp-text "#+BEGIN: \nParagraph" + (let ((elem (org-element-at-point))) + (and (eq (org-element-type elem) 'paragraph) + (= (point-max) (org-element-property :end elem))))))) ;;;; Plain List