Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1380 lines
49 KiB

4 years ago
  1. ;;; org-ref-bibtex.el -- org-ref-bibtex utilities
  2. ;; Copyright(C) 2014 John Kitchin
  3. ;; Author: John Kitchin <jkitchin@andrew.cmu.edu>
  4. ;; URL: https://github.com/jkitchin/org-ref
  5. ;; Version: 0.1
  6. ;; Keywords: org-mode, bibtex
  7. ;; Package-Requires: ((org-ref) (s) (dash) (doi-utils) (key-chord))
  8. ;; This file is not currently part of GNU Emacs.
  9. ;; This program is free software; you can redistribute it and/or
  10. ;; modify it under the terms of the GNU General Public License as
  11. ;; published by the Free Software Foundation; either version 2, or (at
  12. ;; your option) any later version.
  13. ;; This program is distributed in the hope that it will be useful, but
  14. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. ;; General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with this program ; see the file COPYING. If not, write to
  19. ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. ;; Boston, MA 02111-1307, USA.
  21. ;;; Commentary:
  22. ;; org-ref-bibtex-generate-longtitles
  23. ;; org-ref-bibtex-generate-shorttitles
  24. ;; org-ref-stringify-journal-name :: replace a journal name with a string in
  25. ;; `org-ref-bibtex-journal-abbreviations'
  26. ;; org-ref-set-journal-string :: in a bibtex entry run this to replace the
  27. ;; journal with a string
  28. ;;
  29. ;; org-ref-title-case-article :: title case the title in an article or book
  30. ;; org-ref-sentence-case-article :: sentence case the title in an article.
  31. ;; org-ref-replace-nonascii :: replace nonascii characters in a bibtex
  32. ;; entry. Replacements are in `org-ref-nonascii-latex-replacements'.
  33. ;;
  34. ;; org-ref-title-case-article
  35. ;; org-ref-sentence-case-article
  36. ;;
  37. ;; org-ref-bibtex-next-entry :: bound to M-n
  38. ;; org-ref-bibtex-previous-entry :: bound to M-p
  39. ;;
  40. ;; Functions to act on a bibtex entry or file
  41. ;; org-ref-bibtex-hydra/body gives a hydra menu to a lot of useful functions.
  42. ;; org-ref-bibtex-new-entry/body gives a hydra menu to add new bibtex entries.
  43. ;; org-ref-bibtex-file/body gives a hydra menu of actions for the bibtex file
  44. ;;
  45. ;; org-ref-bibtex :: a deprecated menu of actions
  46. (require 'bibtex)
  47. (require 'dash)
  48. (require 'hydra)
  49. (require 'key-chord nil 'no-error)
  50. (require 'message)
  51. (require 's)
  52. (require 'org-ref-citeproc)
  53. (require 'doi-utils)
  54. (defvar org-ref-pdf-directory)
  55. (defvar org-ref-notes-directory)
  56. (defvar org-ref-default-bibliography)
  57. (declare-function reftex-get-bib-field "reftex-cite")
  58. (declare-function key-chord-define-global "key-chord")
  59. (declare-function org-ref-find-bibliography "org-ref-core")
  60. (declare-function org-ref-open-bibtex-pdf "org-ref-core")
  61. (declare-function org-ref-open-bibtex-notes "org-ref-core")
  62. (declare-function org-ref-clean-bibtex-entry "org-ref-core")
  63. (declare-function org-ref-open-in-browser "org-ref-core")
  64. (declare-function org-ref-sort-bibtex-entry "org-ref-core")
  65. (declare-function org-ref-build-full-bibliography "org-ref-core")
  66. (declare-function helm-tag-bibtex-entry "org-ref-helm")
  67. (declare-function bibtex-completion-edit-notes "bibtex-completion")
  68. (declare-function bibtex-completion-get-value "bibtex-completion")
  69. (declare-function bibtex-completion-get-entry "bibtex-completion")
  70. (declare-function parsebib-find-next-item "parsebib")
  71. (declare-function parsebib-read-entry "parsebib")
  72. (declare-function helm-bibtex "helm-bibtex")
  73. (declare-function helm "helm")
  74. ;;; Code:
  75. ;; This is duplicated from org-ref-core to try to avoid a byte-compile error.
  76. (add-to-list 'load-path
  77. (expand-file-name
  78. "citeproc"
  79. (file-name-directory (or load-file-name (buffer-file-name)))))
  80. (add-to-list 'load-path
  81. (expand-file-name
  82. "citeproc/csl"
  83. (file-name-directory (or load-file-name (buffer-file-name)))))
  84. ;;* Custom variables
  85. (defgroup org-ref-bibtex nil
  86. "Customization group for org-ref-bibtex."
  87. :group 'org-ref-bibtex)
  88. (defcustom org-ref-bibtex-hydra-key-chord
  89. nil
  90. "Key-chord to run `org-ref-bibtex-hydra'.
  91. I like \"jj\""
  92. :type '(choice (const nil :tag "None")
  93. (string))
  94. :group 'org-ref-bibtex)
  95. (defcustom org-ref-bibtex-hydra-key-binding
  96. nil
  97. "Key-binding to run `org-ref-bibtex-hydra'.
  98. I like \"C-c j\"."
  99. :type '(choice (const nil :tag "No binding")
  100. (key-sequence))
  101. :group 'org-ref-bibtex)
  102. (defcustom org-ref-helm-cite-shorten-authors nil
  103. "If non-nil show only last names in the helm selection buffer."
  104. :type 'boolean
  105. :group 'org-ref-bibtex)
  106. (defcustom org-ref-formatted-citation-formats
  107. '(("text" . (("article" . "${author}, ${title}, ${journal}, ${volume}(${number}), ${pages} (${year}). ${doi}")
  108. ("inproceedings" . "${author}, ${title}, In ${editor}, ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  109. ("book" . "${author}, ${title} (${year}), ${address}: ${publisher}.")
  110. ("phdthesis" . "${author}, ${title} (Doctoral dissertation) (${year}). ${school}, ${address}.")
  111. ("inbook" . "${author}, ${title}, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  112. ("incollection" . "${author}, ${title}, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  113. ("proceedings" . "${editor} (Eds.), ${booktitle} (${year}). ${address}: ${publisher}.")
  114. ("unpublished" . "${author}, ${title} (${year}). Unpublished manuscript.")
  115. (nil . "${author}, ${title} (${year}).")))
  116. ("org" . (("article" . "${author}, /${title}/, ${journal}, *${volume}(${number})*, ${pages} (${year}). ${doi}")
  117. ("inproceedings" . "${author}, /${title}/, In ${editor}, ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  118. ("book" . "${author}, /${title}/ (${year}), ${address}: ${publisher}.")
  119. ("phdthesis" . "${author}, /${title}/ (Doctoral dissertation) (${year}). ${school}, ${address}.")
  120. ("inbook" . "${author}, /${title}/, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  121. ("incollection" . "${author}, /${title}/, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
  122. ("proceedings" . "${editor} (Eds.), _${booktitle}_ (${year}). ${address}: ${publisher}.")
  123. ("unpublished" . "${author}, /${title}/ (${year}). Unpublished manuscript.")
  124. (nil . "${author}, /${title}/ (${year})."))))
  125. "Format strings for formatted bibtex entries for different citation backends.
  126. Used in `org-ref-format-entry'."
  127. :type '(alist)
  128. :group 'org-ref-bibtex)
  129. (defcustom org-ref-formatted-citation-backend "text"
  130. "The backend format for formatted citations.
  131. Should be one of the cars of `org-ref-formatted-citation-formats'."
  132. :type 'string
  133. :group 'org-ref-bibtex)
  134. ;;* Journal abbreviations
  135. (defvar org-ref-bibtex-journal-abbreviations
  136. '()
  137. "List of (string journal-full-name journal-abbreviation). Find
  138. new abbreviations at http://cassi.cas.org/search.jsp.")
  139. (defcustom org-ref-bibtex-assoc-pdf-with-entry-move-function 'rename-file
  140. "Function to use when associating pdf files with bibtex entries.
  141. The value should be either `rename-file' or `copy-file'. The former
  142. will move and rename the original file. The latter will leave the
  143. original file in place while creating a renamed copy in
  144. `org-ref-pdf-directory'."
  145. :type 'function
  146. :group 'org-ref-bibtex)
  147. (setq org-ref-bibtex-journal-abbreviations
  148. '(("ACR" "Accounts of Chemical Research" "Acc. Chem. Res.")
  149. ("ACAT" "ACS Catalysis" "ACS Catal.")
  150. ("AM" "Acta Materialia" "Acta Mater.")
  151. ("AMM" "Acta Metallurgica et Materialia" "Acta Metall. Mater.")
  152. ("AEM" "Advanced Energy Materials" "Adv. Energy Mater.")
  153. ("AAMI" "ACS Applied Materials \\& Interfaces"
  154. "ACS Appl. Mater. Interfaces")
  155. ("AMiner" "American Mineralogist" "Am. Mineral.")
  156. ("AngC" "Angewandte Chemie-International Edition"
  157. "Angew. Chem. Int. Edit.")
  158. ("APLM" "APL Materials" "APL Mat.")
  159. ("ACBE" "Applied Catalysis B: Environmental" "Appl. Catal. B-Environ.")
  160. ("APL" "Applied Physics Letters" "Appl. Phys. Lett.")
  161. ("ASS" "Applied Surface Science" "Appl. Surf. Sci.")
  162. ("CL" "Catalysis Letters" "Catal. Lett.")
  163. ("CC" "Catalysis Communications" "Catal. Commun.")
  164. ("CST" "Catalysis Science & Technology" "Catal. Sci. Technol.")
  165. ("CT" "Catalysis Today" "Catal. Today")
  166. ("ChC" "Chemical Communications" "Chem. Commun.")
  167. ("CPL" "Chemical Physics Letters" "Chem. Phys. Lett")
  168. ("CR" "Chemical Reviews" "Chem. Rev.")
  169. ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
  170. ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
  171. ("CM" "Chemistry of Materials" "Chem. Mater.")
  172. ("CSA" "Colloids and Surfaces, A: Physicochemical and Engineering Aspects"
  173. "Colloids Surf., A")
  174. ("CF" "Combustion and Flame" "Combust. Flame")
  175. ("CPMS" "Computational Materials Science" "Comp. Mater. Sci.")
  176. ("CPC" "Computer Physics Communications" "Comput. Phys. Commun.")
  177. ("CSE" "Computing in Science \\& Engineering" "Comput. Sci. Eng.")
  178. ("CGD" "Crystal Growth \\& Design" "Cryst. Growth Des.")
  179. ("CEC" "CrystEngComm" "CrystEngComm")
  180. ("EA" "Electrochimica Acta" "Electrochim. Acta")
  181. ("ECST" "ECS Transactions" "ECS Trans.")
  182. ("EES" "Energy \\& Environmental Science" "Energy Environ. Sci.")
  183. ("HPR" "High Pressure Research" "High Pressure Res.")
  184. ("IC" "Inorganic Chemistry" "Inorg. Chem.")
  185. ("IECR" "Industrial \\& Engineering Chemistry Research"
  186. "Ind. Eng. Chem. Res.")
  187. ("JJAP" "Japanese Journal of Applied Physics" "Jpn. J. Appl. Phys.")
  188. ("JMatR" "Journal of Materials Research" "J. Mater. Res.")
  189. ("JALC" "Journal of Alloys and Compounds" "J. Alloy Compd.")
  190. ("JAC" "Journal of Applied Crystallography" "J. Appl. Crystallogr.")
  191. ("JAE" "Journal of Applied Electrochemistry" "J. Appl. Electrochem.")
  192. ("JAP" "Journal of Applied Physics" "J. Appl. Phys.")
  193. ("JC" "Journal of Catalysis" "J. Catal.")
  194. ("JCP" "Journal of Chemical Physics" "J. Chem. Phys.")
  195. ("JCC" "Journal of Computational Chemistry" "J. Comput. Chem.")
  196. ("JCG" "Journal of Crystal Growth" "J. Crys. Growth")
  197. ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
  198. ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
  199. ("JMSL" "Journal of Materials Science Letters" "J. Mater. Sci. Lett.")
  200. ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
  201. ("JPE" "Journal of Phase Equilibria" "J. Phase Equilib.")
  202. ("JPCS" "Journal of Physics and Chemistry of Solids"
  203. "J. Phys. Chem. Solids")
  204. ("JPCM" "Journal of Physics: Condensed Matter"
  205. "J. Phys.: Condens. Matter")
  206. ("JPS" "Journal of Power Sources" "J. Power Sources")
  207. ("JSSC" "Journal of Solid State Chemistry" "J. Solid State Chem.")
  208. ("JACerS" "Journal of the American Ceramic Society" "J. Am. Ceram. Soc.")
  209. ("JACS" "Journal of the American Chemical Society" "J. Am. Chem. Soc.")
  210. ("JASIST" "Journal of the American Society for Information Science and Technology"
  211. "J. Am. Soc. Inf. Sci. Technol.")
  212. ("JES" "Journal of The Electrochemical Society" "J. Electrochem. Soc.")
  213. ("JEaC" "Journal of Electroanalytical Chemistry" "J. Electroanal. Chem.")
  214. ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
  215. ("JRS" "Journal of Raman Spectroscopy" "J. Raman Spectrosc.")
  216. ("JVST" "Journal of Vacuum Science \\& Technology A"
  217. "J. Vac. Sci. Technol. A")
  218. ("ML" "Materials Letters" "Mater. Lett.")
  219. ("MSE-BS" "Materials Science and Engineering B" "Mat. Sci. Eng. B-Solid")
  220. ("MOLSIM" "Molecular Simulation" "Mol. Sim.")
  221. ("Nature" "Nature" "Nature")
  222. ("NM" "Nature Materials" "Nat. Mater.")
  223. ("NC" "Nature Chemistry" "Nat. Chem.")
  224. ("PML" "Philosophical Magazine Letters" "Phil. Mag. Lett.")
  225. ("PMA" "Philosophical Magazine A" "Phil. Mag. A")
  226. ("PA" "Physica A: Statistical Mechanics and its Applications" "Physica A")
  227. ("PB" "Physica B-Condensed Matter" "Physica B")
  228. ("PCCP" "Physical Chemistry Chemical Physics" "Phys. Chem. Chem. Phys.")
  229. ("PSSB" "physica status solidi (b)" "Phys. Status Solidi B")
  230. ("PRA" "Physical Review A" "Phys. Rev. A")
  231. ("PRB" "Physical Review B" "Phys. Rev. B")
  232. ("PRL" "Physical Review Letters" "Phys. Rev. Lett.")
  233. ("PCM" "Physics and Chemistry of Minerals" "Phys. Chem. Miner.")
  234. ("PNAS" "Proceedings of the National Academy of Sciences of the United States of America"
  235. "Proc. Natl. Acad. Sci. U. S. A.")
  236. ("PSurfSci" "Progress in Surface Science" "Prog. Surf. Sci.")
  237. ("Science" "Science" "Science")
  238. ("SM" "Scripta Materialia" "Scr. Mater.")
  239. ("SABC" "Sensors and Actuators B: Chemical" "Sensor. Actuat. B-Chem.")
  240. ("SS" "Surface Science" "Surf. Sci.")
  241. ("EPJB" "The European Physical Journal B" "Eur. Phys. J. B")
  242. ("JPC" "The Journal of Physical Chemistry" "J. Phys. Chem.")
  243. ("JPCB" "The Journal of Physical Chemistry B" "J. Phys. Chem. B")
  244. ("JPCC" "The Journal of Physical Chemistry C" "J. Phys. Chem. C")
  245. ("JPCL" "The Journal of Physical Chemistry Letters"
  246. "J. Phys. Chem. Lett.")
  247. ("JCP" "The Journal of Chemical Physics" "J. Chem. Phys.")
  248. ("MSMSE" "Modelling and Simulation in Materials Science and Engineering"
  249. "Modell. Simul. Mater. Sci. Eng.")
  250. ("TSF" "Thin Solid Films" "Thin Solid Films")
  251. ("TC" "Topics in Catalysis" "Top. Catal.")
  252. ("WR" "Water Research" "Water Res.")))
  253. ;;;###autoload
  254. (defun org-ref-bibtex-generate-longtitles ()
  255. "Generate longtitles.bib which are @string definitions.
  256. The full journal names are in `org-ref-bibtex-journal-abbreviations'."
  257. (interactive)
  258. (with-temp-file "longtitles.bib"
  259. (dolist (row org-ref-bibtex-journal-abbreviations)
  260. (insert (format "@string{%s=\"%s\"}\n"
  261. (nth 0 row)
  262. (nth 1 row))))))
  263. ;;;###autoload
  264. (defun org-ref-bibtex-generate-shorttitles ()
  265. "Generate shorttitles.bib which are @string definitions.
  266. The abbreviated journal names in `org-ref-bibtex-journal-abbreviations'."
  267. (interactive)
  268. (with-temp-file "shorttitles.bib"
  269. (dolist (row org-ref-bibtex-journal-abbreviations)
  270. (insert (format "@string{%s=\"%s\"}\n"
  271. (nth 0 row)
  272. (nth 2 row))))))
  273. ;;;###autoload
  274. (defun org-ref-stringify-journal-name (&optional key start end)
  275. "Replace journal name in a bibtex entry with a string.
  276. The strings are defined in
  277. `org-ref-bibtex-journal-abbreviations'. The optional arguments KEY,
  278. START and END allow you to use this with `bibtex-map-entries'"
  279. (interactive)
  280. (bibtex-beginning-of-entry)
  281. (when
  282. (string= "article"
  283. (downcase
  284. (cdr (assoc "=type=" (bibtex-parse-entry)))))
  285. (let* ((full-names (mapcar
  286. (lambda (row)
  287. (cons (nth 1 row) (nth 0 row)))
  288. org-ref-bibtex-journal-abbreviations))
  289. (abbrev-names (mapcar
  290. (lambda (row)
  291. (cons (nth 2 row) (nth 0 row)))
  292. org-ref-bibtex-journal-abbreviations))
  293. (journal (s-trim (bibtex-autokey-get-field "journal")))
  294. (bstring (or
  295. (cdr (assoc journal full-names))
  296. (cdr (assoc journal abbrev-names)))))
  297. (when bstring
  298. (bibtex-set-field "journal" bstring t)
  299. (bibtex-fill-entry)))))
  300. ;;;###autoload
  301. (defun org-ref-helm-set-journal-string ()
  302. "Helm interface to set a journal string in a bibtex entry.
  303. Entries come from `org-ref-bibtex-journal-abbreviations'."
  304. (interactive)
  305. (bibtex-set-field
  306. "journal"
  307. (helm :sources
  308. `((name . "journal")
  309. (candidates . ,(mapcar
  310. (lambda (x)
  311. (cons (format "%s | %s" (nth 1 x) (nth 2 x))
  312. (car x)))
  313. org-ref-bibtex-journal-abbreviations))
  314. (action . (lambda (x) (identity x))))
  315. :input (s-trim (bibtex-autokey-get-field "journal")))
  316. t)
  317. (bibtex-fill-entry)
  318. (bibtex-clean-entry))
  319. ;;;###autoload
  320. (defun org-ref-set-journal-string (full-journal-name)
  321. "Set a bibtex journal name to the string that represents FULL-JOURNAL-NAME.
  322. This is defined in `org-ref-bibtex-journal-abbreviations'."
  323. (interactive (list
  324. (completing-read
  325. "Journal: "
  326. (mapcar
  327. (lambda (x)
  328. (nth 1 x))
  329. org-ref-bibtex-journal-abbreviations))))
  330. ;; construct data alist for the string lookup.
  331. (let ((alist (mapcar
  332. (lambda (x)
  333. (cons (nth 1 x) (nth 0 x)))
  334. org-ref-bibtex-journal-abbreviations)))
  335. (bibtex-set-field "journal" (cdr (assoc full-journal-name alist)) t)
  336. (bibtex-fill-entry)
  337. (bibtex-clean-entry)))
  338. ;;* Non-ascii character replacement
  339. ;; see https://github.com/fxcoudert/tools/blob/master/doi2bib for more replacements
  340. (defvar org-ref-nonascii-latex-replacements
  341. '()
  342. "Cons list of non-ascii characters and their LaTeX representations.")
  343. (setq org-ref-nonascii-latex-replacements
  344. '(("í" . "{\\\\'i}")
  345. ("æ" . "{\\\\ae}")
  346. ("ć" . "{\\\\'c}")
  347. ("é" . "{\\\\'e}")
  348. ("ä" . "{\\\\\"a}")
  349. ("è" . "{\\\\`e}")
  350. ("à" . "{\\\\`a}")
  351. ("á" . "{\\\\'a}")
  352. ("ø" . "{\\\\o}")
  353. ("ë" . "{\\\\\"e}")
  354. ("ü" . "{\\\\\"u}")
  355. ("ñ" . "{\\\\~n}")
  356. ("ņ" . "{\\\\c{n}}")
  357. ("" . "{\\\\~n}")
  358. ("å" . "{\\\\aa}")
  359. ("ö" . "{\\\\\"o}")
  360. ("" . "{\\\\'A}")
  361. ("" . "{\\\\'i}")
  362. ("ó" . "{\\\\'o}")
  363. ("" . "{\\\\'o}")
  364. ("" . "{\\\\'u}")
  365. ("ú" . "{\\\\'u}")
  366. ("ý" . "{\\\\'y}")
  367. ("š" . "{\\\\v{s}}")
  368. ("č" . "{\\\\v{c}}")
  369. ("ř" . "{\\\\v{r}}")
  370. ("" . "{\\\\v{s}}")
  371. ("İ" . "{\\\\.I}")
  372. ("ğ" . "{\\\\u{g}}")
  373. ("δ" . "$\\\\delta$")
  374. ("ç" . "{\\\\c{c}}")
  375. ("ß" . "{\\\\ss}")
  376. ("" . "$\\\\le$")
  377. ("" . "$\\\\ge$")
  378. ("<" . "$<$")
  379. ("θ" . "$\\\\theta$")
  380. ("μ" . "$\\\\mu$")
  381. ("" . "$\\\\rightarrow$")
  382. ("" . "$\\\\leftrightharpoons$")
  383. ("×" . "$\\\\times$")
  384. ("°" . "$\\\\deg$")
  385. ("ş" . "{\\\\c{s}}")
  386. ("γ" . "$\\\\gamma$")
  387. ("ɣ" . "$\\\\gamma$")
  388. ("º" . "degC")
  389. ("η" . "$\\\\eta$")
  390. ("µ" . "$\\\\mu$")
  391. ("α" . "$\\\\alpha$")
  392. ("β" . "$\\\\beta$")
  393. ("ɛ" . "$\\\\epsilon$")
  394. ("" . "\\textrm{VI}")
  395. ("" . "\\textrm{III}")
  396. ("" . "\\textrm{V}")
  397. ("λ" . "$\\\\lambda$")
  398. ("π" . "$\\\\pi$")
  399. ("" . "$\\\\infty$")
  400. ("χ" . "$\\\\chi$")
  401. ("" . "\\\\textasciitilde{}")
  402. ("" . "\\\\textemdash{}")
  403. (" " . " ")
  404. ("" . "...")
  405. ("" . "\\\\textbullet ")
  406. ;; I think these are non-ascii spaces. there seems to be more than one.
  407. ("" . " ")
  408. ("" . " ")
  409. (" " . " ")
  410. ("" . "-")
  411. ("" . "-")
  412. ("" . "-")
  413. ("" . "-")
  414. ("" . "\\\\textemdash{}")
  415. ("" . "'")
  416. ("" . "'")
  417. ("" . "'")
  418. ("" . "\"")
  419. ("" . "'")
  420. ("" . "\"")))
  421. ;;;###autoload
  422. (defun org-ref-replace-nonascii ()
  423. "Hook function to replace non-ascii characters in a bibtex entry."
  424. (interactive)
  425. (save-restriction
  426. (bibtex-narrow-to-entry)
  427. (goto-char (point-min))
  428. (dolist (char (mapcar (lambda (x)
  429. (car x))
  430. org-ref-nonascii-latex-replacements))
  431. (while (re-search-forward char nil t)
  432. (replace-match (cdr (assoc char org-ref-nonascii-latex-replacements))))
  433. (goto-char (point-min)))))
  434. ;;* Title case transformations
  435. (defvar org-ref-lower-case-words
  436. '("a" "an" "on" "and" "for"
  437. "the" "of" "in")
  438. "List of words to keep lowercase when changing case in a title.")
  439. (defcustom org-ref-title-case-types '("article" "book")
  440. "List of bibtex entry types in which the title will be converted to
  441. title-case by org-ref-title-case."
  442. :type '(repeat string)
  443. :group 'org-ref-bibtex)
  444. ;;;###autoload
  445. (defun org-ref-title-case (&optional key start end)
  446. "Convert a bibtex entry title and booktitle to title-case.
  447. Convert only if the entry type is a member of the list
  448. `org-ref-title-case-types'. The arguments KEY, START and END are
  449. optional, and are only there so you can use this function with
  450. `bibtex-map-entries' to change all the title entries in articles and
  451. books."
  452. (interactive)
  453. (dolist (field '("title" "booktitle"))
  454. (save-restriction
  455. (bibtex-narrow-to-entry)
  456. (bibtex-beginning-of-entry)
  457. ;; Skip if field is not found in entry
  458. (when (bibtex-search-forward-field field)
  459. (let* ((title (bibtex-autokey-get-field field))
  460. (words (split-string title))
  461. (start 0))
  462. (when
  463. (member (downcase
  464. (cdr (assoc "=type=" (bibtex-parse-entry))))
  465. org-ref-title-case-types)
  466. (setq words (mapcar
  467. (lambda (word)
  468. (cond
  469. ;; words containing more than one . are probably
  470. ;; abbreviations. We do not change those.
  471. ((with-temp-buffer
  472. (insert word)
  473. (goto-char (point-min))
  474. (> (count-matches "\\.") 1))
  475. word)
  476. ;; match words containing {} or \ which are probably
  477. ;; LaTeX or protected words, ignore
  478. ((string-match "\\$\\|{\\|}\\|(\\|)\\|\\\\" word)
  479. word)
  480. ;; these words should not be capitalized, unless they
  481. ;; are the first word
  482. ((-contains? org-ref-lower-case-words
  483. (s-downcase word))
  484. (s-downcase word))
  485. ;; Words that are quoted
  486. ((s-starts-with? "\"" word)
  487. (concat "\"" (s-capitalize (substring word 1))))
  488. (t
  489. (s-capitalize word))))
  490. words))
  491. ;; Check if first word should be capitalized
  492. (when (-contains? org-ref-lower-case-words (car words))
  493. (setf (car words) (s-capitalize (car words))))
  494. (setq title (mapconcat 'identity words " "))
  495. ;; Capitalize letters after a dash
  496. (while
  497. (string-match "[a-zA-Z]-\\([a-z]\\)" title start)
  498. (let ((char (substring title (match-beginning 1) (match-end 1))))
  499. (setf (substring title (match-beginning 1) (match-end 1))
  500. (format "%s" (upcase char)))
  501. (setq start (match-end 1))))
  502. ;; this is defined in doi-utils
  503. (bibtex-set-field
  504. field
  505. title)
  506. (bibtex-fill-entry)))))))
  507. ;;;###autoload
  508. (defun org-ref-title-case-article (&optional key start end)
  509. "Convert a bibtex entry article or book title to title-case.
  510. The arguments KEY, START and END are optional, and are only there
  511. so you can use this function with `bibtex-map-entries' to change
  512. all the title entries in articles and books."
  513. (interactive)
  514. (let ((org-ref-title-case-types '("article")))
  515. (org-ref-title-case)))
  516. ;;;###autoload
  517. (defun org-ref-sentence-case-article (&optional key start end)
  518. "Convert a bibtex entry article title to sentence-case.
  519. The arguments KEY, START and END are optional, and are only there
  520. so you can use this function with `bibtex-map-entries' to change
  521. all the title entries in articles."
  522. (interactive)
  523. (bibtex-beginning-of-entry)
  524. (let* ((title (bibtex-autokey-get-field "title"))
  525. (words (split-string title))
  526. (start 0))
  527. (when
  528. (string= "article"
  529. (downcase
  530. (cdr (assoc "=type="
  531. (bibtex-parse-entry)))))
  532. (setq words (mapcar
  533. (lambda (word)
  534. (if
  535. ;; match words containing {} or \ which are probably
  536. ;; LaTeX or protected words
  537. (string-match "\\$\\|{\\|}\\|\\\\" word)
  538. word
  539. (s-downcase word)))
  540. words))
  541. ;; capitalize first word
  542. (setf (car words) (s-capitalize (car words)))
  543. ;; join the words
  544. (setq title (mapconcat 'identity words " "))
  545. ;; capitalize a word after a :, eg. a subtitle, and protect it
  546. (while
  547. (string-match "[a-z]:\\s-+\\([A-Z]\\)" title start)
  548. (let ((char (substring title (match-beginning 1) (match-end 1))))
  549. (setf (substring title (match-beginning 1) (match-end 1))
  550. (format "%s" (upcase char)))
  551. (setq start (match-end 1))))
  552. ;; this is defined in doi-utils
  553. (bibtex-set-field
  554. "title" title)
  555. ;; clean and refill entry so it looks nice
  556. (bibtex-clean-entry)
  557. (bibtex-fill-entry))))
  558. ;;* Navigation in bibtex file
  559. ;;;###autoload
  560. (defun org-ref-bibtex-next-entry (&optional n)
  561. "Jump to the beginning of the next bibtex entry.
  562. N is a prefix argument. If it is numeric, jump that many entries
  563. forward. Negative numbers do nothing."
  564. (interactive "P")
  565. ;; Note if we start at the beginning of an entry, nothing
  566. ;; happens. We need to move forward a char, and call again.
  567. (when (= (point) (save-excursion
  568. (bibtex-beginning-of-entry)))
  569. (forward-char)
  570. (org-ref-bibtex-next-entry))
  571. ;; search forward for an entry
  572. (when
  573. (re-search-forward bibtex-entry-head nil t (and (numberp n) n))
  574. ;; go to beginning of the entry
  575. (bibtex-beginning-of-entry)))
  576. ;;;###autoload
  577. (defun org-ref-bibtex-previous-entry (&optional n)
  578. "Jump to beginning of the previous bibtex entry.
  579. N is a prefix argument. If it is numeric, jump that many entries back."
  580. (interactive "P")
  581. (bibtex-beginning-of-entry)
  582. (when
  583. (re-search-backward bibtex-entry-head nil t (and (numberp n) n))
  584. (bibtex-beginning-of-entry)))
  585. (defun org-ref-bibtex-mode-keys ()
  586. "Modify keymaps used by `bibtex-mode'."
  587. (local-set-key (kbd "M-n") 'org-ref-bibtex-next-entry)
  588. (local-set-key (kbd "M-p") 'org-ref-bibtex-previous-entry))
  589. ;; add to bibtex-mode-hook
  590. (add-hook 'bibtex-mode-hook 'org-ref-bibtex-mode-keys)
  591. ;;* Functions to act on an entry with a doi
  592. ;;;###autoload
  593. (defun org-ref-bibtex-entry-doi ()
  594. "Get doi from entry at point."
  595. (interactive)
  596. (save-excursion
  597. (bibtex-beginning-of-entry)
  598. (when (not (looking-at bibtex-any-valid-entry-type))
  599. (error "This entry does not appear to be a valid type."))
  600. (let ((entry (bibtex-parse-entry t)))
  601. (when (null entry)
  602. (error "Unable to parse this bibtex entry."))
  603. (reftex-get-bib-field "doi" entry))))
  604. ;; function that ensures that the url field of a bibtex entry is the
  605. ;; properly-formatted hyperlink of the DOI. See
  606. ;; http://blog.crossref.org/2016/09/new-crossref-doi-display-guidelines.html
  607. ;; for more information.
  608. ;;;###autoload
  609. (defun org-ref-bibtex-format-url-if-doi ()
  610. "Hook function to format url to follow the current DOI conventions."
  611. (interactive)
  612. (if (eq (org-ref-bibtex-entry-doi) "") nil
  613. (let ((front-url "https://doi.org/")
  614. (doi (org-ref-bibtex-entry-doi)))
  615. (bibtex-set-field "url"
  616. (concat front-url doi)))))
  617. ;;;###autoload
  618. (defun org-ref-bibtex-wos ()
  619. "Open bibtex entry in Web Of Science if there is a DOI."
  620. (interactive)
  621. (doi-utils-wos (org-ref-bibtex-entry-doi)))
  622. ;;;###autoload
  623. (defun org-ref-bibtex-wos-citing ()
  624. "Open citing articles for bibtex entry in Web Of Science if
  625. there is a DOI."
  626. (interactive)
  627. (doi-utils-wos-citing (org-ref-bibtex-entry-doi)))
  628. ;;;###autoload
  629. (defun org-ref-bibtex-wos-related ()
  630. "Open related articles for bibtex entry in Web Of Science if
  631. there is a DOI."
  632. (interactive)
  633. (doi-utils-wos-related (org-ref-bibtex-entry-doi)))
  634. ;;;###autoload
  635. (defun org-ref-bibtex-crossref ()
  636. "Open the bibtex entry in Crossref by its doi."
  637. (interactive)
  638. (doi-utils-crossref (org-ref-bibtex-entry-doi)))
  639. ;;;###autoload
  640. (defun org-ref-bibtex-google-scholar ()
  641. "Open the bibtex entry at point in google-scholar by its doi."
  642. (interactive)
  643. (let ((doi (org-ref-bibtex-entry-doi)))
  644. (doi-utils-google-scholar
  645. (if (string= "" doi)
  646. (save-excursion
  647. (bibtex-beginning-of-entry)
  648. (reftex-get-bib-field "title" (bibtex-parse-entry t)))
  649. doi))))
  650. ;;;###autoload
  651. (defun org-ref-bibtex-pubmed ()
  652. "Open the bibtex entry at point in Pubmed by its doi."
  653. (interactive)
  654. (doi-utils-pubmed (org-ref-bibtex-entry-doi)))
  655. ;;;###autoload
  656. (defun org-ref-bibtex-pdf (&optional _)
  657. "Open the pdf for the bibtex entry at point.
  658. Thin wrapper to get `org-ref-bibtex' to open pdf, because it
  659. calls functions with a DOI argument."
  660. (interactive)
  661. (org-ref-open-bibtex-pdf))
  662. (defun org-ref-bibtex-get-file-move-func (prefix)
  663. "Determine whether to use `rename-file' or `copy-file' for `org-ref-bibtex-assoc-pdf-with-entry'.
  664. When called with a PREFIX argument,
  665. `org-ref-bibtex-assoc-pdf-with-entry-move-function' switches to the
  666. opposite function from that which is defined in
  667. `org-ref-assoc-pdf-with-entry-move-function'."
  668. (message (format "%s" prefix))
  669. (if (eq prefix nil)
  670. org-ref-bibtex-assoc-pdf-with-entry-move-function
  671. (if (eq org-ref-bibtex-assoc-pdf-with-entry-move-function 'rename-file)
  672. 'copy-file
  673. 'rename-file)))
  674. ;;;###autoload
  675. (defun org-ref-bibtex-assoc-pdf-with-entry (&optional prefix)
  676. "Prompt for pdf associated with entry at point and rename it.
  677. Check whether a pdf already exists in `org-ref-pdf-directory' with the
  678. name '[bibtexkey].pdf'. If the file does not exist, rename it to
  679. '[bibtexkey].pdf' using
  680. `org-ref-bibtex-assoc-pdf-with-entry-move-function' and place it in
  681. `org-ref-pdf-directory'. Optional PREFIX argument toggles between
  682. `rename-file' and `copy-file'."
  683. (interactive "P")
  684. (save-excursion
  685. (bibtex-beginning-of-entry)
  686. (let* ((file (read-file-name "Select file associated with entry: "))
  687. (bibtex-expand-strings t)
  688. (entry (bibtex-parse-entry t))
  689. (key (reftex-get-bib-field "=key=" entry))
  690. (pdf (concat org-ref-pdf-directory (concat key ".pdf")))
  691. (file-move-func (org-ref-bibtex-get-file-move-func prefix)))
  692. (if (file-exists-p pdf)
  693. (message (format "A file named %s already exists" pdf))
  694. (progn
  695. (funcall file-move-func file pdf)
  696. (message (format "Created file %s" pdf)))))))
  697. ;;* Hydra menus
  698. ;;** Hydra menu for bibtex entries
  699. ;; hydra menu for actions on bibtex entries
  700. (defhydra org-ref-bibtex-hydra (:color blue)
  701. "
  702. _p_: Open pdf _y_: Copy key _N_: New entry _w_: WOS
  703. _b_: Open url _f_: Copy formatted entry _o_: Copy entry _c_: WOS citing
  704. _r_: Refile entry _k_: Add keywords _d_: delete entry _a_: WOS related
  705. _e_: Email entry _K_: Edit keywords _L_: clean entry _P_: Pubmed
  706. _U_: Update entry _N_: New entry _R_: Crossref _g_: Google Scholar
  707. _s_: Sort entry _a_: Remove nonascii _h_: helm-bibtex _q_: quit
  708. _u_: Update field _F_: file funcs _A_: Assoc pdf with entry
  709. _n_: Open notes _T_: Title case
  710. _S_: Sentence case
  711. "
  712. ("p" org-ref-open-bibtex-pdf)
  713. ("P" org-ref-bibtex-pubmed)
  714. ("w" org-ref-bibtex-wos)
  715. ("c" org-ref-bibtex-wos-citing)
  716. ("a" org-ref-bibtex-wos-related)
  717. ("R" org-ref-bibtex-crossref)
  718. ("g" org-ref-bibtex-google-scholar)
  719. ("N" org-ref-bibtex-new-entry/body)
  720. ("n" org-ref-open-bibtex-notes)
  721. ("o" (lambda ()
  722. (interactive)
  723. (bibtex-copy-entry-as-kill)
  724. (message "Use %s to paste the entry"
  725. (substitute-command-keys (format "\\[bibtex-yank]")))))
  726. ("d" bibtex-kill-entry)
  727. ("L" org-ref-clean-bibtex-entry)
  728. ("y" (save-excursion
  729. (bibtex-beginning-of-entry)
  730. (when (looking-at bibtex-entry-maybe-empty-head)
  731. (kill-new (bibtex-key-in-head)))))
  732. ("f" (progn
  733. (bibtex-beginning-of-entry)
  734. (kill-new
  735. (org-ref-format-entry
  736. (cdr (assoc "=key=" (bibtex-parse-entry t)))))))
  737. ("k" helm-tag-bibtex-entry)
  738. ("K" (lambda ()
  739. (interactive)
  740. (org-ref-set-bibtex-keywords
  741. (read-string "Keywords: "
  742. (bibtex-autokey-get-field "keywords"))
  743. t)))
  744. ("b" org-ref-open-in-browser)
  745. ("r" (lambda ()
  746. (interactive)
  747. (bibtex-beginning-of-entry)
  748. (bibtex-kill-entry)
  749. (find-file (completing-read
  750. "Bibtex file: "
  751. (f-entries "." (lambda (f) (f-ext? f "bib")))))
  752. (goto-char (point-max))
  753. (bibtex-yank)
  754. (save-buffer)
  755. (kill-buffer)))
  756. ("e" org-ref-email-bibtex-entry)
  757. ("U" (doi-utils-update-bibtex-entry-from-doi (org-ref-bibtex-entry-doi)))
  758. ("u" doi-utils-update-field)
  759. ("F" org-ref-bibtex-file/body)
  760. ("h" helm-bibtex)
  761. ("A" org-ref-bibtex-assoc-pdf-with-entry)
  762. ("a" org-ref-replace-nonascii)
  763. ("s" org-ref-sort-bibtex-entry)
  764. ("T" org-ref-title-case-article)
  765. ("S" org-ref-sentence-case-article)
  766. ("q" nil))
  767. ;; create key-chord and key binding for hydra
  768. (when (and (featurep 'key-chord) org-ref-bibtex-hydra-key-chord)
  769. (key-chord-define-global
  770. org-ref-bibtex-hydra-key-chord
  771. 'org-ref-bibtex-hydra/body))
  772. (when org-ref-bibtex-hydra-key-binding
  773. (define-key bibtex-mode-map org-ref-bibtex-hydra-key-binding 'org-ref-bibtex-hydra/body))
  774. ;;** Hydra menu for new bibtex entries
  775. ;; A hydra for adding new bibtex entries.
  776. (defhydra org-ref-bibtex-new-entry (:color blue)
  777. "New Bibtex entry:"
  778. ("a" bibtex-Article "Article")
  779. ("b" bibtex-Book "Book")
  780. ("i" bibtex-InBook "In book")
  781. ("l" bibtex-Booklet "Booklet")
  782. ("P" bibtex-Proceedings "Proceedings")
  783. ("p" bibtex-InProceedings "In proceedings")
  784. ("m" bibtex-Misc "Misc.")
  785. ("M" bibtex-Manual "Manual")
  786. ("T" bibtex-PhdThesis "PhD Thesis")
  787. ("t" bibtex-MastersThesis "MS Thesis")
  788. ("R" bibtex-TechReport "Report")
  789. ("u" bibtex-Unpublished "unpublished")
  790. ("c" bibtex-InCollection "Article in collection")
  791. ("q" nil "quit"))
  792. ;;** Hydra menu of functions to act on a bibtex file.
  793. (defhydra org-ref-bibtex-file (:color blue)
  794. "Bibtex file functions: "
  795. ("v" bibtex-validate "Validate entries")
  796. ("s" bibtex-sort-buffer "Sort entries")
  797. ("r" bibtex-reformat "Reformat entries")
  798. ("c" bibtex-count-entries "Count entries")
  799. ("p" org-ref-build-full-bibliography "PDF bibliography"))
  800. ;;* DEPRECATED bibtex menu
  801. (defvar org-ref-bibtex-menu-funcs '()
  802. "Functions to run in doi menu.
  803. Each entry is a list of (key menu-name function). The function
  804. must take one argument, the doi. This is somewhat deprecated, as
  805. I prefer the hydra interfaces above.")
  806. (setq org-ref-bibtex-menu-funcs
  807. '(("p" "df" org-ref-bibtex-pdf)
  808. ("C" "opy" (lambda (doi)
  809. (kill-new (org-ref-bib-citation))
  810. (bury-buffer)))
  811. ("w" "os" doi-utils-wos)
  812. ("c" "iting articles" doi-utils-wos-citing)
  813. ("r" "elated articles" doi-utils-wos-related)
  814. ("s" "Google Scholar" doi-utils-google-scholar)
  815. ("P" "Pubmed" doi-utils-pubmed)
  816. ("f" "CrossRef" doi-utils-crossref)))
  817. ;;;###autoload
  818. (defun org-ref-bibtex ()
  819. "Menu command to run in a bibtex entry.
  820. Functions from `org-ref-bibtex-menu-funcs'. They all rely on the
  821. entry having a doi."
  822. (interactive)
  823. ;; construct menu string as a message
  824. (message
  825. (concat
  826. (mapconcat
  827. (lambda (tup)
  828. (concat "[" (elt tup 0) "]"
  829. (elt tup 1) " "))
  830. org-ref-bibtex-menu-funcs "") ": "))
  831. (let* ((input (read-char-exclusive))
  832. (choice (assoc
  833. (char-to-string input) org-ref-bibtex-menu-funcs)))
  834. (when choice
  835. (funcall
  836. (elt
  837. choice
  838. 2)
  839. (org-ref-bibtex-entry-doi)))))
  840. (defalias 'jb 'org-ref-bibtex)
  841. ;;;###autoload
  842. (defun org-ref-email-bibtex-entry ()
  843. "Email current bibtex entry at point and pdf if it exists."
  844. (interactive)
  845. (save-excursion
  846. (bibtex-beginning-of-entry)
  847. (let* ((key (reftex-get-bib-field "=key=" (bibtex-parse-entry t)))
  848. pdf)
  849. ;; when we have org-ref defined we may have pdf to find.
  850. (when (boundp 'org-ref-pdf-directory)
  851. (setq pdf (expand-file-name
  852. (concat key ".pdf")
  853. org-ref-pdf-directory)))
  854. (bibtex-copy-entry-as-kill)
  855. (compose-mail)
  856. (message-goto-body)
  857. (insert (pop bibtex-entry-kill-ring))
  858. (message-goto-subject)
  859. (insert key)
  860. (message "%s exists %s" pdf (file-exists-p pdf))
  861. (when (file-exists-p pdf)
  862. (mml-attach-file pdf))
  863. (message-goto-to))))
  864. ;;* org-ref bibtex keywords
  865. ;; adapted from bibtex-utils.el
  866. ;; these are candidates for selecting keywords/tags
  867. (defun org-ref-bibtex-keywords ()
  868. "Get keywords defined in current bibtex file.
  869. These are in the keywords field, and are comma or semicolon separated."
  870. (save-excursion
  871. (goto-char (point-min))
  872. (let (keywords kstring)
  873. (while (re-search-forward "^\\s-*keywords.*{\\([^}]+\\)}" nil t)
  874. ;; TWS - remove newlines/multiple spaces:
  875. (setq kstring (replace-regexp-in-string
  876. "[ \t\n]+" " "
  877. (match-string 1)))
  878. (mapc
  879. (lambda (v)
  880. (add-to-list 'keywords v t))
  881. (split-string kstring "\\(,\\|;\\)[ \n]*\\|{\\|}" t)))
  882. keywords)))
  883. ;;;###autoload
  884. (defun org-ref-set-bibtex-keywords (keywords &optional arg)
  885. "Add KEYWORDS to a bibtex entry.
  886. If KEYWORDS is a list, it is converted to a comma-separated
  887. string. The KEYWORDS are added to the beginning of the
  888. field. Otherwise KEYWORDS should be a string of comma-separate
  889. keywords. Optional argument ARG prefix arg to replace keywords."
  890. (interactive
  891. (list
  892. (completing-read "Keyword: " (org-ref-bibtex-keywords))
  893. current-prefix-arg))
  894. (bibtex-set-field
  895. "keywords"
  896. (if arg
  897. ;; replace with arg
  898. (if (listp keywords)
  899. (mapconcat 'identity keywords ", ")
  900. keywords)
  901. ;; else concatentate
  902. (concat
  903. (if (listp keywords)
  904. (mapconcat 'identity keywords ", ")
  905. keywords)
  906. (when (not (string= "" (bibtex-autokey-get-field "keywords")))
  907. (concat ", " (bibtex-autokey-get-field "keywords"))))))
  908. (when (buffer-file-name)
  909. (save-buffer)))
  910. (defun org-ref-save-all-bibtex-buffers ()
  911. "Save all bibtex-buffers."
  912. (cl-loop for buffer in (buffer-list)
  913. do
  914. (with-current-buffer buffer
  915. (when (and (buffer-file-name) (f-ext? (buffer-file-name) "bib"))
  916. (save-buffer)))))
  917. ;;* org-ref bibtex cache
  918. (defvar orhc-bibtex-cache-data
  919. '((hashes . ())
  920. (candidates . ()))
  921. "Cache data as an alist.
  922. 'hashes is a list of cons cells (bibfile . hash)
  923. 'candidates is a list of cons cells (bibfile . candidates).
  924. Stored persistently in `orhc-bibtex-cache-file'.")
  925. (defvar orhc-bibtex-cache-file
  926. "~/.orhc-bibtex-cache"
  927. "File to store cached data in.")
  928. (defvar org-ref-bibtex-files nil
  929. "List of bibtex files to get entries from.
  930. This is set internally.")
  931. (defvar orhc-candidate-formats
  932. '(("article" . "${pdf}${notes}|${=key=}| ${author}, ${title}, ${journal} (${year}). ${keywords}")
  933. ("book" . " |${=key=}| ${author}, ${title} (${year}) ${keywords}.")
  934. ("inbook" . " |${=key=}| ${author}, ${chapter} in ${title} (${year}) ${keywords}")
  935. ("techreport" . " |${=key=}| ${title}, ${institution} (${year}). ${keywords}")
  936. ("inproceedings" . " |${=key=}| ${author}, ${title} in ${booktitle} (${year}). ${keywords}")
  937. ("incollection" . " |${=key=}| ${author}, ${title} in ${booktitle} (${year}). ${keywords}")
  938. ("phdthesis" . " |${=key=}| ${author}, ${title}, ${school} (${year}). Phd thesis. ${keywords}")
  939. ("mastersthesis" . " |${=key=}| ${author}, ${title}, ${school} (${year}). MS thesis. ${keywords}")
  940. ("misc" . " |${=key=}| ${author}, ${title}")
  941. ("unpublished" . " |${=key=}| ${author}, ${title}"))
  942. "Formats for candidates.
  943. It is an alist of (=type= . s-format-string).")
  944. ;; when you load, we should check the hashes and files
  945. (defun orhc-load-cache-file ()
  946. "Load the cache file to set `orhc-bibtex-cache-data'."
  947. (when (file-exists-p orhc-bibtex-cache-file)
  948. (with-current-buffer (find-file-noselect orhc-bibtex-cache-file)
  949. (goto-char (point-min))
  950. (setq orhc-bibtex-cache-data (read (current-buffer))))
  951. (when (find-buffer-visiting orhc-bibtex-cache-file)
  952. (kill-buffer (find-buffer-visiting orhc-bibtex-cache-file)))))
  953. (defun orhc-clear-cache ()
  954. "Clear the cache and delete `orhc-bibtex-cache-file'."
  955. (interactive)
  956. (setq orhc-bibtex-cache-data '((hashes . nil)
  957. (candidates . nil)))
  958. (when (find-buffer-visiting orhc-bibtex-cache-file)
  959. (kill-buffer (find-buffer-visiting orhc-bibtex-cache-file)))
  960. (when (file-exists-p orhc-bibtex-cache-file)
  961. (delete-file orhc-bibtex-cache-file))
  962. (message "org-ref-helm-cite cache cleared."))
  963. (defun orhc-bibtex-cache-up-to-date ()
  964. "Return if bibtex caches are up to date.
  965. This means the hash of each bibfile is equal to the one for it in
  966. the cache."
  967. (-all? 'identity
  968. (cl-loop
  969. for bibfile in org-ref-bibtex-files
  970. collect
  971. (string= (with-temp-buffer
  972. (insert-file-contents bibfile)
  973. (secure-hash 'sha256 (current-buffer)))
  974. (or (cdr (assoc
  975. bibfile
  976. (cdr (assoc 'hashes orhc-bibtex-cache-data)))) "")))))
  977. (defun orhc-bibtex-field-formatter (field entry)
  978. "Format FIELD in a bibtex parsed ENTRY.
  979. A few fields are treated specially, e.g. authors are replaced by
  980. comma-separated list, and I put :: around keywords to make it
  981. easier to search specifically for them."
  982. (let ((s (replace-regexp-in-string
  983. "^{\\|}$" ""
  984. (replace-regexp-in-string
  985. "[\n\t\s]+" " "
  986. (or (cdr (assoc field entry))
  987. (and (string= field "author")
  988. (cdr (assoc "editor" entry)))
  989. "")))))
  990. (cond
  991. ((string= field "author")
  992. (if org-ref-helm-cite-shorten-authors
  993. ;; copied from `helm-bibtex-shorten-authors'
  994. (cl-loop for a in (s-split " and " s)
  995. for p = (s-split "," a t)
  996. for sep = "" then ", "
  997. concat sep
  998. if (eq 1 (length p))
  999. concat (-last-item (s-split " +" (car p) t))
  1000. else
  1001. concat (car p))
  1002. (mapconcat 'identity (s-split " and " s) ", ")))
  1003. ((string= field "keywords")
  1004. (if (> (length s) 0)
  1005. (mapconcat (lambda (keyword)
  1006. (concat ":" (s-trim keyword) ":"))
  1007. (s-split "," s)
  1008. " ")
  1009. ""))
  1010. ((string= field "pdf")
  1011. (if (file-exists-p (expand-file-name
  1012. (concat (cdr (assoc "=key=" entry)) ".pdf")
  1013. org-ref-pdf-directory))
  1014. ""
  1015. " "))
  1016. ((string= field "notes")
  1017. (if (file-exists-p (expand-file-name
  1018. (concat (cdr (assoc "=key=" entry)) ".org")
  1019. org-ref-notes-directory))
  1020. ""
  1021. " "))
  1022. ;; catch all the other fields and just return them.
  1023. (t
  1024. s))))
  1025. (defun orhc-update-bibfile-cache (bibfile)
  1026. "Update cache for BIBFILE.
  1027. This generates the candidates for the file. Some of this code is
  1028. adapted from `helm-bibtex-parse-bibliography'. This function runs
  1029. when called, it resets the cache for the BIBFILE."
  1030. ;; check if the bibfile is already open, and preserve this state. i.e. if it
  1031. ;; is not open close it, and if it is leave it open.
  1032. (let ((bibfile-open (find-buffer-visiting bibfile)))
  1033. (with-current-buffer (find-file-noselect bibfile)
  1034. (bibtex-beginning-of-first-entry)
  1035. (message "Updating cache for %s" bibfile)
  1036. (let ((hash (secure-hash 'sha256 (current-buffer)))
  1037. (entries
  1038. (cl-loop
  1039. for entry-type = (parsebib-find-next-item)
  1040. while entry-type
  1041. unless (member-ignore-case entry-type
  1042. '("preamble" "string" "comment"))
  1043. collect
  1044. (let* ((entry (cl-loop for cons-cell in (parsebib-read-entry entry-type)
  1045. ;; we remove all properties too. they
  1046. ;; cause errors in reading/writing.
  1047. collect
  1048. (cons (substring-no-properties
  1049. (downcase (car cons-cell)))
  1050. (substring-no-properties
  1051. ;; clumsy way to remove surrounding
  1052. ;; brackets
  1053. (let ((s (cdr cons-cell)))
  1054. (if (or (and (s-starts-with? "{" s)
  1055. (s-ends-with? "}" s))
  1056. (and (s-starts-with? "\"" s)
  1057. (s-ends-with? "\"" s)))
  1058. (substring s 1 -1)
  1059. s))))))
  1060. ;; (key (cdr (assoc "=key=" entry)))
  1061. )
  1062. (cons
  1063. ;; this is the display string for helm. We try to use the formats
  1064. ;; in `orhc-candidate-formats', but if there isn't one we just put
  1065. ;; all the fields in.
  1066. (s-format
  1067. (or (cdr (assoc (downcase entry-type) orhc-candidate-formats))
  1068. (format "%s: %s" (cdr (assoc "=key=" entry)) entry))
  1069. 'orhc-bibtex-field-formatter
  1070. entry)
  1071. ;; this is the candidate that is returned, the entry a-list +
  1072. ;; file and position.
  1073. (append entry (list (cons "bibfile" (buffer-file-name))
  1074. (cons "position" (point)))))))))
  1075. ;; Now update the cache variables for hash and entries
  1076. (if (assoc bibfile (cdr (assoc 'candidates orhc-bibtex-cache-data)))
  1077. (setf (cdr (assoc bibfile
  1078. (cdr (assoc 'candidates orhc-bibtex-cache-data))))
  1079. entries)
  1080. (cl-pushnew (cons bibfile entries)
  1081. (cdr (assoc 'candidates orhc-bibtex-cache-data))))
  1082. (if (assoc bibfile (cdr (assoc 'hashes orhc-bibtex-cache-data)))
  1083. (setf (cdr (assoc
  1084. bibfile
  1085. (cdr (assoc 'hashes orhc-bibtex-cache-data))))
  1086. hash)
  1087. (cl-pushnew (cons bibfile hash)
  1088. (cdr (assoc 'hashes orhc-bibtex-cache-data))))
  1089. ;; And save it to disk for persistent use
  1090. (with-temp-file orhc-bibtex-cache-file
  1091. (print orhc-bibtex-cache-data (current-buffer)))))
  1092. (unless bibfile-open (kill-buffer (find-buffer-visiting bibfile)))))
  1093. (defun orhc-update-bibtex-cache ()
  1094. "Conditionally update cache for all files in `org-ref-bibtex-files'.
  1095. Files that have the same hash as in the cache are not updated."
  1096. (cl-loop for bibfile in org-ref-bibtex-files
  1097. unless (string= (with-temp-buffer
  1098. (insert-file-contents bibfile)
  1099. (secure-hash 'sha256 (current-buffer)))
  1100. (or (cdr
  1101. (assoc bibfile
  1102. (cdr
  1103. (assoc 'hashes orhc-bibtex-cache-data))))
  1104. ""))
  1105. do
  1106. (orhc-update-bibfile-cache bibfile)))
  1107. (defun orhc-helm-cite-describe-cache ()
  1108. "Show what is in the cache."
  1109. (interactive)
  1110. (let ((hash-cache (cdr (assoc 'hashes orhc-bibtex-cache-data)))
  1111. (candidates-cache (cdr (assoc 'candidates orhc-bibtex-cache-data))))
  1112. (message "%s\n\n%s"
  1113. (mapconcat (lambda (h)
  1114. (format "%s - %s" (car h) (cdr h)))
  1115. hash-cache "\n")
  1116. (mapconcat (lambda (c)
  1117. (format "%s - %s entries" (car c) (length (cdr c))))
  1118. candidates-cache "\n"))))
  1119. (defun orhc-bibtex-candidates ()
  1120. "Return the candidates from cache for files listed in `org-ref-bibtex-files'.
  1121. Update the cache if necessary."
  1122. ;; this only does something when the cache is out of date
  1123. (org-ref-save-all-bibtex-buffers)
  1124. (orhc-update-bibtex-cache)
  1125. (let ((candidates (cdr (assoc 'candidates orhc-bibtex-cache-data))))
  1126. (apply 'append
  1127. (cl-loop for bibfile in org-ref-bibtex-files
  1128. collect (cdr (assoc bibfile candidates))))))
  1129. ;; Now load files and update them if needed. We do this when you load the
  1130. ;; library so they are available later.
  1131. (orhc-load-cache-file)
  1132. (orhc-update-bibtex-cache)
  1133. ;;* org-ref bibtex formatted citation
  1134. (defun org-ref-format-bibtex-entry (entry)
  1135. "Return a formatted citation for the bibtex entry at point.
  1136. Formats are from `org-ref-formatted-citation-formats'. The
  1137. variable `org-ref-formatted-citation-backend' determines the set
  1138. of format strings used."
  1139. (save-excursion
  1140. (bibtex-beginning-of-entry)
  1141. (let* ((formats (cdr (assoc org-ref-formatted-citation-backend org-ref-formatted-citation-formats)))
  1142. (format-string)
  1143. (ref))
  1144. (if (null entry)
  1145. "!!! No entry found !!!"
  1146. (setq format-string (cdr (or (assoc (downcase (bibtex-completion-get-value "=type=" entry)) formats)
  1147. (assoc nil formats))))
  1148. (setq ref (s-format format-string 'bibtex-completion-apa-get-value entry))
  1149. (replace-regexp-in-string "\\([.?!]\\)\\." "\\1" ref)))))
  1150. (defun org-ref-format-entry (key)
  1151. "Returns a formatted bibtex entry for KEY."
  1152. (let* ((bibtex-completion-bibliography (org-ref-find-bibliography)))
  1153. (org-ref-format-bibtex-entry (ignore-errors (bibtex-completion-get-entry key)))))
  1154. (defun org-ref-format-bibtex-entry-at-point ()
  1155. "Return a formatted citation for the bibtex entry at point."
  1156. (save-excursion
  1157. (bibtex-beginning-of-entry)
  1158. (org-ref-format-bibtex-entry (bibtex-parse-entry t))))
  1159. ;; ** using citeproc
  1160. (defun orhc-formatted-citation (entry)
  1161. "Get a formatted string for ENTRY."
  1162. (require 'unsrt)
  1163. (let* ((adaptive-fill-function '(lambda () " "))
  1164. (indent-tabs-mode nil)
  1165. (entry-type (downcase
  1166. (cdr (assoc "=type=" entry))))
  1167. (entry-styles (cdr (assoc 'entries bibliography-style)))
  1168. (entry-fields
  1169. (progn
  1170. (if (cdr (assoc (intern entry-type) entry-styles))
  1171. (cdr (assoc (intern entry-type) entry-styles))
  1172. (warn "%s not found. Using default." entry-type)
  1173. (cdr (assoc 't entry-styles)))))
  1174. (funcs (mapcar
  1175. (lambda (field)
  1176. (if (fboundp (intern
  1177. (format "orcp-%s" field)))
  1178. (intern
  1179. (format "orcp-%s" field))
  1180. ;; No formatter found. just get the data
  1181. `(lambda (entry)
  1182. (orcp-get-entry-field
  1183. ,(symbol-name field) entry))))
  1184. entry-fields)))
  1185. ;; this is the entry. We do this in a buffer to make it
  1186. ;; easy to indent, fill, etc...
  1187. (with-temp-buffer
  1188. (insert (mapconcat (lambda (field-func)
  1189. (funcall field-func entry))
  1190. funcs
  1191. ""))
  1192. (buffer-string))))
  1193. ;; * Extract bibtex blocks from an org-file
  1194. ;;;###autoload
  1195. (defun org-ref-extract-bibtex-blocks (bibfile)
  1196. "Extract all bibtex blocks in buffer to BIBFILE.
  1197. If BIBFILE exists, append, unless you use a prefix arg (C-u), which
  1198. will clobber the file."
  1199. (interactive
  1200. (list (read-file-name "Bibfile: " nil nil nil
  1201. (file-name-nondirectory
  1202. (concat (file-name-sans-extension
  1203. (buffer-file-name))
  1204. ".bib")))))
  1205. (let ((contents ""))
  1206. (when (and (file-exists-p bibfile)
  1207. (not current-prefix-arg))
  1208. (setq contents (with-temp-buffer
  1209. (insert-file-contents bibfile)
  1210. (buffer-string))))
  1211. (save-excursion
  1212. (goto-char (point-min))
  1213. (while (re-search-forward "#\\+BEGIN_SRC bibtex" nil t)
  1214. (setq contents
  1215. (concat
  1216. contents
  1217. (org-element-property :value (org-element-at-point))))))
  1218. (with-temp-file bibfile
  1219. (insert contents))))
  1220. (defun org-ref-bibtex-key-from-doi (doi &optional bib)
  1221. "Return a bibtex entry's key from a DOI.
  1222. BIB is an optional filename to get the entry from. Defaults to
  1223. the first entry of `org-ref-default-bibliography'."
  1224. (let ((bibfile (if bib bib (car org-ref-default-bibliography))))
  1225. (with-temp-buffer
  1226. (insert-file-contents (expand-file-name bibfile))
  1227. (search-forward doi)
  1228. (bibtex-beginning-of-entry)
  1229. (cdr (assoc "=key=" (bibtex-parse-entry))))))
  1230. ;;* The end
  1231. (provide 'org-ref-bibtex)
  1232. ;;; org-ref-bibtex.el ends here