protesilaos / denote

Simple notes for Emacs with an efficient file-naming scheme
https://protesilaos.com/emacs/denote
GNU General Public License v3.0
512 stars 54 forks source link

Denote file duplication #335

Closed heikkil closed 4 months ago

heikkil commented 5 months ago

Now that denote has automatically generated unique identifiers for org headers, I think that denote needs interactive commands to create new header ID:s (as property CUSTOM-ID) on demand for

  1. the current org header,
  2. for all current document headers,
  3. and preferably a dedicated denote file duplication command that takes care of the ID regeneration while asking for a new name and prompting it with the current name.

My use case is a set of denote files that contain monthly tables, code, and visualisations for the home energy usage and generation. The contents and code details keep changing, so creating a template in not feasible. Instead, at the end of the current month, I create a new denote file for the coming month following my naming convention and add the appropriate tag. I then copy and paste the contents of the file of the current month. I then run a few global replace commands to update the date tags and related names. I just realised the obvious that the header ID:s remain the same when they should be recreated to be unique. This requirement is true more generally whenever one copies any header ID to another file.

A quick look at the existing denote commands and functions did not turn up anything useful. Have I missed something?

protesilaos commented 5 months ago

the current org header

We do this indirectly when the user calls org-store-link or when we use denote-org-extras-link-to-heading. Though check the code below.

for all current document headers

About generating CUSTOM_ID for the whole buffer, I have this:

;; Original idea:
;; <https://writequit.org/articles/emacs-org-mode-generate-ids.html>.
(defun prot-org--id-get ()
  "Get the CUSTOM_ID of the current entry.
If the entry already has a CUSTOM_ID, return it as-is, else
create a new one."
  (let* ((pos (point))
         (id (org-entry-get pos "CUSTOM_ID")))
    (if (and id (stringp id) (string-match-p "\\S-" id))
        id
      (setq id (org-id-new "h"))
      (org-entry-put pos "CUSTOM_ID" id)
      id)))

(declare-function org-map-entries "org")

;;;###autoload
(defun prot-org-id-headlines ()
  "Add missing CUSTOM_ID to all headlines in current file."
  (interactive)
  (org-map-entries
   (lambda () (prot-org--id-get))))

;;;###autoload
(defun prot-org-id-headline ()
  "Add missing CUSTOM_ID to headline at point."
  (interactive)
  (prot-org--id-get))

I do not think this is strictly Denote-related. Though we can have it in the Denote manual.

and preferably a dedicated denote file duplication command that takes care of the ID regeneration while asking for a new name and prompting it with the current name.

We can think about how best to address this. I am thinking of a custom command that wraps around denote, like those we have in the manual or use in our code base. Instead of a template, it would fill in the document with contents, while evaluating the variable parts. The heading IDs could be generated afterwards by running the equivalent of prot-org-id-headlines with the denote-after-new-note-hook.

jeanphilippegg commented 5 months ago

a dedicated denote file duplication command that takes care of the ID regeneration while asking for a new name and prompting it with the current name.

While we currently do not allow the modification of the ID, one way to go about it is to first remove the ID from the file name, then use denote-rename-file on the file. The ID will be regenerated and you will be asked for a new name (and prompted with the current name). The front matter will still contain the old ID, but we never use it anyway.

protesilaos commented 5 months ago

From: Jean-Philippe Gagné Guay @.***> Date: Sun, 28 Apr 2024 13:54:01 -0700

a dedicated denote file duplication command that takes care of the ID regeneration while asking for a new name and prompting it with the current name.

While we currently do not allow the modification of the ID, one way to go about it is to first remove the ID from the file name, then use denote-rename-file on the file. The ID will be regenerated and you will be ask for a new name (and prompted with the current name).

Yes, this is a working method.

The front matter will still contain the old ID, but we never use it anyway.

True. Though note that one of the reasons to add front matter is to give other programs some metadata to use (e.g. a custom Org export backend). I do not know if there is any package/command outside of Denote that relies on the front matter we write. But it is better to work with the assumption that some other program needs this.

-- Protesilaos Stavrou https://protesilaos.com

heikkil commented 5 months ago

a dedicated denote file duplication command that takes care of the ID regeneration while asking for a new name and prompting it with the current name.

While we currently do not allow the modification of the ID, one way to go about it is to first remove the ID from the file name, then use denote-rename-file on the file. The ID will be regenerated and you will be asked for a new name (and prompted with the current name). The front matter will still contain the old ID, but we never use it anyway.

All my comments in this issue refer to header IDs, not the file ID that the current denote function set handles well.

Prot, thank you for theese code snippets. I can see how they can be used to build what is needed (when time allows...).

protesilaos commented 4 months ago

Thank you! We can safely close this now.