changeset 57070:3d9707888790

(bibtex-generate-url-list): Change format. Provide a sample complex default. (bibtex-url, bibtex-font-lock-url): Adapt to new format. (bibtex-entry): Use mapc.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 12 Sep 2004 19:52:15 +0000
parents eadbbac38074
children 974e68c1a8c5
files lisp/textmodes/bibtex.el
diffstat 1 files changed, 162 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/textmodes/bibtex.el	Sun Sep 12 18:52:03 2004 +0000
+++ b/lisp/textmodes/bibtex.el	Sun Sep 12 19:52:15 2004 +0000
@@ -1,6 +1,6 @@
 ;;; bibtex.el --- BibTeX mode for GNU Emacs
 
-;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004
+;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004
 ;;           Free Software Foundation, Inc.
 
 ;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
@@ -61,13 +61,13 @@
   :type 'hook)
 
 (defcustom bibtex-field-delimiters 'braces
-  "*Type of field delimiters. Allowed values are `braces' or `double-quotes'."
+  "*Type of field delimiters.  Allowed values are `braces' or `double-quotes'."
   :group 'bibtex
   :type '(choice (const braces)
                  (const double-quotes)))
 
 (defcustom bibtex-entry-delimiters 'braces
-  "*Type of entry delimiters. Allowed values are `braces' or `parentheses'."
+  "*Type of entry delimiters.  Allowed values are `braces' or `parentheses'."
   :group 'bibtex
   :type '(choice (const braces)
                  (const parentheses)))
@@ -154,10 +154,10 @@
 Allowed non-nil values are:
 plain        All entries are sorted alphabetically.
 crossref     All entries are sorted alphabetically unless an entry has a
-             crossref field. These crossrefed entries are placed in
+             crossref field.  These crossrefed entries are placed in
              alphabetical order immediately preceding the main entry.
 entry-class  The entries are divided into classes according to their
-             entry name, see `bibtex-sort-entry-class'. Within each class
+             entry name, see `bibtex-sort-entry-class'.  Within each class
              the entries are sorted alphabetically.
 See also `bibtex-sort-ignore-string-entries'."
   :group 'bibtex
@@ -172,8 +172,8 @@
     ("Book" "Proceedings"))
   "*List of classes of BibTeX entry names, used for sorting entries.
 If value of `bibtex-maintain-sorted-entries' is `entry-class'
-entries are ordered according to the classes they belong to. Each
-class contains a list of entry names. An entry `catch-all' applies
+entries are ordered according to the classes they belong to.  Each
+class contains a list of entry names.  An entry `catch-all' applies
 to all entries not explicitely mentioned.")
 
 (defcustom bibtex-sort-ignore-string-entries t
@@ -763,45 +763,46 @@
   :type '(repeat string))
 
 (defcustom bibtex-generate-url-list
-  '((("url" . t) ("url" t)))
+  '((("url" . ".*:.*"))
+    ;; Example of a complex setup.
+    (("journal" . "\\<\\(PR[ABCDEL]?\\|RMP\\)\\>")
+     "http://publish.aps.org/abstract/"
+     ("journal" ".*" downcase)
+     "/v"
+     ("volume" ".*" 0)
+     "/p"
+     ("pages" "\\`\\([0-9]+\\)" 1)))
   "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).
+Each scheme is of the form ((FIELD . REGEXP) STEP...).
 
 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."
+REGEXP is matched against the text of FIELD.  If the match succeed, then
+this scheme will be used.  If no STEPS are specified the matched text is used
+as the URL, otherwise the URL is built by concatenating the STEPS.
+
+A STEP can be a string or a list (FIELD REGEXP REPLACE) in which case
+the text of FIELD is matched against REGEXP, and is replaced with REPLACE.
+REPLACE can be a string, or a number (which selects the corresponding submatch)
+or a function called with the field's text as argument and with the
+`match-data' properly set.
+
+Case is always ignored.  Always remove the field delimiters."
   :group 'bibtex
   :type '(repeat
-          (list :tag "Scheme" 
+          (list :tag "Scheme"
                 (cons :tag "Matcher" :extra-offset 4
                       (string :tag "BibTeX field")
-                      (choice (regexp :tag "Regexp")
-                              (const :tag "Accept as is" t)))
+		      (regexp :tag "Regexp"))
                 (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))))))))
+			       (regexp :tag "Regexp")
+                               (choice (string :tag "Replacement")
+				       (integer :tag "Sub-match")
+				       (function :tag "Filter"))))))))
 
 ;; bibtex-font-lock-keywords is a user option as well, but since the
 ;; patterns used to define this variable are defined in a later
@@ -1000,8 +1001,7 @@
 (make-variable-buffer-local 'bibtex-reference-keys)
 
 (defvar bibtex-buffer-last-parsed-tick nil
-  "Last value returned by `buffer-modified-tick' when buffer
-was parsed for keys the last time.")
+  "Value of `buffer-modified-tick' last time buffer was parsed for keys.")
 
 (defvar bibtex-parse-idle-timer nil
   "Stores if timer is already installed.")
