branch: externals/denote-org
commit 8362a6445f2b5a5cf9dcff55ebe0a8d99394e90d
Merge: 7873643ac5 29bc8e98c1
Author: Protesilaos Stavrou <i...@protesilaos.com>
Commit: GitHub <nore...@github.com>

    Merge pull request #9 from pprevos/main
    
    Add ability to for dynamic blocks with sequences
---
 README.org    | 24 ++++++++++++++++
 denote-org.el | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/README.org b/README.org
index dc54a167ba..cd9e4e31b7 100644
--- a/README.org
+++ b/README.org
@@ -107,6 +107,8 @@ Evaluate:
 (info "(org) Dynamic Blocks")
 #+end_src
 
+The ~org-dynamic-block-insert-dblock~ function (=C-c C-x x=) provides a 
dropdown menu of all available dynamic blocks.
+
 ** Org dynamic blocks to insert links
 :PROPERTIES:
 :CUSTOM_ID: h:50160fae-6515-4d7d-9737-995ad925e64b
@@ -448,6 +450,28 @@ you get all the parameters included:
   processing using Org facilities (a feature that is outside Denote's
   purview).
 
+** Org dynamic block to insert sequences
+#+findex: denote-org-dblock-insert-sequence
+The Denote-Sequence package enables using the Denote signature as a 
hierarchical indicator inspired by the Folgezettel principle in the 
Zettelkasten methodology.
+
+The =denote-sequence= block can be inserted at point with the command
+~denote-org-dblock-insert-sequence~ or by manually including the
+following in an Org file:
+
+: #+BEGIN: denote-sequence :sequence "1=1" :depth 2
+:
+: #+END:
+
+Both parameters are required.
+
+- The sequence is the root of the hierarchy displayed in the dynamic block.
+
+- The depth is the relative depth from the root note. So in the example above, 
the notes with sequence =1=1=1= and =1=1=2= will be included in the list, but 
not =1=1=2=1=.
+
+- The list of links Links is indented to visualise their hierarchical 
structure.
+
+- When the sequence is an empty string, all notes with sequences are included 
in the list, up to the specified depth.
+
 * Create a note from the current Org subtree
 :PROPERTIES:
 :CUSTOM_ID: h:d0c7cb79-21e5-4176-a6af-f4f68578c8dd
diff --git a/denote-org.el b/denote-org.el
index d3bb0daa74..ab9f04db48 100644
--- a/denote-org.el
+++ b/denote-org.el
@@ -485,9 +485,9 @@ point to a file with a Denote file name."
 ;;    (info "(org) Dynamic Blocks")
 ;;
 ;; The dynamic blocks defined herein are documented at length in the
-;; Denote manual.  See the following node and its subsections:
+;; Denote-Org manual.  See the following node and its subsections:
 ;;
-;;    (info "(denote) Use Org dynamic blocks")
+;;    (info "(denote-org) Use Org dynamic blocks")
 
 ;;;;; Common helper functions
 
