From fba3fd56c4dfc8c27670285fa60d8ccc95eb9d59 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Thu, 12 Oct 2023 13:34:08 +0300 Subject: [PATCH] org-element-org-data-parser: Allow leading blank lines before property drawer * lisp/org-element.el (org-element--get-global-node-properties): (org-element-org-data-parser): (org-element--current-element): Allow blank lines at the beginning of Org document. Blank lines where allowed in the past (:contents-begin started after the blank lines), but it was previously not possible to have top-level property drawer in an Org document starting from blank lines. Now, it is possible. * testing/lisp/test-org-element.el (test-org-element/org-data-parser): Add new tests. Reported-by: Tom Alexander Link: https://orgmode.org/list/0ec8c4ae-4f5b-4e37-8c5c-f92ef497a461@app.fastmail.com --- lisp/org-element.el | 8 +++++++- testing/lisp/test-org-element.el | 34 +++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index 4ffff2434..ec1663b6f 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1528,6 +1528,8 @@ Alter DATA by side effect." (with-current-buffer (org-element-property :buffer data) (org-with-wide-buffer (goto-char (point-min)) + (org-skip-whitespace) + (forward-line 0) (while (and (org-at-comment-p) (bolp)) (forward-line)) (let ((props (org-element--get-node-properties t data)) (has-category? nil)) @@ -1568,6 +1570,8 @@ Return a new syntax node of `org-data' type containing `:begin', (or (org-with-wide-buffer (goto-char (point-min)) + (org-skip-whitespace) + (forward-line 0) (while (and (org-at-comment-p) (bolp)) (forward-line)) (when (looking-at org-property-drawer-re) (goto-char (match-end 0)) @@ -4592,7 +4596,9 @@ element it has to parse." (save-excursion (forward-line -1) ; faster than beginning-of-line (skip-chars-forward "[:blank:]") ; faster than looking-at-p - (not (eolp)))) ; very cheap + (or (not (eolp)) ; very cheap + ;; Document-wide property drawer may be preceded by blank lines. + (progn (skip-chars-backward " \t\n\r") (bobp))))) (_ nil)) (looking-at-p org-property-drawer-re)) (org-element-property-drawer-parser limit)) diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index 5ca8a08db..16de1ec70 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -2750,7 +2750,7 @@ Outside list" (eq 'property-drawer (org-test-with-temp-text "# C\n# C\n:PROPERTIES:\n:prop: value\n:END:" (org-element-type (org-element-at-point))))) - (should-not + (should (eq 'property-drawer (org-test-with-temp-text "\n:PROPERTIES:\n:prop: value\n:END:" (org-element-type (org-element-at-point))))) @@ -3271,6 +3271,38 @@ Outside list" (org-test-with-temp-text "#+BEGIN_VERSE\nC\n#+END_VERSE\n " (= (org-element-property :end (org-element-at-point)) (point-max))))) +;;; Org data. + +(ert-deftest test-org-element/org-data-parser () + "Test `org-data' parser." + ;; Standard test. + (org-test-with-temp-text "This is test." + (let ((data (org-element-lineage (org-element-at-point) 'org-data))) + (should (equal 1 (org-element-begin data))) + (should (equal (point-max) (org-element-end data))))) + ;; Parse top-level property drawer. + (should + (equal + "bar" + (org-test-with-temp-text ":PROPERTIES: +:FOO: bar +:END:" + (org-element-property-inherited :FOO (org-element-at-point))))) + ;; With leading comment line. + (org-test-with-temp-text "# comment +:PROPERTIES: +:FOO: bar +:END:" + (should (equal "bar" (org-element-property-inherited :FOO (org-element-at-point))))) + ;; Blank line on top. + (should + (equal + "bar" + (org-test-with-temp-text " +:PROPERTIES: +:FOO: bar +:END:" + (org-element-property-inherited :FOO (org-element-at-point)))))) ;;; Test Interpreters.