From 8d97d1f2063f19c0c679e54fc082691a495c9303 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Sun, 10 Jan 2016 23:43:14 -0500 Subject: Rewrite configuration with use-package --- lisp/km-bib.el | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 lisp/km-bib.el (limited to 'lisp/km-bib.el') diff --git a/lisp/km-bib.el b/lisp/km-bib.el new file mode 100644 index 0000000..1795587 --- /dev/null +++ b/lisp/km-bib.el @@ -0,0 +1,205 @@ +;;; km-bib.el --- Bibliography configuration + +;; Copyright (C) 2012-2016 Kyle Meyer + +;; Author: Kyle Meyer +;; URL: https://github.com/kyleam/emacs.d + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Code: + +(require 'bibtex) +(require 'dash) +(require 'org) + +(defvar km/bibtex-unimportant-title-words + '("a" "aboard" "about" "above" "absent" "across" "after" "against" + "along" "alongside" "amid" "amidst" "among" "amongst" "an" "and" + "around" "as" "aslant" "astride" "at" "athwart" "atop" + "barring" "before" "behind" "below" "beneath" "beside" "besides" "between" + "beyond" "but" "by" "despite" "down" "during" "except" "failing" + "following" "for" "from" "in" "inside" "into" "like" + "mid" "minus" "near" "next" "nor" "notwithstanding" "of" "off" + "on" "onto" "opposite" "or" "out" "outside" "over" "past" + "per" "plus" "regarding" "round" "save" "since" "so" "than" + "the" "through" "throughout" "till" "times" "to" "toward" "towards" + "under" "underneath" "unlike" "until" "up" "upon" "via" "vs." + "when" "with" "within" "without" "worth" "yet") + "Words to ignore when running `km/bibtex-use-title-case'. +These are taken from +http://lanecc.libguides.com/content.php?pid=38483&sid=295540 and +have only been modified to remove duplicates. This means that +there are some unlikely words in there, but you never know when +the next article you read will have \"athwart\" in the title.") + +(defun km/bibtex-use-title-case () + "Convert title of current BibTeX entry to title case. +Change words in `km/bibtex-unimportant-title-words' to lower +case, unless the word is the first word in the title. Capitalize +all other words unless they are protected by brackets." + (save-excursion + (bibtex-beginning-of-entry) + (let* ((bounds (bibtex-search-forward-field "title" t)) + (beg (bibtex-start-of-text-in-field bounds))) + (goto-char (1- beg)) + (while (re-search-forward "\\(\\W\\)\\(\\w+\\)\\(\\W\\)" + (bibtex-end-of-text-in-field bounds) t) + (cond + ((and (string= (match-string 1) "{") + (string= (match-string 3) "}")) + ;; Go to previous character in case '}' is within the word. + (backward-char)) + ;; Leave commands alone. + ((string= (match-string 1) "\\")) + ;; Capitalize the first word of the title. This will fail if + ;; there is a space after '{'. + ((= (match-beginning 1) beg) + (backward-word) + (capitalize-word 1)) + ;; Subword is separated by '-' or '{'. + ((or (string= (match-string 1) "-") + (string= (match-string 1) "}")) + (backward-word) + (downcase-word 1)) + (t + (backward-word) + (if (member (downcase (match-string-no-properties 2)) + km/bibtex-unimportant-title-words) + (downcase-word 1) + (capitalize-word 1)))))))) + +(defun km/bibtex-single-space-author-list () + "Convert multiple spaces in author list to single space." + (save-excursion + (bibtex-beginning-of-entry) + (let* ((bounds (bibtex-search-forward-field "author" t)) + (beg (bibtex-start-of-text-in-field bounds))) + (when bounds + (goto-char beg) + (while (re-search-forward "\\(\\s-+\\) and" + (bibtex-end-of-text-in-field bounds) t) + (replace-match "" nil nil nil 1)) + (goto-char beg) + (fill-paragraph))))) + +(defun km/bibtex-set-coding-system () + (set-buffer-file-coding-system 'utf-8)) + +(defun km/bibtex-remove-entry-space () + "Remove space in entry header. +For example, convert + + @article { + +to + + @article{" + (save-excursion + (bibtex-beginning-of-entry) + (when (looking-at "@\\w+\\(\\s-+\\)") + (replace-match "" nil nil nil 1)))) + +(defun km/bibtex-downcase-entry () + (save-excursion + (bibtex-beginning-of-entry) + (when (looking-at "^@\\([^{]+\\){") + (replace-match (downcase (match-string-no-properties 1)) + 'fixedcase nil nil 1)))) + +(defun km/bibtex-pages-use-double-hyphen () + "Use double hyphen for page range." + (save-excursion + (bibtex-beginning-of-entry) + (let ((bounds (bibtex-search-forward-field "pages" t))) + (when bounds + (goto-char (bibtex-start-of-text-in-field bounds)) + (and (re-search-forward "[^A-z0-9]*-[^A-z0-9]*" + (bibtex-end-of-text-in-field bounds) t) + (replace-match "--")))))) + +(defun km/bibtex-remove-doi-leader () + "Remove leading part (http:...) of doi URL." + (save-excursion + (bibtex-beginning-of-entry) + (let ((bounds (bibtex-search-forward-field "doi" t))) + (when bounds + (goto-char (bibtex-start-of-text-in-field bounds)) + (and (re-search-forward "http://dx.doi.org/" + (bibtex-end-of-text-in-field bounds) t) + (replace-match "")))))) + +(defun km/bibtex-downcase-keys () + "Downcase keys that are all caps." + (save-excursion + (bibtex-beginning-of-entry) + (let (case-fold-search) + (while (re-search-forward "^\\s-*\\([A-Z]+\\)\\s-*=" nil t) + (replace-match (downcase (match-string 1)) 'fixedcase + nil nil 1))))) + +(defun km/bibtex-downcase-author-and () + (save-excursion + (bibtex-beginning-of-entry) + (let ((bounds (bibtex-search-forward-field "author" t))) + (when bounds + (goto-char (bibtex-start-of-text-in-field bounds)) + (let (case-fold-search) + (while (re-search-forward "\\bAND\\b" + (bibtex-end-of-text-in-field bounds) t) + (replace-match (downcase (match-string 0)) 'fixedcase))))))) + +(defvar km/bibtex-article-fields-to-delete + '("abstract" "issn" "pubmedid" "url" "eprint" "keywords")) + +(defun km/bibtex-delete-article-fields () + (save-excursion + (when (and (bibtex-beginning-of-entry) + (looking-at bibtex-entry-maybe-empty-head) + (string= (downcase (bibtex-type-in-head)) "article")) + (dolist (f km/bibtex-article-fields-to-delete) + (let (bounds) + ;; Make sure field is removed even if it is repeated. + (while (progn (bibtex-beginning-of-entry) + (setq bounds (bibtex-search-forward-field f t))) + (goto-char (bibtex-end-of-field bounds)) + (skip-chars-backward " \t\n") + (delete-region (bibtex-start-of-field bounds) + (point)))))))) + +;;;###autoload +(defun km/browse-doi (doi) + "Open DOI in browser. +When called interactively, take the DOI from the text under +point. The link is opened using the settings of +`org-doi-server-url'." + (interactive (list (km/doi-at-point))) + (browse-url (org-link-escape-browser (concat org-doi-server-url doi)))) + +;;;###autoload +(defun km/copy-doi-as-kill () + "Copy DOI at point to kill ring." + (interactive) + (-when-let (doi (km/doi-at-point)) + (kill-new (message "%s" (concat "doi:" doi))))) + +(defun km/doi-at-point () + "Return DOI at point." + (save-excursion + (skip-chars-backward "-.A-z0-9/") + (and (looking-at "\\(doi:[ \t\n]*\\)*\\([-./A-z0-9]+[A-z0-9]\\)\\b") + (match-string-no-properties 2)))) + +(provide 'km-bib) +;;; km-bib.el ends here -- cgit v1.2.3