Closed swflint closed 1 month ago
From: "Samuel W. Flint" @.***> Date: Sat, 14 Sep 2024 12:18:38 -0700
Would it be possible to define a
denote-org-capture
for capturing to a specific journal note? Similarly one for the current day's journal note?
Do you want this to be specifically done via org-capture?
Note that the commands 'denote-journal-extras-new-entry' and 'denote-journal-extras-new-or-existing-entry' can both prompt for a specific date. Maybe this is a good place to start?
-- Protesilaos Stavrou https://protesilaos.com
Yes, I think integration into org capture would help simplify the use of functions like denote-journal-extras-new-entry
and denote-journal-extras-new-or-existing-entry
, similarly to how it seems denote-org-capture
can help to better integrate new note creation more generally.
From: "Samuel W. Flint" @.***> Date: Mon, 16 Sep 2024 11:02:14 -0700
Yes, I think integration into org capture would help simplify the use of functions like
denote-journal-extras-new-entry
anddenote-journal-extras-new-or-existing-entry
, similarly to how it seemsdenote-org-capture
can help to better integrate new note creation more generally.
Fine, I will check it out and update you accordingly.
-- Protesilaos Stavrou https://protesilaos.com
Can you try these?
(defun denote-journal-extras-org-capture (&optional prompt-for-date)
"Like `denote-journal-extras-new-entry' but for `org-capture'.
When optional PROMPT-FOR-DATE is non-nil, prompt for a date to create a
journal entry for (using the `denote-date-prompt', which can optionally
have the Org date picker, per `denote-date-prompt-use-org-read-date').
Otherwise, use the current date and time."
(let* ((internal-date (when prompt-for-date (denote-date-prompt)))
(date (denote-parse-date internal-date))
(title (denote-journal-extras-daily--title-format date))
(keywords (list denote-journal-extras-keyword))
(id (denote--find-first-unused-id (denote-get-identifier date)))
(template (denote-journal-extras--get-template))
(directory (denote-journal-extras-directory))
(front-matter (denote--format-front-matter title (denote--date date 'org) keywords id 'org)))
(setq denote-last-path (denote-format-file-name directory id keywords title ".org" nil))
(when (file-regular-p denote-last-path)
(user-error "A file named `%s' already exists" denote-last-path))
(concat front-matter template denote-org-capture-specifiers)))
(with-eval-after-load 'org-capture
(add-to-list 'org-capture-templates
'("j" "New journal entry" plain
(file denote-last-path)
#'denote-journal-extras-org-capture
:no-save t
:immediate-finish nil
:kill-buffer t
:jump-to-captured t)))
(with-eval-after-load 'org-capture
(add-to-list 'org-capture-templates
'("J" "New journal entry with date prompt" plain
(file denote-last-path)
(function
(lambda ()
(denote-journal-extras-org-capture :prompt-for-a-date)))
:no-save t
:immediate-finish nil
:kill-buffer t
:jump-to-captured t)))
Note that in the case where we prompt for a date, we do not check if a journal entry already exists. I think this is difficult because we do not have the same flexibility through org-capture
that we do when we define the whole procedure ourselves.
That seems to kind of work. It doesn't appear that either actually checks if a file exists for the date.
I may iterate on this, and would love to contribute, however, my employer has not cooperated with an FSF copyright release.
From: "Samuel W. Flint" @.***> Date: Wed, 18 Sep 2024 07:43:36 -0700
That seems to kind of work. It doesn't appear that either actually checks if a file exists for the date.
No, they do not check. They just create the new note. Maybe there is a way to make this happen via 'org-capture' but I am not sure how best to approach it. We do have the logic in 'denote-journal-extras-new-or-existing-entry' but we need to decide what to do with the CAPTURE buffer (and whatever concomitant state) if we find other notes.
I may iterate on this, and would love to contribute, however, my employer has not cooperated with an FSF copyright release.
Note that you can still contribute ~15 lines of non-trivial changes (yes, this is subject to interpretation). Because here we are modifying existing code that is already FSF-compliant, I think you will be within the limit.
But you can still give me ideas and then I can handle the rest.
-- Protesilaos Stavrou https://protesilaos.com
I had a similar need to yours, and came up with something that works (for me).
Unfortunately denote-org-capture
always creates a new file, and denote-journal-extras
doesn't expose something that can be called from org-capture
.
So we make our own:
(defun my/org-capture-denote-today-file ()
"File to capture daily notes in."
(let*
((title (format-time-string "%A %e %B %Y"))
(keywords (denote-keywords-sort '("day" "mem")))
(extension ".org")
(signature "")
(new-path (denote-format-file-name
(denote-directory)
(denote-get-identifier)
keywords
title
extension
signature))
;; remove directory and timestamp from path to generate regex
;; eg. "/path/to/20241001T002420--tuesday-1-october-2024__mem_proj.org"
;; becomes "20241001T\d{6}--tuesday-1-october-2024__mem_proj.org"
(file-regex (replace-regexp-in-string
"T[0-9]\\{6\\}" "T[0-9]\\{6\\}"
(file-name-nondirectory new-path)
:fixedcase :literal))
(files (denote-directory-files file-regex))
(path (if (seq-empty-p files) new-path (car files))))
(unless (file-exists-p path)
(denote-add-front-matter path title keywords))
path))
Then we can lean on org-capture
for the rest:
(add-to-list 'org-capture-templates
'("m" "Mem" entry (file+headline my/org-capture-denote-today-file "Mem")
"* %U %?\n%i\n%a" :prepend t :kill-buffer t :empty-lines 1))
Looked at this again, and found the cleanest solution hidden in plain sight denote-journal-extra-path-to-new-or-existing-entry
.
That works out of the box with org-capture
:
(add-to-list 'org-capture-templates
'("j" "Journal" entry (file+headline denote-journal-extra-path-to-new-or-existing-entry "Test")
"* %U %?\n%i\n%a" :prepend t :kill-buffer t :empty-lines 1))
My other want would be to allow multiple keywords for journal files, but I think this issue can be closed.
I don't think I would have noticed that with apropos-function
. The rest of the functions/commands in the file are prefixed with denote-journal-extras-
, which makes this slightly less discoverable.
This probably could be closed, but given the solution exists, it may make sense to leave it open until a patch for the manual is made?
I don't think I would have noticed that with
apropos-function
. The rest of the functions/commands in the file are prefixed withdenote-journal-extras-
, which makes this slightly less discoverable.
That is a mistake. I will fix it now.
This probably could be closed, but given the solution exists, it may make sense to leave it open until a patch for the manual is made?
I will do this as well. Thank you both!
I just made the changes to the manual. I used this code in the sample:
(with-eval-after-load 'org-capture
(add-to-list 'org-capture-templates
'("j" "Journal" entry
(file denote-journal-extras-path-to-new-or-existing-entry)
"* %U %?\n%i\n%a"
:kill-buffer t
:empty-lines 1)))
I removed the file+headline
that @cosmicz showed because I was not sure how that would be used in practice. Maybe there would be a separate section like, say, "Notes for the day" where the user would be adding text via org-capture
, but this would be different from another template/command for creating the note?
Anyway, closing now though you are welcome to make further changes and either suggest them here or send a PR. Thanks again!
Would it be possible to define a
denote-org-capture
for capturing to a specific journal note? Similarly one for the current day's journal note?