|
25 | 25 | ;; A BibTeX bibliography manager based on Helm. |
26 | 26 | ;; |
27 | 27 | ;; News: |
| 28 | +;; - 11/23/2015: Added support for keeping all notes in one |
| 29 | +;; org-file. See customization variable |
| 30 | +;; `helm-bibtex-notes-path'. |
28 | 31 | ;; - 11/10/2015: Added support for PDFs specified in a BibTeX |
29 | 32 | ;; field. See customization variable |
30 | 33 | ;; `helm-bibtex-pdf-field'. |
@@ -141,14 +144,42 @@ e.g. \cite{key1,key2}. See the functions |
141 | 144 | :type '(alist :key-type symbol :value-type function)) |
142 | 145 |
|
143 | 146 | (defcustom helm-bibtex-notes-path nil |
144 | | - "The directory in which notes are stored. Helm-bibtex assumes |
145 | | -that the names of these notes are composed of the BibTeX-key plus |
146 | | -a suffix that is specified in `helm-bibtex-notes-extension'." |
| 147 | + "The place where notes are stored. This is either a file, in |
| 148 | +which case all notes are stored in that file, or a directory, in |
| 149 | +which case each publication gets its own notes file in that |
| 150 | +directory. In the latter case, helm-bibtex assumes that the |
| 151 | +names of the note files are composed of the BibTeX-key plus a |
| 152 | +suffix that is specified in `helm-bibtex-notes-extension'." |
147 | 153 | :group 'helm-bibtex |
148 | | - :type 'directory) |
| 154 | + :type '(choice file directory)) |
| 155 | + |
| 156 | +(defcustom helm-bibtex-notes-template-many-files |
| 157 | + "#+TITLE: ${title}\n#+AUTHOR: ${author}\n#+DATE: ${year}\n\n" |
| 158 | + "Template used to create a new note when each note is stored in |
| 159 | +a separate file. '${field-name}' can be used to insert the value |
| 160 | +of a BibTeX field into the template." |
| 161 | + :group 'helm-bibtex |
| 162 | + :type 'string) |
| 163 | + |
| 164 | +(defcustom helm-bibtex-notes-template-one-file |
| 165 | + "* ${author} (${year}): ${title}\n :PROPERTIES:\n :Custom_ID: ${=key=}\n :END:\n\n" |
| 166 | + "Template used to create a new note when all notes are stored |
| 167 | +in one file. '${field-name}' can be used to insert the value of |
| 168 | +a BibTeX field into the template." |
| 169 | + :group 'helm-bibtex |
| 170 | + :type 'string) |
| 171 | + |
| 172 | +(defcustom helm-bibtex-notes-key-pattern |
| 173 | + ":Custom_ID: +%s\\( \\|$\\)" |
| 174 | + "The pattern used to find entries in the notes file. Only |
| 175 | +relevant when all notes are stored in one file. The key can be |
| 176 | +inserted into the pattern using the `format` function." |
| 177 | + :group 'helm-bibtex |
| 178 | + :type 'string) |
149 | 179 |
|
150 | 180 | (defcustom helm-bibtex-notes-extension ".org" |
151 | | - "The extension of the files containing notes." |
| 181 | + "The extension of the files containing notes. This is only |
| 182 | +used when `helm-bibtex-notes-path' is a directory (not a file)." |
152 | 183 | :group 'helm-bibtex |
153 | 184 | :type 'string) |
154 | 185 |
|
@@ -454,20 +485,30 @@ ENTRY is an alist representing an entry as returned by |
454 | 485 | parsebib-read-entry. All the fields not in FIELDS are removed |
455 | 486 | from ENTRY, with the exception of the \"=type=\" and \"=key=\" |
456 | 487 | fields. If FIELDS is empty, all fields are kept. Also add a |
457 | | -=has-pdf= and/or =has-notes= field, if they exist for ENTRY. If |
| 488 | +=has-pdf= and/or =has-note= field, if they exist for ENTRY. If |
458 | 489 | DO-NOT-FIND-PDF is non-nil, this function does not attempt to |
459 | 490 | find a PDF file." |
460 | 491 | (when entry ; entry may be nil, in which case just return nil |
461 | 492 | (let* ((fields (when fields (append fields (list "=type=" "=key=" "=has-pdf=" "=has-note=")))) |
462 | 493 | ; Check for PDF: |
463 | 494 | (entry (if (and (not do-not-find-pdf) (helm-bibtex-find-pdf entry)) |
464 | | - (setq entry (cons (cons "=has-pdf=" helm-bibtex-pdf-symbol) entry)) |
| 495 | + (cons (cons "=has-pdf=" helm-bibtex-pdf-symbol) entry) |
465 | 496 | entry)) |
466 | 497 | (entry-key (cdr (assoc "=key=" entry))) |
467 | 498 | ; Check for notes: |
468 | | - (entry (if (and helm-bibtex-notes-path |
469 | | - (f-file? (f-join helm-bibtex-notes-path |
470 | | - (s-concat entry-key helm-bibtex-notes-extension)))) |
| 499 | + (entry (if (or |
| 500 | + ;; One note file per entry: |
| 501 | + (and helm-bibtex-notes-path |
| 502 | + (f-directory? helm-bibtex-notes-path) |
| 503 | + (f-file? (f-join helm-bibtex-notes-path |
| 504 | + (s-concat entry-key |
| 505 | + helm-bibtex-notes-extension)))) |
| 506 | + ;; All notes in one file: |
| 507 | + (and helm-bibtex-notes-path |
| 508 | + (f-file? helm-bibtex-notes-path) |
| 509 | + (with-current-buffer (find-file-noselect helm-bibtex-notes-path) |
| 510 | + (goto-char (point-min)) |
| 511 | + (re-search-forward (format helm-bibtex-notes-key-pattern entry-key) nil t)))) |
471 | 512 | (cons (cons "=has-note=" helm-bibtex-notes-symbol) entry) |
472 | 513 | entry)) |
473 | 514 | ; Remove unwanted fields: |
@@ -817,8 +858,39 @@ defined. Surrounding curly braces are stripped." |
817 | 858 |
|
818 | 859 | (defun helm-bibtex-edit-notes (key) |
819 | 860 | "Open the notes associated with the entry using `find-file'." |
820 | | - (let ((path (f-join helm-bibtex-notes-path (s-concat key helm-bibtex-notes-extension)))) |
821 | | - (find-file path))) |
| 861 | + (if (f-directory? helm-bibtex-notes-path) |
| 862 | + ; One notes file per publication: |
| 863 | + (let ((path (f-join helm-bibtex-notes-path |
| 864 | + (s-concat key helm-bibtex-notes-extension)))) |
| 865 | + (find-file path) |
| 866 | + (unless (f-exists? path) |
| 867 | + (insert (s-format helm-bibtex-notes-template-many-files |
| 868 | + 'helm-bibtex-apa-get-value |
| 869 | + (helm-bibtex-get-entry key))))) |
| 870 | + ; One file for all notes: |
| 871 | + (unless (and buffer-file-name |
| 872 | + (f-same? helm-bibtex-notes-path buffer-file-name)) |
| 873 | + (find-file-other-window helm-bibtex-notes-path)) |
| 874 | + (widen) |
| 875 | + (goto-char (point-min)) |
| 876 | + (if (re-search-forward (format helm-bibtex-notes-key-pattern key) nil t) |
| 877 | + ; Existing entry found: |
| 878 | + (when (eq major-mode 'org-mode) |
| 879 | + (outline-previous-visible-heading 1) |
| 880 | + (org-narrow-to-subtree) |
| 881 | + (org-show-subtree) |
| 882 | + (org-cycle-hide-drawers nil)) |
| 883 | + ; Create a new entry: |
| 884 | + (let ((entry (helm-bibtex-get-entry key))) |
| 885 | + (goto-char (point-max)) |
| 886 | + (insert (s-format helm-bibtex-notes-template-one-file |
| 887 | + 'helm-bibtex-apa-get-value |
| 888 | + entry))) |
| 889 | + (when (eq major-mode 'org-mode) |
| 890 | + (outline-previous-visible-heading 1) |
| 891 | + (org-narrow-to-subtree) |
| 892 | + (org-cycle-hide-drawers nil) |
| 893 | + (goto-char (point-max)))))) |
822 | 894 |
|
823 | 895 | (defun helm-bibtex-buffer-visiting (file) |
824 | 896 | (or (get-file-buffer file) |
|
0 commit comments