home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / lisp / modes / bibtex.el < prev    next >
Encoding:
Text File  |  1992-06-29  |  31.0 KB  |  876 lines

  1. ;;; BibTeX mode for GNU Emacs
  2. ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
  3.  
  4. ;; This file is part of GNU Emacs.
  5.  
  6. ;; GNU Emacs is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation; either version 1, or (at your option)
  9. ;; any later version.
  10.  
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;; GNU General Public License for more details.
  15.  
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  18. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. ;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06:
  21. ;;;   Added Sun menu support.  Locally bound to right mouse button in 
  22. ;;;   bibtex-mode.  Emacs 18.49 allows local mouse bindings!!
  23. ;;;   Commented out DEAthesis.
  24.  
  25. ;;; Marc Shapiro 6-oct-88
  26. ;;;  * use indent-to-column instead of inserting tabs (changes to 
  27. ;;;    bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to
  28. ;;;    bibtex-make-optional-entry)
  29. ;;;  * C-c C-k deletes the current OPT entry entirely
  30. ;;;  * C-c C-d replaces text of field with ""
  31. ;;;  * renamed bibtex-find-it to bibtex-find-text.  With arg, now goes to
  32. ;;;    start of text.  Fixed bugs in it.
  33.  
  34. ;;; Marc Shapiro 23-sep-88
  35. ;;;  * bibtex-clean-entry moves past end of entry.
  36. ;;;  * bibtex-clean-entry signals mandatory fields left empty.
  37.  
  38. ;;; Marc Shapiro 18-jul-88
  39. ;;;  * Moved all the entry type keystrokes to "C-c C-e something" (instead of
  40. ;;;    "C-c something" previously) to make room for more.  C-c C-e is
  41. ;;;    supposed to stand for "entry" [idea taken from mail-mode].  Moved
  42. ;;;    bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n.
  43. ;;;  * removed binding for "\e[25~"
  44. ;;;  * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to
  45. ;;;    C-c C-c
  46.  
  47. ;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG]
  48. ;;;  * bibtex-pop-previous replaces current field with value of
  49. ;;;    similar field in previous entry.  May be called n times in a row
  50. ;;;    (or with arg n) to pop similar field of n'th previous entry.
  51. ;;;    There is also a bibtex-pop-next to get similar field of next
  52. ;;;    entry.
  53. ;;;  * C-c C-k now kills all empty optional fields of current entry, and
  54. ;;;    removes "OPT" for those optional fields which have text. 
  55.  
  56. ;;; Marc Shapiro 14-dec-87
  57. ;;;   Cosmetic fixes.  Fixed small bug in bibtex-move-outside-of-entry.
  58. ;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87
  59. ;;;   before inserting an entry, make sure we are outside of a bib entry
  60. ;;; Marc Shapiro 3-nov-87
  61. ;;;   addition for France: DEAthesis
  62. ;;; Marc Shapiro 19-oct-1987
  63. ;;;   add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now
  64. ;;;   behave consistently; deletion never occurs blindly.
  65. ;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986
  66. ;;;    align long lines nicely; C-c C-o checks for the "OPT" string;
  67. ;;;    TAB goes to the end of the string; use lower case; use
  68. ;;;    run-hooks
  69.  
  70. ;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28
  71. ;;;   Original version
  72.  
  73. ;;; NOTE by Marc Shapiro, 14-dec-87:
  74. ;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right.
  75. ;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding,
  76. ;;; so it will remain active in all windows.  Yuck!
  77.  
  78. (defvar bibtex-mode-syntax-table nil "")
  79. (defvar bibtex-mode-abbrev-table nil "")
  80. (define-abbrev-table 'bibtex-mode-abbrev-table ())
  81. (defvar bibtex-mode-map (make-sparse-keymap) "")
  82. (defvar bibtex-pop-previous-search-point nil
  83.   "Next point where bibtex-pop-previous should start looking for a similar
  84. entry.")
  85. (defvar bibtex-pop-next-search-point nil
  86.   "Next point where bibtex-pop-next should start looking for a similar
  87. entry.")
  88.  
  89. ;;; A bibtex file is a sequence of entries, either string definitions
  90. ;;; or reference entries.  A reference entry has a type part, a
  91. ;;; key part, and a comma-separated sequence of fields.  A string
  92. ;;; entry has a single field.  A field has a left and right part,
  93. ;;; separated by a '='.  The left part is the name, the right part is
  94. ;;; the text.  Here come the definitions allowing to create and/or parse
  95. ;;; entries and fields:
  96.  
  97. ;;; fields
  98. (defun bibtex-cfield (name text)
  99.   "Create a regexp for a bibtex field of name NAME and text TEXT"
  100.   (concat ",[ \t\n]*\\("
  101.       name
  102.       "\\)[ \t\n]*=[ \t\n]*\\("
  103.       text
  104.       "\\)"))
  105. (defconst bibtex-name-in-cfield 1
  106.   "The regexp subexpression number of the name part in bibtex-cfield.")
  107. (defconst bibtex-text-in-cfield 2
  108.   "The regexp subexpression number of the text part in bibtex-cfield.")
  109.  
  110. (defconst bibtex-field-name "[A-Za-z][---A-Za-z0-9:_+]*"
  111.   "Regexp defining the name part of a bibtex field.")
  112. (defconst bibtex-field-text
  113.   "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][---A-Za-z0-9:_+]*"
  114.   "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.")
  115. (defconst bibtex-field
  116.   (bibtex-cfield bibtex-field-name bibtex-field-text)
  117.   "Regexp defining the format of a bibtex field")
  118.  
  119. (defconst bibtex-name-in-field bibtex-name-in-cfield
  120.   "The regexp subexpression number of the name part in bibtex-field")
  121. (defconst bibtex-text-in-field bibtex-text-in-cfield
  122.   "The regexp subexpression number of the text part in bibtex-field")
  123.  
  124. ;;; references
  125. (defconst bibtex-reference-type
  126.   "@[A-Za-z]+"
  127.   "Regexp defining the type part of a bibtex reference entry")
  128. (defconst bibtex-reference-head
  129.   (concat "^[ \t]*\\("
  130.       bibtex-reference-type
  131.       "\\)[ \t]*[({]\\("
  132.       bibtex-field-name
  133.       "\\)")
  134.   "Regexp defining format of the header line of a bibtex reference entry")
  135. (defconst bibtex-type-in-head 1
  136.   "The regexp subexpression number of the type part in bibtex-reference-head")
  137. (defconst bibtex-key-in-head 2
  138.   "The regexp subexpression number of the key part in
  139. bibtex-reference-head")
  140.  
  141. (defconst bibtex-reference
  142.   (concat bibtex-reference-head
  143.       "\\([ \t\n]*" bibtex-field "\\)*"
  144.       "[ \t\n]*[})]")
  145.   "Regexp defining the format of a bibtex reference entry")
  146. (defconst bibtex-type-in-reference bibtex-type-in-head
  147.   "The regexp subexpression number of the type part in bibtex-reference")
  148. (defconst bibtex-key-in-reference bibtex-key-in-head
  149.   "The regexp subexpression number of the key part in
  150. bibtex-reference")
  151.  
  152. ;;; strings
  153. (defconst bibtex-string
  154.   (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\("
  155.       bibtex-field-name
  156.       "\\)[ \t\n]*=[ \t\n]*\\("
  157.       bibtex-field-text
  158.       "\\)[ \t\n]*[})]")
  159.   "Regexp defining the format of a bibtex string entry")
  160. (defconst bibtex-name-in-string 1
  161.   "The regexp subexpression of the name part in bibtex-string")
  162. (defconst bibtex-text-in-string 2
  163.   "The regexp subexpression of the text part in bibtex-string")
  164.  
  165. (defconst bibtex-name-alignement 2
  166.   "Alignment for the name part in BibTeX fields.
  167. Chosen on aesthetic grounds only.")
  168.  
  169. (defconst bibtex-text-alignment (length "  organization = ")
  170.   "Alignment for the text part in BibTeX fields.
  171. Equal to the space needed for the longest name part.")
  172.  
  173. ;;; bibtex mode:
  174.  
  175. (defun bibtex-mode () 
  176.   "Major mode for editing bibtex files.
  177.  
  178. \\{bibtex-mode-map}
  179.  
  180. A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry.
  181.  
  182. The optional fields start with the string OPT, and thus ignored by BibTeX.
  183. The OPT string may be removed from a field with \\[bibtex-remove-OPT].
  184. \\[bibtex-kill-optional-field] kills the current optional field entirely.
  185. \\[bibtex-remove-double-quotes] removes the double-quotes around the text of
  186. the current field.  \\[bibtex-empty-field] replaces the text of the current
  187. field with the default \"\".
  188.  
  189. The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes
  190. double-quotes from entirely numerical fields, (ii) removes OPT from all
  191. non-empty optional fields, (iii) removes all empty optional fields, and (iv)
  192. checks that no non-optional fields are empty.
  193.  
  194. Use \\[bibtex-find-text] to position the dot at the end of the current field.
  195. Use \\[bibtex-next-field] to move to end of the next field.
  196.  
  197. \\[bibtex-x-environment] binds a mode-specific X menu to control+right
  198. mouse button.
  199. \\[bibtex-sun-environment] binds a mode-specific Sun menu to right
  200. mouse button.
  201.  
  202. Fields:
  203.     address
  204.            Publisher's address
  205.     annote
  206.            Long annotation used for annotated bibliographies (begins sentence)
  207.     author
  208.            Name(s) of author(s), in BibTeX name format
  209.     booktitle
  210.            Book title when the thing being referenced isn't the whole book.
  211.            For book entries, the title field should be used instead.
  212.     chapter
  213.            Chapter number
  214.     edition
  215.            Edition of a book (e.g., \"second\")
  216.     editor
  217.            Name(s) of editor(s), in BibTeX name format.
  218.            If there is also an author field, then the editor field should be
  219.            for the book or collection that the work appears in
  220.     howpublished
  221.             How something strange has been published (begins sentence)
  222.     institution
  223.            Sponsoring institution
  224.     journal
  225.            Journal name (macros are provided for many)
  226.     key
  227.            Alphabetizing and labeling key (needed when no author or editor)
  228.     month
  229.            Month (macros are provided)
  230.     note
  231.            To help the reader find a reference (begins sentence)
  232.     number
  233.            Number of a journal or technical report
  234.     organization
  235.            Organization (sponsoring a conference)
  236.     pages
  237.            Page number or numbers (use `--' to separate a range)
  238.     publisher
  239.            Publisher name
  240.     school
  241.            School name (for theses)
  242.     series
  243.            The name of a series or set of books.
  244.            An individual book will will also have it's own title
  245.     title
  246.            The title of the thing being referenced
  247.     type
  248.            Type of a technical report (e.g., \"Research Note\") to be used
  249.            instead of the default \"Technical Report\"
  250.     volume
  251.            Volume of a journal or multivolume work
  252.     year
  253.            Year---should contain only numerals
  254. ---------------------------------------------------------
  255. Entry to this mode calls the value of bibtex-mode-hook if that value is
  256. non-nil."
  257.   (interactive)
  258.   (kill-all-local-variables)
  259.   (if bibtex-mode-syntax-table
  260.       (set-syntax-table bibtex-mode-syntax-table)
  261.      (setq bibtex-mode-syntax-table (make-syntax-table))
  262.      (set-syntax-table bibtex-mode-syntax-table)
  263.      (modify-syntax-entry ?\" ".")
  264.      (modify-syntax-entry ?$ "$$  ")
  265.      (modify-syntax-entry ?% "<   ")
  266.      (modify-syntax-entry ?'  "w   ")
  267.      (modify-syntax-entry ?@  "w   ")
  268.      (modify-syntax-entry ?\\ "\\")
  269.      (modify-syntax-entry ?\f ">   ")
  270.      (modify-syntax-entry ?\n ">   ")
  271.      (modify-syntax-entry ?~ " "))
  272.   (use-local-map bibtex-mode-map)
  273.   (setq major-mode 'bibtex-mode)
  274.  
  275.  
  276.   (setq mode-name "BibTeX")
  277.   (set-syntax-table bibtex-mode-syntax-table)
  278.   (setq local-abbrev-table bibtex-mode-abbrev-table)
  279.   (make-local-variable 'paragraph-start)
  280.   (setq paragraph-start "^[ \f\n\t]*$")
  281.  
  282.   (define-key bibtex-mode-map "\t" 'bibtex-find-text)
  283.   (define-key bibtex-mode-map "\n" 'bibtex-next-field)
  284.   (define-key bibtex-mode-map "\C-c\"" 'bibtex-remove-double-quotes)
  285.   (define-key bibtex-mode-map "\C-c\C-c" 'bibtex-clean-entry)
  286.   (define-key bibtex-mode-map "\C-c?" 'describe-mode)
  287.   (define-key bibtex-mode-map "\C-c\C-p" 'bibtex-pop-previous)
  288.   (define-key bibtex-mode-map "\C-c\C-n" 'bibtex-pop-next)
  289.   (define-key bibtex-mode-map "\C-c\C-k" 'bibtex-kill-optional-field)
  290.   (define-key bibtex-mode-map "\C-c\C-d" 'bibtex-empty-field)
  291.  
  292.   (define-key bibtex-mode-map "\C-c\C-e\C-a" 'bibtex-Article)
  293.   (define-key bibtex-mode-map "\C-c\C-e\C-b" 'bibtex-Book)
  294.   ;; (define-key bibtex-mode-map "\C-c\C-e\C-d" 'bibtex-DEAthesis)
  295.   (define-key bibtex-mode-map "\C-c\C-e\C-c" 'bibtex-InProceedings)
  296.   (define-key bibtex-mode-map "\C-c\C-e\C-i" 'bibtex-InBook)
  297.   (define-key bibtex-mode-map "\C-c\C-ei" 'bibtex-InCollection)
  298.   (define-key bibtex-mode-map "\C-c\C-eI" 'bibtex-InProceedings)
  299.   (define-key bibtex-mode-map "\C-c\C-e\C-m" 'bibtex-Manual)
  300.   (define-key bibtex-mode-map "\C-c\C-em" 'bibtex-MastersThesis)
  301.   (define-key bibtex-mode-map "\C-c\C-eM" 'bibtex-Misc)
  302.   (define-key bibtex-mode-map "\C-c\C-o" 'bibtex-remove-OPT)
  303.   (define-key bibtex-mode-map "\C-c\C-e\C-p" 'bibtex-PhdThesis)
  304.   (define-key bibtex-mode-map "\C-c\C-ep" 'bibtex-Proceedings)
  305.   (define-key bibtex-mode-map "\C-c\C-e\C-t" 'bibtex-TechReport)
  306.   (define-key bibtex-mode-map "\C-c\C-e\C-s" 'bibtex-string)
  307.   (define-key bibtex-mode-map "\C-c\C-e\C-u" 'bibtex-Unpublished)
  308.  
  309.   (auto-fill-mode 1)            ; nice alignements
  310.   (setq left-margin (+ bibtex-text-alignment 1))
  311.  
  312.   (run-hooks 'bibtex-mode-hook))
  313.  
  314. (defun bibtex-move-outside-of-entry ()
  315.   "Make sure we are outside of a bib entry"
  316.   (cond ((or
  317.       (= (point) (point-max))
  318.       (= (point) (point-min))
  319.       (looking-at "[ \n]*@")
  320.       )
  321.      t)
  322.     (t
  323.      (backward-paragraph)
  324.      (forward-paragraph)))
  325.   (re-search-forward "[ \t\n]*" (point-max) t))
  326.  
  327. (defun bibtex-entry (entry-type required optional)
  328.   (bibtex-move-outside-of-entry)
  329.   (insert "@" entry-type "{")
  330.   (mapcar 'bibtex-make-entry required)
  331.   (mapcar 'bibtex-make-optional-entry optional)
  332.   (insert "\n}\n\n")
  333.   (forward-char -3)
  334.   (up-list -1)
  335.   (forward-char 1))
  336.  
  337. (defun bibtex-make-entry (str)
  338.   (interactive "sBibTeX entry type: ")
  339.   (insert ",\n")
  340.   (indent-to-column bibtex-name-alignement)
  341.   (insert str " = ")
  342.   (indent-to-column bibtex-text-alignment)
  343.   (insert "\"\"")
  344.   nil)
  345.  
  346. (defun bibtex-make-optional-entry (str)
  347.   (interactive "sOptional BibTeX entry type: ")
  348.   (insert ",\n")
  349.   (indent-to-column bibtex-name-alignement)
  350.   (insert "OPT" str " = ")
  351.   (indent-to-column bibtex-text-alignment)
  352.   (insert "\"\"")
  353.   nil)
  354.  
  355. (defun bibtex-Article ()
  356.   (interactive)
  357.   (bibtex-entry "Article" '("author" "title" "journal" "year")
  358.         '("volume" "number" "pages" "month" "note")))
  359.  
  360. (defun bibtex-Book ()
  361.   (interactive)
  362.   (bibtex-entry "Book" '("author" "title" "publisher" "year")
  363.         '("editor" "volume" "series" "address"
  364.                "edition" "month" "note")))
  365.  
  366. (defun bibtex-Booklet ()
  367.   (interactive)
  368.   (bibtex-entry "Booklet" '("title")
  369.         '("author" "howpublished" "address" "month" "year" "note")))
  370.  
  371. ;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's)
  372. (defun bibtex-DEAthesis ()
  373.   (interactive)
  374.   (bibtex-entry "DEAthesis" '("author" "title" "school" "year")
  375.         '("address" "month" "note")))
  376.  
  377. (defun bibtex-InBook ()
  378.   (interactive)
  379.   (bibtex-entry "InBook" '("author" "title" "chapter" "publisher" "year")
  380.         '("editor" "pages" "volume" "series" "address"
  381.                "edition" "month" "note")))
  382.  
  383. (defun bibtex-InCollection ()
  384.   (interactive)
  385.   (bibtex-entry "InCollection" '("author" "title" "booktitle"
  386.                       "publisher" "year")
  387.         '("editor" "chapter" "pages" "address" "month" "note")))
  388.  
  389.  
  390. (defun bibtex-InProceedings ()
  391.   (interactive)
  392.   (bibtex-entry "InProceedings" '("author" "title" "booktitle" "year")
  393.         '("editor" "pages" "organization" "publisher"
  394.                "address" "month" "note")))
  395.  
  396. (defun bibtex-Manual ()
  397.   (interactive)
  398.   (bibtex-entry "Manual" '("title")
  399.         '("author" "organization" "address" "edition" "year"
  400.                "month" "note")))
  401.  
  402. (defun bibtex-MastersThesis ()
  403.   (interactive)
  404.   (bibtex-entry "MastersThesis" '("author" "title" "school" "year")
  405.         '("address" "month" "note")))
  406.  
  407. (defun bibtex-Misc ()
  408.   (interactive)
  409.   (bibtex-entry "Misc" '()
  410.         '("author" "title" "howpublished" "year" "month" "note")))
  411.  
  412. (defun bibtex-PhdThesis ()
  413.   (interactive)
  414.   (bibtex-entry "PhdThesis" '("author" "title" "school" "year")
  415.         '("address" "month" "note")))
  416.  
  417. (defun bibtex-Proceedings ()
  418.   (interactive)
  419.   (bibtex-entry "Proceedings" '("title" "year")
  420.         '("editor" "publisher" "organization"
  421.                "address" "month" "note")))
  422. (defun bibtex-TechReport ()
  423.   (interactive)
  424.   (bibtex-entry "TechReport" '("author" "title" "institution" "year")
  425.         '("type" "number" "address" "month" "note")))
  426.  
  427.  
  428. (defun bibtex-Unpublished ()
  429.   (interactive)
  430.   (bibtex-entry "Unpublished" '("author" "title" "note")
  431.         '("year" "month")))
  432.  
  433. (defun bibtex-string ()
  434.   (interactive)
  435.   (bibtex-move-outside-of-entry)
  436.   (insert "@string{ = """"}\n")
  437.   (previous-line 1)
  438.   (forward-char 8))
  439.  
  440.  
  441. (defun bibtex-next-field (arg)
  442.   "Finds end of text of next BibTeX field; with arg, to its beginning"
  443.   (interactive "P")
  444.   (bibtex-inside-field)
  445.   (let ((start (point)))
  446.     (condition-case ()
  447.     (progn
  448.       (bibtex-enclosing-field)
  449.       (goto-char (match-end 0))
  450.       (forward-char 2))
  451.       (error
  452.        (goto-char start)
  453.        (end-of-line)
  454.        (forward-char 1))))
  455.   (bibtex-find-text arg))
  456.  
  457. (defun bibtex-find-text (arg)
  458.   "Go to end of text of current field; with arg, go to beginning."
  459.   (interactive "P")
  460.   (bibtex-inside-field)
  461.   (bibtex-enclosing-field)
  462.   (if arg
  463.       (progn
  464.     (goto-char (match-beginning bibtex-text-in-field))
  465.     (if (looking-at "\"")
  466.         (forward-char 1)))
  467.     (goto-char (match-end bibtex-text-in-field))
  468.     (if (= (preceding-char) ?\")
  469.     (forward-char -1))))
  470.  
  471. (defun bibtex-remove-OPT ()
  472.   "Removes the 'OPT' starting optional arguments and goes to end of text"
  473.   (interactive)
  474.   (bibtex-inside-field)
  475.   (bibtex-enclosing-field)
  476.   (save-excursion
  477.     (goto-char (match-beginning bibtex-name-in-field))
  478.     (if (looking-at "OPT")
  479.     (delete-char (length "OPT"))))
  480.   (bibtex-inside-field))
  481.  
  482. (defun bibtex-inside-field ()
  483.   "Try to avoid point being at end of a bibtex field."
  484.   (interactive)
  485.   (end-of-line)
  486.   (skip-chars-backward " \t")
  487.   (cond ((= (preceding-char) ?,)
  488.      (forward-char -1)))
  489.   (forward-char -1))
  490.  
  491. (defun bibtex-remove-double-quotes ()
  492.   "Removes \"\" around string."
  493.   (interactive)
  494.   (save-excursion
  495.     (bibtex-inside-field)
  496.     (bibtex-enclosing-field)
  497.     (let ((start (match-beginning bibtex-text-in-field))
  498.       (stop (match-end  bibtex-text-in-field)))
  499.       (goto-char stop)
  500.       (forward-char -1)
  501.       (if (looking-at "\"")
  502.       (delete-char 1))
  503.       (goto-char start)
  504.       (if (looking-at "\"")
  505.       (delete-char 1)))))
  506.  
  507. (defun bibtex-kill-optional-field ()
  508.   "Kill the entire enclosing optional BibTeX field"
  509.   (interactive)
  510.   (bibtex-inside-field)
  511.   (bibtex-enclosing-field)
  512.   (goto-char (match-beginning bibtex-name-in-field))
  513.   (let ((the-end (match-end 0))
  514.     (the-beginning (match-beginning 0)))
  515.     (if (looking-at "OPT")
  516.     (progn
  517.       (goto-char the-end)
  518.       (skip-chars-forward " \t\n,")
  519.       (kill-region the-beginning the-end))
  520.       (error "Mandatory fields can't be killed"))))
  521.  
  522. (defun bibtex-empty-field ()
  523.   "Delete the text part of the current field, replace with empty text"
  524.   (interactive)
  525.   (bibtex-inside-field)
  526.   (bibtex-enclosing-field)
  527.   (goto-char (match-beginning bibtex-text-in-field))
  528.   (kill-region (point) (match-end bibtex-text-in-field))
  529.   (insert "\"\"")
  530.   (bibtex-find-text t))
  531.  
  532.  
  533. (defun bibtex-pop-previous (arg)
  534.   "Replace text of current field with the text of similar field in previous entry.
  535. With arg, go up ARG entries.  Repeated, goes up so many times.  May be
  536. intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
  537.   (interactive "p")
  538.   (bibtex-inside-field)
  539.   (save-excursion
  540.     ; parse current field
  541.     (bibtex-enclosing-field)
  542.     (let ((start-old-text (match-beginning bibtex-text-in-field))
  543.       (stop-old-text  (match-end bibtex-text-in-field))
  544.       (start-name (match-beginning bibtex-name-in-field))
  545.       (stop-name (match-end bibtex-name-in-field))
  546.       (new-text))
  547.       (goto-char start-name)
  548.       ; construct regexp for previous field with same name as this one
  549.       (let ((matching-entry
  550.          (bibtex-cfield
  551.           (buffer-substring (if (looking-at "OPT")
  552.                     (+ (point) (length "OPT"))
  553.                   (point))
  554.                 stop-name)
  555.           bibtex-field-text)))
  556.     
  557.     ; if executed several times in a row, start each search where the
  558.     ; last one finished
  559.     (cond ((or (eq last-command 'bibtex-pop-previous)
  560.            (eq last-command 'bibtex-pop-next))
  561.            t
  562.            )
  563.           (t
  564.            (bibtex-enclosing-reference)
  565.            (setq bibtex-pop-previous-search-point (match-beginning 0))
  566.            (setq bibtex-pop-next-search-point (match-end 0))))
  567.     (goto-char bibtex-pop-previous-search-point)
  568.     
  569.     ; Now search for arg'th previous similar field
  570.     (cond
  571.      ((re-search-backward matching-entry (point-min) t arg)
  572.       (setq new-text
  573.         (buffer-substring (match-beginning bibtex-text-in-cfield)
  574.                   (match-end bibtex-text-in-cfield)))
  575.       ; Found a matching field. Remember boundaries.
  576.       (setq bibtex-pop-next-search-point (match-end 0))
  577.       (setq bibtex-pop-previous-search-point (match-beginning 0))
  578.       (bibtex-flash-head)
  579.       ; Go back to where we started, delete old text, and pop new.
  580.       (goto-char stop-old-text)
  581.       (delete-region start-old-text stop-old-text)
  582.       (insert new-text))
  583.      (t                ; search failed
  584.       (error "No previous matching BibTeX field."))))))
  585.   (setq this-command 'bibtex-pop-previous))
  586.  
  587. (defun bibtex-pop-next (arg)
  588.   "Replace text of current field with the text of similar field in next entry.
  589. With arg, go up ARG entries.  Repeated, goes up so many times.  May be
  590. intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
  591.   (interactive "p")
  592.   (bibtex-inside-field)
  593.   (save-excursion
  594.     ; parse current field
  595.     (bibtex-enclosing-field)
  596.     (let ((start-old-text (match-beginning bibtex-text-in-field))
  597.       (stop-old-text  (match-end bibtex-text-in-field))
  598.       (start-name (match-beginning bibtex-name-in-field))
  599.       (stop-name (match-end bibtex-name-in-field))
  600.       (new-text))
  601.       (goto-char start-name)
  602.       ; construct regexp for next field with same name as this one,
  603.       ; ignoring possible OPT's
  604.       (let ((matching-entry
  605.          (bibtex-cfield
  606.           (buffer-substring (if (looking-at "OPT")
  607.                     (+ (point) (length "OPT"))
  608.                   (point))
  609.                 stop-name)
  610.           bibtex-field-text)))
  611.     
  612.     ; if executed several times in a row, start each search where the
  613.     ; last one finished
  614.     (cond ((or (eq last-command 'bibtex-pop-next)
  615.            (eq last-command 'bibtex-pop-previous))
  616.            t
  617.            )
  618.           (t
  619.            (bibtex-enclosing-reference)
  620.            (setq bibtex-pop-previous-search-point (match-beginning 0))
  621.            (setq bibtex-pop-next-search-point (match-end 0))))
  622.     (goto-char bibtex-pop-next-search-point)
  623.     
  624.     ; Now search for arg'th next similar field
  625.     (cond
  626.      ((re-search-forward matching-entry (point-max) t arg)
  627.       (setq new-text
  628.         (buffer-substring (match-beginning bibtex-text-in-cfield)
  629.                   (match-end bibtex-text-in-cfield)))
  630.       ; Found a matching field. Remember boundaries.
  631.       (setq bibtex-pop-next-search-point (match-end 0))
  632.       (setq bibtex-pop-previous-search-point (match-beginning 0))
  633.       (bibtex-flash-head)
  634.       ; Go back to where we started, delete old text, and pop new.
  635.       (goto-char stop-old-text)
  636.       (delete-region start-old-text stop-old-text)
  637.       (insert new-text))
  638.      (t                ; search failed
  639.       (error "No next matching BibTeX field."))))))
  640.   (setq this-command 'bibtex-pop-next))
  641.  
  642. (defun bibtex-flash-head ()
  643.   "Flash at BibTeX reference head before point, if exists.  (Moves point)."
  644.   (let ((flash))
  645.     (cond ((re-search-backward bibtex-reference-head (point-min) t)
  646.        (goto-char (match-beginning bibtex-type-in-head))
  647.        (setq flash (match-end bibtex-key-in-reference)))
  648.       (t
  649.        (end-of-line)
  650.        (skip-chars-backward " \t")
  651.        (setq flash (point))
  652.        (beginning-of-line)
  653.        (skip-chars-forward " \t")))
  654.     (if (pos-visible-in-window-p (point))
  655.     (sit-for 1)
  656.       (message "From: %s"
  657.            (buffer-substring (point) flash)))))
  658.  
  659.  
  660.  
  661. (defun bibtex-enclosing-field ()
  662.   "Search for BibTeX field enclosing point.
  663. Point moves to end of field; also, use match-beginning and match-end
  664. to parse the field."
  665.   (condition-case errname
  666.       (bibtex-enclosing-regexp bibtex-field)
  667.     (search-failed
  668.      (error "Can't find enclosing BibTeX field."))))
  669.  
  670. (defun bibtex-enclosing-reference ()
  671.   "Search for BibTeX reference enclosing point.
  672. Point moves to end of reference; also, use match-beginning and match-end
  673. to parse the reference."
  674.   (condition-case errname
  675.       (bibtex-enclosing-regexp bibtex-reference)
  676.     (search-failed
  677.      (error "Can't find enclosing BibTeX reference."))))
  678.  
  679. (defun bibtex-enclosing-regexp (regexp)
  680.   "Search for REGEXP enclosing point.
  681. Point moves to end of REGEXP.  See also match-beginning and match-end.
  682. If an enclosing REGEXP is not found, signals search-failed; point is left in
  683. an undefined location.
  684.  
  685. [Doesn't something like this exist already?]"
  686.   
  687.   (interactive "sRegexp: ")
  688.   ; compute reasonable limits for the loop
  689.   (let* ((initial (point))
  690.      (right (if (re-search-forward regexp (point-max) t)
  691.             (match-end 0)
  692.           (point-max)))
  693.      (left
  694.       (progn
  695.         (goto-char initial)
  696.         (if (re-search-backward regexp (point-min) t)
  697.         (match-beginning 0)
  698.           (point-min)))))
  699.     ; within the prescribed limits, loop until a match is found
  700.     (goto-char left)
  701.     (re-search-forward regexp right nil 1)
  702.     (if (> (match-beginning 0) initial)
  703.     (signal 'search-failed (list regexp)))      
  704.     (while (<= (match-end 0) initial)
  705.       (re-search-forward regexp right nil 1)
  706.       (if (> (match-beginning 0) initial)
  707.       (signal 'search-failed (list regexp))))
  708.     ))
  709.  
  710. (defun bibtex-clean-entry ()
  711.   "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."
  712.   (interactive)
  713.   (bibtex-enclosing-reference)
  714.   (goto-char (match-beginning 0))
  715.   (let ((start (point)))
  716.     (save-restriction
  717.       (narrow-to-region start (match-end 0))
  718.       (while (re-search-forward bibtex-field (point-max) t 1)
  719.     (let ((begin-field (match-beginning 0))
  720.           (end-field (match-end 0))
  721.           (begin-name (match-beginning bibtex-name-in-field))
  722.           (end-name (match-end  bibtex-name-in-field))
  723.           (begin-text (match-beginning bibtex-text-in-field))
  724.           (end-text (match-end bibtex-text-in-field))
  725.           )
  726.       (goto-char begin-name)
  727.       (cond ((looking-at "OPT")
  728.          (goto-char begin-text)
  729.          (if (looking-at "\"\"") ; empty: delete whole field
  730.              (delete-region begin-field end-field)
  731.            ; otherwise: not empty, delete "OPT"
  732.            (goto-char begin-name)
  733.            (delete-char (length "OPT"))
  734.            (goto-char begin-field) ; and loop to go through next test
  735.            ))
  736.         (t
  737.          (goto-char begin-text)
  738.          (cond ((looking-at "\"[0-9]+\"") ; if numerical,
  739.             (goto-char end-text)
  740.             (delete-char -1) ; delete enclosing double-quotes
  741.             (goto-char begin-text)
  742.             (delete-char 1)
  743.             (goto-char end-field) ; go to end for next search
  744.             (forward-char -2) ; to compensate for the 2 quotes deleted
  745.             )
  746.                ((looking-at "\"\"") ; if empty quotes, complain
  747.             (forward-char 1)
  748.             (error "Mandatory field ``%s'' is empty"
  749.                    (buffer-substring begin-name end-name)))
  750.                (t
  751.             (goto-char end-field))))))))
  752.     (goto-char start)
  753.     (skip-chars-forward "@a-zA-Z")
  754.     (bibtex-enclosing-reference)
  755.     (goto-char (match-end 0))
  756.     (skip-chars-forward " \t\n ")))
  757.  
  758.  
  759.  
  760. ;;; X window menus for bibtex mode
  761.  
  762. (defun bibtex-x-help (arg)
  763.   "Mouse commands for BibTeX mode"
  764.   
  765.   (let ((selection
  766.      (x-popup-menu
  767.       arg
  768.       '("BibTeX commands"
  769.         ("BibTeX entry types"
  770.          (" article in conference Proceedings " . bibtex-InProceedings)
  771.          ("        Article in journal         " . bibtex-Article)
  772.          ("               Book                " . bibtex-Book)
  773.          ("             Booklet               " . bibtex-Booklet)
  774.          ("         Master's Thesis           " . bibtex-MastersThesis)
  775.          ;; ("            DEA Thesis             " . bibtex-DEAthesis)
  776.          ("            Phd. Thesis            " . bibtex-PhdThesis)
  777.          ("         Technical Report          " . bibtex-TechReport)
  778.          ("         technical Manual          " . bibtex-Manual)
  779.          ("      conference Proceedings       " . bibtex-Proceedings)
  780.          ("        a chapter in a Book        " . bibtex-InBook)
  781.          ("    an article in a Collection     " . bibtex-InCollection)
  782.          ("           miscellaneous           " . bibtex-Misc)
  783.          ("            unpublished            " . bibtex-Unpublished)
  784.          ("              string               " . bibtex-string)
  785.          )
  786.         ("Moving around and editing"
  787.          ("            next field             " . bibtex-next-field)
  788.          ("          to end of field          " . bibtex-find-text)
  789.          ("snatch from similar preceding field" . bibtex-pop-previous)
  790.          ("snatch from similar following field" . bibtex-pop-next)
  791.          ("            remove OPT             " . bibtex-remove-OPT)
  792.          ("           remove quotes           "
  793.           . bibtex-remove-double-quotes)
  794.          ("          clean up entry           " . bibtex-clean-entry)
  795.          )
  796.         ("help"
  797.          ("       describe BibTeX mode        " . describe-mode)
  798.          )))))
  799.     (and selection (call-interactively selection))))
  800.  
  801. (defun bibtex-x-environment ()
  802.   "Set up X menus for BibTeX mode.  Call it as bibtex-mode-hook, or interactively"
  803.   (interactive)
  804.   (require 'x-mouse)
  805.   (define-key mouse-map x-button-c-right 'bibtex-x-help)
  806.   )
  807.  
  808.  
  809.  
  810. ;; Please don't send anything to bug-gnu-emacs about these Sunwindows functions
  811. ;; since we aren't interested.  See etc/SUN-SUPPORT for the reasons why
  812. ;; we consider this nothing but a distraction from our work.
  813.  
  814. (if (fboundp 'defmenu)
  815.     ;; ## jwz: added this eval so that this file can be compiled correctly;
  816.     ;; if the defmenu macro isn't around at compile-time, we will compile a
  817.     ;; totally bogus set of function calls instead.
  818.     (eval '(progn
  819.  
  820. (defmenu bibtex-sun-entry-menu 
  821.   ("Article In Conf. Proc."
  822.    (lambda () (eval-in-window *menu-window* (bibtex-InProceedings))))
  823.   ("Article In Journal"
  824.    (lambda () (eval-in-window *menu-window* (bibtex-Article))))
  825.   ("Book"
  826.    (lambda () (eval-in-window *menu-window* (bibtex-Book))))
  827.   ("Booklet"
  828.    (lambda () (eval-in-window *menu-window* (bibtex-Booklet))))
  829.   ("Master's Thesis"
  830.    (lambda () (eval-in-window *menu-window* (bibtex-MastersThesis))))
  831.   ;;("DEA Thesis" bibtex-DEAthesis)
  832.   ("PhD. Thesis"
  833.    (lambda () (eval-in-window *menu-window* (bibtex-PhdThesis))))
  834.   ("Technical Report"
  835.    (lambda () (eval-in-window *menu-window* (bibtex-TechReport))))
  836.   ("Technical Manual"
  837.    (lambda () (eval-in-window *menu-window* (bibtex-Manual))))
  838.   ("Conference Proceedings"
  839.    (lambda () (eval-in-window *menu-window* (bibtex-Proceedings))))
  840.   ("In A Book"
  841.    (lambda () (eval-in-window *menu-window* (bibtex-InBook))))
  842.   ("In A Collection"
  843.    (lambda () (eval-in-window *menu-window* (bibtex-InCollection))))
  844.   ("Miscellaneous"
  845.    (lambda () (eval-in-window *menu-window* (bibtex-Misc))))
  846.   ("Unpublished"
  847.    (lambda () (eval-in-window *menu-window* (bibtex-Unpublished)))))
  848.  
  849. (defmenu bibtex-sun-menu
  850.   ("BibTeX menu")
  851.   ("add entry" . bibtex-sun-entry-menu)
  852.   ("add string"
  853.    (lambda () (eval-in-window *menu-window* (bibtex-string))))
  854.   ;("next field" bibtex-next-position)
  855.   ;("to end of field" bibtex-find-it)
  856. ;  ("remove OPT"
  857. ;   (lambda () (eval-in-window *menu-window* (bibtex-remove-opt))))
  858. ;  ("remove quotes"
  859. ;   (lambda () (eval-in-window *menu-window* (bibtex-remove-double-quotes))))
  860. ;  ("remove this line"
  861. ;   (lambda () (eval-in-window *menu-window* (kill-current-line))))
  862.   ("describe BibTeX mode"
  863.    (lambda () (eval-in-window *menu-window* (describe-mode))))
  864.   ("Main Emacs menu" . emacs-menu))
  865.  
  866. (defun bibtex-sun-menu-eval (window x y)
  867.   "Pop-up menu of BibTeX commands."
  868.   (sun-menu-evaluate window (1+ x) (1- y) 'bibtex-sun-menu))
  869.  
  870. (defun bibtex-sun-environment ()
  871.   "Set up sun menus for BibTeX mode.  Call it as bibtex-mode-hook, or interactively"
  872.   (interactive)
  873.   (local-set-mouse  '(text right) 'bibtex-sun-menu-eval))
  874.  
  875. )))  ; matches (if...
  876.