Commit d528bff7 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

(bibtex-mark-active, bibtex-run-with-idle-timer): Move `if' inside the defun.

(bibtex-autokey-titleword-ignore): Regexp is used in a case insensitive env.
(bibtex-mode-map): Rearrange order of menus.
(bibtex-quoted-string-re): Obsolete.
(bibtex-complete-key-cleanup): Variable replaced by new function.
(bibtex-font-lock-keywords): Use backquotes.
(bibtex-font-lock-url-regexp): New internal variable.
(bibtex-name-in-field): New opt arg remove-opt-alt to remove "OPT" and "ALT".
(bibtex-insert-current-kill, bibtex-make-field)
(bibtex-prepare-new-entry, bibtex-yank-pop, bibtex-String): Use unless.
(bibtex-parse-field-text): Simplify.
(bibtex-string=): New helper function.
(bibtex-member-of-regexp): Merge with bibtex-autokey-get-title.
(bibtex-map-entries): Use bibtex-string=.
(bibtex-search-entry): Use not.
(bibtex-enclosing-field): Fix docstring.
(bibtex-assoc-regexp): Obsolete.
(bibtex-format-entry): Use assoc-string and bibtex-string=.
(bibtex-autokey-get-names): Handle empty name field.
(bibtex-parse-strings): Use assoc-string and unless.
(bibtex-complete-string-cleanup): Expansion list is passed as an argument.
Use assoc-string.
(bibtex-pop): Simplify.
(bibtex-mode): Set font-lock-extra-managed-props.
(bibtex-entry-update): Use assoc-string.
(bibtex-parse-entry): Remove "OPT" and "ALT" from FIELD.
(bibtex-autofill-entry): Use bibtex-string=.
(bibtex-print-help-message): Simplify.
(bibtex-find-entry): New optional arg START.
(bibtex-validate): Use bibtex-string= and assoc-string.
Do not call obsolete function compilation-parse-errors.
(bibtex-remove-delimiters): Only remove delimiters if present.
(bibtex-copy-entry-as-kill): Add docstring.
(bibtex-clean-entry): Use bibtex-string=. Handle empty keys.
Detect duplicate keys if bibtex-maintain-sorted-entries is nil.
(bibtex-complete): Use bibtex-predefined-month-strings,
bibtex-string=, and new function bibtex-complete-key-cleanup.
(bibtex-generate-url-list): New variable.
(bibtex-url): New command bound to C-c C-l and mouse-2.
(bibtex-url-map): New local keymap for bibtex-url-mouse.
(bibtex-font-lock-url): New function.
parent 0608b1a0
......@@ -617,6 +617,8 @@ version 4.7 or newer, compiles to Info pages with embedded images.
'sql-sqlite'.
 
** BibTeX mode:
*** The new command bibtex-url browses a URL for the BibTeX entry at
point (bound to C-c C-l and mouse-2 on clickable fields).
*** The new command bibtex-entry-update (bound to C-c C-u) updates
an existing BibTeX entry.
*** New `bibtex-entry-format' option `required-fields', enabled by default.
......
2004-09-10 Stefan Monnier <monnier@iro.umontreal.ca>
* textmodes/bibtex.el (bibtex-mark-active)
(bibtex-run-with-idle-timer): Move the `if' inside the defun.
2004-09-10 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
* textmodes/bibtex.el (bibtex-autokey-titleword-ignore): Regexp is
used in a case insensitive environment.
(bibtex-mode-map): Rearrange order of menus.
(bibtex-quoted-string-re): Obsolete.
(bibtex-complete-key-cleanup): Variable replaced by new function.
(bibtex-font-lock-keywords): Use backquotes.
(bibtex-font-lock-url-regexp): New internal variable.
(bibtex-name-in-field): New optional arg remove-opt-alt to remove
"OPT" and "ALT".
(bibtex-insert-current-kill, bibtex-make-field)
(bibtex-prepare-new-entry, bibtex-yank-pop, bibtex-String): Use unless.
(bibtex-parse-field-text): Simplify.
(bibtex-string=): New helper function.
(bibtex-member-of-regexp): Merge with bibtex-autokey-get-title.
(bibtex-map-entries): Use bibtex-string=.
(bibtex-search-entry): Use not.
(bibtex-enclosing-field): Fix docstring.
(bibtex-assoc-regexp): Obsolete.
(bibtex-format-entry): Use assoc-string and bibtex-string=.
(bibtex-autokey-get-names): Handle empty name field.
(bibtex-parse-strings): Use assoc-string and unless.
(bibtex-complete-string-cleanup): Expansion list is passed as an arg.
Use assoc-string.
(bibtex-pop): Simplify.
(bibtex-mode): Set font-lock-extra-managed-props.
(bibtex-entry-update): Use assoc-string.
(bibtex-parse-entry): Remove "OPT" and "ALT" from FIELD.
(bibtex-autofill-entry): Use bibtex-string=.
(bibtex-print-help-message): Simplify.
(bibtex-find-entry): New optional arg START.
(bibtex-validate): Use bibtex-string= and assoc-string.
Do not call obsolete function compilation-parse-errors.
(bibtex-remove-delimiters): Only remove delimiters if present.
(bibtex-copy-entry-as-kill): Add docstring.
(bibtex-clean-entry): Use bibtex-string=. Handle empty keys.
Detect duplicate keys if bibtex-maintain-sorted-entries is nil.
(bibtex-complete): Use bibtex-predefined-month-strings,
bibtex-string=, and new function bibtex-complete-key-cleanup.
(bibtex-generate-url-list): New variable.
(bibtex-url): New command bound to C-c C-l and mouse-2.
(bibtex-url-map): New local keymap for bibtex-url-mouse.
(bibtex-font-lock-url): New function.
2004-09-09 Stefan Monnier <monnier@iro.umontreal.ca>
* progmodes/grep.el (grep-mode): Remove unnecessary autoload.
......
......@@ -640,7 +640,7 @@ See `bibtex-generate-autokey' for details."
(defcustom bibtex-autokey-titleword-ignore
'("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
"[^A-Z].*" ".*[^a-zA-Z0-9].*")
"[^A-Z].*" ".*[^A-Z0-9].*")
"*Determines words from the title that are not to be used in the key.
Each item of the list is a regexp. If a word of the title matchs a
regexp from that list, it is not included in the title part of the key.
......@@ -762,11 +762,46 @@ If non-nil, the column for the equal sign is the value of
"Automatically fill fields if possible for those BibTeX entry types."
:type '(repeat string))
(defcustom bibtex-complete-key-cleanup nil
"*Function called by `bibtex-complete' after insertion of a key fragment."
:group 'bibtex-autokey
:type '(choice (const :tag "None" nil)
(function :tag "Cleanup function")))
(defcustom bibtex-generate-url-list
'((("url" . t) ("url" t)))
"List of schemes for generating the URL of a BibTeX entry.
These schemes are used by `bibtex-url'.
Each scheme is of the form ((FIELD . REGEXP) STEPS).
FIELD is a field name as returned by `bibtex-parse-entry'.
REGEXP is matched against the text of FIELD.
If the match succeeds, the list STEPS is used to generate the URL.
If REGEXP is t, always generate the URL if FIELD is present.
If an element of STEPS is a list (FIELD MATCH FILTER),
the text of FIELD is matched against MATCH.
If MATCH is t, the text of FIELD is accepted as is.
If MATCH is a cons cell (REGEXP . REPLACE), the text is matched against REGEXP.
If REPLACE is a string, the text is replaced with REPLACE. If REPLACE is a
number, it specifies which parenthesized expression in the match is taken.
The optional element FILTER is a function for piping the match through it.
The text strings are then concatenated to generate the URL.
If an element of STEPS is a string, it is simply added to the URL.
Case is always ignored. Always remove the field delimiters."
:group 'bibtex
:type '(repeat
(list :tag "Scheme"
(cons :tag "Matcher" :extra-offset 4
(string :tag "BibTeX field")
(choice (regexp :tag "Regexp")
(const :tag "Accept as is" t)))
(repeat :tag "Steps to generate URL" :inline t
(choice
(string :tag "Literal text")
(list (string :tag "BibTeX field")
(choice (const :tag "Accept as is" t)
(cons (string :tag "Field")
(choice (regexp :tag "Regexp")
(integer :tag "Matched parenthesis"))))
(option (function :tag "Filter" :value ignore))))))))
;; bibtex-font-lock-keywords is a user option as well, but since the
;; patterns used to define this variable are defined in a later
......@@ -801,6 +836,7 @@ If non-nil, the column for the equal sign is the value of
(define-key km "\C-c}" 'bibtex-remove-delimiters)
(define-key km "\C-c\C-c" 'bibtex-clean-entry)
(define-key km "\C-c\C-q" 'bibtex-fill-entry)
(define-key km "\C-c\C-s" 'bibtex-find-entry)
(define-key km "\C-c?" 'bibtex-print-help-message)
(define-key km "\C-c\C-p" 'bibtex-pop-previous)
(define-key km "\C-c\C-n" 'bibtex-pop-next)
......@@ -821,6 +857,7 @@ If non-nil, the column for the equal sign is the value of
(define-key km "\C-c\C-b" 'bibtex-entry)
(define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
(define-key km "\C-c\C-rw" 'widen)
(define-key km "\C-c\C-l" 'bibtex-url)
(define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
(define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
(define-key km "\C-c\C-ei" 'bibtex-InCollection)
......@@ -854,21 +891,7 @@ If non-nil, the column for the equal sign is the value of
("Moving in BibTeX Buffer"
["Find Entry" bibtex-find-entry t]
["Find Crossref Entry" bibtex-find-crossref t])
("Operating on Current Entry"
["Fill Entry" bibtex-fill-entry t]
["Clean Entry" bibtex-clean-entry t]
"--"
["Kill Entry" bibtex-kill-entry t]
["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
["Paste Most Recently Killed Entry" bibtex-yank t]
["Paste Previously Killed Entry" bibtex-yank-pop t]
"--"
["Ispell Entry" bibtex-ispell-entry t]
["Ispell Entry Abstract" bibtex-ispell-abstract t]
["Narrow to Entry" bibtex-narrow-to-entry t]
"--"
["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
(fboundp 'reftex-view-crossref-from-bibtex)])
("Operating on Current Field"
["Fill Field" fill-paragraph t]
["Remove Delimiters" bibtex-remove-delimiters t]
......@@ -888,12 +911,28 @@ If non-nil, the column for the equal sign is the value of
["String or Key Complete" bibtex-complete t]
"--"
["Help about Current Field" bibtex-print-help-message t])
("Operating on Current Entry"
["Fill Entry" bibtex-fill-entry t]
["Clean Entry" bibtex-clean-entry t]
["Update Entry" bibtex-entry-update t]
"--"
["Kill Entry" bibtex-kill-entry t]
["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
["Paste Most Recently Killed Entry" bibtex-yank t]
["Paste Previously Killed Entry" bibtex-yank-pop t]
"--"
["Ispell Entry" bibtex-ispell-entry t]
["Ispell Entry Abstract" bibtex-ispell-abstract t]
["Narrow to Entry" bibtex-narrow-to-entry t]
"--"
["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
(fboundp 'reftex-view-crossref-from-bibtex)])
("Operating on Buffer or Region"
["Validate Entries" bibtex-validate t]
["Sort Entries" bibtex-sort-buffer t]
["Reformat Entries" bibtex-reformat t]
["Count Entries" bibtex-count-entries t])
("Miscellaneous"
["Count Entries" bibtex-count-entries t]
"--"
["Convert Alien Buffer" bibtex-convert-alien t])))
(easy-menu-define
......@@ -915,6 +954,13 @@ If non-nil, the column for the equal sign is the value of
["String" bibtex-String t]
["Preamble" bibtex-Preamble t]))
(defvar bibtex-url-map
(let ((km (make-sparse-keymap)))
(define-key km [(mouse-2)] 'bibtex-url)
km)
"Local keymap for clickable URLs.")
(fset 'bibtex-url-map bibtex-url-map)
;; Internal Variables
......@@ -1040,38 +1086,32 @@ was parsed for keys the last time.")
(defconst bibtex-empty-field-re "\"\"\\|{}"
"Regexp matching an empty field.")
(defconst bibtex-quoted-string-re
(concat "\""
"\\("
"[^\"\\]" ; anything but quote or backslash
"\\|"
"\\("
"\\\\\\(.\\|\n\\)" ; any backslash quoted character
"\\)"
"\\)*"
"\"")
"Regexp matching a field string enclosed by quotes.")
(defconst bibtex-font-lock-syntactic-keywords
`((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
(substring bibtex-comment-start 1) "\\>")
1 '(11))))
(defvar bibtex-font-lock-keywords
(list
;; entry type and reference key
(list bibtex-entry-maybe-empty-head
(list bibtex-type-in-head 'font-lock-function-name-face)
(list bibtex-key-in-head 'font-lock-constant-face nil t))
;; optional field names (treated as comments)
(list
(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
1 'font-lock-comment-face)
;; field names
(list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
1 'font-lock-variable-name-face))
;; entry type and reference key
`((,bibtex-entry-maybe-empty-head
(,bibtex-type-in-head font-lock-function-name-face)
(,bibtex-key-in-head font-lock-constant-face nil t))
;; optional field names (treated as comments)
(,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
1 font-lock-comment-face)
;; field names
(,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
1 font-lock-variable-name-face)
;; url
(bibtex-font-lock-url 0 '(face nil mouse-face highlight
keymap bibtex-url-map)))
"*Default expressions to highlight in BibTeX mode.")
(defvar bibtex-font-lock-url-regexp
(concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t)
"\\>[ \t]*=[ \t]*")
"Regexp for `bibtex-font-lock-url'.")
(defvar bibtex-field-name-for-parsing nil
"Temporary variable storing the name string to be parsed by the callback
function `bibtex-parse-field-name'.")
......@@ -1089,22 +1129,22 @@ function `bibtex-parse-field-name'.")
;; Special support taking care of variants
(defvar zmacs-regions)
(if (boundp 'mark-active)
(defun bibtex-mark-active ()
(defalias 'bibtex-mark-active
(if (boundp 'mark-active)
;; In Emacs mark-active indicates if mark is active.
mark-active)
(defun bibtex-mark-active ()
(lambda () mark-active)
;; In XEmacs (mark) returns nil when not active.
(if zmacs-regions (mark) (mark t))))
(if (fboundp 'run-with-idle-timer)
;; timer.el is distributed with Emacs
(fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
;; timer.el is not distributed with XEmacs
;; Notice that this does not (yet) pass the arguments, but they
;; are not used (yet) in bibtex.el. Fix if needed.
(defun bibtex-run-with-idle-timer (secs repeat function &rest args)
(start-itimer "bibtex" function secs (if repeat secs nil) t)))
(lambda () (if zmacs-regions (mark) (mark t)))))
(defalias 'bibtex-run-with-idle-timer
(if (fboundp 'run-with-idle-timer)
;; timer.el is distributed with Emacs
'run-with-idle-timer
;; timer.el is not distributed with XEmacs
;; Notice that this does not (yet) pass the arguments, but they
;; are not used (yet) in bibtex.el. Fix if needed.
(lambda (secs repeat function &rest args)
(start-itimer "bibtex" function secs (if repeat secs nil) t))))
;; Support for hideshow minor mode
......@@ -1215,9 +1255,9 @@ returned, nil otherwise. Move point to end of field text."
((setq boundaries (bibtex-parse-field-string))
(goto-char (cdr boundaries)))
((setq failure t)))
(if (not (looking-at "[ \t\n]*#[ \t\n]*"))
(setq end-point (point))
(goto-char (match-end 0))))
(if (looking-at "[ \t\n]*#[ \t\n]*")
(goto-char (match-end 0))
(setq end-point (point))))
(if (and (not failure)
end-point)
(cons starting-point end-point))))
......@@ -1294,10 +1334,15 @@ current entry. Do not move point."
(defsubst bibtex-end-of-text-in-field (bounds)
(cddr bounds))
(defun bibtex-name-in-field (bounds)
"Get content of name in BibTeX field defined via BOUNDS."
(buffer-substring-no-properties (nth 1 (car bounds))
(nth 2 (car bounds))))
(defun bibtex-name-in-field (bounds &optional remove-opt-alt)
"Get content of name in BibTeX field defined via BOUNDS.
If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
(let ((name (buffer-substring-no-properties (nth 1 (car bounds))
(nth 2 (car bounds)))))
(if (and remove-opt-alt
(string-match "\\`\\(OPT\\|ALT\\)" name))
(substring name 3)
name)))
(defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
"Get content of text in BibTeX field defined via BOUNDS.
......@@ -1438,6 +1483,10 @@ delimiters if present."
;; Helper Functions
(defsubst bibtex-string= (str1 str2)
"Return t if two strings are equal, ignoring case."
(eq t (compare-strings str1 0 nil str2 0 nil t)))
(defun bibtex-delete-whitespace ()
"Delete all whitespace starting at point."
(if (looking-at "[ \t\n]+")
......@@ -1448,15 +1497,6 @@ delimiters if present."
(+ (count-lines 1 (point))
(if (equal (current-column) 0) 1 0)))
(defun bibtex-member-of-regexp (string list)
"Return non-nil if STRING is exactly matched by an element of LIST.
The value is actually the tail of LIST whose car matches STRING."
(let (case-fold-search)
(while (and list
(not (string-match (concat "\\`\\(?:" (car list) "\\)\\'") string)))
(setq list (cdr list)))
list))
(defun bibtex-skip-to-valid-entry (&optional backward)
"Unless at beginning of a valid BibTeX entry, move point to beginning of the
next valid one. With optional argument BACKWARD non-nil, move backward to
......@@ -1501,7 +1541,7 @@ FUN will not be called for @String entries."
(end (copy-marker (save-excursion (bibtex-end-of-entry)))))
(save-excursion
(if (or (and (not bibtex-sort-ignore-string-entries)
(string-equal "string" (downcase entry-type)))
(bibtex-string= entry-type "string"))
(assoc-string entry-type bibtex-entry-field-alist t))
(funcall fun key beg end)))
(goto-char end)))))
......@@ -1575,7 +1615,7 @@ are defined, but only for the head part of the entry
(if found
(progn (goto-char (match-beginning 0))
found)
(cond ((equal noerror nil)
(cond ((not noerror)
;; yell
(error "Backward search of BibTeX entry failed"))
((equal noerror t)
......@@ -1684,10 +1724,10 @@ are defined, but only for the head part of the entry
(forward-char -1)))
(defun bibtex-enclosing-field (&optional noerr)
"Search for BibTeX field enclosing point. Point moves to end of field.
"Search for BibTeX field enclosing point.
Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
no error is signalled. In this case, bounds are returned on success,
nil otherwise."
nil otherwise. Does not move point."
(let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
(if (and bounds
(<= (bibtex-start-of-field bounds) (point))
......@@ -1732,8 +1772,7 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
(message "Mark set")
(bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
((equal bibtex-last-kill-command 'entry)
(if (not (eobp))
(bibtex-beginning-of-entry))
(unless (eobp) (bibtex-beginning-of-entry))
(set-mark (point))
(message "Mark set")
(insert (elt current 1)))
......@@ -1741,15 +1780,6 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
(error "Unknown tag field: %s. Please submit a bug report"
bibtex-last-kill-command))))))
(defun bibtex-assoc-regexp (regexp alist)
"Return non-nil if REGEXP matches the car of an element of ALIST.
The value is actually the element of ALIST matched by REGEXP.
Case is ignored if `case-fold-search' is non-nil in the current buffer."
(while (and alist
(not (string-match regexp (caar alist))))
(setq alist (cdr alist)))
(car alist))
(defun bibtex-format-entry ()
"Helper function for `bibtex-clean-entry'.
Formats current entry according to variable `bibtex-entry-format'."
......@@ -1764,7 +1794,7 @@ Formats current entry according to variable `bibtex-entry-format'."
unify-case inherit-booktitle)
bibtex-entry-format))
crossref-key bounds alternatives-there non-empty-alternative
entry-list req-field-list field-done field-list)
entry-list req-field-list field-list)
;; identify entry type
(goto-char (point-min))
......@@ -1792,9 +1822,7 @@ Formats current entry according to variable `bibtex-entry-format'."
;; one alternative is non-empty
(goto-char (point-min))
(let* ((fields-alist (bibtex-parse-entry))
(case-fold-search t)
(field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
fields-alist)))
(field (assoc-string "crossref" fields-alist t)))
(setq crossref-key (and field
(not (string-match bibtex-empty-field-re
(cdr field)))
......@@ -1806,9 +1834,7 @@ Formats current entry according to variable `bibtex-entry-format'."
(dolist (rfield req-field-list)
(when (nth 3 rfield) ; we should have an alternative
(setq alternatives-there t
field (bibtex-assoc-regexp
(concat "\\`\\(ALT\\)?" (car rfield) "\\'")
fields-alist))
field (assoc-string (car rfield) fields-alist t))
(if (and field
(not (string-match bibtex-empty-field-re
(cdr field))))
......@@ -1887,7 +1913,7 @@ Formats current entry according to variable `bibtex-entry-format'."
;; update page dashes
(if (and (memq 'page-dashes format)
(string-match "\\`\\(OPT\\)?pages\\'" field-name)
(bibtex-string= field-name "pages")
(progn (goto-char beg-text)
(looking-at
"\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
......@@ -1896,7 +1922,7 @@ Formats current entry according to variable `bibtex-entry-format'."
;; use book title of crossref'd entry
(if (and (memq 'inherit-booktitle format)
empty-field
(equal (downcase field-name) "booktitle")
(bibtex-string= field-name "booktitle")
crossref-key)
(let ((title (save-restriction
(widen)
......@@ -1909,7 +1935,7 @@ Formats current entry according to variable `bibtex-entry-format'."
;; Use booktitle to set a missing title.
(if (and empty-field
(equal (downcase field-name) "title"))
(bibtex-string= field-name "title"))
(let ((booktitle (bibtex-text-in-field "booktitle")))
(when booktitle
(setq empty-field nil)
......@@ -2023,12 +2049,13 @@ applied to the content of FIELD. It is an alist with pairs
"Get contents of the name field of the current entry.
Do some modifications based on `bibtex-autokey-name-change-strings'
and return results as a list."
(let ((case-fold-search t))
(mapcar 'bibtex-autokey-demangle-name
(split-string (bibtex-autokey-get-field
"author\\|editor"
bibtex-autokey-name-change-strings)
"[ \t\n]+and[ \t\n]+"))))
(let ((case-fold-search t)
(names (bibtex-autokey-get-field "author\\|editor"
bibtex-autokey-name-change-strings)))
;; Some entries do not have a name field.
(unless (string= "" names)
(mapcar 'bibtex-autokey-demangle-name
(split-string names "[ \t\n]+and[ \t\n]+")))))
(defun bibtex-autokey-demangle-name (fullname)
"Get the last part from a well-formed name and perform abbreviations."
......@@ -2059,18 +2086,18 @@ and return results as a list."
(defun bibtex-autokey-get-title ()
"Get title field contents up to a terminator."
(let ((titlestring
(let ((case-fold-search t)
(titlestring
(bibtex-autokey-get-field "title"
bibtex-autokey-titleword-change-strings)))
;; ignore everything past a terminator
(let ((case-fold-search t))
(dolist (terminator bibtex-autokey-title-terminators)
(if (string-match terminator titlestring)
(setq titlestring (substring titlestring 0 (match-beginning 0))))))
(dolist (terminator bibtex-autokey-title-terminators)
(if (string-match terminator titlestring)
(setq titlestring (substring titlestring 0 (match-beginning 0)))))
;; gather words from titlestring into a list. Ignore
;; specific words and use only a specific amount of words.
(let ((counter 0)
case-fold-search titlewords titlewords-extra titleword end-match)
titlewords titlewords-extra titleword end-match)
(while (and (or (not (numberp bibtex-autokey-titlewords))
(< counter (+ bibtex-autokey-titlewords
bibtex-autokey-titlewords-stretch)))
......@@ -2078,8 +2105,12 @@ and return results as a list."
(setq end-match (match-end 0)
titleword (substring titlestring
(match-beginning 0) end-match))
(unless (bibtex-member-of-regexp titleword
bibtex-autokey-titleword-ignore)
(unless (let ((lst bibtex-autokey-titleword-ignore))
(while (and lst
(not (string-match (concat "\\`\\(?:" (car lst)
"\\)\\'") titleword)))
(setq lst (cdr lst)))
lst)
(setq titleword
(funcall bibtex-autokey-titleword-case-convert titleword))
(if (or (not (numberp bibtex-autokey-titlewords))
......@@ -2097,7 +2128,7 @@ and return results as a list."
"Do some abbreviations on TITLEWORD.
The rules are defined in `bibtex-autokey-titleword-abbrevs'
and `bibtex-autokey-titleword-length'."
(let ((case-folde-search t)
(let ((case-fold-search t)
(alist bibtex-autokey-titleword-abbrevs))
(while (and alist
(not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
......@@ -2308,7 +2339,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
bounds key)
(if (listp add)
(dolist (string add)
(unless (assoc (car string) strings)
(unless (assoc-string (car string) strings t)
(push string strings))))
(catch 'userkey
(while (setq bounds (bibtex-search-forward-string))
......@@ -2317,9 +2348,9 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
;; user has aborted by typing a key --> return `aborted'
(throw 'userkey 'aborted))
(setq key (bibtex-reference-key-in-string bounds))
(if (not (assoc key strings))
(push (cons key (bibtex-text-in-string bounds t))
strings))
(unless (assoc-string key strings t)
(push (cons key (bibtex-text-in-string bounds t))
strings))
(goto-char (bibtex-end-of-text-in-string bounds)))
;; successful operation --> return `bibtex-strings'
(setq bibtex-strings strings))))))
......@@ -2409,11 +2440,12 @@ of a word, all strings are listed. Return completion."
;; return value is handled by choose-completion-string-functions
nil))))
(defun bibtex-complete-string-cleanup (str)
(defun bibtex-complete-string-cleanup (str strings-alist)
"Cleanup after inserting string STR.
Remove enclosing field delimiters for string STR. Display message with
expansion of STR."
(let ((pair (assoc str bibtex-strings)))
Remove enclosing field delimiters for string STR. Display message with
expansion of STR using expansion list STRINGS-ALIST."
(let ((pair (if (stringp str)
(assoc-string str strings-alist t))))
(when pair
(if (cdr pair)
(message "Abbreviation for `%s'" (cdr pair)))
......@@ -2427,6 +2459,38 @@ expansion of STR."
(bibtex-end-of-text-in-field bounds)))
(bibtex-remove-delimiters))))))))
(defun bibtex-complete-key-cleanup (key)
"Display message on entry KEY after completion of a crossref key."
(save-excursion
;; Don't do anything if we completed the key of an entry.
(let ((pnt (bibtex-beginning-of-entry)))
(if (and (stringp key)
(bibtex-find-entry key)
(/= pnt (point)))
(let* ((bibtex-autokey-name-case-convert 'identity)
(bibtex-autokey-name-length 'infty)
(nl (bibtex-autokey-get-names))
(name (concat (nth 0 nl) (if (nth 1 nl) " etal")))
(year (bibtex-autokey-get-field "year"))
(bibtex-autokey-titlewords 5)
(bibtex-autokey-titlewords-stretch 2)
(bibtex-autokey-titleword-case-convert 'identity)
(bibtex-autokey-titleword-length 5)
(title (mapconcat 'identity
(bibtex-autokey-get-title) " "))
(journal (bibtex-autokey-get-field
"journal" bibtex-autokey-transcriptions))
(volume (bibtex-autokey-get-field "volume"))
(pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . "")))))
(message "Ref:%s"
(mapconcat (lambda (arg)
(if (not (string= "" (cdr arg)))
(concat (car arg) (cdr arg))))
`((" " . ,name) (" " . ,year)
(": " . ,title) (", " . ,journal)
(" " . ,volume) (":" . ,pages))
"")))))))
(defun bibtex-choose-completion-string (choice buffer mini-p base-size)
;; Code borrowed from choose-completion-string:
;; We must duplicate the code from choose-completion-string
......@@ -2460,17 +2524,7 @@ expansion of STR."
(bounds (bibtex-enclosing-field))
(start-old-text (bibtex-start-of-text-in-field bounds))
(stop-old-text (bibtex-end-of-text-in-field bounds))
(start-name (bibtex-start-of-name-in-field bounds))
(stop-name (bibtex-end-of-name-in-field bounds))
;; construct regexp for field with same name as this one,
;; ignoring possible OPT's or ALT's
(field-name (progn
(goto-char start-name)
(buffer-substring-no-properties
(if (looking-at "\\(OPT\\)\\|\\(ALT\\)")