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