home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / bibtex-mode.el < prev    next >
Encoding:
Text File  |  1993-02-03  |  56.7 KB  |  1,567 lines

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