From 641f7364785a19327195251595634b32827ef1df Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Fri, 1 Apr 2022 18:37:10 -0700 Subject: [PATCH] [oni-org] Add dynamic block for org for linking together projects This is similar to my backlinks dynamic block, but it supports links by id and will print them as a checkbox so that the project can track progress by using the progress cookies. --- oni-org/oni-org.el | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/oni-org/oni-org.el b/oni-org/oni-org.el index b6d9105..6bdf04c 100644 --- a/oni-org/oni-org.el +++ b/oni-org/oni-org.el @@ -810,5 +810,49 @@ This is an around advice for ‘org-html--svg-image’ as FUN." (add-to-list 'org-duration-units `("p" . ,oni-org-pomodoro-duration)) (org-duration-set-regexps)) +;;; Projects + +(defun oni-org-pick-project (property) + (when (string= property "PROJECT") + (org-map-entries (lambda () (concat (buffer-name) ":" (mapconcat (lambda (x) x) (org-get-outline-path t) ":"))) "CATEGORY=\"project\""))) + +(defun oni-org-link-project (value) + (let* ((split-value (split-string value ":")) + (marker (org-find-olp split-value))) + (save-excursion + (goto-char marker) + (format "[[id:%s][%s]]" (org-id-get-create) (car (last split-value)))))) + +(add-to-list 'org-properties-postprocess-alist '("PROJECT" . oni-org-link-project)) + +(add-hook 'org-property-allowed-value-functions #'oni-org-pick-project) + +(defun oni-org-dblock-write-project-steps (_params) + "Generate backlinks to org headings." + (let ((current-heading (nth 4 (org-heading-components))) + (current-heading-id + (let ((properties (org-entry-properties))) + (or (alist-get "CUSTOM_ID" properties nil nil #'string=) + (org-id-get-create)))) + backlinks) + (when (not (null current-heading-id)) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward (rx-to-string `(or (seq "[[id:" ,current-heading-id "]") + (seq "#" ,current-heading-id "]"))) nil t) + (unless (or (oni-org-in-dblock-p) + (oni-org-at-origin-property-p)) + (let ((components (org-heading-components))) + (push (list (org-entry-is-done-p) (point) (nth 4 components)) backlinks)))))) + (insert (string-join + (mapcar (lambda (link) + (concat "- " (if (car link) "[X]" "[ ]") " [[*" (caddr link) "][" (caddr link) "]]")) + (sort (seq-uniq backlinks (lambda (a b) (= (cadr a) (cadr b)))) + (lambda (a b) (< (cadr a) (cadr b))))) + "\n")) + (org-update-statistics-cookies nil))) + +(defalias 'org-dblock-write:oni-project-steps 'oni-org-dblock-write-project-steps) + (provide 'oni-org) ;;; oni-org.el ends here