org-noter-citar.el 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. ;;; org-noter-citar.el --- Module for finding note files from `citar' -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2021 c1-g
  3. ;; Author: c1-g <char1iegordon@protonmail.com>
  4. ;; Keywords: convenience
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. ;;; Code:
  16. (require 'citar)
  17. (require 'org-ref)
  18. (require 'seq)
  19. ;; Regexp stolen from org-roam-bibtex; orb-utils-citekey-re.
  20. (defvar org-noter-citar-cite-key-re
  21. (rx
  22. (or
  23. (seq (group-n 2 (regexp
  24. ;; If Org-ref is available, use its types
  25. ;; default to "cite"
  26. (if (boundp 'org-ref-cite-types)
  27. (regexp-opt
  28. (mapcar
  29. (lambda (el)
  30. ;; Org-ref v3 cite type is a list of strings
  31. ;; Org-ref v2 cite type is a plain string
  32. (or (car-safe el) el))
  33. org-ref-cite-types))
  34. "cite")))
  35. ":"
  36. (or
  37. ;; Org-ref v2 style `cite:links'
  38. (group-n 1 (+ (any "a-zA-Z0-9_:.-")))
  39. ;; Org-ref v3 style `cite:Some&key'
  40. (seq (*? (not "&")) "&"
  41. (group-n 1 (+ (any "!#-+./:<>-@^-`{-~-" word))))))
  42. ;; Org-cite [cite/@citations]
  43. (seq "@" (group-n 1 (+ (any "!#-+./:<>-@^-`{-~-" word))))))
  44. "Universal regexp to match citations in ROAM_REFS.
  45. Supports Org-ref v2 and v3 and Org-cite.")
  46. (defun org-noter-citar-find-document-from-refs (cite-key)
  47. "Return a note file associated with CITE-KEY.
  48. When there is more than one note files associated with CITE-KEY, have
  49. user select one of them."
  50. (when (and (stringp cite-key) (string-match org-noter-citar-cite-key-re cite-key))
  51. (let* ((key (match-string 1 cite-key))
  52. (entries (citar--ensure-entries (list key)))
  53. (files (citar-file--files-for-multiple-entries
  54. entries
  55. (append citar-library-paths citar-notes-paths) nil))
  56. (url (list (citar-get-link (car entries))))
  57. (documents (flatten-list (append (seq-remove #'file-directory-p files) url))))
  58. (cond ((= (length documents) 1)
  59. (car documents))
  60. ((> (length documents) 1)
  61. (completing-read (format "Which document from %s?: " key) documents))))))
  62. (defun org-noter-citar-find-key-from-this-file (filename)
  63. (let* ((entry-alist (mapcan (lambda (entry)
  64. (when-let ((file (citar-get-value citar-file-variable entry)))
  65. (list (cons file (citar-get-value "=key=" entry)))))
  66. (citar--get-candidates)))
  67. (key (alist-get filename entry-alist nil nil (lambda (s regexp)
  68. (string-match-p regexp s)))))
  69. (when key
  70. (file-name-with-extension key "org"))))
  71. (add-to-list 'org-noter-parse-document-property-hook #'org-noter-citar-find-document-from-refs)
  72. (add-to-list 'org-noter-find-additional-notes-functions #'org-noter-citar-find-key-from-this-file)
  73. (provide 'org-noter-citar)
  74. ;;; org-noter-citar.el ends here