home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / lisp / bibtex.el < prev    next >
Text File  |  1996-09-28  |  61KB  |  1,607 lines

  1. ;;; bibtex.el --- BibTeX mode for GNU Emacs
  2.  
  3. ;; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Bengt Martensson <ubrinf!mond!bengt>
  6. ;;    Mark Shapiro <shapiro@corto.inria.fr>
  7. ;;    Mike Newton <newton@gumby.cs.caltech.edu>
  8. ;;    Aaron Larson <alarson@src.honeywell.com>
  9. ;; Version: 1.3.1
  10. ;; Maintainer:Aaron Larson <alarson@src.honeywell.com>
  11. ;; Adapted-By: ESR
  12. ;; Keywords: tex, bib
  13.  
  14. ;; This file is part of GNU Emacs.
  15.  
  16. ;; GNU Emacs is free software; you can redistribute it and/or modify
  17. ;; it under the terms of the GNU General Public License as published by
  18. ;; the Free Software Foundation; either version 2, or (at your option)
  19. ;; any later version.
  20.  
  21. ;; GNU Emacs is distributed in the hope that it will be useful,
  22. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24. ;; GNU General Public License for more details.
  25.  
  26. ;; You should have received a copy of the GNU General Public License
  27. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  28. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  
  30. ;;; TODO distribute texinfo file.
  31.  
  32. ;;; LCD Archive Entry:
  33. ;;; bibtex-mode|Bengt Martensson, Marc Shapiro, Aaron Larson|
  34. ;;; alarson@src.honeywell.com|
  35. ;;; Support for maintaining BibTeX format bibliography databases|
  36. ;;; 93-03-29|version 1.3|~/modes/bibtex-mode.el.Z|
  37.  
  38. ;;; Commentary:
  39.  
  40. ;;; BUGS:
  41. ;;;   1. using regular expressions to match the entire bibtex entry dies
  42. ;;;      on long bibtex entires (e.g. those containing abstracts) since
  43. ;;;      the length of regular expression matches is fairly limited.
  44. ;;;   2. When inserting a string (with \C-C\C-E\s) hitting a TAB results
  45. ;;;      in the error message "Can't find enclosing Bibtex field" instead
  46. ;;;      of moving to the empty string. [reported by gernot@cs.unsw.oz.au]
  47. ;;;   3. Function string-equalp should be in a library file, not in this
  48. ;;;      file. 
  49.  
  50. ;;; (current keeper: alarson@src.honeywell.com
  51. ;;;  previous: shapiro@corto.inria.fr)
  52.  
  53. ;;; Change Log:
  54.  
  55. ;; Mon Mar 29 14:06:06 1993  Aaron Larson  (alarson at gendibal)
  56. ;;
  57. ;;    * bibtex.el: V1.3 released Mar 30, 1993
  58. ;;    (bibtex-field-name):  Fix to match definition if latex manual,
  59. ;;    specifically letters, digits, and punctuation other than comma.
  60. ;;    Underscore is retained for historical reasons. 
  61. ;;    (bibtex-make-field):  Fix to work around bug in Lucid prin1-to-string
  62. ;;    function as reported by Martin Sjolin <marsj@ida.liu.se>. 
  63. ;;    (bibtex-entry):  minor code cleanup.
  64. ;;    (bibtex-mode-map): Remove key binding (C-c n) for
  65. ;;    narrow-to-bibtex-entry, previous binding violated emacs policy of
  66. ;;    reserving C-c followed by a letter for user customization.
  67. ;;    revise modification history to better conform to FSF changelog
  68. ;;    standards.
  69. ;;    (bibtex-refile-entry): Removed.  Would need disclaimer papers to
  70. ;;    incorporate it into official sources, and unable to contact author.
  71. ;;    Fix minor "syntax" errors in documentation strings and such found
  72. ;;    by new byte compiler.  Funs bibtex-mode, bibtex-remove-double-quotes
  73. ;;
  74. ;;
  75. ;; Fri Jan 15 14:06:06 1993  Aaron Larson  (alarson at gendibal)
  76. ;;
  77. ;;    * bibtex.el: V1.2 released Feb 15 1993
  78. ;;    (find-bibtex-entry-location bibtex-make-field): Fixed placement of
  79. ;;    "interactive specification".  [Bug report from
  80. ;;    mernst@theory.lcs.mit.edu] 
  81. ;;    Fixed problem where bibtex-entry would fail if user typed entry
  82. ;;    name in wrong case.
  83. ;;    (bibtex-inside-field) Position the cursor _before_ the last comma
  84. ;;    on a line (the comma is not necessarily "inside" the field); this
  85. ;;    does not seem to break any existing code. ref sct@dcs.edinburgh.ac.uk
  86. ;;    (bibtex-enclosing-field, bibtex-enclosing-reference): leave
  87. ;;    point unmoved if no enclosing field/reference is found.  As a
  88. ;;    result of changes (3) and (4) bibtex-next-field works properly,
  89. ;;    even when called from the entry key position. 
  90. ;;    (bibtex-remove-OPT): realign the '=' after removing the 'opt'.
  91. ;;    (bibtex-clean-entry): always remove any trailing comma from the
  92. ;;    end of a bibtex entry (these commas get stripped automatically when
  93. ;;    optional fields are killed by bibtex-kill-optional-field, but can be
  94. ;;    left if optional fields are removed by other means).
  95. ;;    (bibtex-x-help) Replace tab with spaces in X menu as noted by
  96. ;;    khera@cs.duke.edu
  97. ;;    (bibtex-refile-entry): Added (from brannon@jove.cs.caltech.edu)
  98. ;;    (bibtex-sort-ignore-string-entries sort-bibtex-entries,
  99. ;;    map-bibtex-entries): Added variable as requested by  
  100. ;;    gernot@cs.unsw.oz.au, required changes to funs.
  101. ;;    (bibtex-current-entry-label): Added at request of
  102. ;;    yasuro@maekawa.is.uec.ac.jp
  103. ;;    (bibtex-DEAthesis:) Deleted along with corresponding entry from
  104. ;;    bibtex-x-help  per shapiro@corto.inria.fr 
  105. ;;    Moved narrow-to-bibtex-entry from C-c C-n to C-c n (the previous
  106. ;;    binding was in conflict with the binding for bibtex-pop-next.
  107. ;;    bug report from [shapiro@corto.inria.fr]
  108. ;;
  109.  
  110. ;;; 
  111. ;;; alarson@src.honeywell.com 92-Feb-13
  112. ;;;   1. Made bibtex-entry user callable, now prompts for entry type (e.g.
  113. ;;;      Article), with completion, and bound it to a key.  This is now my
  114. ;;;      preferred way to add most entries. 
  115. ;;;   2. Made fields of a bibtex entry derived from the alist bibtex-entry-
  116. ;;;      field-alist.
  117. ;;;   3. Fixed handling of escaped double quotes, e.g. "Schr{\"o}dinger".
  118. ;;;   4. Fixed bug where unhiding bibtex entries moved point.
  119. ;;;   5. Made "field name" specs permit (name . value) for defaulting.  E.g. 
  120. ;;;       (setq bibtex-mode-user-optional-fields '(("library" . "alarson")))
  121. ;;;      will generate the field:
  122. ;;;       library    = "alarson",
  123. ;;;   6. Added binding for narrow-to-bibtex-entry
  124. ;;;   7. Adding a bibtex entry now runs hook: bibtex-add-entry-hook
  125. ;;;   8. Made bibtex-clean-entry fixup text alignment, and eliminated the
  126. ;;;      dependency on bibtex-enclosing-reference which has a problem with
  127. ;;;      long entries (e.g. those containing abstracts).
  128. ;;; 
  129. ;;; alarson@src.honeywell.com 92-Jan-31
  130. ;;;   Added support for: ispell, beginning/end of entry movement, a simple
  131. ;;;   outline like mode (hide the bodies of bibtex entries), support for
  132. ;;;   sorting bibtex entries, and maintaining them in sorted order, and
  133. ;;;   simple buffer validation.
  134. ;;;   User visible functions added:
  135. ;;;      ispell-{abstract,bibtex-entry}, {beginning,end}-of-bibtex-entry
  136. ;;;      hide-bibtex-entry-bodies, sort-bibtex-entries, validate-bibtex-
  137. ;;;      buffer, find-bibtex-duplicates
  138. ;;;   user visible variables added:
  139. ;;;      bibtex-maintain-sorted-entries
  140. ;;;   new local keybindings:
  141. ;;;     "    tex-insert-quote
  142. ;;;     C-c$   ispell-bibtex-entry
  143. ;;;     M-C-a  beginning-of-bibtex-entry
  144. ;;;     M-C-e  end-of-bibtex-entry
  145. ;;; Mike Newton (newton@gumby.cs.caltech.edu) 90.11.17
  146. ;;;  * Handle items like
  147. ;;;          title = poft # "Fifth Tri-quarterly" # random-conf,
  148. ;;;    and   title = {This title is inside curlies}
  149. ;;;  * added user settable, always present, optional fields
  150. ;;;  * fixed 'bibtex-find-it's doc string's location
  151. ;;;  * bibtex-field-text made more general (it wouldn't handle the # construct)
  152. ;;;        and it now handles a small subset of the {} cases
  153.  
  154. ;;; Bengt Martensson, March 6
  155. ;;;   Adapted to Bibtex 0.99 by updating the optional fields according
  156. ;;;   to the document BibTeXing, Oren Patashnik, dated January 31, 1988.
  157. ;;;   Updated documentation strings accordingly.  Added (provide 'bibtex).
  158. ;;;   If bibtex-include-OPT-crossref is non-nil, every entry will have
  159. ;;;   an OPTcrossref field, analogously for bibtex-include-OPTkey and
  160. ;;;   bibtex-include-OPTannote.  Added bibtex-preamble, bound to ^C^EP,
  161. ;;;   and also found in X- and sun-menus.  Cleaned up the sun-menu
  162. ;;;   stuff, and made it more uniform with the X-menu stuff.  Marc: I
  163. ;;;   strongly suspect that I broke your parsing...  (Or, more
  164. ;;;   correctly, BibTeX 0.99 broke it.)
  165. ;;;   Added bibtex-clean-entry-zap-empty-opts, defvar'd to t.  If it
  166. ;;;   is nil, bibtex-clean-entry will leave empty optional fields alone.
  167.  
  168. ;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06:
  169. ;;;   Added Sun menu support.  Locally bound to right mouse button in 
  170. ;;;   bibtex-mode.  Emacs 18.49 allows local mouse bindings!!
  171. ;;;   Commented out DEAthesis.
  172.  
  173. ;;; Marc Shapiro 6-oct-88
  174. ;;;  * skip-whitespace replaced by skip-chars-forward
  175. ;;;  * use indent-to-column instead of inserting tabs (changes to 
  176. ;;;    bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to
  177. ;;;    bibtex-make-optional-entry)
  178. ;;;  * C-c C-k deletes the current OPT entry entirely
  179. ;;;  * C-c C-d replaces text of field with ""
  180. ;;;  * renamed bibtex-find-it to bibtex-find-text.  With arg, now goes to
  181. ;;;    start of text.  Fixed bugs in it.
  182.  
  183. ;;; Marc Shapiro 23-sep-88
  184. ;;;  * bibtex-clean-entry moves past end of entry.
  185. ;;;  * bibtex-clean-entry signals mandatory fields left empty.
  186.  
  187. ;;; Marc Shapiro 18-jul-88
  188. ;;;  * Fixed bug in bibtex-flash-entry
  189. ;;;  * Moved all the entry type keystrokes to "C-c C-e something" (instead of
  190. ;;;    "C-c something" previously) to make room for more.  C-c C-e is
  191. ;;;    supposed to stand for "entry" [idea taken from mail-mode].  Moved
  192. ;;;    bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n.
  193. ;;;  * removed binding for "\e[25~"
  194. ;;;  * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to
  195. ;;;    C-c C-c
  196.  
  197. ;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG]
  198. ;;;  * bibtex-pop-previous replaces current field with value of
  199. ;;;    similar field in previous entry.  May be called n times in a row
  200. ;;;    (or with arg n) to pop similar field of n'th previous entry.
  201. ;;;    There is also a bibtex-pop-next to get similar field of next
  202. ;;;    entry.
  203. ;;;  * C-c C-k now kills all empty optional fields of current entry, and
  204. ;;;    removes "OPT" for those optional fields which have text. 
  205.  
  206. ;;; Marc Shapiro 14-dec-87
  207. ;;;   Cosmetic fixes.  Fixed small bug in bibtex-move-outside-of-entry.
  208. ;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87
  209. ;;;   before inserting an entry, make sure we are outside of a bib entry
  210. ;;; Marc Shapiro 3-nov-87
  211. ;;;   addition for France: DEAthesis
  212. ;;; Marc Shapiro 19-oct-1987
  213. ;;;   add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now
  214. ;;;   behave consistently; deletion never occurs blindly.
  215. ;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986
  216. ;;;    align long lines nicely; C-c C-o checks for the "OPT" string;
  217. ;;;    TAB goes to the end of the string; use lower case; use
  218. ;;;    run-hooks
  219.  
  220. ;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28
  221. ;;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 87-06-28
  222. ;;;   Original version
  223.  
  224. ;;; Code:
  225.  
  226. ;;; NOTE by Marc Shapiro, 14-dec-87:
  227. ;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right.
  228. ;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding,
  229. ;;; so it will remain active in all windows.  Yuck!
  230.  
  231. (provide 'bibtex)
  232.  
  233. ;;; these guys typically don't have autoloads...[alarson:19920131.1548CST]
  234. ;;; Check for fboundp first so that if user autoloads them from non standard 
  235. ;;; places, the users bindings will take precedence.
  236. (if (not (fboundp 'tex-insert-quote))
  237.     (autoload 'tex-insert-quote "tex-mode"))
  238. (if (not (fboundp 'sort-subr))
  239.     (autoload 'sort-subr "sort"))
  240.  
  241. ;;; These should be in a more generally accessible location. 
  242.  
  243. (defun string-equalp (s1 s2)
  244.   "Like string= except differences in case are ignored."
  245.   (let ((ss1 (if (symbolp s1) (symbol-name s1) s1))
  246.     (ss2 (if (symbolp s2) (symbol-name s2) s2)))
  247.     (and (= (length ss1) (length ss2))
  248.      (string-equal (upcase ss1) (upcase ss2)))))
  249.  
  250.  
  251.  
  252.  
  253. (defvar bibtex-clean-entry-zap-empty-opts t
  254.   "*If non-nil, bibtex-clean-entry will delete all empty optional fields.")
  255.  
  256. (defvar bibtex-include-OPTcrossref t
  257.   "*If non-nil, all entries will have an OPTcrossref field.")
  258. (defvar bibtex-include-OPTkey t
  259.   "*If non-nil, all entries will have an OPTkey field.")
  260. (defvar bibtex-include-OPTannote t
  261.   "*If non-nil, all entries will have an OPTannote field.")
  262.  
  263. ;; note: the user should be allowed to have their own list of always
  264. ;;       available optional fields.  exs: "keywords" "categories"
  265.  
  266. (defvar bibtex-mode-user-optional-fields nil        ;no default value
  267.   "*List of optional fields that user want to have as always present 
  268. when making a bibtex entry.  One possibility is for ``keywords''.  
  269. Entries can be either strings or conses, in which case the car should be 
  270. string and the cdr the value to be inserted.")
  271.  
  272. (defvar bibtex-mode-syntax-table
  273.   (let ((st (make-syntax-table)))
  274.     ;; [alarson:19920214.1004CST] make double quote a string quote
  275.     (modify-syntax-entry ?\" "\"" st)
  276.     (modify-syntax-entry ?$ "$$  " st)
  277.     (modify-syntax-entry ?% "<   " st)
  278.     (modify-syntax-entry ?'  "w   " st)
  279.     (modify-syntax-entry ?@  "w   " st)
  280.     (modify-syntax-entry ?\\ "\\" st)
  281.     (modify-syntax-entry ?\f ">   " st)
  282.     (modify-syntax-entry ?\n ">   " st)
  283.     (modify-syntax-entry ?~ " " st)
  284.     st))
  285.  
  286. (defvar bibtex-mode-abbrev-table nil "")
  287. (define-abbrev-table 'bibtex-mode-abbrev-table ())
  288. (defvar bibtex-mode-map
  289.   (let ((km (make-sparse-keymap)))
  290.     
  291.     (define-key km "\t" 'bibtex-find-text)
  292.     (define-key km "\n" 'bibtex-next-field)
  293.     (define-key km "\C-c\"" 'bibtex-remove-double-quotes)
  294.     (define-key km "\C-c\C-c" 'bibtex-clean-entry)
  295.     (define-key km "\C-c?" 'describe-mode)
  296.     (define-key km "\C-c\C-p" 'bibtex-pop-previous)
  297.     (define-key km "\C-c\C-n" 'bibtex-pop-next)
  298.     (define-key km "\C-c\C-k" 'bibtex-kill-optional-field)
  299.     (define-key km "\C-c\C-d" 'bibtex-empty-field)
  300.  
  301.     ;; [alarson:19920131.1543CST]
  302.     (define-key km "\""   'tex-insert-quote)
  303.     (define-key km "\C-c$"   'ispell-bibtex-entry)
  304.     (define-key km "\M-\C-a"   'beginning-of-bibtex-entry)
  305.     (define-key km "\M-\C-e"   'end-of-bibtex-entry)
  306.     (define-key km "\C-c\C-b"   'bibtex-entry)
  307. ;    (define-key km "\C-cn" 'narrow-to-bibtex-entry)
  308.  
  309.     (define-key km "\C-c\C-e\C-a" 'bibtex-Article)
  310.     (define-key km "\C-c\C-e\C-b" 'bibtex-Book)
  311. ;    (define-key km "\C-c\C-e\C-d" 'bibtex-DEAthesis)
  312.     (define-key km "\C-c\C-e\C-c" 'bibtex-InProceedings)
  313.     (define-key km "\C-c\C-e\C-i" 'bibtex-InBook)
  314.     (define-key km "\C-c\C-ei" 'bibtex-InCollection)
  315.     (define-key km "\C-c\C-eI" 'bibtex-InProceedings)
  316.     (define-key km "\C-c\C-e\C-m" 'bibtex-Manual)
  317.     (define-key km "\C-c\C-em" 'bibtex-MastersThesis)
  318.     (define-key km "\C-c\C-eM" 'bibtex-Misc)
  319.     (define-key km "\C-c\C-o" 'bibtex-remove-OPT)
  320.     (define-key km "\C-c\C-e\C-p" 'bibtex-PhdThesis)
  321.     (define-key km "\C-c\C-ep" 'bibtex-Proceedings)
  322.     (define-key km "\C-c\C-eP" 'bibtex-preamble)
  323.     (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
  324.     (define-key km "\C-c\C-e\C-s" 'bibtex-string)
  325.     (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
  326.     km))
  327.  
  328. (defvar bibtex-pop-previous-search-point nil
  329.   "Next point where bibtex-pop-previous should start looking for a similar
  330. entry.")
  331.  
  332. (defvar bibtex-pop-next-search-point nil
  333.   "Next point where bibtex-pop-next should start looking for a similar
  334. entry.")
  335.  
  336. (defvar bibtex-entry-field-alist
  337.   '(
  338.     ("Article" . ((("author" "title" "journal" "year")
  339.            ("volume" "number" "pages" "month" "note"))
  340.           (("author" "title")
  341.            ("journal" "year" "volume" "number" "pages"
  342.             "month" "note"))))
  343.     ("Book" . ((("author" "title" "publisher" "year")
  344.         ("editor" "volume" "number" "series" "address"
  345.          "edition" "month" "note"))))
  346.     ("Booklet" . ((("title")
  347.            ("author" "howpublished" "address" "month" "year" "note"))))
  348.     
  349.     ;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's)
  350. ;    ("DEAthesis" . ((("author" "title" "school" "year")
  351. ;             ("address" "month" "note"))))
  352.     
  353.     ("InBook" . ((("author" "title" "chapter" "publisher" "year")
  354.           ("editor" "pages" "volume" "number" "series" "address"
  355.            "edition" "month" "type" "note"))
  356.          (("author" "title" "chapter")
  357.           ("publisher" "year" "editor" "pages" "volume" "number"
  358.            "series" "address" "edition" "month" "type" "note"))))
  359.  
  360.  
  361.     ("InCollection" . ((("author" "title"
  362.              "booktitle" "publisher" "year")
  363.             ("editor" "volume" "number" "series" "type" "chapter"
  364.              "pages" "address" "edition" "month" "note"))
  365.                (("author" "title")
  366.             ("booktitle" "publisher" "year"
  367.              "editor" "volume" "number" "series" "type" "chapter"
  368.              "pages" "address" "edition" "month" "note"))))
  369.  
  370.  
  371.     ("InProceedings" . ((("author" "title" "booktitle" "year")
  372.              ("editor" "volume" "number" "series" "pages"
  373.               "organization" "publisher" "address" "month" "note"))
  374.             (("author" "title")
  375.              ("editor" "volume" "number" "series" "pages"
  376.               "booktitle" "year"
  377.               "organization" "publisher" "address" "month" "note"))))
  378.  
  379.  
  380.     ("Manual" . ((("title")
  381.           ("author" "organization" "address" "edition" "year"
  382.            "month" "note"))))
  383.  
  384.     ("MastersThesis" . ((("author" "title" "school" "year")
  385.              ("address" "month" "note" "type"))))
  386.  
  387.     ("Misc" . ((()
  388.         ("author" "title" "howpublished" "year" "month" "note"))))
  389.  
  390.     ("PhdThesis" . ((("author" "title" "school" "year")
  391.              ("address" "month" "type" "note"))))
  392.  
  393.     ("Proceedings" . ((("title" "year")
  394.                ("editor" "volume" "number" "series" "publisher"
  395.             "organization" "address" "month" "note"))))
  396.  
  397.     ("TechReport" . ((("author" "title" "institution" "year")
  398.               ("type" "number" "address" "month" "note"))))
  399.  
  400.     ("Unpublished" . ((("author" "title" "note")
  401.                ("year" "month"))))
  402.     )
  403.  
  404.   "List of (entry-name (required optional) (crossref-required crossref-optional))
  405. tripples.  If the third element is nil, then the first pair can be used.  Required
  406. and optional are lists of strings.  All entry creation functions use this variable
  407. to generate entries, and bibtex-entry ensures the entry type is valid.  This 
  408. variable can be used for example to make bibtex manipulate a different set of entry
  409. types, e.g. a crossreference document of organization types.")
  410.  
  411.  
  412. ;;; A bibtex file is a sequence of entries, either string definitions
  413. ;;; or reference entries.  A reference entry has a type part, a
  414. ;;; key part, and a comma-separated sequence of fields.  A string
  415. ;;; entry has a single field.  A field has a left and right part,
  416. ;;; separated by a '='.  The left part is the name, the right part is
  417. ;;; the text.  Here come the definitions allowing to create and/or parse
  418. ;;; entries and fields:
  419.  
  420. ;;; fields
  421. (defun bibtex-cfield (name text)
  422.   "Create a regexp for a bibtex field of name NAME and text TEXT"
  423.   (concat ",[ \t\n]*\\("
  424.       name
  425.       "\\)[ \t\n]*=[ \t\n]*\\("
  426.       text
  427.       "\\)"))
  428. (defconst bibtex-name-in-cfield 1
  429.   "The regexp subexpression number of the name part in bibtex-cfield.")
  430. (defconst bibtex-text-in-cfield 2
  431.   "The regexp subexpression number of the text part in bibtex-cfield.")
  432.  
  433. ;;; KAWATA Yasuro <yasuro@qqqq.maekawa.is.uec.ac.jp> reported bug that "/"
  434. ;;; was not premitted in field names.  The old value of this var was:
  435. ;;;    "[A-Za-z][---A-Za-z0-9:_+]*"
  436. ;;; According to the LaTeX manual, page 71, the legal values are letters,
  437. ;;; digits, and punctuation other than comma.  Section 2.1 defines
  438. ;;; punctuation as:
  439. ;;;     .:;,?!`'()[]-/*@
  440. ;;; and says that += can be used in normal text.  Specifically #$%&~_^\{}
  441. ;;; are called out as special chars.  Some experimentation with LaTeX
  442. ;;; indicates that # and ~ definitely don't work, but that the following
  443. ;;; citation does! \cite{a0.:;?!`'()[]-/*@_&$^+=|<>}.  I chose here to
  444. ;;; permit _ since it was previously allowed, but otherwise to only handle
  445. ;;; punc and +=
  446. ;;; Amendment:  I couldn't get a regexp with both "[]"'s and hyphen to
  447. ;;; work.  It looks like you need them both to be the first entries in a
  448. ;;; regexp pattern. [alarson:19930315.0900CST]
  449. ;;;
  450. ;;; New amendment[MB]: I have corrected the following regexp according to 
  451. ;;; emacs19 rules.  I also added ']' to the list of characters allowed in 
  452. ;;; a field name.
  453.  
  454. (defconst bibtex-field-name "[A-Za-z][]A-Za-z0-9.:;?!`'()/*@_+=-]*"
  455.   "Regexp defining the name part of a bibtex field.")
  456.  
  457. ;; bibtex-field-text must be able to handle
  458. ;;   title = "Proc. Fifteenth Annual" # STOC,
  459. ;;   month = "10~" # jan,
  460. ;;   year = "{\noopsort{1973c}}1981",
  461. ;;   month = apr # "-" # may,
  462. ;;   key = {Volume-2},
  463. ;;   note = "Volume~2 is listed under Knuth \cite{book-full}"
  464. ;; i have added a few of these, but not all! -- MON
  465.  
  466. (defconst bibtex-field-const
  467.   "[0-9A-Za-z][A-Za-z0-9:_+-]*"
  468.   "Format of a bibtex field constant.")
  469.  
  470. (defconst bibtex-field-string
  471.   (concat
  472.     "\"[^\"]*[^\\\\]\"\\|\"\"")
  473.   "Match either a string or an empty string.")
  474.  
  475. (defconst bibtex-field-string-or-const
  476.   (concat bibtex-field-const "\\|" bibtex-field-string)
  477.   "Match either bibtex-field-string or bibtex-field-const.")
  478.  
  479. (defconst bibtex-field-text
  480.   (concat
  481.     "\\(" bibtex-field-string-or-const "\\)"
  482.         "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*\\|"
  483.     "{[^{}]*[^\\\\]}")
  484.   "Regexp defining the text part of a bibtex field: either a string, or
  485. an empty string, or a constant followed by one or more # / constant pairs.
  486. Also matches simple {...} patterns.")
  487.  
  488. ;(defconst bibtex-field-text
  489. ;  "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][A-Za-z0-9:_+-]*"
  490. ;  "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.")
  491.  
  492. (defconst bibtex-field
  493.   (bibtex-cfield bibtex-field-name bibtex-field-text)
  494.   "Regexp defining the format of a bibtex field")
  495.  
  496. (defconst bibtex-name-in-field bibtex-name-in-cfield
  497.   "The regexp subexpression number of the name part in bibtex-field")
  498. (defconst bibtex-text-in-field bibtex-text-in-cfield
  499.   "The regexp subexpression number of the text part in bibtex-field")
  500.  
  501. ;;; references
  502. (defconst bibtex-reference-type
  503.   "@[A-Za-z]+"
  504.   "Regexp defining the type part of a bibtex reference entry")
  505. (defconst bibtex-reference-head
  506.   (concat "^[ \t]*\\("
  507.       bibtex-reference-type
  508.       "\\)[ \t]*[({]\\("
  509.       bibtex-field-name
  510.       "\\)")
  511.   "Regexp defining format of the header line of a bibtex reference entry")
  512. (defconst bibtex-type-in-head 1
  513.   "The regexp subexpression number of the type part in bibtex-reference-head")
  514. (defconst bibtex-key-in-head 2
  515.   "The regexp subexpression number of the key part in
  516. bibtex-reference-head")
  517.  
  518. (defconst bibtex-reference
  519.   (concat
  520.    ;; This is the unparenthesized equivalent of bibtex-reference-head:
  521.    "^[ \t]*"
  522.    bibtex-reference-type
  523.    "[ \t]*[({]\\("
  524.    bibtex-field-name
  525.    "\\)"
  526.    ;; End of unparenthesized equivalent of bibtex-reference-head
  527.    "\\([ \t\n]*" bibtex-field "\\)*"
  528.    "[ \t\n]*[})]")
  529.   "Regexp defining the format of a bibtex reference entry")
  530. (defconst bibtex-type-in-reference bibtex-type-in-head
  531.   "The regexp subexpression number of the type part in bibtex-reference")
  532. (defconst bibtex-key-in-reference bibtex-key-in-head
  533.   "The regexp subexpression number of the key part in
  534. bibtex-reference")
  535.  
  536. ;;; strings
  537. (defconst bibtex-string
  538.   (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\("
  539.       bibtex-field-name
  540.       "\\)[ \t\n]*=[ \t\n]*\\("
  541.       bibtex-field-text
  542.       "\\)[ \t\n]*[})]")
  543.   "Regexp defining the format of a bibtex string entry")
  544. (defconst bibtex-name-in-string 1
  545.   "The regexp subexpression of the name part in bibtex-string")
  546. (defconst bibtex-text-in-string 2
  547.   "The regexp subexpression of the text part in bibtex-string")
  548.  
  549. (defconst bibtex-name-alignment 2
  550.   "Alignment for the name part in BibTeX fields.
  551. Chosen on aesthetic grounds only.")
  552.  
  553. (defconst bibtex-text-alignment (length "  organization = ")
  554.   "Alignment for the text part in BibTeX fields.
  555. Equal to the space needed for the longest name part.")
  556.  
  557. (defun bibtex-current-entry-label (&optional include-cite kill)
  558.   "Return the label of the bibtex entry containing, or preceding point.
  559. Optional argument INCLUDE-CITE, if true means put a '\\cite{}' around the
  560. returned value.  Second optional argument KILL, if true, means place the
  561. returned value in the kill buffer.  Interactively; providing prefix
  562. argument makes INCLUDE-CITE true, and kill is true by default.
  563.  
  564. Rationale:
  565. The intention is that someone will write a function that can be bound to
  566. a mouse key so that people entering TeX can just mouse on the bibtex entry
  567. and have the citation key inserted at the current point (which will almost
  568. certainly be in some other buffer).  In the interim this function is 
  569. marginally useful for keyboard binding and is not bound by default.  
  570. Suggested binding is ^C-k."
  571.   (interactive (list current-prefix-arg t))
  572.   (save-excursion
  573.     (beginning-of-bibtex-entry)
  574.     (re-search-forward bibtex-reference-head (save-excursion (end-of-bibtex-entry) (point)))
  575.     (let* ((key (buffer-substring (match-beginning bibtex-key-in-head)
  576.                   (match-end bibtex-key-in-head)))
  577.        (val (if include-cite
  578.             (format "\\cite{%s}" key)
  579.             key)))
  580.       (if kill
  581.       (kill-new val))
  582.       val)))
  583.  
  584. ;;; bibtex mode:
  585.  
  586. ;;;###autoload
  587. (defun bibtex-mode () 
  588.   "Major mode for editing bibtex files.
  589.  
  590. \\{bibtex-mode-map}
  591.  
  592. A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry.
  593.  
  594. The optional fields start with the string OPT, and thus ignored by BibTeX.
  595. The OPT string may be removed from a field with \\[bibtex-remove-OPT].
  596. \\[bibtex-kill-optional-field] kills the current optional field entirely.
  597. \\[bibtex-remove-double-quotes] removes the double-quotes around the text of
  598. the current field.  \\[bibtex-empty-field] replaces the text of the current
  599. field with the default \"\".
  600.  
  601. The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes
  602. double-quotes from entirely numerical fields, (ii) removes OPT from all
  603. non-empty optional fields, (iii) removes all empty optional fields, and (iv)
  604. checks that no non-optional fields are empty.
  605.  
  606. Use \\[bibtex-find-text] to position the dot at the end of the current field.
  607. Use \\[bibtex-next-field] to move to end of the next field.
  608.  
  609. The following may be of interest as well:
  610.  
  611.   Functions:
  612.     find-bibtex-duplicates
  613.     find-bibtex-entry-location
  614.     hide-bibtex-entry-bodies
  615.     sort-bibtex-entries
  616.     validate-bibtex-buffer
  617.  
  618.   Variables:
  619.     bibtex-clean-entry-zap-empty-opts
  620.     bibtex-entry-field-alist
  621.     bibtex-include-OPTannote
  622.     bibtex-include-OPTcrossref
  623.     bibtex-include-OPTkey
  624.     bibtex-maintain-sorted-entries
  625.     bibtex-mode-user-optional-fields
  626.  
  627. Fields:
  628.     address
  629.            Publisher's address
  630.     annote
  631.            Long annotation used for annotated bibliographies (begins sentence)
  632.     author
  633.            Name(s) of author(s), in BibTeX name format
  634.     booktitle
  635.            Book title when the thing being referenced isn't the whole book.
  636.            For book entries, the title field should be used instead.
  637.     chapter
  638.            Chapter number
  639.     crossref
  640.        The database key of the entry being cross referenced.
  641.     edition
  642.            Edition of a book (e.g., \"second\")
  643.     editor
  644.            Name(s) of editor(s), in BibTeX name format.
  645.            If there is also an author field, then the editor field should be
  646.            for the book or collection that the work appears in
  647.     howpublished
  648.             How something strange has been published (begins sentence)
  649.     institution
  650.            Sponsoring institution
  651.     journal
  652.            Journal name (macros are provided for many)
  653.     key
  654.            Alphabetizing and labeling key (needed when no author or editor)
  655.     month
  656.            Month (macros are provided)
  657.     note
  658.            To help the reader find a reference (begins sentence)
  659.     number
  660.            Number of a journal or technical report
  661.     organization
  662.            Organization (sponsoring a conference)
  663.     pages
  664.            Page number or numbers (use `--' to separate a range)
  665.     publisher
  666.            Publisher name
  667.     school
  668.            School name (for theses)
  669.     series
  670.            The name of a series or set of books.
  671.            An individual book will will also have it's own title
  672.     title
  673.            The title of the thing being referenced
  674.     type
  675.            Type of a technical report (e.g., \"Research Note\") to be used
  676.            instead of the default \"Technical Report\"
  677.     volume
  678.            Volume of a journal or multivolume work
  679.     year
  680.            Year---should contain only numerals
  681. ---------------------------------------------------------
  682. Entry to this mode calls the value of bibtex-mode-hook if that value is
  683. non-nil."
  684.   (interactive)
  685.   (kill-all-local-variables)
  686.   (set-syntax-table bibtex-mode-syntax-table)
  687.   (use-local-map bibtex-mode-map)
  688.   (setq major-mode 'bibtex-mode)
  689.   (setq mode-name "BibTeX")
  690.   (set-syntax-table bibtex-mode-syntax-table)
  691.   (setq local-abbrev-table bibtex-mode-abbrev-table)
  692.   (make-local-variable 'paragraph-start)
  693.   (make-local-variable 'comment-start)
  694.   (setq comment-start "%")
  695.   (setq paragraph-start "^[ \f\n\t]*$")
  696.   (auto-fill-mode 1)            ; nice alignments
  697.   (setq left-margin (+ bibtex-text-alignment 1))
  698.  
  699.   (run-hooks 'bibtex-mode-hook))
  700.  
  701. (defun bibtex-move-outside-of-entry ()
  702.   "Make sure we are outside of a bib entry"
  703.   (cond ((or
  704.       (= (point) (point-max))
  705.       (= (point) (point-min))
  706.       (looking-at "[ \n]*@")
  707.       )
  708.      t)
  709.     (t
  710.      (backward-paragraph)
  711.      (forward-paragraph)))
  712.   (re-search-forward "[ \t\n]*" (point-max) t))
  713.  
  714. (defun ispell-abstract ()
  715.   (interactive)
  716.   (beginning-of-bibtex-entry)
  717.   (re-search-forward "^[ \t]*[OPT]*abstract[ \t]*=")
  718.   (ispell-region (point)
  719.          (save-excursion (forward-sexp) (point))))
  720.  
  721. (defun beginning-of-bibtex-entry ()
  722.   (interactive)
  723.   (re-search-backward "^@" nil 'move))
  724.  
  725. (defun skip-whitespace-and-comments ()
  726.   ;; It might be a good idea to have forward-sexp with argument 0 do what
  727.   ;; this function tries to do, namely skip whitespace and comments.
  728.   ;; Maybe a better name for this would be skip-to-next-sexp.
  729.   ;; alternative implementation:
  730.   ;;   (let ((parse-sexp-ignore-comments t))
  731.   ;;     (forward-sexp 1)
  732.   ;;     (forward-sexp -1))
  733.   ;; but I've had problems with this not getting the parse of comments
  734.   ;; right going backward if they contain unbalanced expressions or string
  735.   ;; quotes. [alarson:19920217.1021CST]
  736.   (let ((md (match-data)))
  737.     (unwind-protect
  738.     (while (cond ((looking-at "\\s>+\\|\\s +")
  739.               ;; was whitespace
  740.               ;; NOTE: also checked end-comment.  In latex and
  741.               ;; lisp modes, newline is an end comment, but it
  742.               ;; should also be a whitespace char.
  743.               (goto-char (match-end 0)))
  744.              ;; If looking at beginning of comment, skip to end.
  745.              ((looking-at "\\s<")
  746.               (re-search-forward "\\s>"))))              
  747.       (store-match-data md))))
  748.  
  749. ;;; [alarson:19920214.1007CST]
  750. (defun end-of-bibtex-entry ()
  751.   "If inside an entry, move to the end of it, otherwise move to the end
  752. of the next entry."
  753.   (interactive)
  754.   ;; if point was previously at the end of an entry, this puts us
  755.   ;; inside the next entry, otherwise we remain in the current one.
  756.   (progn
  757.     (skip-whitespace-and-comments)
  758. ;;;     (skip-chars-forward " \t\n") 
  759.     (end-of-line))
  760.   (beginning-of-bibtex-entry)
  761.   (let ((parse-sexp-ignore-comments t))
  762.     (forward-sexp) ; skip entry type
  763.     (forward-sexp) ; skip entry body
  764.     ))
  765. ;(defun end-of-bibtex-entry ()
  766. ;  (interactive)
  767. ;  (re-search-forward "}$" nil 'move))
  768.   
  769. (defun ispell-bibtex-entry ()
  770.   (interactive)
  771.   (ispell-region (progn (beginning-of-bibtex-entry) (point))
  772.          (progn (end-of-bibtex-entry) (point))))
  773.  
  774. (defun narrow-to-bibtex-entry ()
  775.   (interactive)
  776.   (save-excursion
  777.     (narrow-to-region (progn (beginning-of-bibtex-entry) (point))
  778.               (progn (end-of-bibtex-entry) (point)))))
  779.  
  780.  
  781. (defun beginning-of-first-bibtex-entry ()
  782.   (goto-char (point-min))
  783.   (cond
  784.    ((re-search-forward "^@" nil 'move)
  785.     (beginning-of-line))
  786.    ((and (bobp) (eobp))
  787.     nil)
  788.    (t
  789.     (message "Warning: No bibtex entries found!"))))
  790.  
  791. (defun hide-bibtex-entry-bodies (&optional arg)
  792.   "Hide all lines between first and last bibtex entries not beginning with @.
  793. With argument, show all text."
  794.   (interactive "P")
  795.   (save-excursion
  796.     (beginning-of-first-bibtex-entry)
  797.     ;; subst-char-in-region modifies the buffer, despite what the
  798.     ;; documentation says...
  799.     (let ((modifiedp (buffer-modified-p))
  800.       (buffer-read-only nil))
  801.       (if arg
  802.       (subst-char-in-region (point) (point-max) ?\r ?\n t)
  803.     (while (save-excursion (re-search-forward "\n[^@]" (point-max) t))
  804.       ;; (save-excursion (replace-regexp "\n\\([^@]\\)" "\r\\1"))
  805.       (save-excursion
  806.         (while (re-search-forward "\n\\([^@]\\)" nil t)
  807.           (replace-match "\r\\1" nil nil)))))
  808.       (setq selective-display (not arg))
  809.       (set-buffer-modified-p modifiedp))))
  810.  
  811. (defvar bibtex-sort-ignore-string-entries nil
  812.   "*If true, bibtex @STRING entries are ignored when determining ordering
  813. of the buffer (e.g. sorting, locating alphabetical position for new entries,
  814. etc.)")
  815.  
  816. (defun sort-bibtex-entries ()
  817.   "Sort bibtex entries alphabetically by key.
  818. Text before the first bibtex entry, and following the last is not affected.
  819. If bibtex-sort-ignore-string-entries is true, @string entries will be ignored.
  820.  
  821. Bugs:
  822.   1. Text between the closing brace ending one bibtex entry, and the @ starting 
  823.      the next, is considered part of the PRECEDING entry.  Perhaps it should be
  824.      part of the following entry."
  825.   (interactive)
  826.   (save-restriction
  827.     (beginning-of-first-bibtex-entry)
  828.     (narrow-to-region (point)
  829.               (save-excursion
  830.             (goto-char (point-max))
  831.             (beginning-of-bibtex-entry)
  832.             (end-of-bibtex-entry)
  833.             (point)))
  834.     (sort-subr nil            ; reversep
  835.            ;; beginning of record function
  836.            'forward-line
  837.            ;; end of record function
  838.            (function (lambda () (and (re-search-forward "}\\s-*\n[\n \t]*@" nil 'move)
  839.                      (forward-char -2))))
  840.            ;; start of key function
  841.            (if bibtex-sort-ignore-string-entries
  842.            (function (lambda ()
  843.                    (while (and (re-search-forward "^\\s-*\\([@a-zA-Z]*\\)\\s-*{\\s-*")
  844.                        (string-equalp "@string"
  845.                               (buffer-substring (match-beginning 1)
  846.                                         (match-end 1)))))
  847.                    nil))
  848.            (function (lambda () (re-search-forward "{\\s-*") nil)))
  849.            ;; end of key function
  850.            (function (lambda () (search-forward ",")))
  851.            )))
  852.   
  853. (defun map-bibtex-entries (fun)
  854.   "Call FUN for each bibtex entry starting with the current, to the end of the file.
  855. FUN is called with one argument, the key of the entry, and with point inside the entry.
  856. If bibtex-sort-ignore-string-entries is true, FUN will not be called for @string entries."
  857.   (beginning-of-bibtex-entry)
  858.   (while (re-search-forward "^@[^{]*{[ \t]*\\([^, ]*\\)" nil t)
  859.     (if (and bibtex-sort-ignore-string-entries
  860.          (string-equalp "@string{"
  861.                 (buffer-substring (match-beginning 0)
  862.                           (match-beginning 1))))
  863.     nil ; ignore the @string entry.
  864.       (funcall fun (buffer-substring (match-beginning 1) (match-end 1))))))
  865.   
  866. (defun find-bibtex-entry-location (entry-name)
  867.   "Searches from beginning of current buffer looking for place to put the
  868. bibtex entry named ENTRY-NAME.  Buffer is assumed to be in sorted order,
  869. without duplicates (see \\[sort-bibtex-entries]), if it is not, an error will
  870. be signalled."
  871.   (interactive "sBibtex entry key: ")
  872.   (let ((previous nil)
  873.     point)
  874.     (beginning-of-first-bibtex-entry)
  875.     (or (catch 'done
  876.       (map-bibtex-entries (function (lambda (current)
  877.                  (cond
  878.                   ((string-equal entry-name current)
  879.                    (error "Entry duplicates existing!"))
  880.                   ((or (null previous)
  881.                        (string< previous current))
  882.                    (setq previous current
  883.                      point (point))
  884.                    (if (string< entry-name current)
  885.                        (progn
  886.                      (beginning-of-bibtex-entry)
  887.                      ;; Many schemes append strings to
  888.                      ;; existing entries to resolve them,
  889.                      ;; so initial substring matches may
  890.                      ;; indicate a duplicate entry.  
  891.                      (let ((idx (string-match (regexp-quote entry-name) current)))
  892.                        (if (and (integerp idx)
  893.                             (zerop idx))
  894.                            (progn
  895.                          (message "Warning: Entry %s may be a duplicate of %s!"
  896.                               entry-name current)
  897.                          (ding t))))
  898.                      (throw 'done t))))
  899.                   ((string-equal previous current)
  900.                    (error "Duplicate here with previous!"))
  901.                   (t (error "Entries out of order here!")))))))
  902.     (end-of-bibtex-entry))))
  903.  
  904. (defun validate-bibtex-buffer ()
  905.   "Find some typical errors in bibtex files.
  906.   1. At signs (@) not as first char of a line.
  907.   2. Double quotes (\") inside strings.
  908.   3. Closing braces (}) not the last character of a line."
  909.   (interactive)
  910.   (let ((point (point)))
  911.     (while (re-search-forward ".@" nil t)
  912.       (let* ((foo (parse-partial-sexp (save-excursion (beginning-of-bibtex-entry)
  913.                               (point))
  914.                       (point)))
  915.          (in-a-string (nth 3 foo)))
  916.     (if (not in-a-string)
  917.         (error "At sign (@) out of place!"))))
  918.     (goto-char point)
  919.     (while (search-forward "\"" nil t)
  920.       (or (looking-at "[,}][ \t]*$")
  921.       (char-equal (preceding-char) ?\")
  922.       ;; some versions put closing brace on separate line.
  923.       (looking-at "[ \t]*\n}")
  924.       (save-excursion
  925.         (save-restriction
  926.           (narrow-to-region (point)
  927.                 (progn (beginning-of-line) (point)))
  928.           (looking-at "^[ \t]*[a-zA-Z]+[ \t]*=[ \t]*\"$")))
  929.       (error "Quote out of place, or missing \",\" or \"}\"!")))
  930.     (goto-char point)
  931.     ;; This is only approximate, should actually search for close braces,
  932.     ;; then see if they are inside a string, or at the end of a line.
  933.     ;; This just gets the typical case of whitespace after a closing brace.
  934.     (while (search-forward "}[ \t]+$" nil t)
  935.       (error "Brace not last char of line!"))
  936.     (goto-char point)
  937.     (message "Bibtex buffer appears o.k.")))
  938.  
  939. (defun find-bibtex-duplicates ()
  940.   "Searches forward in current buffer looking for duplicate bibtex entries.
  941. Buffer is assumed to be sorted, see \\[sort-bibtex-entries]"
  942.   (interactive)
  943.   (let ((point (point)))
  944.     ;; errors if things are not right...
  945.     (find-bibtex-entry-location (make-string 10 255))
  946.     (goto-char point)
  947.     (message "No duplicates found!")))
  948.  
  949.  
  950. ;;; assoc doesn't ignore case, so we need an assoc that does...
  951. (defun assoc-string-equalp (thing alist)
  952.   (or (assoc thing alist)
  953.       (while (and alist
  954.           (not (string-equalp thing (car (car alist)))))
  955.     (setq alist (cdr alist)))
  956.       (car alist)))
  957.  
  958. (defvar bibtex-maintain-sorted-entries nil
  959.   "*If true, bibtex-mode will attempt to maintain all bibtex entries in 
  960. sorted order.  
  961.  
  962. Note that this is more a property of a file than a personal preference and
  963. as such should normally be set via a file local variable entry.")
  964.  
  965. (defun bibtex-entry (entry-type &optional required optional)
  966.   (interactive (let* ((completion-ignore-case t)
  967.               (e-t (completing-read "Entry Type: " bibtex-entry-field-alist
  968.                         nil t)))
  969.          (list e-t)))
  970.   (if (and (null required) (null optional))
  971.       (let* ((e (assoc-string-equalp entry-type bibtex-entry-field-alist))
  972.          (r-n-o (elt e 1))
  973.          (c-ref (elt e 2)))
  974.     (if (null e)
  975.       (error "Bibtex entry type %s not defined!"))
  976.     (if (and bibtex-include-OPTcrossref c-ref)
  977.         (setq required (elt c-ref 0)
  978.           optional (elt c-ref 1))
  979.       (setq required (elt r-n-o 0)
  980.         optional (elt r-n-o 1)))))
  981.   (let ((key (if bibtex-maintain-sorted-entries
  982.          (read-string (format "%s key: " entry-type)))))
  983.     (if key
  984.     (find-bibtex-entry-location key))    
  985.     (bibtex-move-outside-of-entry)
  986.     (insert "@" entry-type "{")
  987.     (if key
  988.     (insert key))
  989.     (save-excursion
  990.       (mapcar 'bibtex-make-field required)
  991.       (if bibtex-include-OPTcrossref
  992.       (bibtex-make-optional-field "crossref"))
  993.       (if bibtex-include-OPTkey
  994.       (bibtex-make-optional-field "key"))
  995.       (mapcar 'bibtex-make-optional-field optional)
  996.       (mapcar 'bibtex-make-optional-field 
  997.           bibtex-mode-user-optional-fields)
  998.       (if bibtex-include-OPTannote
  999.       (bibtex-make-optional-field "annote"))
  1000.       (insert "\n}\n\n"))
  1001.     (if key
  1002.     (bibtex-next-field t))
  1003.     (run-hooks 'bibtex-add-entry-hook)))
  1004.  
  1005. ;; (defun bibtex-entry (entry-type required optional)
  1006. ;;   (bibtex-move-outside-of-entry)
  1007. ;;   (insert (concat "@" entry-type "{,\n\n}\n\n"))
  1008. ;;   (previous-line 3)
  1009. ;;   (insert (mapconcat 'bibtex-make-entry required ",\n"))
  1010. ;;   (if required
  1011. ;;       (if optional
  1012. ;;       (insert ",\n")))
  1013. ;;   (insert (mapconcat 'bibtex-make-OPT-entry optional ",\n"))
  1014. ;;   (if bibtex-mode-user-optional-fields        ;MON...
  1015. ;;       (progn
  1016. ;;     (if optional
  1017. ;;         (insert ",\n"))
  1018. ;;     (insert (mapconcat 'bibtex-make-OPT-entry
  1019. ;;                bibtex-mode-user-optional-fields
  1020. ;;                ",\n"))))        ;MON
  1021. ;;  (up-list -1)
  1022. ;;  (forward-char 1))
  1023.  
  1024.  
  1025. (defun bibtex-make-field (e-t)
  1026.   (interactive "sBibTeX entry type: ")
  1027.   (let ((name  (if (consp e-t) (car e-t) e-t))
  1028.     (value (if (consp e-t) (cdr e-t) "")))
  1029.     (insert ",\n")
  1030.     (indent-to-column bibtex-name-alignment)
  1031.     (insert name " = ")
  1032.     (indent-to-column bibtex-text-alignment)
  1033.     ;; lucid emacs prin1-to-string breaks the undo chain.  When they fix
  1034.     ;; that, the  hack can be removed. [alarson:19930316.0805CST]
  1035. ;    (insert (prin1-to-string value))
  1036.     ;; begin hack
  1037.     (insert (format (if (stringp value) "\"%s\"" "%s")
  1038.             value))
  1039.     ;; end hack
  1040.     nil))
  1041.  
  1042. (defun bibtex-make-optional-field (e-t)
  1043.   (interactive "sOptional BibTeX entry type: ")
  1044.   (if (consp e-t)
  1045.       (setq e-t (cons (concat "OPT" (car e-t)) (cdr e-t)))
  1046.     (setq e-t (concat "OPT" e-t)))
  1047.   (bibtex-make-field e-t))
  1048.  
  1049. ;; What to do about crossref?  if present, journal and year are 
  1050. ;; both optional.  Due to this, i move all of them into optional. -- MON
  1051.  
  1052. (defun bibtex-Article ()
  1053.   (interactive)
  1054.   (bibtex-entry "Article"))
  1055.  
  1056. (defun bibtex-Book ()
  1057.   (interactive)
  1058.   (bibtex-entry "Book"))
  1059.  
  1060. (defun bibtex-Booklet ()
  1061.   (interactive)
  1062.   (bibtex-entry "Booklet"))
  1063.  
  1064. ;(defun bibtex-DEAthesis ()
  1065. ;  (interactive)
  1066. ;  (bibtex-entry "DEAthesis"))
  1067.  
  1068. (defun bibtex-InBook ()
  1069.   (interactive)
  1070.   (bibtex-entry "InBook"))
  1071.  
  1072. (defun bibtex-InCollection ()
  1073.   (interactive)
  1074.   (bibtex-entry "InCollection"))
  1075.  
  1076. (defun bibtex-InProceedings ()
  1077.   (interactive)
  1078.   (bibtex-entry "InProceedings"))
  1079.  
  1080. (defun bibtex-Manual ()
  1081.   (interactive)
  1082.   (bibtex-entry "Manual"))
  1083.  
  1084. (defun bibtex-MastersThesis ()
  1085.   (interactive)
  1086.   (bibtex-entry "MastersThesis"))
  1087.  
  1088. (defun bibtex-Misc ()
  1089.   (interactive)
  1090.   (bibtex-entry "Misc"))
  1091.  
  1092. (defun bibtex-PhdThesis ()
  1093.   (interactive)
  1094.   (bibtex-entry "PhdThesis"))
  1095.  
  1096. (defun bibtex-Proceedings ()
  1097.   (interactive)
  1098.   (bibtex-entry "Proceedings"))
  1099.  
  1100. (defun bibtex-TechReport ()
  1101.   (interactive)
  1102.   (bibtex-entry "TechReport"))
  1103.  
  1104. (defun bibtex-Unpublished ()
  1105.   (interactive)
  1106.   (bibtex-entry "Unpublished"))
  1107.  
  1108. (defun bibtex-string ()
  1109.   (interactive)
  1110.   (bibtex-move-outside-of-entry)
  1111.   (insert "@string{ = \"\"}\n")
  1112.   (previous-line 1)
  1113.   (forward-char 8))
  1114.  
  1115. (defun bibtex-preamble ()
  1116.   (interactive)
  1117.   (bibtex-move-outside-of-entry)
  1118.   (insert "@Preamble{}\n")
  1119.   (previous-line 1)
  1120.   (forward-char 10))
  1121.  
  1122. (defun bibtex-next-field (arg)
  1123.   "Finds end of text of next BibTeX field; with arg, to its beginning"
  1124.   (interactive "P")
  1125.   (bibtex-inside-field)
  1126.   (let ((start (point)))
  1127.     (condition-case ()
  1128.     (progn
  1129.       (bibtex-enclosing-field)
  1130.       (goto-char (match-end 0))
  1131.       (forward-char 2))
  1132.       (error
  1133.        (goto-char start)
  1134.        (end-of-line)
  1135.        (forward-char 1))))
  1136.   (bibtex-find-text arg))
  1137.  
  1138. ;; (defun bibtex-next-field ()
  1139. ;;   "Finds end of text of next field."
  1140. ;;   (interactive)
  1141. ;;   (condition-case ()
  1142. ;;       (progn
  1143. ;;     (bibtex-inside-field)
  1144. ;;     (re-search-forward ",[ \t\n]*" (point-max) 1)
  1145. ;;     (bibtex-enclosing-field)
  1146. ;;     (bibtex-inside-field))
  1147. ;;     (error nil)))
  1148.  
  1149. (defun bibtex-find-text (arg)
  1150.   "Go to end of text of current field; with arg, go to beginning."
  1151.   (interactive "P")
  1152.   (bibtex-inside-field)
  1153.   (bibtex-enclosing-field)
  1154.   (if arg
  1155.       (progn
  1156.     (goto-char (match-beginning bibtex-text-in-field))
  1157.     (if (looking-at "\"")
  1158.         (forward-char 1)))
  1159.     (goto-char (match-end bibtex-text-in-field))
  1160.     (if (= (preceding-char) ?\")
  1161.     (forward-char -1))))
  1162.  
  1163. ;; (defun bibtex-find-text ()
  1164. ;;   "Go to end of text of current field."
  1165. ;;   (interactive)
  1166. ;;   (condition-case ()
  1167. ;;       (progn
  1168. ;;     (bibtex-inside-field)
  1169. ;;     (bibtex-enclosing-field)
  1170. ;;     (goto-char (match-end bibtex-text-in-field))
  1171. ;;     (bibtex-inside-field))
  1172. ;;     (error nil)))
  1173.  
  1174. (defun bibtex-remove-OPT ()
  1175.   "Removes the 'OPT' starting optional arguments and goes to end of text"
  1176.   (interactive)
  1177.   (bibtex-inside-field)
  1178.   (bibtex-enclosing-field)
  1179.   (save-excursion
  1180.     (goto-char (match-beginning bibtex-name-in-field))
  1181.     (if (looking-at "OPT")
  1182.     ;; sct@dcs.edinburgh.ac.uk
  1183.      (progn
  1184.        (delete-char (length "OPT"))
  1185.        (search-forward "=")
  1186.        (delete-horizontal-space)
  1187.        (indent-to-column bibtex-text-alignment))))
  1188.   (bibtex-inside-field))
  1189.  
  1190. (defun bibtex-inside-field ()
  1191.   "Try to avoid point being at end of a bibtex field."
  1192.   (interactive)
  1193.   (end-of-line)
  1194.   (skip-chars-backward " \t")        ;MON - maybe delete these chars?
  1195.   (cond ((= (preceding-char) ?,)
  1196.      (forward-char -2))) ; -1 --> -2 sct@dcs.edinburgh.ac.uk
  1197.   (cond ((= (preceding-char) ?\")
  1198.      (forward-char -1))))        ;MON - only go back if quote
  1199.  
  1200. (defun bibtex-remove-double-quotes ()
  1201.   "Removes \"\" around string."
  1202.   (interactive)
  1203.   (save-excursion
  1204.     (bibtex-inside-field)
  1205.     (bibtex-enclosing-field)
  1206.     (let ((start (match-beginning bibtex-text-in-field))
  1207.       (stop (match-end  bibtex-text-in-field)))
  1208.       (goto-char stop)
  1209.       (forward-char -1)
  1210.       (if (looking-at "\"")
  1211.       (delete-char 1))
  1212.       (goto-char start)
  1213.       (if (looking-at "\"")
  1214.       (delete-char 1)))))
  1215.  
  1216. (defun bibtex-kill-optional-field ()
  1217.   "Kill the entire enclosing optional BibTeX field"
  1218.   (interactive)
  1219.   (bibtex-inside-field)
  1220.   (bibtex-enclosing-field)
  1221.   (goto-char (match-beginning bibtex-name-in-field))
  1222.   (let ((the-end (match-end 0))
  1223.     (the-beginning (match-beginning 0)))
  1224.     (if (looking-at "OPT")
  1225.     (progn
  1226.       (goto-char the-end)
  1227.       (skip-chars-forward " \t\n,")
  1228.       (kill-region the-beginning the-end))
  1229.       (error "Mandatory fields can't be killed"))))
  1230.  
  1231. (defun bibtex-empty-field ()
  1232.   "Delete the text part of the current field, replace with empty text"
  1233.   (interactive)
  1234.   (bibtex-inside-field)
  1235.   (bibtex-enclosing-field)
  1236.   (goto-char (match-beginning bibtex-text-in-field))
  1237.   (kill-region (point) (match-end bibtex-text-in-field))
  1238.   (insert "\"\"")
  1239.   (bibtex-find-text t))
  1240.  
  1241.  
  1242. (defun bibtex-pop-previous (arg)
  1243.   "Replace text of current field with the text of similar field in previous entry.
  1244. With arg, go up ARG entries.  Repeated, goes up so many times.  May be
  1245. intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
  1246.   (interactive "p")
  1247.   (bibtex-inside-field)
  1248.   (save-excursion
  1249.     ; parse current field
  1250.     (bibtex-enclosing-field)
  1251.     (let ((start-old-text (match-beginning bibtex-text-in-field))
  1252.       (stop-old-text  (match-end bibtex-text-in-field))
  1253.       (start-name (match-beginning bibtex-name-in-field))
  1254.       (stop-name (match-end bibtex-name-in-field))
  1255.       (new-text))
  1256.       (goto-char start-name)
  1257.       ; construct regexp for previous field with same name as this one
  1258.       (let ((matching-entry
  1259.          (bibtex-cfield
  1260.           (buffer-substring (if (looking-at "OPT")
  1261.                     (+ (point) (length "OPT"))
  1262.                   (point))
  1263.                 stop-name)
  1264.           bibtex-field-text)))
  1265.     
  1266.     ; if executed several times in a row, start each search where the
  1267.     ; last one finished
  1268.     (cond ((or (eq last-command 'bibtex-pop-previous)
  1269.            (eq last-command 'bibtex-pop-next))
  1270.            t
  1271.            )
  1272.           (t
  1273.            (bibtex-enclosing-reference)
  1274.            (setq bibtex-pop-previous-search-point (match-beginning 0))
  1275.            (setq bibtex-pop-next-search-point (match-end 0))))
  1276.     (goto-char bibtex-pop-previous-search-point)
  1277.     
  1278.     ; Now search for arg'th previous similar field
  1279.     (cond
  1280.      ((re-search-backward matching-entry (point-min) t arg)
  1281.       (setq new-text
  1282.         (buffer-substring (match-beginning bibtex-text-in-cfield)
  1283.                   (match-end bibtex-text-in-cfield)))
  1284.       ; Found a matching field. Remember boundaries.
  1285.       (setq bibtex-pop-next-search-point (match-end 0))
  1286.       (setq bibtex-pop-previous-search-point (match-beginning 0))
  1287.       (bibtex-flash-head)
  1288.       ; Go back to where we started, delete old text, and pop new.
  1289.       (goto-char stop-old-text)
  1290.       (delete-region start-old-text stop-old-text)
  1291.       (insert new-text))
  1292.      (t                ; search failed
  1293.       (error "No previous matching BibTeX field."))))))
  1294.   (setq this-command 'bibtex-pop-previous))
  1295.  
  1296. (defun bibtex-pop-next (arg)
  1297.   "Replace text of current field with the text of similar field in next entry.
  1298. With arg, go up ARG entries.  Repeated, goes up so many times.  May be
  1299. intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
  1300.   (interactive "p")
  1301.   (bibtex-inside-field)
  1302.   (save-excursion
  1303.     ; parse current field
  1304.     (bibtex-enclosing-field)
  1305.     (let ((start-old-text (match-beginning bibtex-text-in-field))
  1306.       (stop-old-text  (match-end bibtex-text-in-field))
  1307.       (start-name (match-beginning bibtex-name-in-field))
  1308.       (stop-name (match-end bibtex-name-in-field))
  1309.       (new-text))
  1310.       (goto-char start-name)
  1311.       ; construct regexp for next field with same name as this one,
  1312.       ; ignoring possible OPT's
  1313.       (let ((matching-entry
  1314.          (bibtex-cfield
  1315.           (buffer-substring (if (looking-at "OPT")
  1316.                     (+ (point) (length "OPT"))
  1317.                   (point))
  1318.                 stop-name)
  1319.           bibtex-field-text)))
  1320.     
  1321.     ; if executed several times in a row, start each search where the
  1322.     ; last one finished
  1323.     (cond ((or (eq last-command 'bibtex-pop-next)
  1324.            (eq last-command 'bibtex-pop-previous))
  1325.            t
  1326.            )
  1327.           (t
  1328.            (bibtex-enclosing-reference)
  1329.            (setq bibtex-pop-previous-search-point (match-beginning 0))
  1330.            (setq bibtex-pop-next-search-point (match-end 0))))
  1331.     (goto-char bibtex-pop-next-search-point)
  1332.     
  1333.     ; Now search for arg'th next similar field
  1334.     (cond
  1335.      ((re-search-forward matching-entry (point-max) t arg)
  1336.       (setq new-text
  1337.         (buffer-substring (match-beginning bibtex-text-in-cfield)
  1338.                   (match-end bibtex-text-in-cfield)))
  1339.       ; Found a matching field. Remember boundaries.
  1340.       (setq bibtex-pop-next-search-point (match-end 0))
  1341.       (setq bibtex-pop-previous-search-point (match-beginning 0))
  1342.       (bibtex-flash-head)
  1343.       ; Go back to where we started, delete old text, and pop new.
  1344.       (goto-char stop-old-text)
  1345.       (delete-region start-old-text stop-old-text)
  1346.       (insert new-text))
  1347.      (t                ; search failed
  1348.       (error "No next matching BibTeX field."))))))
  1349.   (setq this-command 'bibtex-pop-next))
  1350.  
  1351. (defun bibtex-flash-head ()
  1352.   "Flash at BibTeX reference head before point, if exists.  (Moves point)."
  1353.   (let ((flash))
  1354.     (cond ((re-search-backward bibtex-reference-head (point-min) t)
  1355.        (goto-char (match-beginning bibtex-type-in-head))
  1356.        (setq flash (match-end bibtex-key-in-reference)))
  1357.       (t
  1358.        (end-of-line)
  1359.        (skip-chars-backward " \t")
  1360.        (setq flash (point))
  1361.        (beginning-of-line)
  1362.        (skip-chars-forward " \t")))
  1363.     (if (pos-visible-in-window-p (point))
  1364.     (sit-for 1)
  1365.       (message "From: %s"
  1366.            (buffer-substring (point) flash)))))
  1367.  
  1368.  
  1369.  
  1370. (defun bibtex-enclosing-field ()
  1371.   "Search for BibTeX field enclosing point.
  1372. Point moves to end of field; also, use match-beginning and match-end
  1373. to parse the field."
  1374.   ;; sct@dcs.edinburgh.ac.uk
  1375.   (let ((old-point (point)))
  1376.     (condition-case errname
  1377.      (bibtex-enclosing-regexp bibtex-field)
  1378.       (search-failed
  1379.        (goto-char old-point)
  1380.        (error "Can't find enclosing BibTeX field.")))))
  1381.  
  1382. (defun bibtex-enclosing-reference ()
  1383.   "Search for BibTeX reference enclosing point.
  1384. Point moves to end of reference; also, use match-beginning and match-end
  1385. to parse the reference."
  1386.   ;; sct@dcs.edinburgh.ac.uk
  1387.   (let ((old-point (point)))
  1388.     (condition-case errname
  1389.      (bibtex-enclosing-regexp bibtex-reference)
  1390.       (search-failed
  1391.        (goto-char old-point)
  1392.        (error "Can't find enclosing BibTeX reference.")))))
  1393.  
  1394. (defun bibtex-enclosing-regexp (regexp)
  1395.   "Search for REGEXP enclosing point.
  1396. Point moves to end of REGEXP.  See also match-beginning and match-end.
  1397. If an enclosing REGEXP is not found, signals search-failed; point is left in
  1398. an undefined location.
  1399.  
  1400. [Doesn't something like this exist already?]"
  1401.   
  1402.   (interactive "sRegexp: ")
  1403.   ; compute reasonable limits for the loop
  1404.   (let* ((initial (point))
  1405.      (right (if (re-search-forward regexp (point-max) t)
  1406.             (match-end 0)
  1407.           (point-max)))
  1408.      (left
  1409.       (progn
  1410.         (goto-char initial)
  1411.         (if (re-search-backward regexp (point-min) t)
  1412.         (match-beginning 0)
  1413.           (point-min)))))
  1414.     ; within the prescribed limits, loop until a match is found
  1415.     (goto-char left)
  1416.     (re-search-forward regexp right nil 1)
  1417.     (if (> (match-beginning 0) initial)
  1418.     (signal 'search-failed (list regexp)))      
  1419.     (while (<= (match-end 0) initial)
  1420.       (re-search-forward regexp right nil 1)
  1421.       (if (> (match-beginning 0) initial)
  1422.       (signal 'search-failed (list regexp))))
  1423.     ))
  1424.  
  1425. (defun bibtex-clean-entry ()
  1426.   "For all optional fields of current BibTeX entry: if empty, kill the whole field; otherwise, remove the \"OPT\" string in the name; if text numerical, remove double-quotes.  For all mandatory fields: if empty, signal error."
  1427.   (interactive)
  1428.   (beginning-of-bibtex-entry)
  1429.   (let ((start (point)))
  1430.     (save-restriction
  1431.       (narrow-to-region start (save-excursion (end-of-bibtex-entry) (point)))
  1432.       (while (re-search-forward bibtex-field (point-max) t 1)
  1433.     (let ((begin-field (match-beginning 0))
  1434.           (end-field (match-end 0))
  1435.           (begin-name (match-beginning bibtex-name-in-field))
  1436.           (end-name (match-end  bibtex-name-in-field))
  1437.           (begin-text (match-beginning bibtex-text-in-field))
  1438.           (end-text (match-end bibtex-text-in-field))
  1439.           )
  1440.       (goto-char begin-name)
  1441.       (cond ((and
  1442.           (looking-at "OPT")
  1443.           bibtex-clean-entry-zap-empty-opts)
  1444.          (goto-char begin-text)
  1445.          (if (looking-at "\"\"") ; empty: delete whole field
  1446.              (delete-region begin-field end-field)
  1447.            ; otherwise: not empty, delete "OPT"
  1448.            (goto-char begin-name)
  1449.            (delete-char (length "OPT"))
  1450.            (progn
  1451.              ;; fixup alignment. [alarson:19920309.2047CST]
  1452.              (search-forward "=")
  1453.              (delete-horizontal-space)
  1454.              (indent-to-column bibtex-text-alignment))
  1455.            (goto-char begin-field) ; and loop to go through next test
  1456.            ))
  1457.         (t
  1458.          (goto-char begin-text)
  1459.          (cond ((looking-at "\"[0-9]+\"") ; if numerical,
  1460.             (goto-char end-text)
  1461.             (delete-char -1) ; delete enclosing double-quotes
  1462.             (goto-char begin-text)
  1463.             (delete-char 1)
  1464.             (goto-char end-field) ; go to end for next search
  1465.             (forward-char -2) ; to compensate for the 2 quotes deleted
  1466.             )
  1467.                ((looking-at "\"\"") ; if empty quotes, complain
  1468.             (forward-char 1)
  1469.             (if (not (or (equal (buffer-substring
  1470.                          begin-name
  1471.                          (+ begin-name 3))
  1472.                         "OPT")
  1473.                      (equal (buffer-substring
  1474.                          begin-name
  1475.                          (+ begin-name 3))
  1476.                         "opt")))
  1477.                 (error "Mandatory field ``%s'' is empty"
  1478.                    (buffer-substring begin-name end-name))))
  1479.                (t
  1480.             (goto-char end-field))))))))
  1481.     (goto-char start)
  1482.     (end-of-bibtex-entry)
  1483.     ;; sct@dcs.edinburgh.ac.uk
  1484.     (save-excursion
  1485.       (backward-char 1)
  1486.       (skip-syntax-backward " >")
  1487.       (if (eq (preceding-char) ?,)
  1488.        (backward-delete-char 1)))
  1489.     (skip-whitespace-and-comments)))
  1490.  
  1491.  
  1492. ;;; Menus for bibtex mode
  1493.  
  1494. (define-key bibtex-mode-map [menu-bar entry-types]
  1495.   (cons "Entry Types" (make-sparse-keymap "Entry Types")))
  1496.  
  1497. (define-key bibtex-mode-map [menu-bar entry-types bibtex-InProceedings]
  1498.   '(" article in conference Proceedings " . bibtex-InProceedings))
  1499. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Article]
  1500.   '("        Article in journal         " . bibtex-Article))
  1501. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Book]
  1502.   '("               Book                " . bibtex-Book))
  1503. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Booklet]
  1504.   '("             Booklet               " . bibtex-Booklet))
  1505. (define-key bibtex-mode-map [menu-bar entry-types bibtex-InProceedings]
  1506.   '("            Conference             " . bibtex-InProceedings))
  1507. (define-key bibtex-mode-map [menu-bar entry-types bibtex-MastersThesis]
  1508.   '("         Master's Thesis           " . bibtex-MastersThesis))
  1509. ;define-key bibtex-mode-map [menu-bar entry-types bibtex-DEAthesis]
  1510. ;'(("            DEA Thesis             " . bibtex-DEAthesis))
  1511. (define-key bibtex-mode-map [menu-bar entry-types bibtex-PhdThesis]
  1512.   '("            Phd. Thesis            " . bibtex-PhdThesis))
  1513. (define-key bibtex-mode-map [menu-bar entry-types bibtex-TechReport]
  1514.   '("         Technical Report          " . bibtex-TechReport))
  1515. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Manual]
  1516.   '("         technical Manual          " . bibtex-Manual))
  1517. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Proceedings]
  1518.   '("      conference Proceedings       " . bibtex-Proceedings))
  1519. (define-key bibtex-mode-map [menu-bar entry-types bibtex-InBook]
  1520.   '("        a chapter in a Book        " . bibtex-InBook))
  1521. (define-key bibtex-mode-map [menu-bar entry-types bibtex-InCollection]
  1522.   '("    an article in a Collection     " . bibtex-InCollection))
  1523. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Misc]
  1524.   '("           miscellaneous           " . bibtex-Misc))
  1525. (define-key bibtex-mode-map [menu-bar entry-types bibtex-Unpublished]
  1526.   '("            unpublished            " . bibtex-Unpublished))
  1527. (define-key bibtex-mode-map [menu-bar entry-types bibtex-string]
  1528.   '("              string               " . bibtex-string))
  1529. (define-key bibtex-mode-map [menu-bar entry-types bibtex-preamble]
  1530.   '("             preamble              " . bibtex-preamble))
  1531.  
  1532. (define-key bibtex-mode-map [menu-bar move/edit]
  1533.   (cons "Bibtex Edit" (make-sparse-keymap "Bibtex Edit")))
  1534.  
  1535. (define-key bibtex-mode-map [menu-bar move/edit bibtex-next-field]
  1536.   '("            next field             " . bibtex-next-field))
  1537. (define-key bibtex-mode-map [menu-bar move/edit bibtex-find-text]
  1538.   '("          to end of field          " . bibtex-find-text))
  1539. (define-key bibtex-mode-map [menu-bar move/edit bibtex-pop-previous]
  1540.   '("snatch from similar preceding field" . bibtex-pop-previous))
  1541. (define-key bibtex-mode-map [menu-bar move/edit bibtex-pop-next]
  1542.   '("snatch from similar following field" . bibtex-pop-next))
  1543. (define-key bibtex-mode-map [menu-bar move/edit bibtex-remove-OPT]
  1544.   '("            remove OPT             " . bibtex-remove-OPT))
  1545. (define-key bibtex-mode-map [menu-bar move/edit bibtex-remove-double-quotes]
  1546.   '("           remove quotes           " . bibtex-remove-double-quotes))
  1547. (define-key bibtex-mode-map [menu-bar move/edit bibtex-clean-entry]
  1548.   '("          clean up entry           " . bibtex-clean-entry))
  1549. (define-key bibtex-mode-map [menu-bar move/edit find-bibtex-duplicates]
  1550.   '("          find duplicates          " . find-bibtex-duplicates))
  1551. (define-key bibtex-mode-map [menu-bar move/edit sort-bibtex-entries]
  1552.   '("           sort entries            " . sort-bibtex-entries))
  1553. (define-key bibtex-mode-map [menu-bar move/edit validate-bibtex-buffer]
  1554.   '("         validate entries          " . validate-bibtex-buffer))
  1555.  
  1556.  
  1557. ;; Please don't send anything to bug-gnu-emacs about these Sunwindows functions
  1558. ;; since we aren't interested.  See etc/SUN-SUPPORT for the reasons why
  1559. ;; we consider this nothing but a distraction from our work.
  1560.  
  1561. ;(defmacro eval-in-menu-window (&rest l)
  1562. ;  "Evaluates its argument in the window in which the mouse button was pressed."
  1563. ;  (list 'eval-in-window '*menu-window* l))
  1564.  
  1565. ;(defmenu bibtex-sun-entry-menu 
  1566. ;  ("Article In Conf. Proc." eval-in-menu-window bibtex-InProceedings)
  1567. ;  ("Article In Journal" eval-in-menu-window bibtex-Article)
  1568. ;  ("Book" eval-in-menu-window bibtex-Book)
  1569. ;  ("Booklet" eval-in-menu-window bibtex-Booklet)
  1570. ;  ("Master's Thesis" eval-in-menu-window bibtex-MastersThesis)
  1571. ;  ("PhD. Thesis" eval-in-menu-window bibtex-PhdThesis)
  1572. ;  ("Technical Report" eval-in-menu-window bibtex-TechReport)
  1573. ;  ("Technical Manual" eval-in-menu-window bibtex-Manual)
  1574. ;  ("Conference Proceedings" eval-in-menu-window bibtex-Proceedings)
  1575. ;  ("In A Book" eval-in-menu-window bibtex-InBook)
  1576. ;  ("In A Collection" eval-in-menu-window bibtex-InCollection)
  1577. ;  ("Miscellaneous" eval-in-menu-window bibtex-Misc)
  1578. ;  ("Unpublished" eval-in-menu-window bibtex-Unpublished)
  1579. ;  ("string" eval-in-menu-window bibtex-string)
  1580. ;  ("preamble" eval-in-menu-window bibtex-preamble))
  1581. ;
  1582. ;(defmenu bibtex-sun-menu
  1583. ;  ("BibTeX menu")
  1584. ;  ("add entry" . bibtex-sun-entry-menu)
  1585. ;  ("next field" eval-in-menu-window bibtex-next-field nil)
  1586. ;  ("to end of field" eval-in-menu-window bibtex-find-text nil)
  1587. ;  ("snatch similar preceding field" eval-in-menu-window bibtex-pop-previous 1)
  1588. ;  ("snatch similar following field" eval-in-menu-window bibtex-pop-next 1)
  1589. ;  ("remove OPT" eval-in-menu-window bibtex-remove-OPT)
  1590. ;  ("remove quotes" eval-in-menu-window bibtex-remove-double-quotes)
  1591. ;  ("clean entry" eval-in-menu-window bibtex-clean-entry)
  1592. ;  ("describe BibTeX mode" eval-in-menu-window describe-mode)
  1593. ;  ("Main Emacs menu" . emacs-menu))
  1594.  
  1595. ;(defun bibtex-sun-menu-eval (window x y)
  1596. ;  "Pop-up menu of BibTeX commands."
  1597. ;  (sun-menu-evaluate window (1+ x) (1- y) 'bibtex-sun-menu))
  1598. ;
  1599. ;(defun bibtex-sun-environment ()
  1600. ;  "Set up sun menus for BibTeX mode.  Call it as bibtex-mode-hook, or
  1601. ;interactively"
  1602. ;  (interactive)
  1603. ;  (local-set-mouse  '(text right) 'bibtex-sun-menu-eval))
  1604. ;
  1605.  
  1606. ;;; bibtex.el ends here
  1607.