branch: externals/denote-org commit e06efdadb0f9f213ddb476969e3f9602c06a66ec Author: Peter Prevos <pe...@prevos.net> Commit: Peter Prevos <pe...@prevos.net>
Add dynamic block for hierarchic sequences Implement a new Org dynamic block to list children of a specified file up to a given depth. Include functions for inserting the sequence and updating the dynamic block. --- denote-org.el | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/denote-org.el b/denote-org.el index d3dd075fca..f296c45785 100644 --- a/denote-org.el +++ b/denote-org.el @@ -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