@@ -1103,7 +1103,7 @@
     (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
      1 font-lock-variable-name-face)
     ;; url
-    (bibtex-font-lock-url 0 '(face nil mouse-face highlight 
+    (bibtex-font-lock-url 0 '(face nil mouse-face highlight
                                    keymap bibtex-url-map)))
   "*Default expressions to highlight in BibTeX mode.")
 
@@ -1113,8 +1113,8 @@
   "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'.")
+  "Regexp of field name to be parsed by function `bibtex-parse-field-name'.
+Passed by dynamic scoping.")
 
 (defvar bibtex-sort-entry-class-alist
   (let ((i -1) alist)
@@ -1123,8 +1123,9 @@
       (dolist (entry class)
         ;; all entry names should be downcase (for ease of comparison)
         (push (cons (if (stringp entry) (downcase entry) entry) i) alist))))
-  "Alist for the classes of the entry types if the value of
-`bibtex-maintain-sorted-entries' is `entry-class'.")
+  "Alist mapping entry types to their sorting index.
+Auto-generated from `bibtex-sort-entry-class'.
+Used when `bibtex-maintain-sorted-entries' is `entry-class'.")
 
 
 ;; Special support taking care of variants
@@ -1149,15 +1150,11 @@
 
 ;; Support for hideshow minor mode
 (defun bibtex-hs-forward-sexp (arg)
-  "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
-  (if (< arg 0)
-      (backward-sexp 1)
-    (if (looking-at "@\\S(*\\s(")
-        (progn
-          (goto-char (match-end 0))
-          (forward-char -1)
-          (forward-sexp 1))
-      (forward-sexp 1))))
+  "Replacement for `forward-sexp' to be used by `hs-minor-mode'.
+ARG is ignored."
+  (if (looking-at "@\\S(*\\s(")
+    (goto-char (1- (match-end 0))))
+  (forward-sexp 1))
 
 (add-to-list
  'hs-special-modes-alist
@@ -1184,7 +1181,7 @@
   "Parse the field name stored in `bibtex-field-name-for-parsing'.
 If the field name is found, return a triple consisting of the position of the
 very first character of the match, the actual starting position of the name
-part and end position of the match. Move point to end of field name.
+part and end position of the match.  Move point to end of field name.
 If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceeding
 BibTeX field as necessary."
   (cond ((looking-at ",[ \t\n]*")
@@ -1246,7 +1243,7 @@
 The text part is either a string, or an empty string, or a constant followed
 by one or more <# (string|constant)> pairs.  If a syntactically correct text
 is found, a pair containing the start and end position of the text is
-returned, nil otherwise. Move point to end of field text."
+returned, nil otherwise.  Move point to end of field text."
   (let ((starting-point (point))
         end-point failure boundaries)
     (while (not (or end-point failure))
@@ -1274,8 +1271,8 @@
   "Search forward to find a field of name NAME.
 If a syntactically correct field is found, a pair containing the boundaries of
 the name and text parts of the field is returned.  The search is limited by
-optional arg BOUND. If BOUND is t the search is limited by the end of the current
-entry. Do not move point."
+optional arg BOUND.  If BOUND is t the search is limited by the end of the
+current entry.  Do not move point."
   (save-match-data
     (save-excursion
       (unless (integer-or-marker-p bound)
@@ -1301,8 +1298,8 @@
   "Search backward to find a field of name NAME.
 If a syntactically correct field is found, a pair containing the boundaries of
 the name and text parts of the field is returned.  The search is limited by
-optional arg BOUND. If BOUND is t the search is limited by the beginning of the
-current entry. Do not move point."
+optional arg BOUND.  If BOUND is t the search is limited by the beginning of the
+current entry.  Do not move point."
   (save-match-data
     (save-excursion
       (unless (integer-or-marker-p bound)
@@ -1356,7 +1353,7 @@
       content)))
 
 (defun bibtex-text-in-field (field &optional follow-crossref)
-  "Get content of field FIELD of current BibTeX entry. Return nil if not found.
+  "Get content of field FIELD of current BibTeX entry.  Return nil if not found.
 If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
   (save-excursion
     (save-restriction
@@ -1396,7 +1393,7 @@
   "Parse the postfix part of a BibTeX string entry, including the text.
 If the string postfix is found, return a triple consisting of the position of
 the actual starting and ending position of the text and the very last
-character of the string entry. Move point past BibTeX string entry."
+character of the string entry.  Move point past BibTeX string entry."
   (let* ((case-fold-search t)
          (bounds (bibtex-parse-field-text)))
     (when bounds
@@ -1418,7 +1415,7 @@
 (defun bibtex-search-forward-string ()
   "Search forward to find a BibTeX string entry.
 If a syntactically correct entry is found, a pair containing the boundaries of
-the reference key and text parts of the string is returned. Do not move point."
+the reference key and text parts of the string is returned.  Do not move point."
   (save-excursion
     (save-match-data
       (let ((case-fold-search t)
@@ -1434,7 +1431,7 @@
 (defun bibtex-search-backward-string ()
   "Search backward to find a BibTeX string entry.
 If a syntactically correct entry is found, a pair containing the boundaries of
-the reference key and text parts of the field is returned. Do not move point."
+the reference key and text parts of the field is returned.  Do not move point."
   (save-excursion
     (save-match-data
       (let ((case-fold-search t)
@@ -1475,7 +1472,7 @@
                                   (match-end bibtex-type-in-head)))
 
 (defun bibtex-key-in-head (&optional empty)
-  "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
+  "Extract BibTeX key in head.  Return optional arg EMPTY if key is empty."
   (if (match-beginning bibtex-key-in-head)
       (buffer-substring-no-properties (match-beginning bibtex-key-in-head)
                                       (match-end bibtex-key-in-head))
@@ -1484,7 +1481,7 @@
 ;; Helper Functions
 
 (defsubst bibtex-string= (str1 str2)
-  "Return t if two strings are equal, ignoring case."
+  "Return t if STR1 and STR2 are equal, ignoring case."
   (eq t (compare-strings str1 0 nil str2 0 nil t)))
 
 (defun bibtex-delete-whitespace ()
@@ -1498,12 +1495,13 @@
      (if (equal (current-column) 0) 1 0)))
 
 (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
-beginning of previous valid one. A valid entry is a syntactical correct one
+  "Move point to beginning of the next valid BibTeX entry.
+Do not move if we are already at beginning of a valid BibTeX entry.
+With optional argument BACKWARD non-nil, move backward to
+beginning of previous valid one.  A valid entry is a syntactical correct one
 with type contained in `bibtex-entry-field-alist' or, if
 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
-entry. Return buffer position of beginning and ending of entry if a valid
+entry.  Return buffer position of beginning and ending of entry if a valid
 entry is found, nil otherwise."
   (interactive "P")
   (let ((case-fold-search t)
@@ -1528,9 +1526,9 @@
 
 (defun bibtex-map-entries (fun)
   "Call FUN for each BibTeX entry starting with the current.
-Do this to the end of the file. FUN is called with three arguments, the key of
+Do this to the end of the file.  FUN is called with three arguments, the key of
 the entry and the buffer positions (marker) of beginning and end of entry.
-Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil,
+Point is inside the entry.  If `bibtex-sort-ignore-string-entries' is non-nil,
 FUN will not be called for @String entries."
   (let ((case-fold-search t))
     (bibtex-beginning-of-entry)
@@ -1596,8 +1594,8 @@
 
 (defun bibtex-search-entry (empty-head &optional bound noerror backward)
   "Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
-BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
-is non-nil, search is done in reverse direction. Point is moved past the
+BOUND and NOERROR are exactly as in `re-search-forward'.  If BACKWARD
+is non-nil, search is done in reverse direction.  Point is moved past the
 closing delimiter (at the beginning of entry if BACKWARD is non-nil).
 Return a cons pair with buffer positions of beginning and end of entry.
 After call to this function MATCH-BEGINNING and MATCH-END functions
@@ -1700,7 +1698,7 @@
     (skip-chars-forward " \t\n")))
 
 (defun bibtex-beginning-of-first-entry ()
-  "Go to the beginning of the first BibTeX entry in buffer. Return point."
+  "Go to the beginning of the first BibTeX entry in buffer.  Return point."
   (goto-char (point-min))
   (if (re-search-forward "^[ \t]*@" nil 'move)
       (beginning-of-line))
@@ -1725,9 +1723,9 @@
 
 (defun bibtex-enclosing-field (&optional noerr)
   "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. Does not move 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.  Does not move point."
   (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
     (if (and bounds
              (<= (bibtex-start-of-field bounds) (point))
@@ -1737,7 +1735,7 @@
         (error "Can't find enclosing BibTeX field")))))
 
 (defun bibtex-enclosing-entry-maybe-empty-head ()
-  "Search for BibTeX entry enclosing point. Move point to end of entry.
+  "Search for BibTeX entry enclosing point.  Move point to end of entry.
 Beginning (but not end) of entry is given by (`match-beginning' 0)."
   (let ((case-fold-search t)
         (old-point (point)))
@@ -2016,8 +2014,8 @@
 (defun bibtex-autokey-abbrev (string len)
   "Return an abbreviation of STRING with at least LEN characters.
 If LEN is positive the abbreviation is terminated only after a consonant
-or at the word end. If LEN is negative the abbreviation is strictly
-enforced using abs (LEN) characters. If LEN is not a number, STRING
+or at the word end.  If LEN is negative the abbreviation is strictly
+enforced using abs (LEN) characters.  If LEN is not a number, STRING
 is returned unchanged."
   (cond ((or (not (numberp len))
              (<= (length string) (abs len)))
@@ -2033,9 +2031,9 @@
                string)))))
 
 (defun bibtex-autokey-get-field (field &optional change-list)
-  "Get content of BibTeX field FIELD. Return empty string if not found.
+  "Get content of BibTeX field FIELD.  Return empty string if not found.
 Optional arg CHANGE-LIST is a list of substitution patterns that is
-applied to the content of FIELD. It is an alist with pairs
+applied to the content of FIELD.  It is an alist with pairs
 \(OLD-REGEXP . NEW-STRING\)."
   (let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref))
         case-fold-search)
@@ -2058,7 +2056,7 @@
               (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."
+  "Get the last part from a well-formed FULLNAME and perform abbreviations."
   (let* (case-fold-search
          (name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
                       ;; Name is of the form "von Last, First" or
@@ -2150,7 +2148,7 @@
     `bibtex-autokey-name-change-strings' to the corresponding new
     one (see documentation of this variable for further detail).
  4. For every of at least first `bibtex-autokey-names' names in
-    the name field, determine the last name. If there are maximal
+    the name field, determine the last name.  If there are maximal
     `bibtex-autokey-names' + `bibtex-autokey-names-stretch'
     names, all names are used.
  5. From every last name, take at least `bibtex-autokey-name-length'
@@ -2159,12 +2157,12 @@
     `bibtex-autokey-name-case-convert'.
  7. Build the name part of the key by concatenating all
     abbreviated last names with the string
-    `bibtex-autokey-name-separator' between any two. If there are
+    `bibtex-autokey-name-separator' between any two.  If there are
     more names than are used in the name part, prepend the string
     contained in `bibtex-autokey-additional-names'.
  8. Build the year part of the key by truncating the contents of
     the year field to the rightmost `bibtex-autokey-year-length'
-    digits (useful values are 2 and 4). If the year field (or any
+    digits (useful values are 2 and 4).  If the year field (or any
     other field required to generate the key) is absent, but the entry
     has a valid crossref field and the variable
     `bibtex-autokey-use-crossref' is non-nil, use the field of the
@@ -2180,7 +2178,7 @@
     appear in `bibtex-autokey-titleword-ignore'.
     Build the title part of the key by using at least the first
     `bibtex-autokey-titlewords' words from this
-    abbreviated title. If the abbreviated title ends after
+    abbreviated title.  If the abbreviated title ends after
     maximal `bibtex-autokey-titlewords' +
     `bibtex-autokey-titlewords-stretch' words, all
     words from the abbreviated title are used.
@@ -2201,13 +2199,13 @@
     and the title part with `bibtex-autokey-name-year-separator'
     between the name part and the year part if both are non-empty
     and `bibtex-autokey-year-title-separator' between the year
-    part and the title part if both are non-empty. If the year
+    part and the title part if both are non-empty.  If the year
     part is empty, but not the other two parts,
     `bibtex-autokey-year-title-separator' is used as well.
 16. If the value of `bibtex-autokey-before-presentation-function'
-    is non-nil, it must be a function taking one argument. This
+    is non-nil, it must be a function taking one argument.  This
     function is then called with the generated key as the
-    argument. The return value of this function (a string) is
+    argument.  The return value of this function (a string) is
     used as the key.
 17. If the value of `bibtex-autokey-edit-before-use' is non-nil,
     the key is then presented in the minibuffer to the user,
@@ -2261,9 +2259,9 @@
 The buffer might possibly be restricted.
 Find both entry keys and crossref entries.
 If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of
-simply resetting it. If ADD is an alist of keys, also add ADD to
-`bibtex-reference-keys'. If ABORTABLE is non-nil abort on user
-input. If VERBOSE is non-nil gives messages about progress.
+simply resetting it.  If ADD is an alist of keys, also add ADD to
+`bibtex-reference-keys'.  If ABORTABLE is non-nil abort on user
+input.  If VERBOSE is non-nil gives messages about progress.
 Return alist of keys if parsing was completed, `aborted' otherwise."
   (let ((reference-keys (if (and add
                                  (listp bibtex-reference-keys))
@@ -2327,8 +2325,8 @@
   "Set `bibtex-strings' to the string definitions in the whole buffer.
 The buffer might possibly be restricted.
 If ADD is non-nil add the new strings to `bibtex-strings' instead of
-simply resetting it. If ADD is an alist of strings, also add ADD to
-`bibtex-strings'. If ABORTABLE is non-nil abort on user input.
+simply resetting it.  If ADD is an alist of strings, also add ADD to
+`bibtex-strings'.  If ABORTABLE is non-nil abort on user input.
 Return alist of strings if parsing was completed, `aborted' otherwise."
   (save-excursion
     (save-match-data
@@ -2388,7 +2386,8 @@
       (append bibtex-predefined-strings (nreverse compl)))))
 
 (defun bibtex-parse-buffers-stealthily ()
-  "Called by `bibtex-run-with-idle-timer'. Whenever emacs has been idle
+  "Parse buffer in the background during idle time.
+Called by `bibtex-run-with-idle-timer'.  Whenever Emacs has been idle
 for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting
 with the current) are parsed."
   (save-excursion
@@ -2412,9 +2411,9 @@
         (setq buffers (cdr buffers))))))
 
 (defun bibtex-complete-internal (completions)
-  "Complete word fragment before point to longest prefix of one
-string defined in list COMPLETIONS.  If point is not after the part
-of a word, all strings are listed. Return completion."
+  "Complete word fragment before point to longest prefix of COMPLETIONS.
+COMPLETIONS should be a list of strings.  If point is not after the part
+of a word, all strings are listed.  Return completion."
   (let* ((case-fold-search t)
          (beg (save-excursion
                 (re-search-backward "[ \t{\"]")
@@ -2514,7 +2513,8 @@
     (set-window-point window (point))))
 
 (defun bibtex-pop (arg direction)
-  "Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
+  "Fill current field from the ARG'th same field's text in DIRECTION.
+Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
   (let (bibtex-help-message)
     (bibtex-find-text nil))
   (save-excursion
@@ -2577,15 +2577,15 @@
 General information on working with BibTeX mode:
 
 You should use commands such as \\[bibtex-Book] to get a template for a
-specific entry. You should then fill in all desired fields using
-\\[bibtex-next-field] to jump from field to field. After having filled
+specific entry.  You should then fill in all desired fields using
+\\[bibtex-next-field] to jump from field to field.  After having filled
 in all desired fields in the entry, you should clean the new entry
 with the command \\[bibtex-clean-entry].
 
 Some features of BibTeX mode are available only by setting the variable
-`bibtex-maintain-sorted-entries' to non-nil. However, then BibTeX mode will
+`bibtex-maintain-sorted-entries' to non-nil.  However, then BibTeX mode will
 work only with buffers containing valid (syntactical correct) entries
-and with entries being sorted. This is usually the case, if you have
+and with entries being sorted.  This is usually the case, if you have
 created a buffer completely with BibTeX mode and finished every new
 entry with \\[bibtex-clean-entry].
 
@@ -2736,7 +2736,7 @@
     (cons required optional)))
 
 (defun bibtex-entry (entry-type)
-  "Insert a new BibTeX entry.
+  "Insert a new BibTeX entry of type ENTRY-TYPE.
 After insertion it calls the functions in `bibtex-add-entry-hook'."
   (interactive (let* ((completion-ignore-case t)
                       (e-t (completing-read
@@ -2753,8 +2753,8 @@
     (insert "@" entry-type (bibtex-entry-left-delimiter))
     (if key (insert key))
     (save-excursion
-      (mapcar 'bibtex-make-field (car field-list))
-      (mapcar 'bibtex-make-optional-field (cdr field-list))
+      (mapc 'bibtex-make-field (car field-list))
+      (mapc 'bibtex-make-optional-field (cdr field-list))
       (if bibtex-comma-after-last-field
           (insert ","))
       (insert "\n")
@@ -2887,7 +2887,8 @@
   "Make a field named FIELD in current BibTeX entry.
 FIELD is either a string or a list of the form
 \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
-`bibtex-entry-field-alist'."
+`bibtex-entry-field-alist'.
+If CALLED-BY-YANK is non-nil, don't insert delimiters."
   (interactive
    (list (let ((completion-ignore-case t)
                (field-list (bibtex-field-list
@@ -2929,8 +2930,8 @@
 (defun bibtex-beginning-of-entry ()
   "Move to beginning of BibTeX entry (beginning of line).
 If inside an entry, move to the beginning of it, otherwise move to the
-beginning of the previous entry. If point is ahead of all BibTeX entries
-move point to the beginning of buffer. Return the new location of point."
+beginning of the previous entry.  If point is ahead of all BibTeX entries
+move point to the beginning of buffer.  Return the new location of point."
   (interactive)
   (skip-chars-forward " \t")
   (if (looking-at "@")
@@ -2941,7 +2942,7 @@
 (defun bibtex-end-of-entry ()
   "Move to end of BibTeX entry (past the closing brace).
 If inside an entry, move to the end of it, otherwise move to the end
-of the previous entry. Do not move if ahead of first entry.
+of the previous entry.  Do not move if ahead of first entry.
 Return the new location of point."
   (interactive)
   (let ((case-fold-search t)
@@ -3041,9 +3042,9 @@
                       (bibtex-end-of-entry))))
 
 (defun bibtex-entry-index ()
-  "Return the index of the BibTeX entry at point. Move point.
+  "Return the index of the BibTeX entry at point.  Move point.
 The index is a list (KEY CROSSREF-KEY ENTRY-NAME) that is used for sorting
-the entries of the BibTeX buffer. Return nil if no entry found."
+the entries of the BibTeX buffer.  Return nil if no entry found."
   (let ((case-fold-search t))
     (if (re-search-forward bibtex-entry-maybe-empty-head nil t)
         (let ((key (bibtex-key-in-head))
@@ -3093,8 +3094,8 @@
 (defun bibtex-sort-buffer ()
   "Sort BibTeX buffer alphabetically by key.
 The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
-If its value is nil use plain sorting. Text outside of BibTeX entries is not
-affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
+If its value is nil use plain sorting.  Text outside of BibTeX entries is not
+affected.  If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
 will be ignored."
   (interactive)
   (save-restriction
@@ -3156,7 +3157,7 @@
 INDEX is a list (KEY CROSSREF-KEY ENTRY-NAME).
 Move point where the entry KEY should be placed.
 If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
-search to look for place for KEY. This will fail if buffer is not in
+search to look for place for KEY.  This will fail if buffer is not in
 sorted order, see \\[bibtex-validate].)
 Return t if preparation was successful or nil if entry KEY already exists."
   (let ((key (nth 0 index))
@@ -3562,7 +3563,7 @@
 Check that no required fields are empty and formats entry dependent
 on the value of `bibtex-entry-format'.
 If the reference key of the entry is empty or a prefix argument is given,
-calculate a new reference key. (Note: this will only work if fields in entry
+calculate a new reference key.  (Note: this will only work if fields in entry
 begin on separate lines prior to calling `bibtex-clean-entry' or if
 'realign is contained in `bibtex-entry-format'.)
 Don't call `bibtex-clean-entry' on @Preamble entries.
@@ -3962,7 +3963,7 @@
 (defun bibtex-url (&optional event)
   "Browse a URL for the BibTeX entry at position PNT.
 The URL is generated using the schemes defined in `bibtex-generate-url-list'
-\(see there\). Then the URL is passed to `browse-url'."
+\(see there\).  Then the URL is passed to `browse-url'."
   (interactive (list last-input-event))
   (save-excursion
     (if event (posn-set-point (event-end event)))
@@ -3972,39 +3973,40 @@
           (lst bibtex-generate-url-list)
           field url scheme)
       (while (setq scheme (car lst))
-        (when (and (setq field (assoc-string (caar scheme) fields-alist t))
-                   (or (eq t (cdar scheme))
-                       (string-match (cdar scheme) (cdr field))))
-          (setq lst nil)
+        (when (and (setq field (cdr (assoc-string (caar scheme)
+						  fields-alist t)))
+		   (progn
+		     (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" field)
+			 (setq field (match-string 1 field)))
+		     (string-match (cdar scheme) field)))
+	  (setq lst nil)
+	  (if (null (cdr scheme))
+	      (setq url (match-string 0 field)))
           (dolist (step (cdr scheme))
-            (cond ((stringp step)
-                   (setq url (concat url step)))
-                  ((setq field (assoc-string (car step) fields-alist t))
-                   ;; always remove field delimiters
-                   (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" 
-                                                  (cdr field))
-                                    (match-string 1 (cdr field))
-                                  (cdr field)))
-                          (str (cond ((eq t (nth 1 step))
-                                      text)
-                                     ((and (consp (nth 1 step))
-                                           (string-match (car (nth 1 step))
-                                                         text))
-                                      (if (numberp (cdr (nth 1 step)))
-                                          (match-string (cdr (nth 1 step))
-                                                        text)
-                                        (replace-match (cdr (nth 1 step))
-                                                       nil nil text)))
-                                     ;; If the scheme is set up correctly,
-                                     ;; we should never reach this point
-                                     (t (error "Match failed: %s" text)))))
-                     (setq url (concat url (if (fboundp (nth 2 step))
-                                               (funcall (nth 2 step) str)
-                                             str)))))
-                  ;; If the scheme is set up correctly,
-                  ;; we should never reach this point
-                  (t (error "Step failed: %s" step))))
-          (message "%s" url)
+	    (cond ((stringp step)
+		   (setq url (concat url step)))
+		  ((setq field (assoc-string (car step) fields-alist t))
+		   ;; always remove field delimiters
+		   (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" 
+						  (cdr field))
+				    (match-string 1 (cdr field))
+				  (cdr field)))
+			  (str (if (string-match (nth 1 step) text)
+				   (cond
+				    ((functionp (nth 2 step))
+				     (funcall (nth 2 step) text))
+				    ((numberp (nth 2 step))
+				     (match-string (nth 2 step) text))
+				    (t
+				     (replace-match (nth 2 step) nil nil text)))
+				 ;; If the scheme is set up correctly,
+				 ;; we should never reach this point
+				 (error "Match failed: %s" text))))
+                     (setq url (concat url str))))
+		  ;; If the scheme is set up correctly,
+		  ;; we should never reach this point
+		  (t (error "Step failed: %s" step))))
+	  (message "%s" url)
           (browse-url url))
         (setq lst (cdr lst)))
     (unless url (message "No URL known.")))))
@@ -4014,29 +4016,23 @@
   (let ((case-fold-search t)
         (bounds (bibtex-enclosing-field t))
         (pnt (point))
-        found url)
+	found field)
     ;; We use start-of-field as syntax-begin
     (goto-char (if bounds (bibtex-start-of-field bounds) pnt))
     (while (and (not found)
-                (search-forward-regexp bibtex-font-lock-url-regexp bound t)
-                (save-match-data (setq bounds (bibtex-parse-field-text)))
-                (>= bound (car bounds)))
-      (let ((field (match-string-no-properties 1))
-            (lst bibtex-generate-url-list))
-        (while (and (not found)
-                    (setq url (caar lst)))
-          (when (bibtex-string= field (car url))
-            (if (eq t (cdr url))
-                (progn
-                  (goto-char (min bound (cdr bounds)))
-                  (set-match-data (list (car bounds) (point)))
-                  (setq found t))
-              (goto-char (car bounds))
-              (setq found (search-forward-regexp (cdr url) 
-                                                 (min bound (cdr bounds)) t)))
-            (if (< (match-beginning 0) pnt)
-                (setq found nil)))
-          (setq lst (cdr lst)))))
+		(prog1 (re-search-forward bibtex-font-lock-url-regexp bound t)
+		  (setq field (match-string-no-properties 1)))
+		(setq bounds (bibtex-parse-field-text))
+		(>= bound (car bounds))
+		(>= (car bounds) pnt))
+      (let ((lst bibtex-generate-url-list) url)
+	(goto-char (car bounds))
+	(while (and (not found)
+		    (setq url (caar lst)))
+	  (when (bibtex-string= field (car url))
+	    (setq found (re-search-forward (cdr url) (cdr bounds) t)))
+	  (setq lst (cdr lst))))
+      (goto-char (cdr bounds)))
     found))