emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/denote 643f52677c: Define 'denote-files' Org dynamic bl


From: ELPA Syncer
Subject: [elpa] externals/denote 643f52677c: Define 'denote-files' Org dynamic block
Date: Thu, 23 Nov 2023 03:57:38 -0500 (EST)

branch: externals/denote
commit 643f52677c09cbdb3e40bcfc30bd0ec89df15ff5
Author: Protesilaos Stavrou <info@protesilaos.com>
Commit: Protesilaos Stavrou <info@protesilaos.com>

    Define 'denote-files' Org dynamic block
---
 README.org           | 41 +++++++++++++++++++++++++++++++++++++++++
 denote-org-dblock.el | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

diff --git a/README.org b/README.org
index ef1a6d2512..ccd5dff1dc 100644
--- a/README.org
+++ b/README.org
@@ -2450,6 +2450,47 @@ Evaluate:
 Dynamic blocks are particularly useful for metanote entries that
 reflect on the status of earlier notes 
([[#h:6060a7e6-f179-4d42-a9de-a9968aaebecc][Writing metanotes]]).
 
+** Org dynamic block to insert file contents
+:PROPERTIES:
+:CUSTOM_ID: h:f15fa143-5036-416f-9bff-1bcabbb03456
+:END:
+
+[ Part of {{{development-version}}}. ]
+
+Denote can optionally use Org's dynamic blocks facility to produce a
+section that lists entire file contents 
([[#h:8b542c50-dcc9-4bca-8037-a36599b22779][Use Org dynamic blocks]]).
+This works by instrucing Org to match a regular expression of Denote
+files, the same way we do with Denote links 
([[#h:9bec2c83-36ca-4951-aefc-7187c5463f90][Insert links matching a regexp]]). 
+
+This is useful to, for example, compile a dynamically concatenated
+list of scattered thoughts on a given topic, like =^2023.*_emacs= for
+long entry that incorporates all the notes written in 2023 with the
+keyword =emacs=.
+
+To produce such a block, use the following syntax in an Org file and
+type =C-c C-c= on the =#+BEGIN= line (type =C-c C-c= again to
+recalculate the block):
+
+: #+BEGIN: denote-files :regexp "YOUR-REGEXP-HERE"
+:
+: #+END:
+
+The =:regexp= parameter is mandatory. Its value is a string,
+representing a regular expression to match Denote file names. Its
+value may also be an ~rx~ expression instead of a string, as noted in
+the previous section about Org dynamic blocks.
+
+#+vindex: denote-org-dblock-file-contents-separator
+File contents are inserted verbatim. They are separated by the
+~denote-org-dblock-file-contents-separator~, which introduces some
+empty lines and a horizontal rule between them to visually distinguish
+individual files. Though the block accepts an optional parameter of
+=:file-separator=, which takes a string as a value. It is recommended
+to include newline characters (=\n=) in the string for better results.
+
+A =:block-name= parameter adds a =#+name= to the results for further
+processing using Org facilities (this is outside Denote's purview).
+
 * Minibuffer histories
 :PROPERTIES:
 :CUSTOM_ID: h:82dc1203-d689-44b2-9a6c-b37776209651
diff --git a/denote-org-dblock.el b/denote-org-dblock.el
index b3498b07aa..b6486a3574 100644
--- a/denote-org-dblock.el
+++ b/denote-org-dblock.el
@@ -149,5 +149,43 @@ Used by `org-dblock-update' with PARAMS provided by the 
dynamic block."
       (insert (denote-link--prepare-links files file nil))
       (join-line)))) ;; remove trailing empty line
 
+;;;; Dynamic block with entire file contents
+
+(defvar denote-org-dblock-file-contents-separator
+  (concat "\n\n" (make-string 50 ?-) "\n\n\n")
+  "Fallback separator used by `denote-org-dblock-add-files'.")
+
+;;;###autoload
+(defun denote-org-dblock-add-files (regexp &optional separator)
+  "Insert files matching REGEXP.
+Seaprate them with the optional SEPARATOR.  If SEPARATOR is nil,
+use the `denote-org-dblock-file-contents-separator'."
+  (let ((files (denote-directory-files-matching-regexp regexp)))
+    ;; FIXME 2023-11-23: Do not use a separator for the last file.
+    ;; Not a big issue, but is worth checking.
+    (mapc
+     (lambda (file)
+       ;; NOTE 2023-11-23: I tried to just do `insert-file-contents'
+       ;; without the temporary buffer, but it seems that the point is
+       ;; not moved, so the SEPARATOR does not follow the contents.
+       (let ((contents (with-temp-buffer
+                         (insert-file-contents file)
+                         (buffer-string))))
+         (insert (concat contents
+                         (or separator
+                             denote-org-dblock-file-contents-separator)))))
+     files)))
+
+(defun org-dblock-write:denote-files (params)
+  "Function to update `denote-files' Org Dynamic blocks.
+Used by `org-dblock-update' with PARAMS provided by the dynamic block."
+  (let* ((regexp (plist-get params :regexp))
+         (rx (if (listp regexp) (macroexpand `(rx ,regexp)) regexp))
+         (block-name (plist-get params :block-name))
+         (separator (plist-get params :file-separator)))
+    (when block-name
+      (insert "#+name: " block-name "\n"))
+    (when rx (denote-org-dblock-add-files rx separator))))
+
 (provide 'denote-org-dblock)
 ;;; denote-org-dblock.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]