branch: externals/denote-sequence
commit cd4314955232db945b5f06000634085db1387f4d
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>

    Split denote-sequence-alphanumeric-delimited-p into its helper functions 
with relevant tests
    
    This thing has proven to be a beast. I think I have gotten right now
    and am able to continue implementing this feature.
---
 denote-sequence.el            | 102 +++++++++++++++++++++++++++++++++---------
 tests/denote-sequence-test.el |  23 ++++++++++
 2 files changed, 103 insertions(+), 22 deletions(-)

diff --git a/denote-sequence.el b/denote-sequence.el
index 02d51feefa..ab0e3d06a1 100644
--- a/denote-sequence.el
+++ b/denote-sequence.el
@@ -107,6 +107,80 @@ zx (z is 26 and x is 25)."
              (not (string-match-p "=" sequence)))
     sequence))
 
+(defun denote-sequence--alphanumeric-delimited-split (sequence)
+  "Split SEQUENCE to test for the alphanumeric delimited scheme."
+  (let ((start 0)
+        (strings nil))
+    (while (string-match "[0-9]+\\|[[:alpha:]]+\\|=" sequence start)
+      (push (match-string 0 sequence) strings)
+      (setq start (match-end 0)))
+    (nreverse strings)))
+
+(defun denote-sequence--alphanumeric-delimited-check-alternation 
(split-sequence)
+  "Return non-nil if SPLIT-SEQUENCE alternates between numbers and letters.
+
+SPLIT-SEQUENCE is an alphanumeric delimited sequence that is split into
+separate strings at each level of depth, like this:
+
+    (list \"1\" \"=\" \"a\" \"1\" \"b\" \"=\" \"2\" \"a\" \"1\")"
+  (catch 'error
+    (let ((last-type nil)
+          (current-type nil))
+      (dolist (string split-sequence)
+        (cond
+         ((string-match-p "\\`[0-9]+\\'" string)
+          (setq current-type 'numeric))
+         ((string-match-p "\\`[[:alpha:]]+\\'" string)
+          (setq current-type 'alpha)))
+        (unless (string= "=" string)
+          (when (eq current-type last-type)
+            (throw 'error nil))
+          (setq last-type current-type))))
+    t))
+
+(defun denote-sequence--alphanumeric-delimited-check-depths (split-sequence)
+  "Return non-nil if SPLIT-SEQUENCE is correctly delimited.
+More specifically, return non-nil if there is 1 level of depth before
+the first delimiter and then up to 3 for every subsequent delimiter.
+
+SPLIT-SEQUENCE is an alphanumeric delimited sequence that is split into
+separate strings at each level of depth, like this:
+
+    (list \"1\" \"=\" \"a\" \"1\" \"b\" \"=\" \"2\" \"a\" \"1\")"
+  (let ((levels-of-depth nil)
+        (current-depth 0))
+    (dolist (string split-sequence)
+      (if (string= string "=")
+          (progn
+            (push current-depth levels-of-depth)
+            (setq current-depth 0))
+        (setq current-depth (+ current-depth 1))))
+    (push current-depth levels-of-depth)
+    (setq levels-of-depth (nreverse levels-of-depth))
+    (catch 'error
+      (let ((first-level t))
+        (dolist (level levels-of-depth)
+          (if first-level
+              (progn
+                (setq first-level nil)
+                (unless (= level 1)
+                  (throw 'error nil)))
+            (unless (<= level 3)
+              (throw 'error nil)))))
+      (cond
+       ((and (length> levels-of-depth 2)
+             (= (car levels-of-depth) 1)
+             (seq-every-p
+              (lambda (level)
+                (= level 3))
+              (butlast (cdr levels-of-depth))))
+        levels-of-depth)
+       ((or (length= levels-of-depth 1)
+            (length= levels-of-depth 2))
+        levels-of-depth)
+       (t
+        nil)))))
+
 (defun denote-sequence-alphanumeric-delimited-p (sequence)
   "Return SEQUENCE if it is an alphanumeric and delimited.
 Refer to the `denote-sequence-scheme' for the details."
@@ -114,28 +188,12 @@ Refer to the `denote-sequence-scheme' for the details."
    ((string-match-p "\\`[0-9]+\\'" sequence)
     sequence)
    (t
-    (when (and (string-match-p "=" sequence)
-               (not (denote-sequence-numeric-p sequence)))
-      (let ((start 0)
-            (strings nil))
-        (while (string-match "[0-9]+\\|[[:alpha:]]+" sequence start)
-            (push (match-string 0 sequence) strings)
-            (setq start (match-end 0)))
-        (catch 'error
-          (let ((last-type nil)
-                (current-type nil))
-            ;; FIXME 2026-03-23: We need to test for length of each
-            ;; segment.  Specifically, the first should be 1, then
-            ;; every other should be maximum 3 (where the numbers
-            ;; refer to levels of depth).
-            (dolist (string (nreverse strings))
-              (if (string-match-p "\\`[0-9]+\\'" string)
-                  (setq current-type 'numeric)
-                (setq current-type 'alpha))
-              (when (eq current-type last-type)
-                (throw 'error nil))
-              (setq last-type current-type)))
-          sequence))))))
+    (when-let* ((_ (string-match-p "=" sequence))
+                (_ (not (denote-sequence-numeric-p sequence)))
+                (strings (denote-sequence--alphanumeric-delimited-split 
sequence))
+                (_ (denote-sequence--alphanumeric-delimited-check-alternation 
strings))
+                (_ (denote-sequence--alphanumeric-delimited-check-depths 
strings)))
+      sequence))))
 
 (defun denote-sequence-user-selected-scheme-p (sequence)
   "Return SEQUENCE if it is consistent with `denote-sequence-scheme'.
diff --git a/tests/denote-sequence-test.el b/tests/denote-sequence-test.el
index f962022063..c2d73520e0 100644
--- a/tests/denote-sequence-test.el
+++ b/tests/denote-sequence-test.el
@@ -60,6 +60,29 @@
   (should (string= (denote-sequence-alphanumeric-p "1") "1"))
   (should (string= (denote-sequence-alphanumeric-p "1a") "1a")))
 
+(ert-deftest dst-denote-sequence--alphanumeric-delimited-check-alternation ()
+  "Test that `denote-sequence--alphanumeric-delimited-check-alternation' does 
the right thing.
+This helper function only checks that we alternate between numbers and
+letters.  It is not responsible to validate the levels of depth."
+  (should-not (denote-sequence--alphanumeric-delimited-check-alternation '("1" 
"=" "a" "=" "a")))
+  (should (denote-sequence--alphanumeric-delimited-check-alternation '("1" "=" 
"a" "=" "1"))))
+
+(ert-deftest dst-denote-sequence--alphanumeric-delimited-check-depths ()
+  "Test that `denote-sequence--alphanumeric-delimited-check-depths' does the 
right thing.
+This helper function is not responsible for checking whether the
+sequence alternates between numbers and letters.  It only checks the
+levels of depth between delimiters."
+  (should-not (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" 
"a" "=" "1")))
+  (should-not (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" 
"a" "=" "1" "a")))
+  (should-not (denote-sequence--alphanumeric-delimited-check-depths '("1" "a" 
"=" "1" "a" "=" "1" "a")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" 
"1")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" "1" 
"a")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" "1" 
"a" "1")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" "1" 
"a" "1" "=" "1")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" "1" 
"a" "1" "=" "1" "a")))
+  (should (denote-sequence--alphanumeric-delimited-check-depths '("1" "=" "1" 
"a" "1" "=" "1" "a" "1"))))
+
 (ert-deftest dst-denote-sequence-alphanumeric-delimited-p ()
   "Test that `denote-sequence-alphanumeric-delimited-p' does what it is 
supposed to."
   (should-not (denote-sequence-alphanumeric-delimited-p "1a"))

Reply via email to