branch: externals/org commit 26e68816bdae78c24a26274fe3e79df8998f3488 Author: Nicolas Goaziou <m...@nicolasgoaziou.fr> Commit: Nicolas Goaziou <m...@nicolasgoaziou.fr>
element: Integrate some syntax constants * lisp/org-element.el (org-element-archive-tag): (org-element-clock-line-re): (org-element-comment-string): (org-element-closed-keyword): (org-element-deadline-keyword): (org-element-scheduled-keyword): (org-element-planning-keywords-re): (org-element-planning-line-re): (org-element-drawer-re): (org-element-dynamic-block-open-re): (org-element-headline-re): New constants. (org-element-drawer-parser): (org-element-dynamic-block-parser): (org-element--footnote-separator): (org-element--get-node-properties): (org-element--get-time-properties): (org-element-headline-parser): (org-element-headline-interpreter): (org-element-inlinetask-parser): (org-element--list-struct): (org-element-paragraph-parser): (org-element-planning-parser): (org-element-planning-interpreter): (org-element--current-element): (org-element--cache-for-removal): (org-element-cache-map): (org-element-context): Use new constants so as to not use org.el's. * testing/lisp/test-org-element.el (test-org-element/headline-comment-keyword): (test-org-element/headline-archive-tag): * testing/lisp/test-ox.el (test-org-export/handle-options): Fix tests. --- lisp/org-element.el | 147 ++++++++++++++++++++++++++------------- testing/lisp/test-org-element.el | 37 ++++------ testing/lisp/test-ox.el | 23 +++--- 3 files changed, 121 insertions(+), 86 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index 6e228d4..8102387 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -82,25 +82,14 @@ (declare-function outline-next-heading "outline" ()) (declare-function outline-previous-heading "outline" ()) -(defvar org-archive-tag) -(defvar org-clock-line-re) -(defvar org-closed-string) -(defvar org-comment-string) (defvar org-complex-heading-regexp) -(defvar org-dblock-start-re) -(defvar org-deadline-string) (defvar org-done-keywords) -(defvar org-drawer-regexp) (defvar org-edit-src-content-indentation) -(defvar org-keyword-time-not-clock-regexp) (defvar org-match-substring-regexp) (defvar org-odd-levels-only) -(defvar org-outline-regexp-bol) -(defvar org-planning-line-re) (defvar org-property-drawer-re) (defvar org-property-format) (defvar org-property-re) -(defvar org-scheduled-string) (defvar org-src-preserve-indentation) (defvar org-tags-column) (defvar org-time-stamp-formats) @@ -117,6 +106,9 @@ ;; `org-element-update-syntax' builds proper syntax regexps according ;; to current setup. +(defconst org-element-archive-tag "ARCHIVE" + "Tag marking a substree as archived.") + (defconst org-element-citation-key-re (rx "@" (group (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~")))) "Regexp matching a citation key. @@ -130,6 +122,56 @@ Key is located in match group 1.") "Regexp matching a citation prefix. Style, if any, is located in match group 1.") +(defconst org-element-clock-line-re + (rx line-start (0+ (or ?\t ?\s)) "CLOCK:") + "Regexp matching a clock line.") + +(defconst org-element-comment-string "COMMENT" + "String marker for commented headlines.") + +(defconst org-element-closed-keyword "CLOSED:" + "Keyword used to close TODO entries.") + +(defconst org-element-deadline-keyword "DEADLINE:" + "Keyword used to mark deadline entries.") + +(defconst org-element-scheduled-keyword "SCHEDULED:" + "Keyword used to mark scheduled entries.") + +(defconst org-element-planning-keywords-re + (regexp-opt (list org-element-closed-keyword + org-element-deadline-keyword + org-element-scheduled-keyword)) + "Regexp matching any planning line keyword.") + +(defconst org-element-planning-line-re + (rx-to-string + `(seq line-start (0+ (any ?\s ?\t)) + (group (regexp ,org-element-planning-keywords-re)))) + "Regexp matching a planning line.") + +(defconst org-element-drawer-re + (rx line-start (0+ (any ?\s ?\t)) + ":" (group (1+ (any ?- ?_ word))) ":" + (0+ (any ?\s ?\t)) line-end) + "Regexp matching opening or closing line of a drawer. +Drawer's name is located in match group 1.") + +(defconst org-element-dynamic-block-open-re + (rx line-start (0+ (any ?\s ?\t)) + "#+BEGIN:" (0+ (any ?\s ?\t)) + (group (1+ word)) + (opt + (1+ (any ?\s ?\t)) + (group (1+ nonl)))) + "Regexp matching the opening line of a dynamic block. +Dynamic block's name is located in match group 1. +Parameters are in match group 2.") + +(defconst org-element-headline-re + (rx line-start (1+ "*") " ") + "Regexp matching a headline.") + (defvar org-element-paragraph-separate nil "Regexp to separate paragraphs in an Org buffer. In the case of lines starting with \"#\" and \":\", this regexp @@ -789,8 +831,10 @@ Assume point is at beginning of drawer." (org-element-paragraph-parser limit affiliated) (save-excursion (let* ((drawer-end-line (match-beginning 0)) - (name (progn (looking-at org-drawer-regexp) - (match-string-no-properties 1))) + (name + (progn + (looking-at org-element-drawer-re) + (match-string-no-properties 1))) (begin (car affiliated)) (post-affiliated (point)) ;; Empty drawers have no contents. @@ -845,9 +889,10 @@ Assume point is at beginning of dynamic block." (org-element-paragraph-parser limit affiliated) (let ((block-end-line (match-beginning 0))) (save-excursion - (let* ((name (progn (looking-at org-dblock-start-re) - (match-string-no-properties 1))) - (arguments (match-string-no-properties 3)) + (let* ((name (progn + (looking-at org-element-dynamic-block-open-re) + (match-string-no-properties 1))) + (arguments (match-string-no-properties 2)) (begin (car affiliated)) (post-affiliated (point)) ;; Empty blocks have no contents. @@ -885,7 +930,7 @@ CONTENTS is the contents of the element." ;;;; Footnote Definition (defconst org-element--footnote-separator - (concat org-outline-regexp-bol "\\|" + (concat org-element-headline-re "\\|" org-footnote-definition-re "\\|" "^\\([ \t]*\n\\)\\{2,\\}") "Regexp used as a footnote definition separator.") @@ -982,7 +1027,7 @@ parse properties for property drawer at point." (save-excursion (unless at-point-p? (forward-line) - (when (looking-at-p org-planning-line-re) (forward-line))) + (when (looking-at-p org-element-planning-line-re) (forward-line))) (when (looking-at org-property-drawer-re) (forward-line) (let ((end (match-end 0)) properties) @@ -1010,16 +1055,16 @@ parse properties for property drawer at point." "Return time properties associated to headline at point. Return value is a plist." (save-excursion - (when (progn (forward-line) (looking-at org-planning-line-re)) - (let ((end (line-end-position)) plist) - (while (re-search-forward org-keyword-time-not-clock-regexp end t) - (goto-char (match-end 1)) + (when (progn (forward-line) (looking-at org-element-planning-line-re)) + (let ((end (line-end-position)) + plist) + (while (re-search-forward org-element-planning-keywords-re end t) (skip-chars-forward " \t") - (let ((keyword (match-string 1)) + (let ((keyword (match-string 0)) (time (org-element-timestamp-parser))) - (cond ((equal keyword org-scheduled-string) + (cond ((equal keyword org-element-scheduled-keyword) (setq plist (plist-put plist :scheduled time))) - ((equal keyword org-deadline-string) + ((equal keyword org-element-deadline-keyword) (setq plist (plist-put plist :deadline time))) (t (setq plist (plist-put plist :closed time)))))) plist)))) @@ -1058,7 +1103,8 @@ Assume point is at beginning of the headline." (progn (goto-char (match-end 0)) (aref (match-string 0) 2)))) (commentedp - (and (let (case-fold-search) (looking-at org-comment-string)) + (and (let ((case-fold-search nil)) + (looking-at org-element-comment-string)) (goto-char (match-end 0)))) (title-start (prog1 (point) (unless (or todo priority commentedp) @@ -1073,7 +1119,7 @@ Assume point is at beginning of the headline." (title-end (point)) (raw-value (org-trim (buffer-substring-no-properties title-start title-end))) - (archivedp (member org-archive-tag tags)) + (archivedp (member org-element-archive-tag tags)) (footnote-section-p (and org-footnote-section (string= org-footnote-section raw-value))) (standard-props (org-element--get-node-properties)) @@ -1099,7 +1145,7 @@ Assume point is at beginning of the headline." (line-beginning-position 2)))) (robust-begin (and contents-begin (progn (goto-char contents-begin) - (when (looking-at-p org-planning-line-re) + (when (looking-at-p org-element-planning-line-re) (forward-line)) (when (looking-at org-property-drawer-re) (goto-char (match-end 0))) @@ -1173,7 +1219,7 @@ CONTENTS is the contents of the element." (concat (make-string (if org-odd-levels-only (1- (* level 2)) level) ?*) (and todo (concat " " todo)) - (and commentedp (concat " " org-comment-string)) + (and commentedp (concat " " org-element-comment-string)) (and priority (format " [#%c]" priority)) " " (if (and org-footnote-section @@ -1321,7 +1367,7 @@ Assume point is at beginning of the inline task." (buffer-substring-no-properties title-start title-end))) (task-end (save-excursion (end-of-line) - (and (re-search-forward org-outline-regexp-bol limit t) + (and (re-search-forward org-element-headline-re limit t) (looking-at-p "[ \t]*END[ \t]*$") (line-beginning-position)))) (standard-props (and task-end (org-element--get-node-properties))) @@ -1616,7 +1662,7 @@ CONTENTS is the contents of the element." (re-search-forward (format "^[ \t]*#\\+END%s[ \t]*$" (match-string 1)) limit t))) - ((and (looking-at org-drawer-regexp) + ((and (looking-at org-element-drawer-re) (re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))) (forward-line)))))))) @@ -2506,7 +2552,7 @@ Assume point is at the beginning of the paragraph." ((not (and (re-search-forward org-element-paragraph-separate limit 'move) (progn (beginning-of-line) t)))) - ((looking-at org-drawer-regexp) + ((looking-at org-element-drawer-re) (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) ((looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") @@ -2571,14 +2617,14 @@ containing `:closed', `:deadline', `:scheduled', `:begin', (end (point)) closed deadline scheduled) (goto-char begin) - (while (re-search-forward org-keyword-time-not-clock-regexp end t) - (goto-char (match-end 1)) + (while (re-search-forward org-element-planning-keywords-re end t) (skip-chars-forward " \t" end) - (let ((keyword (match-string 1)) + (let ((keyword (match-string 0)) (time (org-element-timestamp-parser))) - (cond ((equal keyword org-closed-string) (setq closed time)) - ((equal keyword org-deadline-string) (setq deadline time)) - (t (setq scheduled time))))) + (cond + ((equal keyword org-element-closed-keyword) (setq closed time)) + ((equal keyword org-element-deadline-keyword) (setq deadline time)) + (t (setq scheduled time))))) (list 'planning (list :closed closed :deadline deadline @@ -2595,15 +2641,15 @@ containing `:closed', `:deadline', `:scheduled', `:begin', (delq nil (list (let ((deadline (org-element-property :deadline planning))) (when deadline - (concat org-deadline-string " " + (concat org-element-deadline-keyword " " (org-element-timestamp-interpreter deadline nil)))) (let ((scheduled (org-element-property :scheduled planning))) (when scheduled - (concat org-scheduled-string " " + (concat org-element-scheduled-keyword " " (org-element-timestamp-interpreter scheduled nil)))) (let ((closed (org-element-property :closed planning))) (when closed - (concat org-closed-string " " + (concat org-element-closed-keyword " " (org-element-timestamp-interpreter closed nil)))))) " ")) @@ -4117,7 +4163,7 @@ element it has to parse." (org-element--cache-find (point) t))) (element (progn (while (and element (not (and (eq (point) (org-element-property :begin element)) - (eq mode (org-element-property :mode element))))) + (eq mode (org-element-property :mode element))))) (setq element (org-element-property :parent element))) element)) (old-element element) @@ -4163,7 +4209,7 @@ element it has to parse." ;; Planning. ((and (eq mode 'planning) (eq ?* (char-after (line-beginning-position 0))) - (looking-at org-planning-line-re)) + (looking-at org-element-planning-line-re)) (org-element-planning-parser limit)) ;; Property drawer. ((and (pcase mode @@ -4179,7 +4225,8 @@ element it has to parse." ;; a footnote definition: next item is always a paragraph. ((not (bolp)) (org-element-paragraph-parser limit (list (point)))) ;; Clock. - ((looking-at org-clock-line-re) (org-element-clock-parser limit)) + ((looking-at org-element-clock-line-re) + (org-element-clock-parser limit)) ;; Inlinetask. ((looking-at "^\\*+ ") (org-element-inlinetask-parser limit raw-secondary-p)) @@ -4196,7 +4243,7 @@ element it has to parse." ((looking-at org-element--latex-begin-environment) (org-element-latex-environment-parser limit affiliated)) ;; Drawer. - ((looking-at org-drawer-regexp) + ((looking-at org-element-drawer-re) (org-element-drawer-parser limit affiliated)) ;; Fixed Width ((looking-at "[ \t]*:\\( \\|$\\)") @@ -4259,7 +4306,7 @@ element it has to parse." ;; Start with a full rule. (and (looking-at rule-regexp) - (< next limit) ;no room for a table.el table + (< next limit) ;no room for a table.el table (save-excursion (end-of-line) (cond @@ -6595,7 +6642,7 @@ known element in cache (it may start after END)." (org-with-point-at (org-element-property :contents-begin up) (unless (save-match-data - (when (looking-at-p org-planning-line-re) + (when (looking-at-p org-element-planning-line-re) (forward-line)) (when (looking-at org-property-drawer-re) (< beg (match-end 0)))) @@ -7198,13 +7245,13 @@ of FUNC. Changes to elements made in FUNC will also alter the cache." restrict-elements))) (cons (org-with-limited-levels - org-outline-regexp-bol) + org-element-headline-re) 'match-beg)) (`headline+inlinetask (cons (if (eq '(inlinetask) restrict-elements) (org-inlinetask-outline-regexp) - org-outline-regexp-bol) + org-element-headline-re) 'match-beg)) ;; TODO: May add other commonly ;; searched elements as needed. @@ -7596,7 +7643,7 @@ Providing it allows for quicker computation." (let ((end (match-end 4))) (if (not end) (throw 'objects-forbidden element) (goto-char (match-beginning 4)) - (when (looking-at org-comment-string) + (when (looking-at org-element-comment-string) (goto-char (match-end 0))) (if (>= (point) end) (throw 'objects-forbidden element) (narrow-to-region (point) end)))))) diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index 560ba59..47e841a 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -1199,32 +1199,27 @@ Some other text "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))))) + (should-not (org-element-property :commentedp (org-element-at-point)))) ;; Standard position. (org-test-with-temp-text "* COMMENT Headline" - (let ((org-comment-string "COMMENT") - (headline (org-element-at-point))) + (let ((headline (org-element-at-point))) (should (org-element-property :commentedp headline)) (should (equal (org-element-property :raw-value headline) "Headline")))) ;; Case sensitivity. - (org-test-with-temp-text "* COMMENT Headline" - (let* ((org-comment-string "Comment") - (headline (org-element-at-point))) + (org-test-with-temp-text "* Comment Headline" + (let ((headline (org-element-at-point))) (should-not (org-element-property :commentedp headline)) (should (equal (org-element-property :raw-value headline) - "COMMENT Headline")))) + "Comment Headline")))) ;; With another keyword. (org-test-with-temp-text "* TODO COMMENT Headline" - (let* ((org-comment-string "COMMENT") - (org-todo-keywords '((sequence "TODO" "DONE"))) + (let* ((org-todo-keywords '((sequence "TODO" "DONE"))) (headline (org-element-at-point))) (should (org-element-property :commentedp headline)) (should (equal (org-element-property :raw-value headline) "Headline")))) ;; With the keyword only. (org-test-with-temp-text "* COMMENT" - (let* ((org-comment-string "COMMENT") - (headline (org-element-at-point))) + (let* ((headline (org-element-at-point))) (should (org-element-property :commentedp headline)) (should (equal (org-element-property :raw-value headline) ""))))) @@ -1233,23 +1228,19 @@ Some other text ;; Reference test. (should-not (org-test-with-temp-text "* Headline" - (let ((org-archive-tag "ARCHIVE")) - (org-element-property :archivedp (org-element-at-point))))) + (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))))) + (let ((headline (org-element-at-point))) + (should (org-element-property :archivedp headline)))) ;; 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))))) + (let ((headline (org-element-at-point))) + (should (org-element-property :archivedp headline)))) ;; Tag is case-sensitive. (should-not - (org-test-with-temp-text "* Headline :ARCHIVE:" - (let ((org-archive-tag "Archive")) - (org-element-property :archivedp (org-element-at-point)))))) + (org-test-with-temp-text "* Headline :Archive:" + (org-element-property :archivedp (org-element-at-point))))) (ert-deftest test-org-element/headline-properties () "Test properties from property drawer." diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 5455804..25e02b2 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -536,24 +536,21 @@ Paragraph" (equal "" (let (org-export-filter-body-functions org-export-filter-final-output-functions) - (org-test-with-temp-text "* Head1 :archive:" - (let ((org-archive-tag "archive")) - (org-export-as (org-test-default-backend) - nil nil nil '(:with-archived-trees nil))))))) + (org-test-with-temp-text "* Head1 :ARCHIVE:" + (org-export-as (org-test-default-backend) + nil nil nil '(:with-archived-trees nil)))))) (should (string-match - "\\* Head1[ \t]+:archive:" + "\\* Head1[ \t]+:ARCHIVE:" (org-test-with-temp-text "* Head1 :archive:\nbody\n** Sub-head 2" - (let ((org-archive-tag "archive")) - (org-export-as (org-test-default-backend) nil nil nil - '(:with-archived-trees headline)))))) + (org-export-as (org-test-default-backend) nil nil nil + '(:with-archived-trees headline))))) (should (string-match - "\\`\\* Head1[ \t]+:archive:\n\\'" - (org-test-with-temp-text "* Head1 :archive:" - (let ((org-archive-tag "archive")) - (org-export-as (org-test-default-backend) - nil nil nil '(:with-archived-trees t)))))) + "\\`\\* Head1[ \t]+:ARCHIVE:\n\\'" + (org-test-with-temp-text "* Head1 :ARCHIVE:" + (org-export-as (org-test-default-backend) + nil nil nil '(:with-archived-trees t))))) ;; Broken links. Depending on `org-export-with-broken-links', raise ;; an error, ignore link or mark is as broken in output. (should-error