Hi, Here is the updated patch, including the fix to only trigger on actual headlines (and not bold or similar), the readability improvement for beg-of-next-line and a fix to call point-max only once per branch. I also switched all the regex over to use the rx macro. I left out the tests because since they would entail quite a bit of additional work that is out of scope for this patch. The rx changes mean that the patch is now over the tiny change limit, I went ahead and sent a request to ass...@gnu.org so we don't have to wait around if things look good. Best, Tom
From 8c36ffa82c138057a03c813aa0c7616f04744a72 Mon Sep 17 00:00:00 2001 From: Tom Gillespie <tgbugs@gmail.com> Date: Wed, 11 Dec 2019 17:57:47 -0800 Subject: org.el: 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. --- lisp/org.el | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 8e3024c93..14840d8ca 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -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) -- 2.24.1