Add support for org-id

For a discussion, read issue 8 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/8>.
This commit is contained in:
Protesilaos Stavrou 2022-06-22 20:17:24 +03:00 committed by Kaushal Modi
parent 25cc5a79e6
commit d6543cfa0d
3 changed files with 47 additions and 7 deletions

View file

@ -196,6 +196,9 @@ and/or the documentation string of `display-buffer'."
(defconst denote-link--format-org "[[denote:%s][%s]]"
"Format of Org link to note.")
(defconst denote-link--format-org-with-id "[[id:%s][%s]]"
"Format of Org link to note for `denote-use-org-id'.")
(defconst denote-link--format-markdown "[%2$s](denote:%1$s)"
"Format of Markdown link to note.")
@ -203,7 +206,7 @@ and/or the documentation string of `display-buffer'."
"Format of identifier-only link to note.")
(defconst denote-link--regexp-org
(concat "\\[\\[" "denote:" "\\(?1:" denote--id-regexp "\\)" "]" "\\[.*?]]"))
(concat "\\[\\[" "\\(denote\\|[Ii][Dd]\\):" "\\(?1:" denote--id-regexp "\\)" "]" "\\[.*?]]"))
(defconst denote-link--regexp-markdown
(concat "\\[.*?]" "(denote:" "\\(?1:" denote--id-regexp "\\)" ")"))
@ -213,9 +216,12 @@ and/or the documentation string of `display-buffer'."
(defun denote-link--file-type-format (file)
"Return link format based on FILE format."
(let ((org-format (if denote-use-org-id
denote-link--format-org-with-id
denote-link--format-org)))
(pcase (file-name-extension file)
("md" denote-link--format-markdown)
(_ denote-link--format-org))) ; Includes backup files. Maybe we can remove them?
(_ org-format)))) ; Includes backup files. Maybe we can remove them?
(defun denote-link--file-type-regexp (file)
"Return link regexp based on FILE format."

View file

@ -39,7 +39,7 @@ The match that needs to be extracted is explicityly marked as
group 1.")
(defconst denote-retrieve--identifier-regexp
"^.?.?\\b\\(?:identifier\\|ID\\)\\s-*[:=]\\s-*[\"']?\\(?1:[0-9T]+\\)[\"']?"
"^.?.?\\b\\(?:identifier\\|[Ii][Dd]\\)\\s-*[:=]\\s-*[\"']?\\(?1:[0-9T]+\\)[\"']?"
"Regular expression for identifier key and value.
The match that needs to be extracted is explicityly marked as
group 1.")

View file

@ -211,6 +211,25 @@ is suspended: we use whatever the user wants."
(string :tag "Custom format for `format-time-string'"))
:group 'denote)
(defcustom denote-use-org-id nil
"When non-nil use the ID property and link type in Org files.
To use the ID property, a PROPERTIES drawer is added to the top
of newly created notes. Furthermore, newly created links will
use the standard 'id:' hyperlink type instead of the custom
'denote:' type.
In practical terms, the ID ensures maximum compatibility with the
Org ecosystem.
When the value is nil, Denote uses a generic front matter for new
notes and links rely on the custom 'denote:' type (which should
behave the same as the standard 'file:' type).
Other files types beside Org always use the 'denote:' links and
keep their generic front matter."
:type 'boolean
:group 'denote)
;;;; Main variables
(defconst denote--id-format "%Y%m%dT%H%M%S"
@ -246,6 +265,8 @@ We consider those characters illigal for our purposes.")
`(metadata (category . ,category))
(complete-with-action action candidates string pred))))
(defvar org-id-extra-files)
(defun denote-directory ()
"Return path of variable `denote-directory' as a proper directory."
(let* ((val (or (buffer-local-value 'denote-directory (current-buffer))
@ -253,6 +274,8 @@ We consider those characters illigal for our purposes.")
(path (if (or (eq val 'default-directory) (eq val 'local)) default-directory val)))
(unless (file-directory-p path)
(make-directory path t))
(when (and denote-use-org-id (require 'org-id nil t))
(setq org-id-extra-files (directory-files path nil "\.org$")))
(file-name-as-directory path)))
(defun denote--extract (regexp str &optional group)
@ -508,6 +531,16 @@ and do not use any empty line before it.
These help ensure consistency and might prove useful if we need
to operate on the front matter as a whole.")
(defvar denote-org-with-id-front-matter
":PROPERTIES:
:ID: %4$s
:END:
#+title: %1$s
#+date: %2$s
#+filetags: %3$s
\n"
"Like `denote-org-front-matter' but for `denote-use-org-id'.")
(defun denote--file-meta-header (title date keywords id &optional filetype)
"Front matter for new notes.
@ -517,12 +550,13 @@ TITLE, DATE, KEYWORDS, FILENAME, ID are all strings which are
Optional FILETYPE is one of the values of `denote-file-type',
else that variable is used."
(let ((kw-space (denote--file-meta-keywords keywords))
(kw-toml (denote--file-meta-keywords keywords 'toml)))
(kw-toml (denote--file-meta-keywords keywords 'toml))
(org-front (if denote-use-org-id denote-org-with-id-front-matter denote-org-front-matter)))
(pcase (or filetype denote-file-type)
('markdown-toml (format denote-toml-front-matter title date kw-toml id))
('markdown-yaml (format denote-yaml-front-matter title date kw-space id))
('text (format denote-text-front-matter title date kw-space id denote-text-front-matter-delimiter))
(_ (format denote-org-front-matter title date kw-space id)))))
(_ (format org-front title date kw-space id)))))
(defun denote--path (title keywords &optional dir id)
"Return path to new file with TITLE and KEYWORDS.