branch: externals/denote
commit bde689cc9b5b2a641c02b6045825327e9add9c20
Author: Protesilaos Stavrou <i...@protesilaos.com>
Commit: Protesilaos Stavrou <i...@protesilaos.com>

    Remove Org extras as part of the wider project reorganisation
    
    Covered here: 
<https://protesilaos.com/codelog/2025-02-11-emacs-splitting-denote-many-packages/>
    
    Issue in the main Denote GitHub repository: 
<https://github.com/protesilaos/denote/issues/543>.
---
 denote-org-dblock.el |  70 -----
 denote-org-extras.el | 794 ---------------------------------------------------
 2 files changed, 864 deletions(-)

diff --git a/denote-org-dblock.el b/denote-org-dblock.el
deleted file mode 100644
index ca4c89ed21..0000000000
--- a/denote-org-dblock.el
+++ /dev/null
@@ -1,70 +0,0 @@
-;;; denote-org-dblock.el --- Compatibility alieases for Denote Org Dynamic 
blocks -*- lexical-binding: t -*-
-
-;; Copyright (C) 2022-2025  Free Software Foundation, Inc.
-
-;; Authors: Elias Storms <elias.sto...@gmail.com>,
-;;          Protesilaos Stavrou <i...@protesilaos.com>
-;; Maintainer: Protesilaos Stavrou <i...@protesilaos.com>
-;; Deprecated-since: 3.0.0
-;; URL: https://github.com/protesilaos/denote
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; This file defines compatibility aliases for Org dynamic blocks set
-;; up by Denote.  The new source of these is the denote-org-extras.el.
-;;
-;; Below is the old commentary.
-;;
-;; * * *
-;;
-;; This file defines Org dynamic blocks using the facility described
-;; in the Org manual.  Evaluate this:
-;;
-;;    (info "(org) Dynamic Blocks")
-;;
-;; The dynamic blocks defined herein are documented at length in the
-;; Denote manual.  See the following node and its subsections:
-;;
-;;    (info "(denote) Use Org dynamic blocks")
-
-;;; Code:
-
-(require 'denote-org-extras)
-
-(define-obsolete-function-alias
-  'denote-org-dblock-insert-links
-  'denote-org-extras-dblock-insert-links
-  "3.0.0")
-
-(define-obsolete-function-alias
-  'denote-org-dblock-insert-backlinks
-  'denote-org-extras-dblock-insert-backlinks
-  "3.0.0")
-
-(define-obsolete-function-alias
-  'denote-org-dblock-insert-files
-  'denote-org-extras-dblock-insert-files
-  "3.0.0")
-
-(display-warning
- 'denote
- "`denote-org-dblock.el' is obsolete; use `denote-org-extras.el'"
- :warning)
-
-(provide 'denote-org-dblock)
-;;; denote-org-dblock.el ends here
diff --git a/denote-org-extras.el b/denote-org-extras.el
deleted file mode 100644
index cec840e44b..0000000000
--- a/denote-org-extras.el
+++ /dev/null
@@ -1,794 +0,0 @@
-;;; denote-org-extras.el --- Denote extensions for Org mode -*- 
lexical-binding: t -*-
-
-;; Copyright (C) 2024-2025  Free Software Foundation, Inc.
-
-;; Author: Protesilaos Stavrou <i...@protesilaos.com>
-;; Maintainer: Protesilaos Stavrou <i...@protesilaos.com>
-;; URL: https://github.com/protesilaos/denote
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Optional extensions to Denote that work specifically with Org mode.
-
-;;; Code:
-
-(require 'denote)
-(require 'denote-sort)
-(require 'org)
-
-;;;; Link to file and heading
-
-(defun denote-org-extras--get-outline (file)
-  "Return `outline-regexp' headings and line numbers of FILE."
-  (with-current-buffer (find-file-noselect file)
-    (let ((outline-regexp (format "^\\(?:%s\\)" (or (bound-and-true-p 
outline-regexp) "\\*+ ")))
-          candidates)
-      (save-excursion
-        (goto-char (point-min))
-        (while (if (bound-and-true-p outline-search-function)
-                   (funcall outline-search-function)
-                 (re-search-forward outline-regexp nil t))
-          (push
-           ;; NOTE 2024-01-20: The -5 (minimum width) is a
-           ;; sufficiently high number to keep the alignment
-           ;; consistent in most cases.  Larger files will simply
-           ;; shift the heading text in minibuffer, but this is not an
-           ;; issue anymore.
-           (format "%-5s %s"
-                   (line-number-at-pos (point))
-                   (buffer-substring-no-properties (line-beginning-position) 
(line-end-position)))
-           candidates)
-          (goto-char (1+ (line-end-position)))))
-      (if candidates
-          (nreverse candidates)
-        (user-error "No outline")))))
-
-(define-obsolete-function-alias
-  'denote-org-extras--outline-prompt
-  'denote-org-extras-outline-prompt
-  "3.1.0")
-
-(defun denote-org-extras-outline-prompt (&optional file)
-  "Prompt for outline among headings retrieved by 
`denote-org-extras--get-outline'.
-With optional FILE use the outline of it, otherwise use that of
-the current file."
-  (let ((current-file (or file buffer-file-name)))
-    (completing-read
-     (format "Select heading inside `%s': "
-             (propertize (file-name-nondirectory current-file) 'face 
'denote-faces-prompt-current-name))
-     (denote--completion-table-no-sort 'imenu (denote-org-extras--get-outline 
current-file))
-     nil :require-match)))
-
-(defun denote-org-extras--get-heading-and-id-from-line (line file)
-  "Return heading text and CUSTOM_ID from the given LINE in FILE."
-  (with-current-buffer (find-file-noselect file)
-    (save-excursion
-      (goto-char (point-min))
-      (forward-line (1- line))
-      (cons (denote-link-ol-get-heading)
-            (if (eq denote-org-store-link-to-heading 'context)
-                (org-entry-get (point) "CUSTOM_ID")
-              (denote-link-ol-get-id))))))
-
-(defun denote-org-extras-format-link-with-heading (file heading-id description 
&optional format)
-  "Prepare link to FILE with HEADING-ID using DESCRIPTION.
-Optional FORMAT is the exact link pattern to use."
-  (when (region-active-p)
-    (setq description (buffer-substring-no-properties (region-beginning) 
(region-end)))
-    (denote--delete-active-region-content))
-  (format
-   (or format "[[denote:%s::#%s][%s]]")
-   (denote-retrieve-filename-identifier file)
-   heading-id
-   description))
-
-;;;###autoload
-(defun denote-org-extras-link-to-heading ()
-  "Link to file and then specify a heading to extend the link to.
-
-The resulting link has the following pattern:
-
-[[denote:IDENTIFIER::#ORG-HEADING-CUSTOM-ID]][Description::Heading text]].
-
-Because only Org files can have links to individual headings,
-limit the list of possible files to those which include the .org
-file extension (remember that Denote works with many file types,
-per the user option `denote-file-type').
-
-The user option `denote-org-extras-store-link-to-heading'
-determined whether the `org-store-link' function can save a link
-to the current heading.  Such links look the same as those of
-this command, though the functionality defined herein is
-independent of it.
-
-To only link to a file, use the `denote-link' command.
-
-Also see `denote-org-extras-backlinks-for-heading'."
-  (declare (interactive-only t))
-  (interactive nil org-mode)
-  (unless (derived-mode-p 'org-mode)
-    (user-error "Links to headings only work between Org files"))
-  (let ((context-p (eq denote-org-store-link-to-heading 'context)))
-    (when-let* ((file (denote-file-prompt ".*\\.org"))
-                (file-text (denote-get-link-description file))
-                (heading (denote-org-extras-outline-prompt file))
-                (line (string-to-number (car (split-string heading "\t"))))
-                (heading-data (denote-org-extras--get-heading-and-id-from-line 
line file))
-                (heading-text (car heading-data))
-                (heading-id (if (and context-p (null (cdr heading-data)))
-                                heading-text
-                              (cdr heading-data)))
-                (description (denote-link-format-heading-description file-text 
heading-text)))
-      (insert
-       (denote-org-extras-format-link-with-heading
-        file
-        heading-id
-        description
-        (when (equal heading-text heading-id)
-          "[[denote:%s::*%s][%s]]"))))))
-
-;;;; Heading backlinks
-
-(defun denote-org-extras--get-file-id-and-heading-id-or-context ()
-  "Return link to current file and heading.
-If a CUSTOM_ID is present and the value of the user option
-`denote-org-store-link-to-heading' is set to `context', then return a
-regexp that matches both the CUSTOM_ID and the context of the current
-heading.  This looks like:
-
-    \\(ID::*HEADING-TEXT\\|ID::#HEADING-ID\\)
-
-If CUSTOM_ID is present but `denote-org-store-link-to-heading' is not
-set to `context', then return a patternf of the following form:
-
-    ID::#HEADING-ID"
-  (when-let* ((id (denote-retrieve-filename-identifier-with-error 
buffer-file-name)))
-    (let ((context-p (eq denote-org-store-link-to-heading 'context))
-          (heading-id (org-entry-get (point) "CUSTOM_ID")))
-      (cond
-       ((and context-p heading-id)
-        (format "\\(%s::%s%s\\|#%s\\)" id (shell-quote-argument "*") 
(denote-link-ol-get-heading) heading-id))
-       (context-p
-        (concat id "::" (shell-quote-argument "*") 
(denote-link-ol-get-heading)))
-       (heading-id
-        (concat id "::#" heading-id))
-       (t
-        (error "No way to get link to a heading at point in file `%s'" 
buffer-file-name))))))
-
-(defun denote-org-extras--get-backlinks-buffer-name (text)
-  "Format a buffer name for `denote-org-extras-backlinks-for-heading' with 
TEXT."
-  (format "*Denote HEADING backlinks for %S*" text))
-
-(defun denote-org-extras--get-backlinks-for-heading (file-and-heading-id)
-  "Get backlinks to FILE-AND-HEADING-ID as a list of strings."
-  (when-let* ((files (denote-directory-files nil :omit-current :text-only))
-              (xref-file-name-display 'abs)
-              (matches-in-files (xref-matches-in-files file-and-heading-id 
files))
-              (xref-alist (xref--analyze matches-in-files)))
-    (mapcar
-     (lambda (x)
-       (denote-get-file-name-relative-to-denote-directory (car x)))
-     xref-alist)))
-
-;;;###autoload
-(defun denote-org-extras-backlinks-for-heading ()
-  "Produce backlinks for the current heading.
-This otherwise has the same behaviour as `denote-backlinks'---refer to
-that for the details.
-
-Also see `denote-org-extras-link-to-heading'."
-  (interactive)
-  (when-let* ((heading-id 
(denote-org-extras--get-file-id-and-heading-id-or-context))
-              (heading-text (substring-no-properties 
(denote-link-ol-get-heading))))
-    (denote-link--prepare-backlinks heading-id ".*\\.org" 
(denote-org-extras--get-backlinks-buffer-name heading-text))))
-
-;;;; Extract subtree into its own note
-
-(defun denote-org-extras--get-heading-date ()
-  "Try to return a timestamp for the current Org heading.
-This can be used as the value for the DATE argument of the
-`denote' command."
-  (when-let* ((pos (point))
-              (timestamp (or (org-entry-get pos "DATE")
-                             (org-entry-get pos "CREATED")
-                             (org-entry-get pos "CLOSED"))))
-    (date-to-time timestamp)))
-
-;;;###autoload
-(defun denote-org-extras-extract-org-subtree ()
-  "Create new Denote note using the current Org subtree as input.
-Remove the subtree from its current file and move its contents into a
-new Denote file (a subtree is a heading with all of its contents,
-including subheadings).
-
-Take the text of the subtree's top level heading and use it as the title
-of the new note.
-
-If the heading has any tags, use them as the keywords of the new note.
-If the Org file has any #+filetags use them as well (Org's filetags are
-inherited by the headings).  If none of these are true and the user
-option `denote-prompts' includes an entry for keywords, then prompt for
-keywords.  Else do not include any keywords.
-
-If the heading has a PROPERTIES drawer, retain it for further review.
-
-If the heading's PROPERTIES drawer includes a DATE or CREATED property,
-or there exists a CLOSED statement with a timestamp value, use that to
-derive the date (or date and time) of the new note (if there is only a
-date, the time is taken as 00:00).  If more than one of these is
-present, the order of preference is DATE, then CREATED, then CLOSED.  If
-none of these is present, use the current time.  If the `denote-prompts'
-includes an entry for a date, then prompt for a date at this stage (also
-see `denote-date-prompt-use-org-read-date').
-
-For the rest, consult the value of the user option `denote-prompts' in
-the following scenaria:
-
-- Optionally prompt for a subdirectory, otherwise produce the new note
-  in the variable `denote-directory'.
-
-- Optionally prompt for a file signature, otherwise do not use one.
-
-Make the new note an Org file regardless of the value of the user option
-`denote-file-type'."
-  (interactive nil org-mode)
-  (unless (derived-mode-p 'org-mode)
-    (user-error "Headings can only be extracted from Org files"))
-  (if-let* ((text (org-get-entry))
-            (heading (denote-link-ol-get-heading)))
-      (let ((tags (org-get-tags))
-            (date (denote-org-extras--get-heading-date))
-            subdirectory
-            signature)
-        (dolist (prompt denote-prompts)
-          (pcase prompt
-            ('keywords (when (not tags) (setq tags (denote-keywords-prompt))))
-            ('subdirectory (setq subdirectory (denote-subdirectory-prompt)))
-            ('date (when (not date) (setq date (denote-date-prompt))))
-            ('signature (setq signature (denote-signature-prompt)))))
-        (delete-region (org-entry-beginning-position)
-                       (save-excursion (org-end-of-subtree t) (point)))
-        (denote heading tags 'org subdirectory date text signature))
-    (user-error "No subtree to extract; aborting")))
-
-;;;; Convert links from `:denote' to `:file' and vice versa
-
-(defun denote-org-extras--get-link-type-regexp (type)
-  "Return regexp for Org link TYPE.
-TYPE is a symbol of either `file' or `denote'.
-
-The regexp consists of four groups.  Group 1 is the link type, 2
-is the target, 3 is the target's search terms, and 4 is the
-description."
-  (let ((group-1))
-    (pcase type
-      ('denote (setq group-1 "denote"))
-      ('file (setq group-1 "file"))
-      (_ (error "`%s' is an unknown link type" type)))
-    (format 
"\\[\\[\\(?1:%s:\\)\\(?:\\(?2:.*?\\)\\(?3:::.*\\)?\\]\\|\\]\\)\\(?4:\\[\\(?:.*?\\)\\]\\)?\\]"
 group-1)))
-
-(defun denote-org-extras--get-path (id)
-  "Return file path to ID according to `org-link-file-path-type'."
-  (if (or (eq org-link-file-path-type 'adaptive)
-          (eq org-link-file-path-type 'relative))
-      (denote-get-relative-path-by-id id)
-    (denote-get-path-by-id id)))
-
-;;;###autoload
-(defun denote-org-extras-convert-links-to-file-type ()
-  "Convert denote: links to file: links in the current Org buffer.
-Ignore all other link types.  Also ignore links that do not
-resolve to a file in the variable `denote-directory'."
-  (interactive nil org-mode)
-  (if (derived-mode-p 'org-mode)
-      (save-excursion
-        (let ((count 0))
-          (goto-char (point-min))
-          (while (re-search-forward (denote-org-extras--get-link-type-regexp 
'denote) nil :no-error)
-            (let* ((id (match-string-no-properties 2))
-                   (search (or (match-string-no-properties 3) ""))
-                   (desc (or (match-string-no-properties 4) ""))
-                   (file (save-match-data (denote-org-extras--get-path id))))
-              (when file
-                (let ((new-text (if desc
-                                    (format "[[file:%s%s]%s]" file search desc)
-                                  (format "[[file:%s%s]]" file search))))
-                  (replace-match new-text :fixed-case :literal)
-                  (setq count (1+ count))))))
-          (message "Converted %d `denote:' links to `file:' links" count)))
-    (user-error "The current file is not using Org mode")))
-
-;;;###autoload
-(defun denote-org-extras-convert-links-to-denote-type ()
-  "Convert file: links to denote: links in the current Org buffer.
-Ignore all other link types.  Also ignore file: links that do not
-point to a file with a Denote file name."
-  (interactive nil org-mode)
-  (if (derived-mode-p 'org-mode)
-      (save-excursion
-        (let ((count 0))
-          (goto-char (point-min))
-          (while (re-search-forward (denote-org-extras--get-link-type-regexp 
'file) nil :no-error)
-            (let* ((file (match-string-no-properties 2))
-                   (search (or (match-string-no-properties 3) ""))
-                   (desc (or (match-string-no-properties 4) ""))
-                   (id (save-match-data (denote-retrieve-filename-identifier 
file))))
-              (when id
-                (let ((new-text (if desc
-                                    (format "[[denote:%s%s]%s]" id search desc)
-                                  (format "[[denote:%s%s]]" id search))))
-                  (replace-match new-text :fixed-case :literal)
-                  (setq count (1+ count))))))
-          (message "Converted %d `file:' links to `denote:' links" count)))
-    (user-error "The current file is not using Org mode")))
-
-;;;; Org dynamic blocks
-
-;; NOTE 2024-01-22 12:26:13 +0200: The following is copied from the
-;; now-deleted denote-org-dblock.el.  Its original author was Elias
-;; Storms <elias.sto...@gmail.com>, with substantial contributions and
-;; further developments by me (Protesilaos).
-
-;; This section defines Org dynamic blocks using the facility described
-;; in the Org manual.  Evaluate this:
-;;
-;;    (info "(org) Dynamic Blocks")
-;;
-;; The dynamic blocks defined herein are documented at length in the
-;; Denote manual.  See the following node and its subsections:
-;;
-;;    (info "(denote) Use Org dynamic blocks")
-
-;;;;; Common helper functions
-
-(defun denote-org-extras-dblock--files (files-matching-regexp &optional 
sort-by-component reverse exclude-regexp)
-  "Return list of FILES-MATCHING-REGEXP in variable `denote-directory'.
-SORT-BY-COMPONENT, REVERSE, EXCLUDE-REGEXP have the same meaning as
-`denote-sort-get-directory-files'.  If both are nil, do not try to
-perform any sorting.
-
-Also see `denote-org-extras-dblock--files-missing-only'."
-  (cond
-   ((and sort-by-component reverse)
-    (denote-sort-get-directory-files files-matching-regexp sort-by-component 
reverse :omit-current exclude-regexp))
-   (sort-by-component
-    (denote-sort-get-directory-files files-matching-regexp sort-by-component 
nil :omit-current exclude-regexp))
-   (reverse
-    (denote-sort-get-directory-files files-matching-regexp 
:no-component-specified reverse :omit-current exclude-regexp))
-   (t
-    (denote-directory-files files-matching-regexp :omit-current nil 
exclude-regexp))))
-
-(defun denote-org-extras-dblock--get-missing-links (regexp)
-  "Return list of missing links to all notes matching REGEXP.
-Missing links are those for which REGEXP does not have a match in
-the current buffer."
-  (let ((found-files (denote-directory-files regexp :omit-current))
-        (linked-files (denote-link--expand-identifiers 
denote-org-link-in-context-regexp)))
-    (if-let* ((final-files (seq-difference found-files linked-files)))
-        final-files
-      (message "All links matching `%s' are present" regexp)
-      '())))
-
-(defun denote-org-extras-dblock--files-missing-only (files-matching-regexp 
&optional sort-by-component reverse)
-  "Return list of missing links to FILES-MATCHING-REGEXP.
-SORT-BY-COMPONENT and REVERSE have the same meaning as
-`denote-sort-files'.  If both are nil, do not try to perform any
-sorting.
-
-Also see `denote-org-extras-dblock--files'."
-  (denote-sort-files
-   (denote-org-extras-dblock--get-missing-links files-matching-regexp)
-   sort-by-component
-   reverse))
-
-;;;;; Dynamic block to insert links
-
-;;;###autoload
-(defun denote-org-extras-dblock-insert-links (regexp)
-  "Create Org dynamic block to insert Denote links matching REGEXP."
-  (interactive
-   (list
-    (denote-files-matching-regexp-prompt))
-   org-mode)
-  (org-create-dblock (list :name "denote-links"
-                           :regexp regexp
-                           :not-regexp nil
-                           :excluded-dirs-regexp nil
-                           :sort-by-component nil
-                           :reverse-sort nil
-                           :id-only nil
-                           :include-date nil))
-  (org-update-dblock))
-
-;; NOTE 2024-03-30: This is how the autoload is done in org.el.
-;;;###autoload
-(eval-after-load 'org
-  '(progn
-     (org-dynamic-block-define "denote-links" 
'denote-org-extras-dblock-insert-links)))
-
-;; TODO 2024-12-04: Maybe we can do this for anything that deals with
-;; regular expressions that users provide?  I prefer not to do the
-;; work if nobody wants it, though I am mentioning this here just in
-;; case.
-(defun denote-org-extras--parse-rx (regexp)
-  "Parse REGEXP as an `rx' argument or string and return string."
-  (cond
-   ((null regexp)
-    nil)
-   ((listp regexp)
-    (rx-to-string regexp))
-   ((stringp regexp)
-    regexp)
-   (t
-    (error "Regexp `%s' is neither a list nor a string" regexp))))
-
-;;;###autoload
-(defun org-dblock-write:denote-links (params)
-  "Function to update `denote-links' Org Dynamic blocks.
-Used by `org-dblock-update' with PARAMS provided by the dynamic block."
-  (let* ((rx (denote-org-extras--parse-rx (plist-get params :regexp)))
-         (not-rx (denote-org-extras--parse-rx (plist-get params :not-regexp)))
-         (sort (plist-get params :sort-by-component))
-         (reverse (plist-get params :reverse-sort))
-         (include-date (plist-get params :include-date))
-         (block-name (plist-get params :block-name))
-         (denote-excluded-directories-regexp (or (plist-get params 
:excluded-dirs-regexp)
-                                                 
denote-excluded-directories-regexp))
-         (files (denote-org-extras-dblock--files rx sort reverse not-rx)))
-    (when block-name (insert "#+name: " block-name "\n"))
-    (denote-link--insert-links files 'org (plist-get params :id-only) 
:no-other-sorting include-date)
-    (join-line))) ; remove trailing empty line
-
-;;;;; Dynamic block to insert missing links
-
-;; TODO 2024-12-03: Do we need the :not-regexp here?  I think yes,
-;; though I prefer to have a user of this kind of dblock send me their
-;; feedback.
-
-;;;###autoload
-(defun denote-org-extras-dblock-insert-missing-links (regexp)
-  "Create Org dynamic block to insert Denote links matching REGEXP."
-  (interactive
-   (list
-    (denote-files-matching-regexp-prompt))
-   org-mode)
-  (org-create-dblock (list :name "denote-missing-links"
-                           :regexp regexp
-                           :excluded-dirs-regexp nil
-                           :sort-by-component nil
-                           :reverse-sort nil
-                           :id-only nil
-                           :include-date nil))
-  (org-update-dblock))
-
-;; NOTE 2024-03-30: This is how the autoload is done in org.el.
-;;;###autoload
-(eval-after-load 'org
-  '(progn
-     (org-dynamic-block-define "denote-missing-links" 
'denote-org-extras-dblock-insert-missing-links)))
-
-;;;###autoload
-(defun org-dblock-write:denote-missing-links (params)
-  "Function to update `denote-links' Org Dynamic blocks.
-Used by `org-dblock-update' with PARAMS provided by the dynamic block."
-  (let* ((rx (denote-org-extras--parse-rx (plist-get params :regexp)))
-         (sort (plist-get params :sort-by-component))
-         (reverse (plist-get params :reverse-sort))
-         (include-date (plist-get params :include-date))
-         (block-name (plist-get params :block-name))
-         (denote-excluded-directories-regexp (or (plist-get params 
:excluded-dirs-regexp)
-                                                 
denote-excluded-directories-regexp))
-         (files (denote-org-extras-dblock--files-missing-only rx sort 
reverse)))
-    (when block-name (insert "#+name: " block-name "\n"))
-    (denote-link--insert-links files 'org (plist-get params :id-only) 
:no-other-sorting include-date)
-    (join-line))) ; remove trailing empty line
-
-;;;;; Dynamic block to insert backlinks
-
-(defun denote-org-extras-dblock--maybe-sort-backlinks (files sort-by-component 
reverse)
-  "Sort backlink FILES if SORT-BY-COMPONENT and/or REVERSE is non-nil."
-  (cond
-   ((and sort-by-component reverse)
-    (denote-sort-files files sort-by-component reverse))
-   (sort-by-component
-    (denote-sort-files files sort-by-component))
-   (reverse
-    (denote-sort-files files :no-component-specified reverse))
-   (t
-    files)))
-
-;; TODO 2024-12-03: Do we need the :not-regexp here?  I think yes,
-;; though I prefer to have a user of this kind of dblock send me their
-;; feedback.
-
-;;;###autoload
-(defun denote-org-extras-dblock-insert-backlinks ()
-  "Create Org dynamic block to insert Denote backlinks to current file."
-  (interactive nil org-mode)
-  (org-create-dblock (list :name "denote-backlinks"
-                           :excluded-dirs-regexp nil
-                           :sort-by-component nil
-                           :reverse-sort nil
-                           :id-only nil
-                           :this-heading-only nil
-                           :include-date nil))
-  (org-update-dblock))
-
-;; NOTE 2024-03-30: This is how the autoload is done in org.el.
-;;;###autoload
-(eval-after-load 'org
-  '(progn
-     (org-dynamic-block-define "denote-backlinks" 
'denote-org-extras-dblock-insert-backlinks)))
-
-;;;###autoload
-(defun org-dblock-write:denote-backlinks (params)
-  "Function to update `denote-backlinks' Org Dynamic blocks.
-Used by `org-dblock-update' with PARAMS provided by the dynamic block."
-  (when-let* ((files (if (plist-get params :this-heading-only)
-                         (denote-org-extras--get-backlinks-for-heading 
(denote-org-extras--get-file-id-and-heading-id-or-context))
-                       (denote-link-return-backlinks))))
-    (let* ((sort (plist-get params :sort-by-component))
-           (reverse (plist-get params :reverse-sort))
-           (include-date (plist-get params :include-date))
-           (denote-excluded-directories-regexp (or (plist-get params 
:excluded-dirs-regexp)
-                                                   
denote-excluded-directories-regexp))
-           (files (denote-org-extras-dblock--maybe-sort-backlinks files sort 
reverse)))
-      (denote-link--insert-links files 'org (plist-get params :id-only) 
:no-other-sorting include-date)
-      (join-line)))) ; remove trailing empty line
-
-;;;;; Dynamic block to insert entire file contents
-
-(defun denote-org-extras-dblock--get-file-contents (file &optional 
no-front-matter add-links)
-  "Insert the contents of FILE.
-With optional NO-FRONT-MATTER as non-nil, try to remove the front
-matter from the top of the file.  If NO-FRONT-MATTER is a number,
-remove that many lines starting from the top.  If it is any other
-non-nil value, delete from the top until the first blank line.
-
-With optional ADD-LINKS as non-nil, first insert a link to the
-file and then insert its contents.  In this case, format the
-contents as a typographic list.  If ADD-LINKS is `id-only', then
-insert links as `denote-link' does when supplied with an ID-ONLY
-argument."
-  (when (denote-file-is-note-p file)
-    (with-temp-buffer
-      (when add-links
-        (insert
-         (format "- %s\n\n"
-                 (denote-format-link
-                  file
-                  (denote-get-link-description file)
-                  'org
-                  (eq add-links 'id-only)))))
-      (let ((beginning-of-contents (point)))
-        (insert-file-contents file)
-        (when no-front-matter
-          (delete-region
-           (if (natnump no-front-matter)
-               (progn (forward-line no-front-matter) (line-beginning-position))
-             (1+ (re-search-forward "^$" nil :no-error 1)))
-           beginning-of-contents))
-        (when add-links
-          (indent-region beginning-of-contents (point-max) 2)))
-      (buffer-string))))
-
-(defvar denote-org-extras-dblock-file-contents-separator
-  (concat "\n\n" (make-string 50 ?-) "\n\n\n")
-  "Fallback separator used by `denote-org-extras-dblock-add-files'.")
-
-(defun denote-org-extras-dblock--separator (separator)
-  "Return appropriate value of SEPARATOR for 
`denote-org-extras-dblock-add-files'."
-  (cond
-   ((null separator) "")
-   ((stringp separator) separator)
-   (t denote-org-extras-dblock-file-contents-separator)))
-
-(defun denote-org-extras-dblock-add-files (regexp &optional separator 
no-front-matter add-links sort-by-component reverse excluded-dirs-regexp 
exclude-regexp)
-  "Insert files matching REGEXP.
-
-Seaprate them with the optional SEPARATOR.  If SEPARATOR is nil,
-use the `denote-org-extras-dblock-file-contents-separator'.
-
-If optional NO-FRONT-MATTER is non-nil try to remove the front
-matter from the top of the file.  Do it by finding the first
-blank line, starting from the top of the buffer.
-
-If optional ADD-LINKS is non-nil, first insert a link to the file
-and then insert its contents.  In this case, format the contents
-as a typographic list.
-
-If optional SORT-BY-COMPONENT is a symbol among `denote-sort-components',
-sort files matching REGEXP by the corresponding Denote file name
-component.  If the symbol is not among `denote-sort-components',
-fall back to the default identifier-based sorting.
-
-If optional REVERSE is non-nil reverse the sort order.
-
-Optional EXCLUDED-DIRS-REGEXP is the `let' bound value of
-`denote-excluded-directories-regexp'.  When nil, the original value of
-that user option is used.
-
-Optional EXCLUDE-REGEXP is a more general way to exclude files whose
-name matches the given regular expression."
-  (let* ((denote-excluded-directories-regexp (or excluded-dirs-regexp 
denote-excluded-directories-regexp))
-         (files (denote-org-extras-dblock--files regexp sort-by-component 
reverse exclude-regexp))
-         (files-contents (mapcar
-                          (lambda (file) 
(denote-org-extras-dblock--get-file-contents file no-front-matter add-links))
-                          files)))
-    (insert (string-join files-contents (denote-org-extras-dblock--separator 
separator)))))
-
-;;;###autoload
-(defun denote-org-extras-dblock-insert-files (regexp sort-by-component)
-  "Create Org dynamic block to insert Denote files matching REGEXP.
-Sort the files according to SORT-BY-COMPONENT, which is a symbol
-among `denote-sort-components'."
-  (interactive
-   (list
-    (denote-files-matching-regexp-prompt)
-    (denote-sort-component-prompt))
-   org-mode)
-  (org-create-dblock (list :name "denote-files"
-                           :regexp regexp
-                           :not-regexp nil
-                           :excluded-dirs-regexp nil
-                           :sort-by-component sort-by-component
-                           :reverse-sort nil
-                           :no-front-matter nil
-                           :file-separator nil
-                           :add-links nil))
-  (org-update-dblock))
-
-;; NOTE 2024-03-30: This is how the autoload is done in org.el.
-;;;###autoload
-(eval-after-load 'org
-  '(progn
-     (org-dynamic-block-define "denote-files" 
'denote-org-extras-dblock-insert-files)))
-
-;;;###autoload
-(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* ((rx (denote-org-extras--parse-rx (plist-get params :regexp)))
-         (not-rx (denote-org-extras--parse-rx (plist-get params :not-regexp)))
-         (sort (plist-get params :sort-by-component))
-         (reverse (plist-get params :reverse-sort))
-         (block-name (plist-get params :block-name))
-         (separator (plist-get params :file-separator))
-         (no-f-m (plist-get params :no-front-matter))
-         (add-links (plist-get params :add-links))
-         (excluded-dirs (plist-get params :excluded-dirs-regexp)))
-    (when block-name (insert "#+name: " block-name "\n"))
-    (when rx (denote-org-extras-dblock-add-files rx separator no-f-m add-links 
sort reverse excluded-dirs not-rx)))
-  (join-line)) ; remove trailing empty line
-
-;;;; Insert files as headings
-
-(defun denote-org-extras-dblock--extract-regexp (regexp)
-  "Extract REGEXP from the buffer and trim it of surrounding spaces."
-  (string-trim
-   (save-excursion
-     (re-search-forward regexp nil :no-error)
-     (buffer-substring-no-properties (match-end 0) (line-end-position)))))
-
-(defun denote-org-extras-dblock--get-file-contents-as-heading (file add-links)
-  "Insert the contents of Org FILE, formatting the #+title as a heading.
-With optional ADD-LINKS, make the title link to the original file."
-  (when-let* (((denote-file-is-note-p file))
-              (identifier (denote-retrieve-filename-identifier file))
-              (file-type (denote-filetype-heuristics file))
-              ((eq file-type 'org)))
-    (with-temp-buffer
-      (let ((beginning-of-contents (point))
-            title
-            tags)
-        (insert-file-contents file)
-        (setq title (denote-org-extras-dblock--extract-regexp 
(denote--title-key-regexp file-type)))
-        (setq tags (denote-org-extras-dblock--extract-regexp 
(denote--keywords-key-regexp file-type)))
-        (delete-region (1+ (re-search-forward "^$" nil :no-error 1)) 
beginning-of-contents)
-        (goto-char beginning-of-contents)
-        (when (and title tags)
-          (if add-links
-              (insert (format "* [[denote:%s][%s]] %s\n\n" identifier title 
tags))
-            (insert (format "* %s %s\n\n" title tags)))
-          (org-align-tags :all))
-        (while (re-search-forward "^\\(*+?\\) " nil :no-error)
-          (replace-match (format "*%s " "\\1"))))
-      (buffer-string))))
-
-(defun denote-org-extras-dblock-add-files-as-headings (regexp &optional 
add-links sort-by-component reverse excluded-dirs-regexp exclude-regexp)
-  "Insert files matching REGEXP.
-
-If optional ADD-LINKS is non-nil, first insert a link to the file
-and then insert its contents.  In this case, format the contents
-as a typographic list.
-
-If optional SORT-BY-COMPONENT is a symbol among `denote-sort-components',
-sort files matching REGEXP by the corresponding Denote file name
-component.  If the symbol is not among `denote-sort-components',
-fall back to the default identifier-based sorting.
-
-If optional REVERSE is non-nil reverse the sort order.
-
-Optional EXCLUDED-DIRS-REGEXP is the `let' bound value of
-`denote-excluded-directories-regexp'.  When nil, the original value of
-that user option is used.
-
-Optional EXCLUDE-REGEXP is a more general way to exclude files whose
-name matches the given regular expression."
-  (let* ((denote-excluded-directories-regexp (or excluded-dirs-regexp 
denote-excluded-directories-regexp))
-         (files (denote-org-extras-dblock--files regexp sort-by-component 
reverse exclude-regexp))
-         (files-contents (mapcar
-                          (lambda (file)
-                            
(denote-org-extras-dblock--get-file-contents-as-heading file add-links))
-                          files)))
-    (insert (string-join files-contents))))
-
-;;;###autoload
-(defun denote-org-extras-dblock-insert-files-as-headings (regexp 
sort-by-component)
-  "Create Org dynamic block to insert Denote Org files matching REGEXP.
-
-Turn the #+title of each file into a top-level heading.  Then increment
-all original headings in the file by one, so that they become
-subheadings of what once was the #+title.
-
-Use the #+filetags of each file as tags for the top-level heading (what
-was the #+title).
-
-Sort the files according to SORT-BY-COMPONENT, which is a symbol
-among `denote-sort-components'.
-
-IMPORTANT NOTE: This dynamic block only works with Org files, because it
-has to assume the Org notation in order to insert each file's contents
-as its own heading."
-  (interactive
-   (list
-    (denote-files-matching-regexp-prompt)
-    (denote-sort-component-prompt))
-   org-mode)
-  (org-create-dblock (list :name "denote-files-as-headings"
-                           :regexp regexp
-                           :not-regexp nil
-                           :excluded-dirs-regexp nil
-                           :sort-by-component sort-by-component
-                           :reverse-sort nil
-                           :add-links nil))
-  (org-update-dblock))
-
-;; NOTE 2024-03-30: This is how the autoload is done in org.el.
-;;;###autoload
-(eval-after-load 'org
-  '(progn
-     (org-dynamic-block-define "denote-files-as-headings" 
'denote-org-extras-dblock-insert-files-as-headings)))
-
-;;;###autoload
-(defun org-dblock-write:denote-files-as-headings (params)
-  "Function to update `denote-files' Org Dynamic blocks.
-Used by `org-dblock-update' with PARAMS provided by the dynamic block."
-  (let* ((rx (denote-org-extras--parse-rx (plist-get params :regexp)))
-         (not-rx (denote-org-extras--parse-rx (plist-get params :not-regexp)))
-         (sort (plist-get params :sort-by-component))
-         (reverse (plist-get params :reverse-sort))
-         (block-name (plist-get params :block-name))
-         (add-links (plist-get params :add-links))
-         (excluded-dirs (plist-get params :excluded-dirs-regexp)))
-    (when block-name (insert "#+name: " block-name "\n"))
-    (when rx (denote-org-extras-dblock-add-files-as-headings rx add-links sort 
reverse excluded-dirs not-rx)))
-  (join-line)) ; remove trailing empty line
-
-(provide 'denote-org-extras)
-;;; denote-org-extras.el ends here


Reply via email to