org: Fix verbatim block fontification to end blocks on headlines

* lisp/org.el (org-fontify-meta-lines-and-blocks-1): Enhance regex
for finding the end of blocks (i.e., `beg-of-endline') to detect
headlines (i.e., (rx bol (one-or-more "*") space) so that fontification
matches the behavior of org mode (i.e., that headlines are healines,
even in vertabim).

This change aligns the behavior and the visual appearance of verbatim
blocks that contain headlines. When `font-lock-mode' is enabled this
change makes situations like those in (info "(org) Literal Examples")
literally jump off the page.

Overview of new fontification

Source                | fontification before | fontification after  |
\#+BEGIN_EXAMPLE      | org-block-begin-line | org-block-begin-line |
I look verbatim!      | org-block            | org-block            |
* Org headers in      | org-block            | org-level-1          |
verbatim blocks       | org-block            | nil                  |
** highly accordingly | org-block            | org-level-2          |
\#+END_EXAMPLE        | org-block-end-line   | org-meta-line        |

This commit also makes some improvements to the reability of
org-fontify-meta-lines-and-blocks-1.

1. Use the `rx' macro for better readability. Note that the strings
below return with literal tabs when using `rx'. Expansion included for
reference here.

Begin regex.
old: "^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
new: "^\\([[:blank:]]*#\\(\\(\\+[A-Za-z]+:?\\|[[:space:]]\\|$\\)\\(_\\([A-Za-z]+\\)\\)?\\)[[:blank:]]*\\(\\([^	\n ]*\\)[[:blank:]]*\\(.*\\)\\)\\)"

End regex. Note match-string call is stringified for documentation here.
old:                        (concat "^[ \t]*#\\+end" (match-string 4) "\\>.*")
new: "\\(?:\\(^\\(?:\\*+[[:space:]]\\|[[:blank:]]*#\\+end(match-string 4)\\>.*\\)\\)\\)"

Caption regex:
old: "\\([ \t]*#\\+caption\\(?:\\[.*\\]\\)?:\\)[ \t]*"
new: "\\([[:blank:]]*#\\+caption\\(?:\\[.*]\\)?:\\)[[:blank:]]*"

2. Refactor fontification of #+end blocks for readability and to reduce
the number of calls to point-max to one per branch.

TINYCHANGE
This commit is contained in:
Tom Gillespie 2019-12-11 17:57:47 -08:00 committed by Nicolas Goaziou
parent fa74fbb33c
commit 04d2828ad9
1 changed files with 28 additions and 7 deletions

View File

@ -5250,7 +5250,15 @@ by a #."
"Fontify #+ lines and blocks."
(let ((case-fold-search t))
(when (re-search-forward
"^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
(rx bol (group (zero-or-more blank) "#"
(group (group (or (seq "+" (one-or-more (any "a-zA-Z")) (optional ":"))
space
eol))
(optional (group "_" (group (one-or-more (any "a-zA-Z"))))))
(zero-or-more blank)
(group (group (zero-or-more (not (any " \t\n"))))
(zero-or-more blank)
(group (zero-or-more any)))))
limit t)
(let ((beg (match-beginning 0))
(end-of-beginline (match-end 0))
@ -5268,7 +5276,12 @@ by a #."
(setq block-type (downcase (match-string 5))
quoting (member block-type org-protecting-blocks)) ; src, example, export, maybe more
(when (re-search-forward
(concat "^[ \t]*#\\+end" (match-string 4) "\\>.*")
(rx-to-string `(group bol (or (seq (one-or-more "*") space)
(seq (zero-or-more blank)
"#+end"
,(match-string 4)
word-end
(zero-or-more any)))))
nil t) ;; on purpose, we look further than LIMIT
;; We do have a matching #+end line
(setq beg-of-endline (match-beginning 0)
@ -5307,10 +5320,14 @@ by a #."
(add-text-properties
beg (if whole-blockline bol-after-beginline end-of-beginline)
'(face org-block-begin-line))
(add-text-properties
beg-of-endline
(min (point-max) (if whole-blockline (min (point-max) (1+ end-of-endline)) end-of-endline))
'(face org-block-end-line))
(unless (string-prefix-p "*" (match-string 1))
(add-text-properties
beg-of-endline
(if whole-blockline
(let ((beg-of-next-line (1+ end-of-endline)))
(min (point-max) beg-of-next-line))
(min (point-max) end-of-endline))
'(face org-block-end-line)))
t))
((member dc1 '("+title:" "+author:" "+email:" "+date:"))
(org-remove-flyspell-overlays-in
@ -5333,7 +5350,11 @@ by a #."
;; Handle short captions.
(save-excursion
(beginning-of-line)
(looking-at "\\([ \t]*#\\+caption\\(?:\\[.*\\]\\)?:\\)[ \t]*"))
(looking-at (rx (group (zero-or-more blank)
"#+caption"
(optional "[" (zero-or-more any) "]")
":")
(zero-or-more blank))))
(add-text-properties (line-beginning-position) (match-end 1)
'(font-lock-fontified t face org-meta-line))
(add-text-properties (match-end 0) (line-end-position)