From ac88b8ac1117007eca49a0b229d8cee6cba8bc87 Mon Sep 17 00:00:00 2001 Message-Id: From: Ihor Radchenko Date: Sat, 23 Jul 2022 13:13:24 +0800 Subject: [PATCH v4] org-attach-dir-from-id: Do not rely on ID being over 6 chars long * lisp/org-attach.el (org-attach-id-uuid-folder-format): Fall back to "__/ID" when the ID contains 2 chars or less and cannot be split into the "xy/z...." path. (org-attach-id-ts-folder-format): Fall back to "______/ID" path format when the ID contains less than 7 chars and cannot be split into the "YYYYMM/rest" path. (org-attach-dir-from-id): Allow all but first function return nil and be ignored. (org-attach-id-to-path-function-list): Document that all but first function can return nil. Fixes https://orgmode.org/list/KC8PcypJapBpJQtJxM0kX5N7Z0THL2Lq6EQjBMzpw1-vgQf72egZ2JOIlTbPYiqAVD4MdSBhrhBZr2Ykf5DN1mocm1ANvvuKKZShlkgzKYM=@pm.me --- lisp/org-attach.el | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/lisp/org-attach.el b/lisp/org-attach.el index 8509a6564..e4511794f 100644 --- a/lisp/org-attach.el +++ b/lisp/org-attach.el @@ -162,19 +162,27 @@ (defcustom org-attach-archive-delete nil (defun org-attach-id-uuid-folder-format (id) "Translate an UUID ID into a folder-path. Default format for how Org translates ID properties to a path for -attachments. Useful if ID is generated with UUID." - (format "%s/%s" - (substring id 0 2) - (substring id 2))) +attachments. Useful if ID is generated with UUID. + +When ID is too short (less than 3 chars), return \"__/ID\"." + (if (< (length id) 3) + (format "__/%s" id) + (format "%s/%s" + (substring id 0 2) + (substring id 2)))) (defun org-attach-id-ts-folder-format (id) "Translate an ID based on a timestamp to a folder-path. Useful way of translation if ID is generated based on ISO8601 timestamp. Splits the attachment folder hierarchy into -year-month, the rest." - (format "%s/%s" - (substring id 0 6) - (substring id 6))) +year-month, the rest. + +When ID is too short (less than 7 chars), return \"______/ID\"." + (if (< (length id) 7) + (format "______/%s" id) + (format "%s/%s" + (substring id 0 6) + (substring id 6)))) (defcustom org-attach-id-to-path-function-list '(org-attach-id-uuid-folder-format org-attach-id-ts-folder-format) @@ -182,7 +190,12 @@ (defcustom org-attach-id-to-path-function-list '(org-attach-id-uuid-folder-forma The first function in this list defines the preferred function which will be used when creating new attachment folders. All functions of this list will be tried when looking for existing -attachment folders based on ID." +attachment folders based on ID. + +The functions must either return string or nil. If a function returns +nil, its return value will be ignored when looking for existing +attachment folders. The first function in the list must always return +string." :group 'org-attach :package-version '(Org . "9.3") :type '(repeat (function :tag "Function with ID as input"))) @@ -400,11 +413,15 @@ (defun org-attach-dir-from-id (id &optional try-all) (expand-file-name org-attach-id-dir)))) (if try-all (let ((attach-dir attach-dir-preferred) - (fun-list (cdr org-attach-id-to-path-function-list))) + (fun-list (cdr org-attach-id-to-path-function-list)) + rtn) (while (and fun-list (not (file-directory-p attach-dir))) - (setq attach-dir (expand-file-name - (funcall (car fun-list) id) - (expand-file-name org-attach-id-dir))) + (setq rtn (funcall (car fun-list) id)) + ;; Skip nil return values. + (when rtn + (setq attach-dir (expand-file-name + rtn + (expand-file-name org-attach-id-dir)))) (setq fun-list (cdr fun-list))) (if (file-directory-p attach-dir) attach-dir -- 2.35.1