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