branch: externals/hyperbole
commit 23fee3ba1a4ed6454064a0ec26330fa0fb792a4d
Author: Mats Lidell <mats.lid...@lidells.se>
Commit: Mats Lidell <mats.lid...@lidells.se>

    Add support for org face types to support org 9.7 and older
---
 ChangeLog              |  7 ++++++
 hsys-org.el            | 60 ++++++++++++++++++++++++++++++++------------------
 test/hsys-org-tests.el |  4 ++--
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c8f6c08d40..13ddf3d370 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-06-23  Mats Lidell  <ma...@gnu.org>
+
+* hsys-org.el (hsys-org-first-face-type-pos)
+    (hsys-org-last-face-type-pos, hsys-org-region-with-face-type)
+    (hsys-org-is-face-type): Add support for working with org face types
+    to be compatible with org mode 9.7 and older versions.
+
 2024-06-23  Bob Weiner  <r...@gnu.org>
 
 * Makefile: (dockerized-run): Add to intweractively run dockerized versions
diff --git a/hsys-org.el b/hsys-org.el
index 11dbde4471..18983bcaf3 100644
--- a/hsys-org.el
+++ b/hsys-org.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     2-Jul-16 at 14:54:14
-;; Last-Mod:     22-Jun-24 at 23:43:08 by Mats Lidell
+;; Last-Mod:     23-Jun-24 at 23:39:40 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -368,20 +368,32 @@ Match to all todos if `keyword' is nil or the empty 
string."
           (org-occur (concat "^" org-outline-regexp " *" (regexp-quote 
keyword)))
           keyword))
 
-(defun hsys-org-region-with-text-property-value (pos property)
-  "Return region around POS that shares its text PROPERTY value, else nil.
+(defun hsys-org-first-face-type-pos (start org-face-type)
+  "Return the first position for property ORG-FACE-TYPE when viewed from 
START."
+  (let (next)
+    (while (and (setq next (previous-single-property-change start 'face))
+                (hsys-org-is-face-type org-face-type (get-text-property (1- 
next) 'face)))
+      (setq start next))
+    next))
+
+(defun hsys-org-last-face-type-pos (start org-face-type)
+  "Return the last position for property ORG-FACE-TYPE when viewed from START."
+  (let ((pos (next-single-property-change start 'face)))
+    (while (memq org-face-type (get-text-property pos 'face))
+      (setq pos (next-single-property-change pos 'face)))
+    pos))
+
+(defun hsys-org-region-with-face-type (pos org-face-type)
+  "Return region around POS that shares its ORG-FACE-TYPE value, else nil.
 Return the (start . end) buffer positions of the region."
   (when (null pos) (setq pos (point)))
-  (let ((property-value (get-text-property pos property))
-       (start-point pos))
-    (when property-value
-      ;; Can't use previous-single-property-change here because it
-      ;; ignores characters that lack the property, i.e. have nil values.
+  (let ((start-point pos))
+    (when (hsys-org-is-face-type org-face-type (get-text-property pos 'face))
       (if (bobp)
          (setq start-point (point-min))
-       (while (equal (get-text-property (1- start-point) property) 
property-value)
+       (while (hsys-org-is-face-type org-face-type (get-text-property (1- 
start-point) 'face))
          (setq start-point (1- start-point))))
-      (cons start-point (next-single-property-change start-point property)))))
+      (cons start-point (hsys-org-last-face-type-pos start-point 
org-face-type)))))
 
 (defun hsys-org-agenda-item-at-p ()
   "Return non-nil if point is on an Org Agenda view item line, else nil."
@@ -453,7 +465,7 @@ Assume caller has already checked that the current buffer 
is in `org-mode'."
 Link region is (start . end) and includes delimiters, else nil."
   (and (hsys-org-face-at-p 'org-link)
        (equal (get-text-property (point) 'help-echo) "Radio target link")
-       (hsys-org-region-with-text-property-value (point) 'face)))
+       (hsys-org-region-with-face-type (point) 'org-link)))
 
 (defun hsys-org-radio-target-def-at-p ()
   "Return target region iff point is on a <<<radio target>>> definition.
@@ -461,18 +473,19 @@ Target region is (start . end) and includes any 
delimiters, else nil."
   (when (hsys-org-target-at-p)
     (save-excursion
       (unless (looking-at org-radio-target-regexp)
-       (goto-char (or (previous-single-property-change (point) 'face) 
(point-min))))
+       (goto-char (or (hsys-org-first-face-type-pos (point) 'org-target)
+                       (point-min))))
       (when (looking-at "<<<")
        (goto-char (match-end 0)))
       (and (hsys-org-face-at-p 'org-target)
-          (hsys-org-region-with-text-property-value (point) 'face)))))
+          (hsys-org-region-with-face-type (point) 'org-target)))))
 
 (defun hsys-org-radio-target-at-p ()
   "Return region iff point is on a <<<radio target>>> or a link to one.
 The region is (start . end) and includes any delimiters, else nil."
   (and (or (hsys-org-radio-target-def-at-p)
           (hsys-org-radio-target-link-at-p))
-       (hsys-org-region-with-text-property-value (point) 'face)))
+       (hsys-org-region-with-face-type (point) 'org-target)))
 
 (defun hsys-org-internal-target-link-at-p ()
   "Return link text region iff point is on an Org mode internal target link.
@@ -480,7 +493,7 @@ Link region is (start . end) and includes delimiters, else 
nil."
   (and (hsys-org-face-at-p 'org-link)
        (not (equal (get-text-property (point) 'help-echo) "Radio target link"))
        (hsys-org-link-at-p)
-       (hsys-org-region-with-text-property-value (point) 'face)))
+       (hsys-org-region-with-face-type (point) 'org-link)))
 
 (defun hsys-org-internal-target-def-at-p ()
   "Return target region iff point is on <<internal target>> definition.
@@ -488,26 +501,29 @@ Target region is (start . end) and includes any 
delimiters, else nil."
   (when (hsys-org-target-at-p)
     (save-excursion
       (unless (looking-at org-target-regexp)
-       (goto-char (or (previous-single-property-change (point) 'face) 
(point-min))))
+       (goto-char (or (hsys-org-first-face-type-pos (point) 'org-target) 
(point-min))))
       (when (looking-at "<<")
        (goto-char (match-end 0)))
       (and (hsys-org-face-at-p 'org-target)
-          (hsys-org-region-with-text-property-value (point) 'face)))))
+          (hsys-org-region-with-face-type (point) 'org-target)))))
 
 (defun hsys-org-internal-target-at-p ()
   "Return region iff point is on an <<internal target>> or a link to one.
 The region is (start . end) and includes any delimiters, else nil."
   (and (or (hsys-org-internal-target-def-at-p)
           (hsys-org-internal-target-link-at-p))
-       (hsys-org-region-with-text-property-value (point) 'face)))
+       (hsys-org-region-with-face-type (point) 'org-target)))
+
+(defun hsys-org-is-face-type (org-face-type face-prop)
+  "Non-nil if FACE-PROP is a or contain ORG-FACE-TYPE."
+  (when (or (eq face-prop org-face-type)
+           (and (listp face-prop) (memq org-face-type face-prop)))
+    org-face-type))
 
 (defun hsys-org-face-at-p (org-face-type)
   "Return ORG-FACE-TYPE iff point is on a character with that face, else nil.
 ORG-FACE-TYPE must be a symbol, not a symbol name."
-  (let ((face-prop (get-text-property (point) 'face)))
-    (when (or (eq face-prop org-face-type)
-             (and (listp face-prop) (memq org-face-type face-prop)))
-      org-face-type)))
+  (hsys-org-is-face-type org-face-type (get-text-property (point) 'face)))
 
 ;; Adapted from Org code
 (defun hsys-org-search-internal-link-p (target)
diff --git a/test/hsys-org-tests.el b/test/hsys-org-tests.el
index 9b905d066c..01fc3a2f61 100644
--- a/test/hsys-org-tests.el
+++ b/test/hsys-org-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <ma...@gnu.org>
 ;;
 ;; Orig-Date:    23-Apr-21 at 20:55:00
-;; Last-Mod:      9-Apr-24 at 09:32:53 by Mats Lidell
+;; Last-Mod:     23-Jun-24 at 23:08:22 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -41,7 +41,7 @@
     (insert "* 1\n** 2\n*** 3\n")
     (goto-char 1)
     (font-lock-ensure)
-    (should (equal (hsys-org-region-with-text-property-value 1 'face) '(1 . 
4)))))
+    (should (equal (hsys-org-region-with-face-type 1 'org-level-1) '(1 . 4)))))
 
 ;; TODO: org-agenda-item-at-p
 

Reply via email to