From fc41568c60cea6730aca12c7c4a31a841f5cb40f Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Mon, 19 Jan 2015 21:34:57 -0500 Subject: Rewrite bibtex-use-title-case In addition to capitalizing important or unprotected words: - Convert unimportant words to lower case. - Allow protecting brackets to be within a word. - Always capitalize word at start of title unless protected. --- lisp/init-bib.el | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'lisp/init-bib.el') diff --git a/lisp/init-bib.el b/lisp/init-bib.el index b03af20..fe8a8f1 100644 --- a/lisp/init-bib.el +++ b/lisp/init-bib.el @@ -34,22 +34,38 @@ 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. -All words except those in `km/bibtex-unimportant-title-words' are -capitalized." +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." (interactive) (save-excursion (bibtex-beginning-of-entry) - (goto-char (car (cdr (bibtex-search-forward-field "title" t)))) - (while (not (looking-at "},")) - ;; Not using `forward-word' because I want to capture character - ;; before word. If "-" or "{", the word should not be capitalized. - (re-search-forward "\\(.\\)[a-z]+") - (let ((before-word (match-string-no-properties 1)) - (word (thing-at-point 'word))) - (unless (or (member before-word '("-" "{")) - (member word km/bibtex-unimportant-title-words)) + (let* ((text-bounds (cdr (bibtex-search-forward-field "title" t))) + (beg (car text-bounds)) + (end (cadr text-bounds))) + (goto-char (1- beg)) + (while (re-search-forward "\\(\\W\\)\\(\\w+\\)\\(\\W\\)" end t) + (cond + ((and (string= (match-string 1) "{") + (string= (match-string 3) "}")) + ;; Go to previous character in case '}' is within the word. + (backward-char)) + ;; 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)))))) + (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)))))))) (add-hook 'bibtex-clean-entry-hook 'km/bibtex-use-title-case) -- cgit v1.2.3