org-element: Fix parapraph parsing
* lisp/org-element.el (org-element--set-regexps): Refine `org-element-paragraph-separate'. (org-element-paragraph-parser): Fix paragraph parsing when followed by a dual keyword or an ill-formed latex environment. * testing/lisp/test-org-element.el (test-org-element/paragraph-parser): Add tests. Reported-by: Jacob Gerlach <jacobgerlach@gmail.com> <http://permalink.gmane.org/gmane.emacs.orgmode/97256>
This commit is contained in:
parent
2965f8fb0c
commit
eb77fed33f
|
@ -159,16 +159,20 @@ specially in `org-element--object-lex'.")
|
||||||
"$" "\\|"
|
"$" "\\|"
|
||||||
;; Tables (any type).
|
;; Tables (any type).
|
||||||
"\\(?:|\\|\\+-[-+]\\)" "\\|"
|
"\\(?:|\\|\\+-[-+]\\)" "\\|"
|
||||||
;; Blocks (any type), Babel calls and keywords. This
|
;; Comments, keyword-like or block-like constructs.
|
||||||
;; is only an indication and need some thorough check.
|
;; Blocks and keywords with dual values need to be
|
||||||
"#\\(?:[+ ]\\|$\\)" "\\|"
|
;; double-checked.
|
||||||
;; Drawers (any type) and fixed-width areas. This is
|
"#\\(?: \\|$\\|\\+\\(?:"
|
||||||
;; also only an indication.
|
"BEGIN_\\S-+" "\\|"
|
||||||
":" "\\|"
|
"\\S-+\\(?:\\[.*\\]\\)?:\\(?: \\|$\\)\\)\\)"
|
||||||
|
"\\|"
|
||||||
|
;; Drawers (any type) and fixed-width areas. Drawers
|
||||||
|
;; need to be double-checked.
|
||||||
|
":\\(?: \\|$\\|[-_[:word:]]+:[ \t]*$\\)" "\\|"
|
||||||
;; Horizontal rules.
|
;; Horizontal rules.
|
||||||
"-\\{5,\\}[ \t]*$" "\\|"
|
"-\\{5,\\}[ \t]*$" "\\|"
|
||||||
;; LaTeX environments.
|
;; LaTeX environments.
|
||||||
"\\\\begin{\\([A-Za-z0-9]+\\*?\\)}" "\\|"
|
"\\\\begin{\\([A-Za-z0-9*]+\\)}" "\\|"
|
||||||
;; Clock lines.
|
;; Clock lines.
|
||||||
(regexp-quote org-clock-string) "\\|"
|
(regexp-quote org-clock-string) "\\|"
|
||||||
;; Lists.
|
;; Lists.
|
||||||
|
@ -2233,65 +2237,42 @@ Assume point is at the beginning of the paragraph."
|
||||||
(before-blank
|
(before-blank
|
||||||
(let ((case-fold-search t))
|
(let ((case-fold-search t))
|
||||||
(end-of-line)
|
(end-of-line)
|
||||||
(if (not (re-search-forward
|
;; A matching `org-element-paragraph-separate' is not
|
||||||
org-element-paragraph-separate limit 'm))
|
;; necessarily the end of the paragraph. In particular,
|
||||||
limit
|
;; drawers, blocks or LaTeX environments opening lines
|
||||||
;; A matching `org-element-paragraph-separate' is not
|
;; must be closed. Moreover keywords with a secondary
|
||||||
;; necessarily the end of the paragraph. In
|
;; value must belong to "dual keywords".
|
||||||
;; particular, lines starting with # or : as a first
|
(while (not
|
||||||
;; non-space character are ambiguous. We have to
|
(cond
|
||||||
;; check if they are valid Org syntax (e.g., not an
|
((not (and (re-search-forward
|
||||||
;; incomplete keyword).
|
org-element-paragraph-separate limit 'move)
|
||||||
(beginning-of-line)
|
(progn (beginning-of-line) t))))
|
||||||
(while (not
|
((looking-at org-drawer-regexp)
|
||||||
(or
|
(save-excursion
|
||||||
;; There's no ambiguity for other symbols or
|
(re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))
|
||||||
;; empty lines: stop here.
|
((looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)")
|
||||||
(looking-at "[ \t]*\\(?:[^:#]\\|$\\)")
|
(save-excursion
|
||||||
;; Stop at valid fixed-width areas.
|
(re-search-forward
|
||||||
(looking-at "[ \t]*:\\(?: \\|$\\)")
|
(format "^[ \t]*#\\+END_%s[ \t]*$"
|
||||||
;; Stop at drawers.
|
(regexp-quote (match-string 1)))
|
||||||
(and (looking-at org-drawer-regexp)
|
limit t)))
|
||||||
(save-excursion
|
((looking-at org-element--latex-begin-environment)
|
||||||
(re-search-forward
|
(save-excursion
|
||||||
"^[ \t]*:END:[ \t]*$" limit t)))
|
(re-search-forward
|
||||||
;; Stop at valid comments.
|
(format org-element--latex-end-environment
|
||||||
(looking-at "[ \t]*#\\(?: \\|$\\)")
|
(regexp-quote (match-string 1)))
|
||||||
;; Stop at valid dynamic blocks.
|
limit t)))
|
||||||
(and (looking-at org-dblock-start-re)
|
((looking-at "[ \t]*#\\+\\(\\S-+\\)\\[.*\\]:")
|
||||||
(save-excursion
|
(member-ignore-case (match-string 1)
|
||||||
(re-search-forward
|
org-element-dual-keywords))
|
||||||
"^[ \t]*#\\+END:?[ \t]*$" limit t)))
|
;; Everything else is unambiguous.
|
||||||
;; Stop at valid blocks.
|
(t)))
|
||||||
(and (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)")
|
(end-of-line))
|
||||||
(save-excursion
|
|
||||||
(re-search-forward
|
|
||||||
(format "^[ \t]*#\\+END_%s[ \t]*$"
|
|
||||||
(regexp-quote
|
|
||||||
(org-match-string-no-properties 1)))
|
|
||||||
limit t)))
|
|
||||||
;; Stop at valid latex environments.
|
|
||||||
(and (looking-at org-element--latex-begin-environment)
|
|
||||||
(save-excursion
|
|
||||||
(re-search-forward
|
|
||||||
(format org-element--latex-end-environment
|
|
||||||
(regexp-quote
|
|
||||||
(org-match-string-no-properties 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
|
(if (= (point) limit) limit
|
||||||
(goto-char (line-beginning-position)))))
|
(goto-char (line-beginning-position)))))
|
||||||
(contents-end (progn (skip-chars-backward " \r\t\n" contents-begin)
|
(contents-end (save-excursion
|
||||||
(forward-line)
|
(skip-chars-backward " \r\t\n" contents-begin)
|
||||||
(point)))
|
(line-beginning-position 2)))
|
||||||
(end (progn (skip-chars-forward " \r\t\n" limit)
|
(end (progn (skip-chars-forward " \r\t\n" limit)
|
||||||
(if (eobp) (point) (line-beginning-position)))))
|
(if (eobp) (point) (line-beginning-position)))))
|
||||||
(list 'paragraph
|
(list 'paragraph
|
||||||
|
|
|
@ -1744,10 +1744,29 @@ e^{i\\pi}+1=0
|
||||||
(let ((elem (org-element-at-point)))
|
(let ((elem (org-element-at-point)))
|
||||||
(and (eq (org-element-type elem) 'paragraph)
|
(and (eq (org-element-type elem) 'paragraph)
|
||||||
(= (point-max) (org-element-property :end elem))))))
|
(= (point-max) (org-element-property :end elem))))))
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text "Paragraph\n\begin{equation}"
|
||||||
|
(let ((elem (org-element-at-point)))
|
||||||
|
(and (eq (org-element-type elem) 'paragraph)
|
||||||
|
(= (point-max) (org-element-property :end elem))))))
|
||||||
|
;; Stop at affiliated keywords.
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text "Paragraph\n#+NAME: test\n| table |"
|
||||||
|
(let ((elem (org-element-at-point)))
|
||||||
|
(and (eq (org-element-type elem) 'paragraph)
|
||||||
|
(not (org-element-property :name elem))
|
||||||
|
(= (org-element-property :end elem) (line-beginning-position 2))))))
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text
|
||||||
|
"Paragraph\n#+CAPTION[with short caption]: test\n| table |"
|
||||||
|
(let ((elem (org-element-at-point)))
|
||||||
|
(and (eq (org-element-type elem) 'paragraph)
|
||||||
|
(not (org-element-property :name elem))
|
||||||
|
(= (org-element-property :end elem) (line-beginning-position 2))))))
|
||||||
;; Do not steal affiliated keywords from container.
|
;; Do not steal affiliated keywords from container.
|
||||||
(should
|
(should
|
||||||
(org-test-with-temp-text "#+ATTR_LATEX: test\n- item 1"
|
(org-test-with-temp-text "#+ATTR_LATEX: test\n- item<point> 1"
|
||||||
(let ((elem (progn (search-forward "item") (org-element-at-point))))
|
(let ((elem (org-element-at-point)))
|
||||||
(and (eq (org-element-type elem) 'paragraph)
|
(and (eq (org-element-type elem) 'paragraph)
|
||||||
(not (org-element-property :attr_latex elem))
|
(not (org-element-property :attr_latex elem))
|
||||||
(/= (org-element-property :begin elem) 1)))))
|
(/= (org-element-property :begin elem) 1)))))
|
||||||
|
|
Loading…
Reference in New Issue