diff options
author | Nicolas Goaziou <n.goaziou@gmail.com> | 2012-09-30 12:22:40 +0200 |
---|---|---|
committer | Nicolas Goaziou <n.goaziou@gmail.com> | 2012-09-30 13:09:54 +0200 |
commit | 1ad58a8230694fefb5a7cb867b9e6c8dbed50cbc (patch) | |
tree | f676dcdf4ae106351fb1d10dc09061108c62c93a | |
parent | c8c8d0e2d953002c6068204e04bd768798093f20 (diff) | |
download | org-mode-1ad58a8230694fefb5a7cb867b9e6c8dbed50cbc.tar.gz |
org-element: Use stricter regexps for boundaries of elements
* lisp/org-element.el (org-element-center-block-parser):
(org-element-drawer-parser, org-element-dynamic-block-parser,
org-element-example-block-parser, org-element-export-block-parser,
org-element-latex-environment-parser, org-element-paragraph-parser,
org-element-property-drawer-parser, org-element-src-block-parser,
org-element-verse-block-parser): Use stricter regexps for boundaries
of elements.
* testing/lisp/test-org.el: Fix a test.
-rw-r--r-- | lisp/org-element.el | 135 | ||||
-rw-r--r-- | testing/lisp/test-org.el | 2 |
2 files changed, 76 insertions, 61 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el index 3d67ae7..d353f2f 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -478,7 +478,7 @@ containing `:begin', `:end', `:hiddenp', `:contents-begin', Assume point is at the beginning of the block." (let ((case-fold-search t)) (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_CENTER" limit t))) + (re-search-forward "^[ \t]*#\\+END_CENTER[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((block-end-line (match-beginning 0))) @@ -524,7 +524,7 @@ Return a list whose CAR is `drawer' and CDR is a plist containing Assume point is at beginning of drawer." (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward "^[ \t]*:END:" limit t))) + (if (not (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) ;; Incomplete drawer: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((drawer-end-line (match-beginning 0))) @@ -578,7 +578,8 @@ containing `:block-name', `:begin', `:end', `:hiddenp', Assume point is at beginning of dynamic block." (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward org-dblock-end-re limit t))) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END:?[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((block-end-line (match-beginning 0))) @@ -1145,7 +1146,7 @@ containing `:begin', `:end', `:hiddenp', `:contents-begin', Assume point is at the beginning of the block." (let ((case-fold-search t)) (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_QUOTE" limit t))) + (re-search-forward "^[ \t]*#\\+END_QUOTE[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((block-end-line (match-beginning 0))) @@ -1227,7 +1228,8 @@ Assume point is at the beginning of the block." (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(S-+\\)") (upcase (match-string-no-properties 1))))) (if (not (save-excursion - (re-search-forward (concat "^[ \t]*#\\+END_" type) limit t))) + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((block-end-line (match-beginning 0))) @@ -1425,7 +1427,7 @@ containing `:begin', `:end', `:hiddenp', `:value' and Assume point is at comment block beginning." (let ((case-fold-search t)) (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_COMMENT" limit t))) + (re-search-forward "^[ \t]*#\\+END_COMMENT[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((contents-end (match-beginning 0))) @@ -1470,7 +1472,7 @@ containing `:begin', `:end', `:number-lines', `:preserve-indent', `:switches', `:value' and `:post-blank' keywords." (let ((case-fold-search t)) (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_EXAMPLE" limit t))) + (re-search-forward "^[ \t]*#\\+END_EXAMPLE[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((contents-end (match-beginning 0))) @@ -1549,7 +1551,8 @@ Assume point is at export-block beginning." (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") (upcase (org-match-string-no-properties 1))))) (if (not (save-excursion - (re-search-forward (concat "^[ \t]*#\\+END_" type) limit t))) + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((contents-end (match-beginning 0))) @@ -1711,7 +1714,8 @@ Assume point is at the beginning of the latex environment." (env (progn (looking-at "^[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}") (regexp-quote (match-string 1)))) (code-end - (progn (re-search-forward (format "^[ \t]*\\\\end{%s}" env) limit t) + (progn (re-search-forward + (format "^[ \t]*\\\\end{%s}[ \t]*$" env) limit t) (forward-line) (point))) (value (buffer-substring-no-properties code-begin code-end)) @@ -1744,64 +1748,74 @@ containing `:begin', `:end', `:contents-begin' and Assume point is at the beginning of the paragraph." (save-excursion - (let* (;; INNER-PAR-P is non-nil when paragraph is at the + (let* ((contents-begin (point)) + ;; INNER-PAR-P is non-nil when paragraph is at the ;; beginning of an item or a footnote reference. In that ;; case, we mustn't look for affiliated keywords since they ;; belong to the container. (inner-par-p (not (bolp))) - (contents-begin (point)) (keywords (unless inner-par-p (org-element--collect-affiliated-keywords))) (begin (if inner-par-p contents-begin (car keywords))) (before-blank (let ((case-fold-search t)) (end-of-line) - (re-search-forward org-element-paragraph-separate limit 'm) - (while (and (/= (point) limit) - (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 incomplete latex environments. - ((save-excursion - (beginning-of-line) - (looking-at "^[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}")) - (not (save-excursion - (re-search-forward - (format "^[ \t]*\\\\end{%s}" - (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))))) + (if (not (re-search-forward + org-element-paragraph-separate limit 'm)) + limit + ;; A matching `org-element-paragraph-separate' is not + ;; necessarily the end of the paragraph. In + ;; particular, lines starting with # or : as a first + ;; non-space character are ambiguous. We have check + ;; if they are valid Org syntax (i.e. not an + ;; incomplete keyword). + (beginning-of-line) + (while (not + (or + ;; There's no ambiguity for other symbols or + ;; empty lines: stop here. + (looking-at "[ \t]*\\(?:[^:#]\\|$\\)") + ;; Stop at valid fixed-width areas. + (looking-at "[ \t]*:\\(?: \\|$\\)") + ;; Stop at drawers. + (and (looking-at org-drawer-regexp) + (save-excursion + (re-search-forward + "^[ \t]*:END:[ \t]*$" limit t))) + ;; Stop at valid comments. + (looking-at "[ \t]*#\\(?: \\|$\\)") + ;; Stop at valid dynamic blocks. + (and (looking-at org-dblock-start-re) + (save-excursion + (re-search-forward + "^[ \t]*#\\+END:?[ \t]*$" limit t))) + ;; Stop at valid blocks. + (and (looking-at + "[ \t]*#\\+BEGIN_\\(\\S-+\\)[ \t]*$") + (save-excursion + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" + (match-string 1)) + limit t))) + ;; Stop at valid latex environments. + (and (looking-at + "^[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}[ \t]*$") + (save-excursion + (re-search-forward + (format "^[ \t]*\\\\end{%s}[ \t]*$" + (match-string 1)) + limit t))) + ;; Stop at valid keywords. + (looking-at "[ \t]*#\\+\\S-+:") + ;; Skip everything else. + (not + (progn + (end-of-line) + (re-search-forward org-element-paragraph-separate + limit 'm))))) + (beginning-of-line))) + (if (= (point) limit) limit + (goto-char (line-beginning-position))))) (contents-end (progn (skip-chars-backward " \r\t\n" contents-begin) (forward-line) (point))) @@ -1895,7 +1909,7 @@ Assume point is at the beginning of the property drawer." (hidden (org-invisible-p2)) (properties (let (val) - (while (not (looking-at "^[ \t]*:END:")) + (while (not (looking-at "^[ \t]*:END:[ \t]*$")) (when (looking-at "[ \t]*:\\([A-Za-z][-_A-Za-z0-9]*\\):") (push (cons (org-match-string-no-properties 1) (org-trim @@ -1974,7 +1988,8 @@ containing `:language', `:switches', `:parameters', `:begin', Assume point is at the beginning of the block." (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward "^[ \t]*#\\+END_SRC" limit t))) + (if (not (save-excursion (re-search-forward "^[ \t]*#\\+END_SRC[ \t]*$" + limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((contents-end (match-beginning 0))) @@ -2179,7 +2194,7 @@ containing `:begin', `:end', `:contents-begin', `:contents-end', Assume point is at beginning of the block." (let ((case-fold-search t)) (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_VERSE" limit t))) + (re-search-forward "^[ \t]*#\\+END_VERSE[ \t]*$" limit t))) ;; Incomplete block: parse it as a paragraph. (org-element-paragraph-parser limit) (let ((contents-end (match-beginning 0))) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index e7c090d..7519ed2 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -501,7 +501,7 @@ Outside." (should-error (org-backward-element))) ;; 5. At beginning of first element inside a greater element: ;; expected to move to greater element's beginning. - (org-test-with-temp-text "Before.\n#+BEGIN_CENTER\nInside.\n#+END_CENTER." + (org-test-with-temp-text "Before.\n#+BEGIN_CENTER\nInside.\n#+END_CENTER" (goto-line 3) (org-backward-element) (should (looking-at "#\\+BEGIN_CENTER"))) |