@@ -959,6 +959,88 @@ Used by `org-dblock-update' with PARAMS provided by the 
dynamic block."
     (when rx (denote-org-dblock-add-files-as-headings rx add-links sort 
reverse excluded-dirs not-rx)))
   (join-line)) ; remove trailing empty line
 
+;;;;; Dynamic block to insert hierarchic sequences
+
+;;;###autoload
+(with-eval-after-load 'denote-sequence
+  (defun denote-org-dblock-insert-sequence (file depth)
+    "Create Org dynamic block to list all chilren of FILE up to a relative 
DEPTH.
+DEPTH of the root FILE is 1. Using 2 lists children, 3 grandchildren, and so 
on."
+    (interactive
+     (list
+      (denote-sequence-file-prompt
+       (format "List descendants of:"
+               (propertize
+               (denote--rename-dired-file-or-current-file-or-prompt)
+               'face 'denote-faces-prompt-current-name)))
+      (read-number "Maximum relative depth from root node: " 2))
+     (org-mode))
+    (org-create-dblock (list :name "denote-sequence"
+                             :sequence (denote-retrieve-filename-signature 
file)
+                            :depth depth))
+    (org-update-dblock)))
+
+;;;###autoload
+(with-eval-after-load 'denote-sequence
+  (defun org-dblock-write:denote-sequence (params)
+    "Function to update `denote-sequence' Org Dynamic blocks.
+When sequence is an empty string, then use all Denote files with a sequence.
+
+Used by `org-dblock-update' with PARAMS provided by the dynamic block."
+    (let* ((block-name (plist-get params :block-name))
+          (sequence (plist-get params :sequence))
+          (depth (plist-get params :depth))
+          ;; This will not work for people with bespoke 
`denote-file-name-components-order'
+          (parent (denote-directory-files (concat sequence "-")))
+          (children (denote-sequence-get-relative sequence 'all-children))
+          (family (if children
+                      (append parent children)
+                    (denote-sequence-get-all-files)))
+          (files (denote-sequence-get-files-with-max-depth depth family)))
+      (when block-name (insert "#+name: " block-name "\n"))
+      (denote-org--insert-sequence files)
+      (join-line))))
+
+(with-eval-after-load 'denote-sequence
+  (defun denote-sequence-get-files-with-max-depth (max-depth &optional files)
+    "Return members of FILES with sequence depth less or equal than MAX-DEPTH.
+When no FILES are provided, use all files with a sequence signature."
+    (unless files
+      (setq files (denote-sequence-get-all-files)))
+    (let* ((hierarchy '())
+          (files (denote-sequence-sort-files files))
+          (root-sequence (denote-retrieve-filename-signature (car files)))
+           (root-depth (denote-sequence-depth root-sequence)))
+      (message (number-to-string root-depth))
+      (dolist (file files)
+       (let* ((sequence (denote-retrieve-filename-signature file))
+               (depth (denote-sequence-depth sequence)))
+          (when (<= depth (- (+ root-depth max-depth) 1))
+            (push file hierarchy))))
+      (nreverse hierarchy))))
+
+(with-eval-after-load 'denote-sequence
+  (defun denote-org--insert-sequence (files)
+    "Insert indented list of links to sequence FILES."
+    (let* ((root-sequence (denote-retrieve-filename-signature (car files)))
+          (root-depth (denote-sequence-depth root-sequence))
+          (links '()))
+      (message "Inserting %s links" (length files))
+      (dolist (file files)
+       (let* ((sequence (denote-retrieve-filename-signature file))
+              (description (denote-get-link-description file))
+              (link-title (concat sequence ": " description))
+               (link (denote-format-link file link-title 'org nil))
+              (depth (- (denote-sequence-depth sequence) root-depth))
+              (indent (make-string (* depth 2) ?\s))
+              (link-as-list-item (format (concat indent 
denote-link--prepare-links-format) link)))
+         (push link-as-list-item links)))
+      (setq links (nreverse links))
+      (dolist (link links)
+       (insert link)))))
+
+;;; 
+
 ;; NOTE 2024-03-30: This is how the autoload is done in org.el.
 ;;;###autoload
 (eval-after-load 'org
@@ -967,7 +1049,8 @@ Used by `org-dblock-update' with PARAMS provided by the 
dynamic block."
      (org-dynamic-block-define "denote-missing-links" 
'denote-org-dblock-insert-missing-links)
      (org-dynamic-block-define "denote-backlinks" 
'denote-org-dblock-insert-backlinks)
      (org-dynamic-block-define "denote-files" 'denote-org-dblock-insert-files)
-     (org-dynamic-block-define "denote-files-as-headings" 
'denote-org-dblock-insert-files-as-headings)))
+     (org-dynamic-block-define "denote-files-as-headings" 
'denote-org-dblock-insert-files-as-headings)
+     (org-dynamic-block-define "denote-sequence" 
'denote-org-dblock-insert-sequence)))
 
 (provide 'denote-org)
 ;;; denote-org.el ends here

Reply via email to