]> git.donarmstrong.com Git - org-ref.git/blob - jmax-bibtex.el
ba04a3207821ab3f294daf55275b899d768f1601
[org-ref.git] / jmax-bibtex.el
1 ;;; jmax-bibtex.el --- jmax-bibtex utilities
2
3 ;; Copyright(C) 2014 John Kitchin
4
5 ;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
6 ;; URL: https://github.com/jkitchin/org-ref
7 ;; Version: 0.1
8 ;; Keywords: org-mode, bibtex
9 ;; Package-Requires: ((org-ref) (s) (dash) (doi-utils) (key-chord))
10
11 ;; This file is not currently part of GNU Emacs.
12
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2, or (at
16 ;; your option) any later version.
17
18 ;; This program is distributed in the hope that it will be useful, but
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 ;; General Public License for more details.
22
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program ; see the file COPYING.  If not, write to
25 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
27
28 ;;; Commentary:
29
30 ;;
31 ;; jmax-bibtex-generate-longtitles
32 ;; jmax-bibtex-generate-shorttitles
33 ;; jmax-stringify-journal-name :: replace a journal name with a string in `jmax-bibtex-journal-abbreviations'
34 ;; jmax-set-journal-string :: in a bibtex entry run this to replace the journal with a string
35 ;;
36 ;; jmax-replace-nonascii :: replace nonascii characters in a bibtex entry
37 ;;
38 ;; jmax-title-case-article
39 ;; jmax-sentence-case-article
40 ;;
41 ;; jmax-bibtex-next-entry :: bound to M-n
42 ;; jmax-bibtex-previous-entry :: bound to M-p
43 ;;
44 ;; Functions to act on an entry
45 ;; jmax-bibtex-hydra/body gives a hydra menu to a lot of useful functions.
46 ;; jmax-bibtex-new-entry/body gives a hydra menu to add new bibtex entries.
47 ;; jmax-bibtex :: a deprecated menu of actions
48 (require 'hydra)
49 (require 'key-chord)
50
51 ;;; Code:
52 (defgroup jmax-bibtex nil
53   "Customization group for jmax-bibtex.")
54
55
56 (defcustom jmax-bibtex-hydra-key-chord
57   nil
58   "key-chord to run `jmax-bibtex-hydra'.
59 I like \"jj\""
60   :type 'string
61   :group 'jmax-bibtex)
62
63
64 (defcustom jmax-bibtex-hydra-key-binding
65   nil
66   "key-binding to run `jmax-bibtex-hydra'.
67 I like \C-cj."
68   :type 'string
69   :group 'jmax-bibtex)
70
71
72 (defvar jmax-bibtex-journal-abbreviations
73   '(("ACAT" "ACS Catalysis" "ACS Catal.")
74     ("AM" "Acta Materialia" "Acta Mater.")
75     ("AMM" "Acta Metallurgica et Materialia" "Acta Metall. Mater.")
76     ("AMiner" "American Mineralogist" "Am. Mineral.")
77     ("AngC" "Angewandte Chemie-International Edition" "Angew. Chem. Int. Edit.")
78     ("APLM" "APL Materials" "APL Mat.")
79     ("ACBE" "Applied Catalysis B: Environmental" "Appl. Catal. B-Environ.")
80     ("APL" "Applied Physics Letters" "Appl. Phys. Lett.")
81     ("ASS" "Applied Surface Science" "Appl. Surf. Sci.")
82     ("CL" "Catalysis Letters" "Catal. Lett.")
83     ("CST" "Catalysis Science & Technology" "Catal. Sci. Technol.")
84     ("CT" "Catalysis Today" "Catal. Today")
85     ("CPL" "Chemical Physics Letters" "Chem. Phys. Lett")
86     ("CR" "Chemical Reviews" "Chem. Rev.")
87     ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
88     ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
89     ("CM" "Chemistry of Materials" "Chem. Mater.")
90     ("CSA" "Colloids and Surfaces, A: Physicochemical and Engineering Aspects" "Colloids Surf., A")
91     ("CPMS" "Computational Materials Science" "Comp. Mater. Sci.")
92     ("CPC" "Computer Physics Communications" "Comput. Phys. Commun.")
93     ("CGD" "Crystal Growth \\& Design" "Cryst. Growth Des.")
94     ("CEC" "CrystEngComm" "CrystEngComm")
95     ("ECST" "ECS Transactions" "ECS Trans.")
96     ("EES" "Energy \\& Environmental Science" "Energy Environ. Sci.")
97     ("HPR" "High Pressure Research" "High Pressure Res.")
98     ("IC" "Inorganic Chemistry" "Inorg. Chem.")
99     ("IECR" "Industrial \\& Engineering Chemistry Research" "Ind. Eng. Chem. Res.")
100     ("JJAP" "Japanese Journal of Applied Physics" "Jpn. J. Appl. Phys.")
101     ("JMatR" "Journal of  Materials Research" "J. Mater. Res.")
102     ("JALC" "Journal of Alloys and Compounds" "J. Alloy Compd.")
103     ("JAC" "Journal of Applied Crystallography" "J. Appl. Crystallogr.")
104     ("JAP" "Journal of Applied Physics" "J. Appl. Phys.")
105     ("JC" "Journal of Catalysis" "J. Catal.")
106     ("JCP" "Journal of Chemical Physics" "J. Chem. Phys.")
107     ("JCC" "Journal of Computational Chemistry" "J. Comput. Chem.")
108     ("JCG" "Journal of Crystal Growth" "J. Crys. Growth")
109     ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
110     ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
111     ("JMSL" "Journal of Materials Science Letters" "J. Mater. Sci. Lett.")
112     ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
113     ("JPE" "Journal of Phase Equilibria" "J. Phase Equilib.")
114     ("JPCS" "Journal of Physics and Chemistry of Solids" "J. Phys. Chem. Solids")
115     ("JPCM" "Journal of Physics: Condensed Matter" "J. Phys.: Condens. Matter")
116     ("JSSC" "Journal of Solid State Chemistry" "J. Solid State Chem.")
117     ("JACerS" "Journal of the American Ceramic Society" "J. Am. Ceram. Soc.")
118     ("JACS" "Journal of the American Chemical Society" "J. Am. Chem. Soc.")
119     ("JES" "Journal of The Electrochemical Society" "J. Electrochem. Soc.")
120     ("JEaC" "Journal of Electroanalytical Chemistry" "J. Electroanal. Chem.")
121     ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
122     ("JVST" "Journal of Vacuum Science \\& Technology A" "J. Vac. Sci. Technol. A")
123     ("ML" "Materials Letters" "Mater. Lett.")
124     ("MSE-BS" "Materials Science and Engineering B" "Mat. Sci. Eng. B-Solid")
125     ("MOLSIM" "Molecular Simulation" "Mol. Sim.")
126     ("Nature" "Nature" "Nature")
127     ("NM" "Nature Materials" "Nat. Mater.")
128     ("PML" "Philosophical Magazine Letters" "Phil. Mag. Lett.")
129     ("PMA" "Philosophical Magazine A" "Phil. Mag. A")
130     ("PA" "Physica A: Statistical Mechanics and its Applications" "Physica A")
131     ("PB" "Physica B-Condensed Matter" "Physica B")
132     ("PCCP" "Physical Chemistry Chemical Physics" "Phys. Chem. Chem. Phys.")
133     ("PSSB" "physica status solidi (b)" "Phys. Status Solidi B")
134     ("PRA" "Physical Review A" "Phys. Rev. A")
135     ("PRB" "Physical Review B" "Phys. Rev. B")
136     ("PRL" "Physical Review Letters" "Phys. Rev. Lett.")
137     ("PCM" "Physics and Chemistry of Minerals" "Phys. Chem. Miner.")
138     ("PSurfSci" "Progress in Surface Science" "Prog. Surf. Sci.")
139     ("Science" "Science" "Science")
140     ("SABC" "Sensors and Actuators B: Chemical" "Sensor. Actuat. B-Chem.")
141     ("SS" "Surface Science" "Surf. Sci.")
142     ("EPJB" "The European Physical Journal B" "Eur. Phys. J. B")
143     ("JPC" "The Journal of Physical Chemistry" "J. Phys. Chem.")
144     ("JPCB" "The Journal of Physical Chemistry B" "J. Phys. Chem. B")
145     ("JPCC" "The Journal of Physical Chemistry C" "J. Phys. Chem. C")
146     ("JPCL" "The Journal of Physical Chemistry Letters" "J. Phys. Chem. Lett.")
147     ("JCP" "The Journal of Chemical Physics" "J. Chem. Phys.")
148     ("MSMSE" "Modelling and Simulation in Materials Science and Engineering" "Modell. Simul. Mater. Sci. Eng.")
149     ("TSF" "Thin Solid Films" "Thin Solid Films")
150     ("TC" "Topics in Catalysis" "Top. Catal.")
151     ("WR" "Water Research" "Water Res."))
152   "List of (string journal-full-name journal-abbreviation).  Find abbreviations at http://cassi.cas.org/search.jsp.")
153
154
155 (defun jmax-bibtex-generate-longtitles ()
156   "Generate longtitles.bib which are @string definitions.
157 The full journal names are in `jmax-bibtex-journal-abbreviations'."
158   (interactive)
159   (with-temp-file "longtitles.bib"
160     (dolist (row jmax-bibtex-journal-abbreviations)
161       (insert (format "@string{%s=\"%s\"}\n"
162                       (nth 0 row)
163                       (nth 1 row))))))
164
165
166 (defun jmax-bibtex-generate-shorttitles ()
167     "Generate shorttitles.bib which are @string definitions.
168 The abbreviated journal names in `jmax-bibtex-journal-abbreviations'."
169   (interactive)
170   (with-temp-file "shorttitles.bib"
171     (dolist (row jmax-bibtex-journal-abbreviations)
172       (insert (format "@string{%s=\"%s\"}\n"
173                       (nth 0 row)
174                       (nth 2 row))))))
175
176
177 (defun jmax-stringify-journal-name (&optional key start end)
178   "Replace journal name in a bibtex entry with a string.
179 The strings are defined in
180 `jmax-bibtex-journal-abbreviations'.  The optional arguments KEY,
181 START and END allow you to use this with `bibtex-map-entries'"
182   (interactive)
183   (bibtex-beginning-of-entry)
184   (when
185       (string= "article"
186                (downcase
187                 (cdr (assoc "=type=" (bibtex-parse-entry)))))
188     (let* ((full-names (mapcar
189                         (lambda (row)
190                           (cons  (nth 1 row) (nth 0 row)))
191                         jmax-bibtex-journal-abbreviations))
192            (abbrev-names (mapcar
193                           (lambda (row)
194                             (cons  (nth 2 row) (nth 0 row)))
195                           jmax-bibtex-journal-abbreviations))
196            (journal (s-trim (bibtex-autokey-get-field "journal")))
197            (bstring (or
198                      (cdr (assoc journal full-names))
199                      (cdr (assoc journal abbrev-names)))))
200       (when bstring
201         (bibtex-set-field "journal" bstring t)
202         (bibtex-fill-entry)))))
203
204 (defun jmax-set-journal-string (full-journal-name)
205   "Set a bibtex journal name to the string that represents FULL-JOURNAL-NAME.
206 This is defined in `jmax-bibtex-journal-abbreviations'."
207   (interactive (list
208                 (ido-completing-read
209                  "Journal: "
210                  (mapcar
211                   (lambda (x)
212                     (nth 1 x))
213                   jmax-bibtex-journal-abbreviations))))
214   ;; construct data alist for the string lookup.
215   (let ((alist (mapcar
216                 (lambda (x)
217                   (cons (nth 1 x) (nth 0 x)))
218                 jmax-bibtex-journal-abbreviations)))
219     (bibtex-set-field "journal" (cdr (assoc full-journal-name alist)) t)
220     (bibtex-fill-entry)
221     (bibtex-clean-entry)))
222
223 ;; see https://github.com/fxcoudert/tools/blob/master/doi2bib for more replacements
224 (defvar jmax-nonascii-latex-replacements
225   '()
226   "Cons list of non-ascii characters and their LaTeX representations.")
227
228 (setq jmax-nonascii-latex-replacements
229       '(("í" . "{\\\\'i}")
230         ("æ" . "{\\\\ae}")
231         ("ć" . "{\\\\'c}")
232         ("é" . "{\\\\'e}")
233         ("ä" . "{\\\\\"a}")
234         ("è" . "{\\\\`e}")
235         ("à" . "{\\\\`a}")
236         ("á" . "{\\\\'a}")
237         ("ø" . "{\\\\o}")
238         ("ë" . "{\\\\\"e}")
239         ("ü" . "{\\\\\"u}")
240         ("ñ" . "{\\\\~n}")
241         ("ņ" . "{\\\\c{n}}")
242         ("å" . "{\\\\aa}")
243         ("ö" . "{\\\\\"o}")
244         ("Á" . "{\\\\'A}")
245         ("á" . "{\\\\'a}")
246         ("í" . "{\\\\'i}")
247         ("ó" . "{\\\\'o}")
248         ("ó" . "{\\\\'o}")
249         ("ú" .  "{\\\\'u}")
250         ("ú" . "{\\\\'u}")
251         ("š" . "{\\\\v{s}}")
252         ("ř"  . "{\\\\v{r}}")
253         ("İ" . "{\\\\.I}")
254         ("ğ" . "{\\\\u{g}}")
255         ("δ" . "$\\\\delta$")
256         ("ç" . "{\\\\c{c}}")
257         ("ß" . "{\\\\ss}")
258         ("≤" . "$\\\\le$")
259         ("<" . "$\\\\lt$")
260         ("θ" . "$\\\\theta$")
261         ("μ" . "$\\\\mu$")
262         ("→" . "$\\\\rightarrow$")
263         ("⇌" . "$\\\\leftrightharpoons$")
264         ("×" . "$\\\\times$")
265         ("°" . "$\\\\deg$")
266         ("ş" . "{\\\\c{s}}")
267         ("ı" . "i")                    ; I think this is a turkish i
268         ;; I think these are non-ascii spaces. there seems to be more than one.
269         (" " . " ")
270         (" " . " ")
271         ("–" . "-")
272         ("−" . "-")
273         ("–" . "-")
274         ("—" . "-")
275         ("‘" . "'")
276         ("’" . "'")
277         ("“" . "\"")
278         ("’" . "'")
279         ("”" . "\"")))
280
281 (defun jmax-replace-nonascii ()
282   "Hook function to replace non-ascii characters in a bibtex entry."
283
284   (interactive)
285   (save-restriction
286     (bibtex-narrow-to-entry)
287     (goto-char (point-min))
288     (dolist (char (mapcar (lambda (x) (car x)) jmax-nonascii-latex-replacements))
289       (while (re-search-forward char nil t)
290         (replace-match (cdr (assoc char jmax-nonascii-latex-replacements))))
291       (goto-char (point-min))))
292   (save-buffer))
293
294 (add-hook 'org-ref-clean-bibtex-entry-hook 'jmax-replace-nonascii)
295
296
297 (defvar jmax-lower-case-words
298   '("a" "an" "on" "and" "for"
299     "the" "of" "in")
300   "List of words to keep lowercase when changing case in a title.")
301
302
303 (defun jmax-title-case-article (&optional key start end)
304   "Convert a bibtex entry article title to title-case.
305 The arguments KEY, START and END are optional, and are only there
306 so you can use this function with `bibtex-map-entries' to change
307 all the title entries in articles."
308   (interactive)
309   (bibtex-beginning-of-entry)
310
311   (let* ((title (bibtex-autokey-get-field "title"))
312          (words (split-string title))
313          (start 0))
314     (when
315         (string= "article" (downcase (cdr (assoc "=type=" (bibtex-parse-entry)))))
316       (setq words (mapcar
317                    (lambda (word)
318                      (if (or
319                           ;; match words containing {} or \ which are probably
320                           ;; LaTeX or protected words
321                           (string-match "\\$\\|{\\|}\\|\\\\" word)
322                           ;; these words should not be capitalized, unless they
323                           ;; are the first word
324                           (-contains? jmax-lower-case-words (s-downcase word)))
325                          word
326                        (s-capitalize word)))
327                    words))
328
329       ;; Check if first word should be capitalized
330       (when (-contains? jmax-lower-case-words (car words))
331         (setf (car words) (s-capitalize (car words))))
332
333       (setq title (mapconcat 'identity words " "))
334
335       ;; Capitalize letters after a dash
336       (while
337           (string-match "[a-zA-Z]-\\([a-z]\\)" title start)
338         (let ((char (substring title (match-beginning 1) (match-end 1))))
339           (setf (substring title (match-beginning 1) (match-end 1))
340                 (format "%s" (upcase char)))
341           (setq start (match-end 1))))
342
343       ;; this is defined in doi-utils
344       (bibtex-set-field
345        "title"
346        title)
347       (bibtex-fill-entry))))
348
349 (add-hook 'org-ref-clean-bibtex-entry-hook 'jmax-title-case-article)
350
351
352 (defun jmax-sentence-case-article (&optional key start end)
353   "Convert a bibtex entry article title to sentence-case.
354 The arguments KEY, START and END are optional, and are only there
355 so you can use this function with `bibtex-map-entries' to change
356 all the title entries in articles."
357   (interactive)
358   (bibtex-beginning-of-entry)
359
360   (let* ((title (bibtex-autokey-get-field "title"))
361          (words (split-string title))
362          (start 0))
363     (when
364         (string= "article" (downcase (cdr (assoc "=type=" (bibtex-parse-entry)))))
365       (setq words (mapcar
366                    (lambda (word)
367                      (if
368                          ;; match words containing {} or \ which are probably
369                          ;; LaTeX or protected words
370                          (string-match "\\$\\|{\\|}\\|\\\\" word)
371                          word
372                        (s-downcase word)))
373                    words))
374
375       ;; capitalize first word
376       (setf (car words) (s-capitalize (car words)))
377
378       ;; join the words
379       (setq title (mapconcat 'identity words " "))
380
381       ;; capitalize a word after a :, eg. a subtitle, and protect it
382       (while
383           (string-match "[a-z]:\\s-+\\([A-Z]\\)" title start)
384         (let ((char (substring title (match-beginning 1) (match-end 1))))
385           (setf (substring title (match-beginning 1) (match-end 1))
386 ;;              (format "{%s}" (upcase char)))
387                 (format "%s" (upcase char)))
388           (setq start (match-end 1))))
389
390       ;; this is defined in doi-utils
391       (bibtex-set-field
392        "title" title)
393
394       ;; clean and refill entry so it looks nice
395       (bibtex-clean-entry)
396       (bibtex-fill-entry))))
397
398
399
400
401 (defun jmax-bibtex-next-entry (&optional n)
402   "Jump to the beginning of the next bibtex entry.
403 N is a prefix argument.  If it is numeric, jump that many entries
404 forward.  Negative numbers do nothing."
405   (interactive "P")
406   ;; Note if we start at the beginning of an entry, nothing
407   ;; happens. We need to move forward a char, and call again.
408   (when (= (point) (save-excursion
409                      (bibtex-beginning-of-entry)))
410     (forward-char)
411     (jmax-bibtex-next-entry))
412
413   ;; search forward for an entry
414   (when
415       (re-search-forward bibtex-entry-head nil t (and (numberp n) n))
416     ;; go to beginning of the entry
417     (bibtex-beginning-of-entry)))
418
419
420 (defun jmax-bibtex-previous-entry (&optional n)
421   "Jump to beginning of the previous bibtex entry.
422 N is a prefix argument.  If it is numeric, jump that many entries back."
423   (interactive "P")
424   (bibtex-beginning-of-entry)
425  (when
426      (re-search-backward bibtex-entry-head nil t (and (numberp n) n))
427    (bibtex-beginning-of-entry)))
428
429
430 (defun jmax-bibtex-mode-keys ()
431   "Modify keymaps used by `bibtex-mode'."
432   (local-set-key (kbd "M-n") 'jmax-bibtex-next-entry)
433   (local-set-key (kbd "M-p") 'jmax-bibtex-previous-entry))
434
435 ;; add to bibtex-mode-hook
436 (add-hook 'bibtex-mode-hook 'jmax-bibtex-mode-keys)
437
438
439 (defun jmax-bibtex-entry-doi ()
440   "Get doi from entry at point."
441   (interactive)
442   (save-excursion
443     (bibtex-beginning-of-entry)
444     (reftex-get-bib-field "doi" (bibtex-parse-entry t))))
445
446
447 (defun jmax-bibtex-wos ()
448   "Open bibtex entry in Web Of Science if there is a DOI."
449   (interactive)
450   (doi-utils-wos (jmax-bibtex-entry-doi)))
451
452
453 (defun jmax-bibtex-wos-citing ()
454   "Open citing articles for bibtex entry in Web Of Science if there is a DOI."
455   (interactive)
456   (doi-utils-wos-citing (jmax-bibtex-entry-doi)))
457
458
459 (defun jmax-bibtex-wos-related ()
460   "Open related articles for bibtex entry in Web Of Science if there is a DOI."
461   (interactive)
462   (doi-utils-wos-related (jmax-bibtex-entry-doi)))
463
464
465 (defun jmax-bibtex-wos-citing ()
466   "Open citing articles for bibtex entry in Web Of Science if there is a DOI."
467   (interactive)
468   (doi-utils-wos-citing (jmax-bibtex-entry-doi)))
469
470
471 (defun jmax-bibtex-crossref ()
472   "Open the bibtex entry in Crossref by its doi."
473   (interactive)
474   (doi-utils-crossref (jmax-bibtex-entry-doi)))
475
476
477 (defun jmax-bibtex-google-scholar ()
478   "Open the bibtex entry at point in google-scholar by its doi."
479   (interactive)
480   (doi-utils-google-scholar (jmax-bibtex-entry-doi)))
481
482
483 (defun jmax-bibtex-pubmed ()
484   "Open the bibtex entry at point in Pubmed by its doi."
485   (interactive)
486   (doi-utils-pubmed (jmax-bibtex-entry-doi)))
487
488
489 (defun jmax-bibtex-pdf (doi)
490   "Open the pdf for the bibtex entry at point.
491 Thin wrapper to get `jmax-bibtex' to open pdf, because it calls
492 functions with a DOI argument."
493   (interactive)
494   (org-ref-open-bibtex-pdf))
495
496
497 ;; hydra menu for actions on bibtex entries
498 (defhydra jmax-bibtex-hydra (:color blue)
499    "
500 _p_: Open pdf     _y_: Copy key               _n_: New entry     _w_: WOS
501 _b_: Open url     _f_: Copy formatted entry   _o_: Copy entry    _c_: WOS citing
502 _r_: Refile entry _k_: Add keywords           _d_: delete entry  _r_: WOS related
503 _e_: Email entry  _K_: Edit keywords          _L_: clean entry   _P_: Pubmed
504 _U_: Update entry _N_: Open notes             _R_: Crossref      _g_: Google Scholar
505 _s_: Sort entry   _a_: Remove nonascii        _h_: helm-bibtex   _q_: quit
506 _u_: Update field _f_: file funcs
507 "
508    ("p" org-ref-open-bibtex-pdf)
509    ("P" jmax-bibtex-pubmed)
510    ("w" jmax-bibtex-wos)
511    ("c" jmax-bibtex-wos-citing)
512    ("r" jmax-bibtex-wos-related)
513    ("R" jmax-bibtex-crossref)
514    ("g" jmax-bibtex-google-scholar)
515    ("n" jmax-bibtex-new-entry/body)
516    ("N" org-ref-open-bibtex-notes)
517    ("o" bibtex-copy-entry-as-kill)
518    ("d" bibtex-kill-entry)
519    ("L" org-ref-clean-bibtex-entry)
520    ("y" (kill-new  (bibtex-autokey-get-field "=key=")))
521    ("f" bibtex-copy-summary-as-kill)
522    ("k" helm-tag-bibtex-entry)
523    ("K" (lambda ()
524           (interactive)
525           (org-ref-set-bibtex-keywords
526            (read-input "Keywords: "
527                        (bibtex-autokey-get-field "keywords"))
528            t)))
529    ("b" org-ref-open-in-browser)
530    ("r" (lambda () (interactive)
531           (bibtex-beginning-of-entry)
532           (bibtex-kill-entry)
533           (find-file (ido-completing-read
534                       "Bibtex file: "
535                       (f-entries "." (lambda (f) (f-ext? f "bib")))))
536           (goto-char (point-max))
537           (bibtex-yank)
538           (save-buffer)
539           (kill-buffer)))
540    ("e" email-bibtex-entry)
541    ("U" (doi-utils-update-bibtex-entry-from-doi (jmax-bibtex-entry-doi)))
542    ("u" doi-utils-update-field)
543    ("f" jmax-bibtex-file/body)
544    ("h" helm-bibtex)
545    ("a" jmax-replace-nonascii)
546    ("s" org-ref-sort-bibtex-entry)
547    ("q" nil))
548
549 ;; create key-chord and key binding for hydra
550 (when jmax-bibtex-hydra-key-chord
551   (key-chord-define-global
552    jmax-bibtex-hydra-key-chord
553    'jmax-bibtex-hydra/body))
554
555
556 (when jmax-bibtex-hydra-key-binding
557   (global-set-key jmax-bibtex-hydra-key-binding 'jmax-bibtex-hydra/body))
558
559
560 ;; A hydra for adding new bibtex entries.
561 (defhydra jmax-bibtex-new-entry (:color blue)
562   "New Bibtex entry:"
563   ("a" bibtex-Article "Article")
564   ("b" bibtex-Book "Book")
565   ("i" bibtex-InBook "In book")
566   ("l" bibtex-Booklet "Booklet")
567   ("P" bibtex-Proceedings "Proceedings")
568   ("p" bibtex-InProceedings "In proceedings")
569   ("m" bibtex-Misc "Misc.")
570   ("M" bibtex-Manual "Manual")
571   ("T" bibtex-PhdThesis "PhD Thesis")
572   ("t" bibtex-MastersThesis "MS Thesis")
573   ("R" bibtex-TechReport "Report")
574   ("u" bibtex-Unpublished "unpublished")
575   ("c" bibtex-InCollection "Article in collection")
576   ("q" nil "quit"))
577
578 ;; a hydra menu of functions to act on a bibtex file.
579 (defhydra jmax-bibtex-file (:color blue)
580   "Bibtex file functions: "
581   ("v" bibtex-validate "Validate entries")
582   ("s" bibtex-sort-buffer "Sort entries")
583   ("r" bibtex-reformat "Reformat entries")
584   ("c" bibtex-count-entries "Count entries")
585   ("p" org-ref-build-full-bibliography "PDF bibliography"))
586
587
588 (defvar jmax-bibtex-menu-funcs '()
589  "Functions to run in doi menu.
590 Each entry is a list of (key menu-name function).  The function
591 must take one argument, the doi.  This is somewhat deprecated, as
592 I prefer the hydra interfaces above.")
593
594 (setq jmax-bibtex-menu-funcs
595       '(("p" "df" jmax-bibtex-pdf)
596         ("C" "opy" (lambda (doi)
597                      (kill-new (org-ref-bib-citation))
598                      (bury-buffer)))
599         ("w" "os" doi-utils-wos)
600         ("c" "iting articles" doi-utils-wos-citing)
601         ("r" "elated articles" doi-utils-wos-related)
602         ("s" "Google Scholar" doi-utils-google-scholar)
603         ("P" "Pubmed" doi-utils-pubmed)
604         ("f" "CrossRef" doi-utils-crossref)))
605
606 (defun jmax-bibtex ()
607   "Menu command to run in a bibtex entry.
608 Functions from `jmax-bibtex-menu-funcs'.  They all rely on the
609 entry having a doi."
610
611   (interactive)
612   ;; construct menu string as a message
613   (message
614    (concat
615     (mapconcat
616      (lambda (tup)
617        (concat "[" (elt tup 0) "]"
618                (elt tup 1) " "))
619      jmax-bibtex-menu-funcs "") ": "))
620   (let* ((input (read-char-exclusive))
621          (choice (assoc
622                   (char-to-string input) jmax-bibtex-menu-funcs)))
623     (when choice
624       (funcall
625        (elt
626         choice
627         2)
628        (jmax-bibtex-entry-doi)
629        ))))
630
631 (defalias 'jb 'jmax-bibtex)
632
633 (provide 'jmax-bibtex)
634
635 ;;; jmax-bibtex.el ends here