mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-03 08:30:09 +00:00
1021 lines
37 KiB
EmacsLisp
1021 lines
37 KiB
EmacsLisp
|
;;; BibTeX mode for GNU Emacs
|
|||
|
;; Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc.
|
|||
|
|
|||
|
;; This file is part of GNU Emacs.
|
|||
|
|
|||
|
;; GNU Emacs is free software; you can redistribute it and/or modify
|
|||
|
;; it under the terms of the GNU General Public License as published by
|
|||
|
;; the Free Software Foundation; either version 1, or (at your option)
|
|||
|
;; any later version.
|
|||
|
|
|||
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
;; GNU General Public License for more details.
|
|||
|
|
|||
|
;; You should have received a copy of the GNU General Public License
|
|||
|
;; along with GNU Emacs; see the file COPYING. If not, write to
|
|||
|
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||
|
|
|||
|
;;; Mike Newton (newton@gumby.cs.caltech.edu) 91.1.20
|
|||
|
;;; * bibtex.el/bibtex-mode : updated comments to indicate new use of
|
|||
|
;;; address, add minor explanations and fix small omissions.
|
|||
|
;;; * bibtex.el/bibtex-entry : fixed spelling of variable
|
|||
|
|
|||
|
;;; Mike Newton (newton@gumby.cs.caltech.edu) 90.11.17
|
|||
|
;;; * Handle items like
|
|||
|
;;; title = poft # "Fifth Tri-quaterly" # random-conf,
|
|||
|
;;; and title = {This title is inside curlies}
|
|||
|
;;; * added user settable, always present, optional fields
|
|||
|
;;; * fixed 'bibtex-find-it's doc string's location
|
|||
|
;;; * bibtex-field-text made more general (it wouldnt handle the # construct)
|
|||
|
;;; and it now handles a small subset of the {} cases
|
|||
|
;;; * put DEA thesis back in (why get rid of good code?)
|
|||
|
;;; * merged into release 19 version code
|
|||
|
;;; * if cross-ref'ing is on, put 'pages' near top of OPTs, as the other
|
|||
|
;;; entries are unlikely to be used.
|
|||
|
;;; * skip-whitespace replaced by skip-chars-forward (also done
|
|||
|
;;; by Marc Shairo)
|
|||
|
|
|||
|
;;; Bengt Martensson, March 6
|
|||
|
;;; Adapted to Bibtex 0.99 by updating the optional fields according
|
|||
|
;;; to the document BibTeXing, Oren Patashnik, dated January 31, 1988.
|
|||
|
;;; Updated documentation strings accordingly. Added (provide 'bibtex).
|
|||
|
;;; If bibtex-include-OPT-crossref is non-nil, every entry will have
|
|||
|
;;; an OPTcrossref field, analogously for bibtex-include-OPTkey and
|
|||
|
;;; bibtex-include-OPTannote. Added bibtex-preamble, bound to ^C^EP,
|
|||
|
;;; and also found in X- and sun-menus. Cleaned up the sun-menu
|
|||
|
;;; stuff, and made it more uniform with the X-menu stuff. Marc: I
|
|||
|
;;; strongly suspect that I broke your parsing... (Or, more
|
|||
|
;;; correctly, BibTeX 0.99 broke it.)
|
|||
|
;;; Added bibtex-clean-entry-zap-empty-opts, defvar'd to t. If it
|
|||
|
;;; is nil, bibtex-clean-entry will leave empty optional fields alone.
|
|||
|
|
|||
|
;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06:
|
|||
|
;;; Added Sun menu support. Locally bound to right mouse button in
|
|||
|
;;; bibtex-mode. Emacs 18.49 allows local mouse bindings!!
|
|||
|
;;; Commented out DEAthesis.
|
|||
|
|
|||
|
;;; Marc Shapiro 6-oct-88
|
|||
|
;;; * use indent-to-column instead of inserting tabs (changes to
|
|||
|
;;; bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to
|
|||
|
;;; bibtex-make-optional-entry)
|
|||
|
;;; * C-c C-k deletes the current OPT entry entirely
|
|||
|
;;; * C-c C-d replaces text of field with ""
|
|||
|
;;; * renamed bibtex-find-it to bibtex-find-text. With arg, now goes to
|
|||
|
;;; start of text. Fixed bugs in it.
|
|||
|
|
|||
|
;;; Marc Shapiro 23-sep-88
|
|||
|
;;; * bibtex-clean-entry moves past end of entry.
|
|||
|
;;; * bibtex-clean-entry signals mandatory fields left empty.
|
|||
|
|
|||
|
;;; Marc Shapiro 18-jul-88
|
|||
|
;;; * Moved all the entry type keystrokes to "C-c C-e something" (instead of
|
|||
|
;;; "C-c something" previously) to make room for more. C-c C-e is
|
|||
|
;;; supposed to stand for "entry" [idea taken from mail-mode]. Moved
|
|||
|
;;; bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n.
|
|||
|
;;; * removed binding for "\e[25~"
|
|||
|
;;; * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to
|
|||
|
;;; C-c C-c
|
|||
|
|
|||
|
;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG]
|
|||
|
;;; * bibtex-pop-previous replaces current field with value of
|
|||
|
;;; similar field in previous entry. May be called n times in a row
|
|||
|
;;; (or with arg n) to pop similar field of n'th previous entry.
|
|||
|
;;; There is also a bibtex-pop-next to get similar field of next
|
|||
|
;;; entry.
|
|||
|
;;; * C-c C-k now kills all empty optional fields of current entry, and
|
|||
|
;;; removes "OPT" for those optional fields which have text.
|
|||
|
|
|||
|
;;; Marc Shapiro 14-dec-87
|
|||
|
;;; Cosmetic fixes. Fixed small bug in bibtex-move-outside-of-entry.
|
|||
|
;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87
|
|||
|
;;; before inserting an entry, make sure we are outside of a bib entry
|
|||
|
;;; Marc Shapiro 3-nov-87
|
|||
|
;;; addition for France: DEAthesis
|
|||
|
;;; Marc Shapiro 19-oct-1987
|
|||
|
;;; add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now
|
|||
|
;;; behave consistently; deletion never occurs blindly.
|
|||
|
;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986
|
|||
|
;;; align long lines nicely; C-c C-o checks for the "OPT" string;
|
|||
|
;;; TAB goes to the end of the string; use lower case; use
|
|||
|
;;; run-hooks
|
|||
|
|
|||
|
;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28
|
|||
|
;;; (Bengt Martensson <bengt@mathematik.uni-Bremen.de> 87-06-28)
|
|||
|
;;; Original version
|
|||
|
|
|||
|
;;; NOTE by Marc Shapiro, 14-dec-87:
|
|||
|
;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right.
|
|||
|
;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding,
|
|||
|
;;; so it will remain active in all windows. Yuck!
|
|||
|
|
|||
|
(provide 'bibtex)
|
|||
|
|
|||
|
(defvar bibtex-mode-syntax-table nil "")
|
|||
|
(defvar bibtex-mode-abbrev-table nil "")
|
|||
|
(define-abbrev-table 'bibtex-mode-abbrev-table ())
|
|||
|
(defvar bibtex-mode-map (make-sparse-keymap) "")
|
|||
|
(defvar bibtex-pop-previous-search-point nil
|
|||
|
"Next point where `bibtex-pop-previous' should start looking for a similar
|
|||
|
entry.")
|
|||
|
(defvar bibtex-pop-next-search-point nil
|
|||
|
"Next point where `bibtex-pop-next' should start looking for a similar
|
|||
|
entry.")
|
|||
|
|
|||
|
(defvar bibtex-clean-entry-zap-empty-opts t
|
|||
|
"*If non-nil, `bibtex-clean-entry' will delete all empty optional fields.")
|
|||
|
(defvar bibtex-include-OPTcrossref t
|
|||
|
"*If non-nil, all entries will have an `OPTcrossref' field.")
|
|||
|
(defvar bibtex-include-OPTkey t
|
|||
|
"*If non-nil, all entries will have an `OPTkey' field.")
|
|||
|
(defvar bibtex-include-OPTannote t
|
|||
|
"*If non-nil, all entries will have an `OPTannote' field.")
|
|||
|
|
|||
|
;; note: the user should be allowed to have their own list of always
|
|||
|
;; available optional fields. exs: "keywords" "categories"
|
|||
|
(defvar bibtex-mode-user-optional-fields nil ;no default value
|
|||
|
"*List of optional fields that user always wants present in a bibtex entry.
|
|||
|
One possibility is for ``keywords''")
|
|||
|
|
|||
|
|
|||
|
;;; A bibtex file is a sequence of entries, either string definitions
|
|||
|
;;; or reference entries. A reference entry has a type part, a
|
|||
|
;;; key part, and a comma-separated sequence of fields. A string
|
|||
|
;;; entry has a single field. A field has a left and right part,
|
|||
|
;;; separated by a '='. The left part is the name, the right part is
|
|||
|
;;; the text. Here come the definitions allowing to create and/or parse
|
|||
|
;;; entries and fields:
|
|||
|
|
|||
|
;;; fields
|
|||
|
(defun bibtex-cfield (name text)
|
|||
|
"Create a regexp for a bibtex field of name NAME and text TEXT."
|
|||
|
(concat ",[ \t\n]*\\("
|
|||
|
name
|
|||
|
"\\)[ \t\n]*=[ \t\n]*\\("
|
|||
|
text
|
|||
|
"\\)"))
|
|||
|
(defconst bibtex-name-in-cfield 1
|
|||
|
"The regexp subexpression number of the name part in `bibtex-cfield'.")
|
|||
|
(defconst bibtex-text-in-cfield 2
|
|||
|
"The regexp subexpression number of the text part in `bibtex-cfield'.")
|
|||
|
|
|||
|
(defconst bibtex-field-name "[A-Za-z][---A-Za-z0-9:_+]*"
|
|||
|
"Regexp defining the name part of a bibtex field.")
|
|||
|
|
|||
|
;; bibtex-field-text must be able to handle
|
|||
|
;; title = "Proc. Fifteenth Annual" # STOC,
|
|||
|
;; month = "10~" # jan,
|
|||
|
;; year = "{\noopsort{1973c}}1981",
|
|||
|
;; month = apr # "-" # may,
|
|||
|
;; key = {Volume-2},
|
|||
|
;; note = "Volume~2 is listed under Knuth \cite{book-full}"
|
|||
|
;; i have added a few of these, but not all! -- MON
|
|||
|
|
|||
|
(defconst bibtex-field-const
|
|||
|
"[0-9A-Za-z][---A-Za-z0-9:_+]*"
|
|||
|
"Format of a bibtex field constant.")
|
|||
|
(defconst bibtex-field-string
|
|||
|
(concat
|
|||
|
"\"[^\"]*[^\\\\]\"\\|\"\"")
|
|||
|
"Match either a string or an empty string.")
|
|||
|
(defconst bibtex-field-string-or-const
|
|||
|
(concat bibtex-field-const "\\|" bibtex-field-string)
|
|||
|
"Match either `bibtex-field-string' or `bibtex-field-const'.")
|
|||
|
|
|||
|
;(defconst bibtex-field-text
|
|||
|
; "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][---A-Za-z0-9:_+]*"
|
|||
|
; "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.")
|
|||
|
|
|||
|
(defconst bibtex-field-text
|
|||
|
(concat
|
|||
|
"\\(" bibtex-field-string-or-const "\\)"
|
|||
|
"\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*\\|"
|
|||
|
"{[^{}]*[^\\\\]}")
|
|||
|
"Regexp defining the text part of a bibtex field: either a string, or
|
|||
|
an empty string, or a constant followed by one or more # / constant pairs.
|
|||
|
Also matches simple {...} patterns.")
|
|||
|
|
|||
|
(defconst bibtex-field
|
|||
|
(bibtex-cfield bibtex-field-name bibtex-field-text)
|
|||
|
"Regexp defining the format of a bibtex field")
|
|||
|
|
|||
|
(defconst bibtex-name-in-field bibtex-name-in-cfield
|
|||
|
"The regexp subexpression number of the name part in `bibtex-field'.")
|
|||
|
(defconst bibtex-text-in-field bibtex-text-in-cfield
|
|||
|
"The regexp subexpression number of the text part in `bibtex-field'.")
|
|||
|
|
|||
|
;;; references
|
|||
|
(defconst bibtex-reference-type
|
|||
|
"@[A-Za-z]+"
|
|||
|
"Regexp defining the type part of a bibtex reference entry.")
|
|||
|
(defconst bibtex-reference-head
|
|||
|
(concat "^[ \t]*\\("
|
|||
|
bibtex-reference-type
|
|||
|
"\\)[ \t]*[({]\\("
|
|||
|
bibtex-field-name
|
|||
|
"\\)")
|
|||
|
"Regexp defining format of the header line of a bibtex reference entry.")
|
|||
|
(defconst bibtex-type-in-head 1
|
|||
|
"The regexp subexpression number of the type part in `bibtex-reference-head'.")
|
|||
|
(defconst bibtex-key-in-head 2
|
|||
|
"The regexp subexpression number of the key part in `bibtex-reference-head'.")
|
|||
|
|
|||
|
(defconst bibtex-reference
|
|||
|
(concat bibtex-reference-head
|
|||
|
"\\([ \t\n]*" bibtex-field "\\)*"
|
|||
|
"[ \t\n]*[})]")
|
|||
|
"Regexp defining the format of a bibtex reference entry.")
|
|||
|
(defconst bibtex-type-in-reference bibtex-type-in-head
|
|||
|
"The regexp subexpression number of the type part in `bibtex-reference'.")
|
|||
|
(defconst bibtex-key-in-reference bibtex-key-in-head
|
|||
|
"The regexp subexpression number of the key part in `bibtex-reference'.")
|
|||
|
|
|||
|
;;; strings
|
|||
|
(defconst bibtex-string
|
|||
|
(concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\("
|
|||
|
bibtex-field-name
|
|||
|
"\\)[ \t\n]*=[ \t\n]*\\("
|
|||
|
bibtex-field-text
|
|||
|
"\\)[ \t\n]*[})]")
|
|||
|
"Regexp defining the format of a bibtex string entry.")
|
|||
|
(defconst bibtex-name-in-string 1
|
|||
|
"The regexp subexpression of the name part in `bibtex-string'.")
|
|||
|
(defconst bibtex-text-in-string 2
|
|||
|
"The regexp subexpression of the text part in `bibtex-string'.")
|
|||
|
|
|||
|
(defconst bibtex-name-alignement 2
|
|||
|
"Alignment for the name part in BibTeX fields.
|
|||
|
Chosen on aesthetic grounds only.")
|
|||
|
|
|||
|
(defconst bibtex-text-alignment (length " organization = ")
|
|||
|
"Alignment for the text part in BibTeX fields.
|
|||
|
Equal to the space needed for the longest name part.")
|
|||
|
|
|||
|
;;; bibtex mode:
|
|||
|
|
|||
|
;;;###autoload
|
|||
|
(defun bibtex-mode ()
|
|||
|
"Major mode for editing bibtex files.
|
|||
|
|
|||
|
\\{bibtex-mode-map}
|
|||
|
|
|||
|
A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry.
|
|||
|
|
|||
|
The optional fields start with the string OPT, and thus ignored by BibTeX.
|
|||
|
The OPT string may be removed from a field with \\[bibtex-remove-OPT].
|
|||
|
\\[bibtex-kill-optional-field] kills the current optional field entirely.
|
|||
|
\\[bibtex-remove-double-quotes] removes the double-quotes around the text of
|
|||
|
the current field. \\[bibtex-empty-field] replaces the text of the current
|
|||
|
field with the default \"\".
|
|||
|
|
|||
|
The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes
|
|||
|
double-quotes from entirely numerical fields, (ii) removes OPT from all
|
|||
|
non-empty optional fields, (iii) removes all empty optional fields, and (iv)
|
|||
|
checks that no non-optional fields are empty.
|
|||
|
|
|||
|
Use \\[bibtex-find-text] to position the dot at the end of the current field.
|
|||
|
Use \\[bibtex-next-field] to move to end of the next field.
|
|||
|
|
|||
|
\\[bibtex-x-environment] binds a mode-specific X menu to control+right
|
|||
|
mouse button.
|
|||
|
\\[bibtex-sun-environment] binds a mode-specific Sun menu to right
|
|||
|
mouse button.
|
|||
|
|
|||
|
Fields:
|
|||
|
address
|
|||
|
Publisher's address, or for conference, location held
|
|||
|
annote
|
|||
|
Long annotation used for annotated bibliographies (begins sentence)
|
|||
|
author
|
|||
|
Name(s) of author(s), in BibTeX name format
|
|||
|
booktitle
|
|||
|
Book title when the thing being referenced isn't the whole book.
|
|||
|
For book entries, the title field should be used instead.
|
|||
|
chapter
|
|||
|
Chapter number (or section or whatever).
|
|||
|
crossref
|
|||
|
The database key of the entry being cross referenced.
|
|||
|
edition
|
|||
|
Edition of a book (e.g., \"second\")
|
|||
|
editor
|
|||
|
Name(s) of editor(s), in BibTeX name format.
|
|||
|
If there is also an author field, then the editor field should be
|
|||
|
for the book or collection that the work appears in
|
|||
|
howpublished
|
|||
|
How something strange has been published (begins sentence)
|
|||
|
institution
|
|||
|
Sponsoring institution
|
|||
|
journal
|
|||
|
Journal name (macros are provided for many)
|
|||
|
key
|
|||
|
Alphabetizing, labeling and cross-refing key (needed when no
|
|||
|
author or editor)
|
|||
|
month
|
|||
|
Month (macros are provided)
|
|||
|
note
|
|||
|
To help the reader find a reference (begins sentence)
|
|||
|
number
|
|||
|
Number of a journal or technical report
|
|||
|
organization
|
|||
|
Organization (sponsoring a conference)
|
|||
|
pages
|
|||
|
Page number or numbers (use `--' to separate a range)
|
|||
|
publisher
|
|||
|
Publisher name
|
|||
|
school
|
|||
|
School name (for theses)
|
|||
|
series
|
|||
|
The name of a series or set of books.
|
|||
|
An individual book will will also have it's own title
|
|||
|
title
|
|||
|
The title of the thing being referenced
|
|||
|
type
|
|||
|
Type of a technical report (e.g., \"Research Note\") to be used
|
|||
|
instead of the default \"Technical Report\"
|
|||
|
volume
|
|||
|
Volume of a journal or multivolume work
|
|||
|
year
|
|||
|
Year---should contain only numerals
|
|||
|
---------------------------------------------------------
|
|||
|
Entry to this mode calls the value of bibtex-mode-hook if that value is
|
|||
|
non-nil."
|
|||
|
(interactive)
|
|||
|
(kill-all-local-variables)
|
|||
|
(if bibtex-mode-syntax-table
|
|||
|
(set-syntax-table bibtex-mode-syntax-table)
|
|||
|
(setq bibtex-mode-syntax-table (make-syntax-table))
|
|||
|
(set-syntax-table bibtex-mode-syntax-table)
|
|||
|
(modify-syntax-entry ?\" ".")
|
|||
|
(modify-syntax-entry ?$ "$$ ")
|
|||
|
(modify-syntax-entry ?% "< ")
|
|||
|
(modify-syntax-entry ?' "w ")
|
|||
|
(modify-syntax-entry ?@ "w ")
|
|||
|
(modify-syntax-entry ?\\ "\\")
|
|||
|
(modify-syntax-entry ?\f "> ")
|
|||
|
(modify-syntax-entry ?\n "> ")
|
|||
|
(modify-syntax-entry ?~ " "))
|
|||
|
(use-local-map bibtex-mode-map)
|
|||
|
(setq major-mode 'bibtex-mode)
|
|||
|
|
|||
|
|
|||
|
(setq mode-name "BibTeX")
|
|||
|
(set-syntax-table bibtex-mode-syntax-table)
|
|||
|
(setq local-abbrev-table bibtex-mode-abbrev-table)
|
|||
|
(make-local-variable 'paragraph-start)
|
|||
|
(setq paragraph-start "^[ \f\n\t]*$")
|
|||
|
|
|||
|
(define-key bibtex-mode-map "\t" 'bibtex-find-text)
|
|||
|
(define-key bibtex-mode-map "\n" 'bibtex-next-field)
|
|||
|
(define-key bibtex-mode-map "\C-c\"" 'bibtex-remove-double-quotes)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-c" 'bibtex-clean-entry)
|
|||
|
(define-key bibtex-mode-map "\C-c?" 'describe-mode)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-p" 'bibtex-pop-previous)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-n" 'bibtex-pop-next)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-k" 'bibtex-kill-optional-field)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-d" 'bibtex-empty-field)
|
|||
|
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-a" 'bibtex-Article)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-b" 'bibtex-Book)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-d" 'bibtex-DEAthesis)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-c" 'bibtex-InProceedings)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-i" 'bibtex-InBook)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-ei" 'bibtex-InCollection)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-eI" 'bibtex-InProceedings)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-m" 'bibtex-Manual)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-em" 'bibtex-MastersThesis)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-eM" 'bibtex-Misc)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-o" 'bibtex-remove-OPT)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-p" 'bibtex-PhdThesis)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-ep" 'bibtex-Proceedings)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-eP" 'bibtex-preamble)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-t" 'bibtex-TechReport)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-s" 'bibtex-string)
|
|||
|
(define-key bibtex-mode-map "\C-c\C-e\C-u" 'bibtex-Unpublished)
|
|||
|
|
|||
|
(auto-fill-mode 1) ; nice alignements
|
|||
|
(setq left-margin (+ bibtex-text-alignment 1))
|
|||
|
|
|||
|
(run-hooks 'bibtex-mode-hook))
|
|||
|
|
|||
|
(defun bibtex-move-outside-of-entry ()
|
|||
|
"Make sure we are outside of a bib entry"
|
|||
|
(cond ((or
|
|||
|
(= (point) (point-max))
|
|||
|
(= (point) (point-min))
|
|||
|
(looking-at "[ \n]*@")
|
|||
|
)
|
|||
|
t)
|
|||
|
(t
|
|||
|
(backward-paragraph)
|
|||
|
(forward-paragraph)))
|
|||
|
(re-search-forward "[ \t\n]*" (point-max) t))
|
|||
|
|
|||
|
;;
|
|||
|
;; note: this should really take lists of strings OR of lists. in the
|
|||
|
;; second case, one can use either list. (ie:
|
|||
|
;; "name" (("crossref") ("journal" "year")) )
|
|||
|
;;
|
|||
|
|
|||
|
(defun bibtex-entry (entry-type required optional)
|
|||
|
(bibtex-move-outside-of-entry)
|
|||
|
(insert "@" entry-type "{")
|
|||
|
(mapcar 'bibtex-make-field required)
|
|||
|
(if bibtex-include-OPTcrossref
|
|||
|
(bibtex-make-optional-field "crossref"))
|
|||
|
(if bibtex-include-OPTkey
|
|||
|
(bibtex-make-optional-field "key"))
|
|||
|
(mapcar 'bibtex-make-optional-field optional)
|
|||
|
(if bibtex-mode-user-optional-fields ;MON...
|
|||
|
(mapcar 'bibtex-make-optional-field
|
|||
|
bibtex-mode-user-optional-fields))
|
|||
|
(if bibtex-include-OPTannote
|
|||
|
(bibtex-make-optional-field "annote"))
|
|||
|
(insert "\n}\n\n")
|
|||
|
(forward-char -3)
|
|||
|
(up-list -1)
|
|||
|
(forward-char 1))
|
|||
|
|
|||
|
(defun bibtex-make-field (str)
|
|||
|
(interactive "sBibTeX entry type: ")
|
|||
|
(insert ",\n")
|
|||
|
(indent-to-column bibtex-name-alignement)
|
|||
|
(insert str " = ")
|
|||
|
(indent-to-column bibtex-text-alignment)
|
|||
|
(insert "\"\"")
|
|||
|
nil)
|
|||
|
|
|||
|
(defun bibtex-make-optional-field (str)
|
|||
|
(interactive "sOptional BibTeX entry type: ")
|
|||
|
(insert ",\n")
|
|||
|
(indent-to-column bibtex-name-alignement)
|
|||
|
(insert "OPT" str " = ")
|
|||
|
(indent-to-column bibtex-text-alignment)
|
|||
|
(insert "\"\"")
|
|||
|
nil)
|
|||
|
|
|||
|
;; What to do about crossref? if present, journal and year are
|
|||
|
;; both optional. Due to this, i move all of them into optional. -- MON
|
|||
|
|
|||
|
(defun bibtex-Article ()
|
|||
|
(interactive)
|
|||
|
(if bibtex-include-OPTcrossref
|
|||
|
(bibtex-entry "Article" '("author" "title")
|
|||
|
'("journal" "year" "volume" "number" "pages"
|
|||
|
"month" "note"))
|
|||
|
(bibtex-entry "Article" '("author" "title" "journal" "year")
|
|||
|
'("volume" "number" "pages" "month" "note"))))
|
|||
|
|
|||
|
(defun bibtex-Book ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Book" '("author" "title" "publisher" "year")
|
|||
|
'("editor" "volume" "number" "series" "address"
|
|||
|
"edition" "month" "note")))
|
|||
|
|
|||
|
(defun bibtex-Booklet ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Booklet" '("title")
|
|||
|
'("author" "howpublished" "address" "month" "year" "note")))
|
|||
|
|
|||
|
;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's)
|
|||
|
(defun bibtex-DEAthesis ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "DEAthesis" '("author" "title" "school" "year")
|
|||
|
'("address" "month" "note")))
|
|||
|
|
|||
|
(defun bibtex-InBook ()
|
|||
|
(interactive)
|
|||
|
(if bibtex-include-OPTcrossref
|
|||
|
(bibtex-entry "InBook" '("author" "title" "chapter")
|
|||
|
'("publisher" "year" "editor" "pages" "volume" "number"
|
|||
|
"series" "address" "edition" "month" "type" "note"))
|
|||
|
(bibtex-entry "InBook" '("author" "title" "chapter" "publisher" "year")
|
|||
|
'("editor" "pages" "volume" "number" "series" "address"
|
|||
|
"edition" "month" "type" "note"))))
|
|||
|
|
|||
|
;; In next 2, for crossref case, put pages near beginning of
|
|||
|
;; optionals as it will be used most often -- MON
|
|||
|
(defun bibtex-InCollection ()
|
|||
|
(interactive)
|
|||
|
(if bibtex-include-OPTcrossref
|
|||
|
(bibtex-entry "InCollection" '("author" "title")
|
|||
|
'("pages" "booktitle" "publisher" "year"
|
|||
|
"editor" "volume" "number" "series" "type" "chapter"
|
|||
|
"address" "edition" "month" "note"))
|
|||
|
(bibtex-entry "InCollection" '("author" "title"
|
|||
|
"booktitle" "publisher" "year")
|
|||
|
'("editor" "volume" "number" "series" "type" "chapter"
|
|||
|
"pages" "address" "edition" "month" "note"))))
|
|||
|
|
|||
|
(defun bibtex-InProceedings ()
|
|||
|
(interactive)
|
|||
|
(if bibtex-include-OPTcrossref
|
|||
|
(bibtex-entry "InProceedings" '("author" "title")
|
|||
|
'( "pages" "editor" "volume" "number" "series"
|
|||
|
"booktitle" "year"
|
|||
|
"organization" "publisher" "address" "month" "note"))
|
|||
|
(bibtex-entry "InProceedings" '("author" "title" "booktitle" "year")
|
|||
|
'("editor" "volume" "number" "series" "pages"
|
|||
|
"organization" "publisher" "address" "month" "note"))))
|
|||
|
|
|||
|
(defun bibtex-Manual ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Manual" '("title")
|
|||
|
'("author" "organization" "address" "edition" "year"
|
|||
|
"month" "note")))
|
|||
|
|
|||
|
(defun bibtex-MastersThesis ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "MastersThesis" '("author" "title" "school" "year")
|
|||
|
'("address" "month" "note" "type")))
|
|||
|
|
|||
|
(defun bibtex-Misc ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Misc" '()
|
|||
|
'("author" "title" "howpublished" "year" "month" "note")))
|
|||
|
|
|||
|
(defun bibtex-PhdThesis ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "PhdThesis" '("author" "title" "school" "year")
|
|||
|
'("address" "month" "type" "note")))
|
|||
|
|
|||
|
(defun bibtex-Proceedings ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Proceedings" '("title" "year")
|
|||
|
'("editor" "volume" "number" "series" "publisher"
|
|||
|
"organization" "address" "month" "note")))
|
|||
|
|
|||
|
(defun bibtex-TechReport ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "TechReport" '("author" "title" "institution" "year")
|
|||
|
'("type" "number" "address" "month" "note")))
|
|||
|
|
|||
|
|
|||
|
(defun bibtex-Unpublished ()
|
|||
|
(interactive)
|
|||
|
(bibtex-entry "Unpublished" '("author" "title" "note")
|
|||
|
'("year" "month")))
|
|||
|
|
|||
|
(defun bibtex-string ()
|
|||
|
(interactive)
|
|||
|
(bibtex-move-outside-of-entry)
|
|||
|
(insert "@string{ = """"}\n")
|
|||
|
(previous-line 1)
|
|||
|
(forward-char 8))
|
|||
|
|
|||
|
(defun bibtex-preamble ()
|
|||
|
(interactive)
|
|||
|
(bibtex-move-outside-of-entry)
|
|||
|
(insert "@Preamble{}\n")
|
|||
|
(previous-line 1)
|
|||
|
(forward-char 10))
|
|||
|
|
|||
|
(defun bibtex-next-field (arg)
|
|||
|
"Finds end of text of next BibTeX field; with arg, to its beginning"
|
|||
|
(interactive "P")
|
|||
|
(bibtex-inside-field)
|
|||
|
(let ((start (point)))
|
|||
|
(condition-case ()
|
|||
|
(progn
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(goto-char (match-end 0))
|
|||
|
(forward-char 2))
|
|||
|
(error
|
|||
|
(goto-char start)
|
|||
|
(end-of-line)
|
|||
|
(forward-char 1))))
|
|||
|
(bibtex-find-text arg))
|
|||
|
|
|||
|
(defun bibtex-find-text (arg)
|
|||
|
"Go to end of text of current field; with arg, go to beginning."
|
|||
|
(interactive "P")
|
|||
|
(bibtex-inside-field)
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(if arg
|
|||
|
(progn
|
|||
|
(goto-char (match-beginning bibtex-text-in-field))
|
|||
|
(if (looking-at "\"")
|
|||
|
(forward-char 1)))
|
|||
|
(goto-char (match-end bibtex-text-in-field))
|
|||
|
(if (= (preceding-char) ?\")
|
|||
|
(forward-char -1))))
|
|||
|
|
|||
|
(defun bibtex-remove-OPT ()
|
|||
|
"Removes the 'OPT' starting optional arguments and goes to end of text"
|
|||
|
(interactive)
|
|||
|
(bibtex-inside-field)
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(save-excursion
|
|||
|
(goto-char (match-beginning bibtex-name-in-field))
|
|||
|
(if (looking-at "OPT")
|
|||
|
(delete-char (length "OPT"))))
|
|||
|
(bibtex-inside-field))
|
|||
|
|
|||
|
(defun bibtex-inside-field ()
|
|||
|
"Try to avoid point being at end of a bibtex field."
|
|||
|
(interactive)
|
|||
|
(end-of-line)
|
|||
|
(skip-chars-backward " \t") ;delete these chars? -- MON
|
|||
|
(cond ((= (preceding-char) ?,)
|
|||
|
(forward-char -1)))
|
|||
|
(cond ((= (preceding-char) ?\")
|
|||
|
(forward-char -1)))) ;only go back if quote
|
|||
|
|
|||
|
|
|||
|
(defun bibtex-remove-double-quotes ()
|
|||
|
"Removes """" around string."
|
|||
|
(interactive)
|
|||
|
(save-excursion
|
|||
|
(bibtex-inside-field)
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(let ((start (match-beginning bibtex-text-in-field))
|
|||
|
(stop (match-end bibtex-text-in-field)))
|
|||
|
(goto-char stop)
|
|||
|
(forward-char -1)
|
|||
|
(if (looking-at "\"")
|
|||
|
(delete-char 1))
|
|||
|
(goto-char start)
|
|||
|
(if (looking-at "\"")
|
|||
|
(delete-char 1)))))
|
|||
|
|
|||
|
(defun bibtex-kill-optional-field ()
|
|||
|
"Kill the entire enclosing optional BibTeX field"
|
|||
|
(interactive)
|
|||
|
(bibtex-inside-field)
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(goto-char (match-beginning bibtex-name-in-field))
|
|||
|
(let ((the-end (match-end 0))
|
|||
|
(the-beginning (match-beginning 0)))
|
|||
|
(if (looking-at "OPT")
|
|||
|
(progn
|
|||
|
(goto-char the-end)
|
|||
|
(skip-chars-forward " \t\n,")
|
|||
|
(kill-region the-beginning the-end))
|
|||
|
(error "Mandatory fields can't be killed"))))
|
|||
|
|
|||
|
(defun bibtex-empty-field ()
|
|||
|
"Delete the text part of the current field, replace with empty text"
|
|||
|
(interactive)
|
|||
|
(bibtex-inside-field)
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(goto-char (match-beginning bibtex-text-in-field))
|
|||
|
(kill-region (point) (match-end bibtex-text-in-field))
|
|||
|
(insert "\"\"")
|
|||
|
(bibtex-find-text t))
|
|||
|
|
|||
|
|
|||
|
(defun bibtex-pop-previous (arg)
|
|||
|
"Replace text of current field with the text of similar field in previous entry.
|
|||
|
With arg, go up ARG entries. Repeated, goes up so many times. May be
|
|||
|
intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
|
|||
|
(interactive "p")
|
|||
|
(bibtex-inside-field)
|
|||
|
(save-excursion
|
|||
|
; parse current field
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(let ((start-old-text (match-beginning bibtex-text-in-field))
|
|||
|
(stop-old-text (match-end bibtex-text-in-field))
|
|||
|
(start-name (match-beginning bibtex-name-in-field))
|
|||
|
(stop-name (match-end bibtex-name-in-field))
|
|||
|
(new-text))
|
|||
|
(goto-char start-name)
|
|||
|
; construct regexp for previous field with same name as this one
|
|||
|
(let ((matching-entry
|
|||
|
(bibtex-cfield
|
|||
|
(buffer-substring (if (looking-at "OPT")
|
|||
|
(+ (point) (length "OPT"))
|
|||
|
(point))
|
|||
|
stop-name)
|
|||
|
bibtex-field-text)))
|
|||
|
|
|||
|
; if executed several times in a row, start each search where the
|
|||
|
; last one finished
|
|||
|
(cond ((or (eq last-command 'bibtex-pop-previous)
|
|||
|
(eq last-command 'bibtex-pop-next))
|
|||
|
t
|
|||
|
)
|
|||
|
(t
|
|||
|
(bibtex-enclosing-reference)
|
|||
|
(setq bibtex-pop-previous-search-point (match-beginning 0))
|
|||
|
(setq bibtex-pop-next-search-point (match-end 0))))
|
|||
|
(goto-char bibtex-pop-previous-search-point)
|
|||
|
|
|||
|
; Now search for arg'th previous similar field
|
|||
|
(cond
|
|||
|
((re-search-backward matching-entry (point-min) t arg)
|
|||
|
(setq new-text
|
|||
|
(buffer-substring (match-beginning bibtex-text-in-cfield)
|
|||
|
(match-end bibtex-text-in-cfield)))
|
|||
|
; Found a matching field. Remember boundaries.
|
|||
|
(setq bibtex-pop-next-search-point (match-end 0))
|
|||
|
(setq bibtex-pop-previous-search-point (match-beginning 0))
|
|||
|
(bibtex-flash-head)
|
|||
|
; Go back to where we started, delete old text, and pop new.
|
|||
|
(goto-char stop-old-text)
|
|||
|
(delete-region start-old-text stop-old-text)
|
|||
|
(insert new-text))
|
|||
|
(t ; search failed
|
|||
|
(error "No previous matching BibTeX field."))))))
|
|||
|
(setq this-command 'bibtex-pop-previous))
|
|||
|
|
|||
|
(defun bibtex-pop-next (arg)
|
|||
|
"Replace text of current field with the text of similar field in next entry.
|
|||
|
With arg, go up ARG entries. Repeated, goes up so many times. May be
|
|||
|
intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
|
|||
|
(interactive "p")
|
|||
|
(bibtex-inside-field)
|
|||
|
(save-excursion
|
|||
|
; parse current field
|
|||
|
(bibtex-enclosing-field)
|
|||
|
(let ((start-old-text (match-beginning bibtex-text-in-field))
|
|||
|
(stop-old-text (match-end bibtex-text-in-field))
|
|||
|
(start-name (match-beginning bibtex-name-in-field))
|
|||
|
(stop-name (match-end bibtex-name-in-field))
|
|||
|
(new-text))
|
|||
|
(goto-char start-name)
|
|||
|
; construct regexp for next field with same name as this one,
|
|||
|
; ignoring possible OPT's
|
|||
|
(let ((matching-entry
|
|||
|
(bibtex-cfield
|
|||
|
(buffer-substring (if (looking-at "OPT")
|
|||
|
(+ (point) (length "OPT"))
|
|||
|
(point))
|
|||
|
stop-name)
|
|||
|
bibtex-field-text)))
|
|||
|
|
|||
|
; if executed several times in a row, start each search where the
|
|||
|
; last one finished
|
|||
|
(cond ((or (eq last-command 'bibtex-pop-next)
|
|||
|
(eq last-command 'bibtex-pop-previous))
|
|||
|
t
|
|||
|
)
|
|||
|
(t
|
|||
|
(bibtex-enclosing-reference)
|
|||
|
(setq bibtex-pop-previous-search-point (match-beginning 0))
|
|||
|
(setq bibtex-pop-next-search-point (match-end 0))))
|
|||
|
(goto-char bibtex-pop-next-search-point)
|
|||
|
|
|||
|
; Now search for arg'th next similar field
|
|||
|
(cond
|
|||
|
((re-search-forward matching-entry (point-max) t arg)
|
|||
|
(setq new-text
|
|||
|
(buffer-substring (match-beginning bibtex-text-in-cfield)
|
|||
|
(match-end bibtex-text-in-cfield)))
|
|||
|
; Found a matching field. Remember boundaries.
|
|||
|
(setq bibtex-pop-next-search-point (match-end 0))
|
|||
|
(setq bibtex-pop-previous-search-point (match-beginning 0))
|
|||
|
(bibtex-flash-head)
|
|||
|
; Go back to where we started, delete old text, and pop new.
|
|||
|
(goto-char stop-old-text)
|
|||
|
(delete-region start-old-text stop-old-text)
|
|||
|
(insert new-text))
|
|||
|
(t ; search failed
|
|||
|
(error "No next matching BibTeX field."))))))
|
|||
|
(setq this-command 'bibtex-pop-next))
|
|||
|
|
|||
|
(defun bibtex-flash-head ()
|
|||
|
"Flash at BibTeX reference head before point, if exists. (Moves point)."
|
|||
|
(let ((flash))
|
|||
|
(cond ((re-search-backward bibtex-reference-head (point-min) t)
|
|||
|
(goto-char (match-beginning bibtex-type-in-head))
|
|||
|
(setq flash (match-end bibtex-key-in-reference)))
|
|||
|
(t
|
|||
|
(end-of-line)
|
|||
|
(skip-chars-backward " \t")
|
|||
|
(setq flash (point))
|
|||
|
(beginning-of-line)
|
|||
|
(skip-chars-forward " \t")))
|
|||
|
(if (pos-visible-in-window-p (point))
|
|||
|
(sit-for 1)
|
|||
|
(message "From: %s"
|
|||
|
(buffer-substring (point) flash)))))
|
|||
|
|
|||
|
|
|||
|
|
|||
|
(defun bibtex-enclosing-field ()
|
|||
|
"Search for BibTeX field enclosing point.
|
|||
|
Point moves to end of field; also, use match-beginning and match-end
|
|||
|
to parse the field."
|
|||
|
(condition-case errname
|
|||
|
(bibtex-enclosing-regexp bibtex-field)
|
|||
|
(search-failed
|
|||
|
(error "Can't find enclosing BibTeX field."))))
|
|||
|
|
|||
|
(defun bibtex-enclosing-reference ()
|
|||
|
"Search for BibTeX reference enclosing point.
|
|||
|
Point moves to end of reference; also, use match-beginning and match-end
|
|||
|
to parse the reference."
|
|||
|
(condition-case errname
|
|||
|
(bibtex-enclosing-regexp bibtex-reference)
|
|||
|
(search-failed
|
|||
|
(error "Can't find enclosing BibTeX reference."))))
|
|||
|
|
|||
|
(defun bibtex-enclosing-regexp (regexp)
|
|||
|
"Search for REGEXP enclosing point.
|
|||
|
Point moves to end of REGEXP. See also match-beginning and match-end.
|
|||
|
If an enclosing REGEXP is not found, signals search-failed; point is left in
|
|||
|
an undefined location.
|
|||
|
|
|||
|
[Doesn't something like this exist already?]"
|
|||
|
|
|||
|
(interactive "sRegexp: ")
|
|||
|
; compute reasonable limits for the loop
|
|||
|
(let* ((initial (point))
|
|||
|
(right (if (re-search-forward regexp (point-max) t)
|
|||
|
(match-end 0)
|
|||
|
(point-max)))
|
|||
|
(left
|
|||
|
(progn
|
|||
|
(goto-char initial)
|
|||
|
(if (re-search-backward regexp (point-min) t)
|
|||
|
(match-beginning 0)
|
|||
|
(point-min)))))
|
|||
|
; within the prescribed limits, loop until a match is found
|
|||
|
(goto-char left)
|
|||
|
(re-search-forward regexp right nil 1)
|
|||
|
(if (> (match-beginning 0) initial)
|
|||
|
(signal 'search-failed (list regexp)))
|
|||
|
(while (<= (match-end 0) initial)
|
|||
|
(re-search-forward regexp right nil 1)
|
|||
|
(if (> (match-beginning 0) initial)
|
|||
|
(signal 'search-failed (list regexp))))
|
|||
|
))
|
|||
|
|
|||
|
(defun bibtex-clean-entry ()
|
|||
|
"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."
|
|||
|
(interactive)
|
|||
|
(bibtex-enclosing-reference)
|
|||
|
(goto-char (match-beginning 0))
|
|||
|
(let ((start (point)))
|
|||
|
(save-restriction
|
|||
|
(narrow-to-region start (match-end 0))
|
|||
|
(while (re-search-forward bibtex-field (point-max) t 1)
|
|||
|
(let ((begin-field (match-beginning 0))
|
|||
|
(end-field (match-end 0))
|
|||
|
(begin-name (match-beginning bibtex-name-in-field))
|
|||
|
(end-name (match-end bibtex-name-in-field))
|
|||
|
(begin-text (match-beginning bibtex-text-in-field))
|
|||
|
(end-text (match-end bibtex-text-in-field))
|
|||
|
)
|
|||
|
(goto-char begin-name)
|
|||
|
(cond ((and
|
|||
|
(looking-at "OPT")
|
|||
|
bibtex-clean-entry-zap-empty-opts)
|
|||
|
(goto-char begin-text)
|
|||
|
(if (looking-at "\"\"") ; empty: delete whole field
|
|||
|
(delete-region begin-field end-field)
|
|||
|
; otherwise: not empty, delete "OPT"
|
|||
|
(goto-char begin-name)
|
|||
|
(delete-char (length "OPT"))
|
|||
|
(goto-char begin-field) ; and loop to go through next test
|
|||
|
))
|
|||
|
(t
|
|||
|
(goto-char begin-text)
|
|||
|
(cond ((looking-at "\"[0-9]+\"") ; if numerical,
|
|||
|
(goto-char end-text)
|
|||
|
(delete-char -1) ; delete enclosing double-quotes
|
|||
|
(goto-char begin-text)
|
|||
|
(delete-char 1)
|
|||
|
(goto-char end-field) ; go to end for next search
|
|||
|
(forward-char -2) ; to compensate for the 2 quotes deleted
|
|||
|
)
|
|||
|
((looking-at "\"\"") ; if empty quotes, complain
|
|||
|
(forward-char 1)
|
|||
|
(if (not (or (equal (buffer-substring
|
|||
|
begin-name
|
|||
|
(+ begin-name 3))
|
|||
|
"OPT")
|
|||
|
(equal (buffer-substring
|
|||
|
begin-name
|
|||
|
(+ begin-name 3))
|
|||
|
"opt")))
|
|||
|
(error "Mandatory field ``%s'' is empty"
|
|||
|
(buffer-substring begin-name end-name))))
|
|||
|
(t
|
|||
|
(goto-char end-field))))))))
|
|||
|
(goto-char start)
|
|||
|
(skip-chars-forward "@a-zA-Z")
|
|||
|
(bibtex-enclosing-reference)
|
|||
|
(goto-char (match-end 0))
|
|||
|
(skip-chars-forward " \t\n")))
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;;; X window menus for bibtex mode
|
|||
|
|
|||
|
(defun bibtex-x-help (arg)
|
|||
|
"Mouse commands for BibTeX mode"
|
|||
|
|
|||
|
(let ((selection
|
|||
|
(x-popup-menu
|
|||
|
arg
|
|||
|
'("BibTeX commands"
|
|||
|
("BibTeX entry types"
|
|||
|
(" article in conference Proceedings " . bibtex-InProceedings)
|
|||
|
(" Article in journal " . bibtex-Article)
|
|||
|
(" Book " . bibtex-Book)
|
|||
|
(" Booklet " . bibtex-Booklet)
|
|||
|
(" Conference " . bibtex-InProceedings)
|
|||
|
(" Master's Thesis " . bibtex-MastersThesis)
|
|||
|
(" DEA Thesis " . bibtex-DEAthesis)
|
|||
|
(" Phd. Thesis " . bibtex-PhdThesis)
|
|||
|
(" Technical Report " . bibtex-TechReport)
|
|||
|
(" technical Manual " . bibtex-Manual)
|
|||
|
(" conference Proceedings " . bibtex-Proceedings)
|
|||
|
(" a chapter in a Book " . bibtex-InBook)
|
|||
|
(" an article in a Collection " . bibtex-InCollection)
|
|||
|
(" miscellaneous " . bibtex-Misc)
|
|||
|
(" unpublished " . bibtex-Unpublished)
|
|||
|
(" string " . bibtex-string)
|
|||
|
(" preamble " . bibtex-preamble)
|
|||
|
)
|
|||
|
("Moving around and editing"
|
|||
|
(" next field " . bibtex-next-field)
|
|||
|
(" to end of field " . bibtex-find-text)
|
|||
|
("snatch from similar preceding field" . bibtex-pop-previous)
|
|||
|
("snatch from similar following field" . bibtex-pop-next)
|
|||
|
(" remove OPT " . bibtex-remove-OPT)
|
|||
|
(" remove quotes "
|
|||
|
. bibtex-remove-double-quotes)
|
|||
|
(" clean up entry " . bibtex-clean-entry)
|
|||
|
)
|
|||
|
("help"
|
|||
|
(" describe BibTeX mode " . describe-mode)
|
|||
|
)))))
|
|||
|
(and selection (call-interactively selection))))
|
|||
|
|
|||
|
(defun bibtex-x-environment ()
|
|||
|
"Set up X menus for BibTeX mode. Call it as bibtex-mode-hook, or interactively"
|
|||
|
(interactive)
|
|||
|
(require 'x-mouse)
|
|||
|
(define-key mouse-map x-button-c-right 'bibtex-x-help)
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;; Please don't send anything to bug-gnu-emacs about these Sunwindows functions
|
|||
|
;; since we aren't interested. See etc/SUN-SUPPORT for the reasons why
|
|||
|
;; we consider this nothing but a distraction from our work.
|
|||
|
|
|||
|
(if (fboundp 'defmenu)
|
|||
|
(progn
|
|||
|
|
|||
|
(defmenu bibtex-sun-entry-menu
|
|||
|
("Article In Conf. Proc."
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-InProceedings))))
|
|||
|
("Article In Journal"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Article))))
|
|||
|
("Book"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Book))))
|
|||
|
("Booklet"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Booklet))))
|
|||
|
("Master's Thesis"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-MastersThesis))))
|
|||
|
;;("DEA Thesis" bibtex-DEAthesis)
|
|||
|
("PhD. Thesis"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-PhdThesis))))
|
|||
|
("Technical Report"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-TechReport))))
|
|||
|
("Technical Manual"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Manual))))
|
|||
|
("Conference Proceedings"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Proceedings))))
|
|||
|
("In A Book"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-InBook))))
|
|||
|
("In A Collection"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-InCollection))))
|
|||
|
("Miscellaneous"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Misc))))
|
|||
|
("Unpublished"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-Unpublished)))))
|
|||
|
|
|||
|
(defmenu bibtex-sun-menu
|
|||
|
("BibTeX menu")
|
|||
|
("add entry" . bibtex-sun-entry-menu)
|
|||
|
("add string"
|
|||
|
(lambda () (eval-in-window *menu-window* (bibtex-string))))
|
|||
|
;("next field" bibtex-next-position)
|
|||
|
;("to end of field" bibtex-find-it)
|
|||
|
; ("remove OPT"
|
|||
|
; (lambda () (eval-in-window *menu-window* (bibtex-remove-opt))))
|
|||
|
; ("remove quotes"
|
|||
|
; (lambda () (eval-in-window *menu-window* (bibtex-remove-double-quotes))))
|
|||
|
; ("remove this line"
|
|||
|
; (lambda () (eval-in-window *menu-window* (kill-current-line))))
|
|||
|
("describe BibTeX mode"
|
|||
|
(lambda () (eval-in-window *menu-window* (describe-mode))))
|
|||
|
("Main Emacs menu" . emacs-menu))
|
|||
|
|
|||
|
(defun bibtex-sun-menu-eval (window x y)
|
|||
|
"Pop-up menu of BibTeX commands."
|
|||
|
(sun-menu-evaluate window (1+ x) (1- y) 'bibtex-sun-menu))
|
|||
|
|
|||
|
(defun bibtex-sun-environment ()
|
|||
|
"Set up sun menus for BibTeX mode. Call it as bibtex-mode-hook, or interactively"
|
|||
|
(interactive)
|
|||
|
(local-set-mouse '(text right) 'bibtex-sun-menu-eval))
|
|||
|
|
|||
|
)) ; matches (if...
|
|||
|
|
|||
|
;;; ------------- end bibtex-mode.el -------------------------------
|