aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1996-03-08 17:42:30 +0000
committerRichard M. Stallman1996-03-08 17:42:30 +0000
commit31bc4210064165154f599ec048cd167b00578298 (patch)
treed602a6f457e3366ef18893c001f307895c49ed2f
parent1e9c210ba7699f509d82ecdcf6bff54199683e93 (diff)
downloademacs-31bc4210064165154f599ec048cd167b00578298.tar.gz
emacs-31bc4210064165154f599ec048cd167b00578298.zip
(bibtex-pop): New generic function which unifies the
functionality of bibtex-pop-previous and bibtex-pop-next. Now, bibtex-pop moves to the end of field after the pop. Concatenated strings are now handled correctly. Delimiters are not added to non-delimited entries. Changed occurences of bibtex-text-in-cfield to bibtex-text-in-field. (bibtex-pop-previous, bibtex-pop-next): Call bibtex-pop. (bibtex-complete-string): Fixed bug that removed delimiters around the following field if current field is already undelimited on completion. (bibtex-complete-string, bibtex-remove-double-quotes-or-braces): Only remove delimiters if field text is not concatenated. (bibtex-font-lock-keywords): Use the same regexps used in all other places of bibtex.el to parse the buffer. (bibtex-mode): Changed the definition of font-lock-defaults, so that quote-delimited entries aren't fontified as strings anymore. (bibtex-parse-keys): Changed the regexp used for finding crossref entries. (bibtex-field-const, bibtex-reference-key): Fixed the regexp to match more of the characters allowed here by BibTeX/LaTeX. (bibtex-field-name): Made it less restrictive. (bibtex-field-string): Changed so that quote-delimited entries with quotes inside aren't a problem anymore. Changed nesting level of braces in entries to support three inner braces. (bibtex-validate-buffer): By giving an optional argument, the user can now let it not validate the whole buffer, but only the portion starting at point. Small modification in strategy used to find next entry. (bibtex-print-help-message): Ignore case in field name when searching for help text. (bibtex-submit-bug-report): New function.
-rw-r--r--lisp/textmodes/bibtex.el586
1 files changed, 359 insertions, 227 deletions
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 700bf46bac0..645cb1ceb67 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -1,13 +1,13 @@
1;;; bibtex.el --- BibTeX mode for GNU Emacs 1;;; bibtex.el --- BibTeX mode for GNU Emacs
2 2
3;; Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
4 4
5;; Author: Stefan Schoef <schoef@informatik.uni-oldenburg.de> 5;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
6;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 6;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
7;; Mark Shapiro <shapiro@corto.inria.fr> 7;; Mark Shapiro <shapiro@corto.inria.fr>
8;; Mike Newton <newton@gumby.cs.caltech.edu> 8;; Mike Newton <newton@gumby.cs.caltech.edu>
9;; Aaron Larson <alarson@src.honeywell.com> 9;; Aaron Larson <alarson@src.honeywell.com>
10;; Maintainer: Stefan Schoef <schoef@informatik.uni-oldenburg.de> 10;; Maintainer: Stefan Schoef <schoef@offis.uni-oldenburg.de>
11;; Keywords: BibTeX, LaTeX, TeX 11;; Keywords: BibTeX, LaTeX, TeX
12 12
13;; This file is part of GNU Emacs. 13;; This file is part of GNU Emacs.
@@ -45,12 +45,8 @@
45;; 2. Calling bibtex-find-text in a string entry results in the 45;; 2. Calling bibtex-find-text in a string entry results in the
46;; error message "Can't find enclosing Bibtex field" instead of 46;; error message "Can't find enclosing Bibtex field" instead of
47;; moving to the empty string. [reported by gernot@cs.unsw.oz.au] 47;; moving to the empty string. [reported by gernot@cs.unsw.oz.au]
48;; 3. Quotes inside quote-parenthesized fields (like
49;; `author = "Stefan Sch{\"o}f"') break bibtex-validate-buffer.
50;; Further, you must use braces here, if you want to set
51;; bibtex-maintain-sorted-entries to a non-nil value.
52 48
53;; (current keeper: schoef@informatik.uni-oldenburg.de 49;; (current keeper: schoef@offis.uni-oldenburg.de
54;; previous: alarson@src.honeywell.com) 50;; previous: alarson@src.honeywell.com)
55 51
56;;; Code: 52;;; Code:
@@ -409,19 +405,10 @@ See the documentation of function bibtex-generate-autokey for further detail.")
409(defvar bibtex-autokey-edit-before-use t 405(defvar bibtex-autokey-edit-before-use t
410 "*If non-nil, user is allowed to edit the generated key before it is used.") 406 "*If non-nil, user is allowed to edit the generated key before it is used.")
411 407
412(defvar bibtex-font-lock-keywords 408;; bibtex-font-lock-keywords is a user option as well, but since the
413 (list 409;; patterns used to define this variable are defined in a later
414 '("\\(^@\\sw+\\)[ \t]*[({][ \t]*\\([^ \t\n,]*\\)" 410;; section of this file, its definition comes later.
415 (1 font-lock-keyword-face) (2 font-lock-reference-face)) 411
416 ;; reference type and reference label
417 '("^[ \t]*\\(OPT\\sw+\\)[ \t]*="
418 1 font-lock-comment-face)
419 ;; optional field names (treated as comments)
420 '("^[ \t]*\\(\\sw+\\)[ \t]*="
421 1 font-lock-variable-name-face)
422 ;; field names
423 )
424 "*Default expressions to highlight in BibTeX mode.")
425 412
426;; Syntax Table, Keybindings and BibTeX Entry List 413;; Syntax Table, Keybindings and BibTeX Entry List
427(defvar bibtex-mode-syntax-table 414(defvar bibtex-mode-syntax-table
@@ -504,6 +491,12 @@ See the documentation of function bibtex-generate-autokey for further detail.")
504 '("Clean Up Entry" . bibtex-clean-entry)) 491 '("Clean Up Entry" . bibtex-clean-entry))
505(define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-sort-entries] 492(define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-sort-entries]
506 '("Sort Entries" . bibtex-sort-entries)) 493 '("Sort Entries" . bibtex-sort-entries))
494(define-key bibtex-mode-map
495 [menu-bar bibtex-edit bibtex-validate-buffer-from-point]
496 '("Validate Entries Starting at Point" .
497 (lambda ()
498 (interactive)
499 (bibtex-validate-buffer t))))
507(define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-validate-buffer] 500(define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-validate-buffer]
508 '("Validate Entries" . bibtex-validate-buffer)) 501 '("Validate Entries" . bibtex-validate-buffer))
509 502
@@ -540,6 +533,12 @@ See the documentation of function bibtex-generate-autokey for further detail.")
540(define-key bibtex-mode-map [menu-bar entry-types bibtex-Article] 533(define-key bibtex-mode-map [menu-bar entry-types bibtex-Article]
541 '("Article in Journal" . bibtex-Article)) 534 '("Article in Journal" . bibtex-Article))
542 535
536
537;; Bug Reporting
538
539(defconst
540 bibtex-maintainer-address "Stefan Schoef <schoef@offis.uni-oldenburg.de>")
541;; current maintainer
543 542
544 543
545;; Internal Variables 544;; Internal Variables
@@ -568,7 +567,6 @@ See the documentation of function bibtex-generate-autokey for further detail.")
568;; was parsed for keys the last time. 567;; was parsed for keys the last time.
569(make-variable-buffer-local 'bibtex-keys) 568(make-variable-buffer-local 'bibtex-keys)
570 569
571
572 570
573;; Functions to Parse the BibTeX Entries 571;; Functions to Parse the BibTeX Entries
574 572
@@ -585,21 +583,85 @@ See the documentation of function bibtex-generate-autokey for further detail.")
585(defconst bibtex-text-in-cfield 2) 583(defconst bibtex-text-in-cfield 2)
586;; The regexp subexpression number of the text part in bibtex-cfield. 584;; The regexp subexpression number of the text part in bibtex-cfield.
587 585
588(defconst bibtex-field-name "[A-Za-z_-][A-Za-z0-9_-]*") 586(defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*")
589;; Regexp defining the name part of a BibTeX field. 587;; Regexp defining the name part of a BibTeX field.
590 588
591(defconst bibtex-field-const "[0-9A-Za-z][A-Za-z0-9:_+-]*" 589(defconst bibtex-field-const "[][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+")
592 "Format of a bibtex field constant.") 590;; Format of a bibtex field constant (same as bibtex-reference-key (see below))
593 591
594(defconst bibtex-field-string 592(defconst bibtex-field-string-part-not-braced
593 "[^{}]")
594;; Match field string part without braces
595
596(defconst bibtex-field-string-part-no-inner-braces
597 (concat
598 "{"
599 "\\(" bibtex-field-string-part-not-braced "\\)*"
600 "}"))
601;; Match field string part with no inner braces
602
603(defconst bibtex-field-string-part-1-inner-brace
595 (concat 604 (concat
605 "{"
596 "\\(" 606 "\\("
597 "{\\(\\({\\(\\({[^}]*}\\)\\|\\([^{}]\\)\\)*}\\)\\|\\([^{}]\\)\\)*}" 607 "\\(" bibtex-field-string-part-not-braced "\\)"
598 ;; maximal twice nested {} 608 "\\|"
599 "\\)\\|\\(" 609 "\\(" bibtex-field-string-part-no-inner-braces "\\)"
600 "\"[^\"]*[^\\\\]\"\\|\"\"" 610 "\\)*"
601 "\\)")) 611 "}"))
602;; Match either a string or an empty string. 612;; Match field string part with at most 1 inner brace
613
614(defconst bibtex-field-string-part-2-inner-braces
615 (concat
616 "{"
617 "\\("
618 "\\(" bibtex-field-string-part-not-braced "\\)"
619 "\\|"
620 "\\(" bibtex-field-string-part-no-inner-braces "\\)"
621 "\\|"
622 "\\(" bibtex-field-string-part-1-inner-brace "\\)"
623 "\\)*"
624 "}"))
625;; Match field string part with at most 2 inner braces
626
627(defconst bibtex-field-string-part-3-inner-braces
628 (concat
629 "{"
630 "\\("
631 "\\(" bibtex-field-string-part-not-braced "\\)"
632 "\\|"
633 "\\(" bibtex-field-string-part-no-inner-braces "\\)"
634 "\\|"
635 "\\(" bibtex-field-string-part-1-inner-brace "\\)"
636 "\\|"
637 "\\(" bibtex-field-string-part-2-inner-braces "\\)"
638 "\\)*"
639 "}"))
640;; Match field string part with at most 3 inner braces
641
642(defconst bibtex-field-string-braced
643 bibtex-field-string-part-3-inner-braces)
644;; Match braced field string with inner nesting level of braces at most 3
645
646(defconst bibtex-field-string-quoted
647 (concat
648 "\""
649 "\\("
650 "\\(" "[^\"\\]" "\\)" ;; every character except quote or backslash
651 "\\|"
652 "\\(" "\"[A-Za-z-]" "\\)" ;; a quote followed by a letter or dash
653 "\\|"
654 "\\(" "\\\\.\\|\n" "\\)" ;; a backslash followed by any character
655 "\\)*"
656 "\""))
657;; Match quoted field string
658
659(defconst bibtex-field-string
660 (concat
661 "\\(" bibtex-field-string-braced "\\)"
662 "\\|"
663 "\\(" bibtex-field-string-quoted "\\)"))
664;; Match a braced or quoted string
603 665
604(defconst bibtex-field-string-or-const 666(defconst bibtex-field-string-or-const
605 (concat bibtex-field-const "\\|" bibtex-field-string)) 667 (concat bibtex-field-const "\\|" bibtex-field-string))
@@ -608,7 +670,7 @@ See the documentation of function bibtex-generate-autokey for further detail.")
608(defconst bibtex-field-text 670(defconst bibtex-field-text
609 (concat 671 (concat
610 "\\(" bibtex-field-string-or-const "\\)" 672 "\\(" bibtex-field-string-or-const "\\)"
611 "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*")) 673 "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*"))
612;; Regexp defining the text part of a BibTeX field: either a string, 674;; Regexp defining the text part of a BibTeX field: either a string,
613;; or an empty string, or a constant followed by one or more # / 675;; or an empty string, or a constant followed by one or more # /
614;; constant pairs. 676;; constant pairs.
@@ -626,8 +688,9 @@ See the documentation of function bibtex-generate-autokey for further detail.")
626(defconst bibtex-reference-type "@[A-Za-z]+") 688(defconst bibtex-reference-type "@[A-Za-z]+")
627;; Regexp defining the type part of a BibTeX reference entry. 689;; Regexp defining the type part of a BibTeX reference entry.
628 690
629(defconst bibtex-reference-key "[A-Za-z][A-Za-z0-9.:;?!`'/*@_+-]*") 691(defconst bibtex-reference-key "[][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+")
630;; Regexp defining the label part of a BibTeX reference entry. 692;; Regexp defining the label part of a BibTeX reference entry (same as
693;; bibtex-field-const (see above))
631 694
632(defconst bibtex-reference-head 695(defconst bibtex-reference-head
633 (concat "^\\( \\|\t\\)*\\(" 696 (concat "^\\( \\|\t\\)*\\("
@@ -679,6 +742,21 @@ See the documentation of function bibtex-generate-autokey for further detail.")
679(defconst bibtex-text-in-string 2) 742(defconst bibtex-text-in-string 2)
680;; The regexp subexpression of the text part in bibtex-string. 743;; The regexp subexpression of the text part in bibtex-string.
681 744
745(defvar bibtex-font-lock-keywords
746 (list
747 (list bibtex-reference-maybe-empty-head
748 (list bibtex-type-in-head 'font-lock-function-name-face)
749 (list bibtex-key-in-head 'font-lock-reference-face nil t))
750 ;; reference type and reference label
751 (list (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
752 1 'font-lock-comment-face)
753 ;; optional field names (treated as comments)
754 (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
755 1 'font-lock-variable-name-face)
756 ;; field names
757 "*Default expressions to highlight in BibTeX mode."))
758;; now all needed patterns are defined
759
682(defconst bibtex-name-alignment 2) 760(defconst bibtex-name-alignment 2)
683;; Alignment for the name part in BibTeX fields. Chosen on aesthetic 761;; Alignment for the name part in BibTeX fields. Chosen on aesthetic
684;; grounds only. 762;; grounds only.
@@ -687,7 +765,6 @@ See the documentation of function bibtex-generate-autokey for further detail.")
687;; Alignment for the text part in BibTeX fields. Equal to the space 765;; Alignment for the text part in BibTeX fields. Equal to the space
688;; needed for the longest name part. 766;; needed for the longest name part.
689 767
690
691 768
692;; Helper Functions 769;; Helper Functions
693 770
@@ -878,7 +955,7 @@ See the documentation of function bibtex-generate-autokey for further detail.")
878 ;; REGEXP is not found, signals search-failed; point is left in an 955 ;; REGEXP is not found, signals search-failed; point is left in an
879 ;; undefined location. 956 ;; undefined location.
880 ;; Doesn't something like this exist already? 957 ;; Doesn't something like this exist already?
881 ; compute reasonable limits for the loop 958 ;; compute reasonable limits for the loop
882 (let* ((initial (point)) 959 (let* ((initial (point))
883 (right (if (re-search-forward regexp (point-max) t) 960 (right (if (re-search-forward regexp (point-max) t)
884 (match-end 0) 961 (match-end 0)
@@ -1199,10 +1276,23 @@ The generation algorithm works as follows:
1199 (while 1276 (while
1200 (re-search-forward 1277 (re-search-forward
1201 (concat 1278 (concat
1279 "\\(" bibtex-reference-head "\\)"
1280 "\\|"
1202 "\\(" 1281 "\\("
1203 bibtex-reference-head 1282 "^[ \t]*crossref[ \t\n]*=[ \t\n]*"
1204 "\\)\\|\\(" 1283 "\\("
1205 "^[ \t\n]*crossref[ \t\n]*=[ \t\n]*[{\"]\\([A-Za-z][]A-Za-z0-9.:;?!`'()/*@_+-]*\\)[}\"],?$" 1284 "\\({"
1285 bibtex-reference-key
1286 ;; every valid crossref entry must have the
1287 ;; form of a reference key, so we need no
1288 ;; nesting of brace etc. here
1289 "}\\)"
1290 "\\|"
1291 "\\(\""
1292 bibtex-reference-key
1293 "\"\\)"
1294 "\\)"
1295 ",?$"
1206 "\\)") 1296 "\\)")
1207 nil t) 1297 nil t)
1208 (if (and 1298 (if (and
@@ -1218,8 +1308,8 @@ The generation algorithm works as follows:
1218 (setq 1308 (setq
1219 label 1309 label
1220 (buffer-substring-no-properties 1310 (buffer-substring-no-properties
1221 (match-beginning (+ 3 bibtex-key-in-head)) 1311 (1+ (match-beginning (+ 3 bibtex-key-in-head)))
1222 (match-end (+ 3 bibtex-key-in-head))))) 1312 (1- (match-end (+ 3 bibtex-key-in-head))))))
1223 (if (not (assoc label labels)) 1313 (if (not (assoc label labels))
1224 (setq labels 1314 (setq labels
1225 (cons (list label) labels)))))) 1315 (cons (list label) labels))))))
@@ -1235,13 +1325,17 @@ The generation algorithm works as follows:
1235 (let ((fill-prefix (make-string (+ bibtex-text-alignment 1) ? ))) 1325 (let ((fill-prefix (make-string (+ bibtex-text-alignment 1) ? )))
1236 (do-auto-fill))) 1326 (do-auto-fill)))
1237 1327
1238
1239 1328
1240;; Interactive Functions: 1329;; Interactive Functions:
1241 1330
1242;;;###autoload 1331;;;###autoload
1243(defun bibtex-mode () 1332(defun bibtex-mode ()
1244 "Major mode for editing BibTeX files. 1333 "Major mode for editing BibTeX files.
1334To submit a problem report, enter `\\[bibtex-submit-bug-report]' from a
1335bibtex-mode buffer. This automatically sets up a mail buffer with
1336version information already added. You just need to add a description
1337of the problem, including a reproducable test case and send the
1338message.
1245 1339
1246\\{bibtex-mode-map} 1340\\{bibtex-mode-map}
1247 1341
@@ -1383,9 +1477,79 @@ non-nil."
1383 (setq auto-fill-function 'bibtex-auto-fill-function) 1477 (setq auto-fill-function 'bibtex-auto-fill-function)
1384 (set (make-local-variable 'font-lock-defaults) 1478 (set (make-local-variable 'font-lock-defaults)
1385 '(bibtex-font-lock-keywords 1479 '(bibtex-font-lock-keywords
1386 nil t ((?_ . "w") (?- . "w") (?$ . "\"")))) 1480 nil t ((?$ . "\"")
1481 ;; Mathematical expressions should be fontified as strings
1482 (?\" . ".")
1483 ;; Quotes are field delimiters and quote-delimited
1484 ;; entries should be fontified in the same way as
1485 ;; brace-delimited ones
1486 )))
1387 (run-hooks 'bibtex-mode-hook)) 1487 (run-hooks 'bibtex-mode-hook))
1388 1488
1489(defun bibtex-submit-bug-report ()
1490 "Submit via mail a bug report on bibtex.el."
1491 (interactive)
1492 (if (y-or-n-p "Do you want to submit a bug report on BibTeX mode? ")
1493 (progn
1494 (require 'reporter)
1495 (let ((reporter-prompt-for-summary-p t))
1496 (reporter-submit-bug-report
1497 bibtex-maintainer-address
1498 "bibtex.el"
1499 (list
1500 'system-configuration
1501 'system-configuration-options
1502 'bibtex-sort-ignore-string-entries
1503 'bibtex-maintain-sorted-entries
1504 'bibtex-field-left-delimiter
1505 'bibtex-field-right-delimiter
1506 ;; Possible sorting and parsing bugs
1507 'bibtex-mode-user-optional-fields
1508 ;; Possible format error
1509 'bibtex-predefined-strings
1510 'bibtex-string-files
1511 ;; Possible format error
1512 'bibtex-font-lock-keywords
1513 ;; Possible bugs regarding fontlocking
1514 'bibtex-autokey-names
1515 'bibtex-autokey-name-change-strings
1516 'bibtex-autokey-name-length
1517 'bibtex-autokey-name-separator
1518 'bibtex-autokey-year-length
1519 'bibtex-autokey-titlewords
1520 'bibtex-autokey-title-terminators
1521 'bibtex-autokey-titlewords-stretch
1522 'bibtex-autokey-titleword-first-ignore
1523 'bibtex-autokey-titleword-abbrevs
1524 'bibtex-autokey-titleword-change-strings
1525 'bibtex-autokey-titleword-length
1526 'bibtex-autokey-titleword-separator
1527 'bibtex-autokey-name-year-separator
1528 'bibtex-autokey-year-title-separator
1529 'bibtex-autokey-edit-before-use
1530 ;; Possible bugs regarding automatic labels
1531 'bibtex-entry-field-alist
1532 ;; Possible format error
1533 'bibtex-help-message
1534 'bibtex-include-OPTcrossref
1535 'bibtex-include-OPTkey
1536 'bibtex-include-OPTannote
1537 'bibtex-clean-entry-zap-empty-opts
1538 ;; User variables which shouldn't cause any errors
1539 )
1540 nil nil
1541 (concat "Hi Stefan,
1542
1543I want to report a bug on Emacs BibTeX mode.
1544I've read the `Bugs' section in the `Emacs' info page, so I know how
1545to make a clear and unambiguous report. I have started a fresh Emacs
1546via `"invocation-name " --no-init-file --no-site-file', thereafter (in
1547case I'm reporting on a version of `bibtex.el' which is not part of
1548the standard emacs distribution) I loaded the questionable version
1549of `bibtex.el' with `M-x load-file', and then, to produce the buggy
1550behaviour, I did the following:")))
1551 (message nil))))
1552
1389(defun bibtex-entry (entry-type &optional required optional) 1553(defun bibtex-entry (entry-type &optional required optional)
1390 "Inserts a new BibTeX entry. 1554 "Inserts a new BibTeX entry.
1391Calls the value of bibtex-add-entry-hook if that value is non-nil." 1555Calls the value of bibtex-add-entry-hook if that value is non-nil."
@@ -1487,9 +1651,10 @@ Calls the value of bibtex-add-entry-hook if that value is non-nil."
1487 '(("key" 1651 '(("key"
1488 "Key used for label creation if author and editor fields are missing")))))) 1652 "Key used for label creation if author and editor fields are missing"))))))
1489 (goto-char pnt) 1653 (goto-char pnt)
1490 (if (assoc field-name list-of-entries) 1654 (let ((comment (assoc-ignore-case field-name list-of-entries)))
1491 (message (elt (assoc field-name list-of-entries) 1)) 1655 (if comment
1492 (message "NO COMMENT AVAILABLE")))) 1656 (message (elt comment 1))
1657 (message "NO COMMENT AVAILABLE")))))
1493 1658
1494(defun bibtex-make-field (e-t) 1659(defun bibtex-make-field (e-t)
1495 "Makes a field named E-T in current BibTeX entry." 1660 "Makes a field named E-T in current BibTeX entry."
@@ -1560,7 +1725,6 @@ of the previous entry."
1560 (narrow-to-region (progn (bibtex-beginning-of-entry) (point)) 1725 (narrow-to-region (progn (bibtex-beginning-of-entry) (point))
1561 (progn (bibtex-end-of-entry) (point))))) 1726 (progn (bibtex-end-of-entry) (point)))))
1562 1727
1563
1564(defun bibtex-hide-entry-bodies (&optional arg) 1728(defun bibtex-hide-entry-bodies (&optional arg)
1565 "Hide all lines between first and last BibTeX entries not beginning with @. 1729 "Hide all lines between first and last BibTeX entries not beginning with @.
1566With argument, show all text." 1730With argument, show all text."
@@ -1704,16 +1868,22 @@ occurred, and t in all other cases."
1704 (goto-char right)))) 1868 (goto-char right))))
1705 t))) 1869 t)))
1706 1870
1707(defun bibtex-validate-buffer () 1871(defun bibtex-validate-buffer (&optional from-point)
1708 "Validate if the current BibTeX buffer is syntactically correct. 1872 "Validate if the current BibTeX buffer is syntactically correct.
1709Any garbage (e.g. comments) before the first \"@\" is not tested (so 1873Any garbage (e.g. comments) before the first \"@\" is not tested (so
1710you can put comments here)." 1874you can put comments here).
1711 (interactive) 1875With non-nil FROM-POINT it starts with entry enclosing point."
1876 (interactive "P")
1712 (let ((pnt (point)) 1877 (let ((pnt (point))
1713 (max (point-max))) 1878 (starting-point
1879 (progn
1880 (if from-point
1881 (bibtex-beginning-of-entry)
1882 (beginning-of-first-bibtex-entry))
1883 (point))))
1714 ;; looking if entries fit syntactical structure 1884 ;; looking if entries fit syntactical structure
1715 (goto-char (point-min)) 1885 (goto-char starting-point)
1716 (while (< (re-search-forward "@\\|\\'") max) 1886 (while (re-search-forward "^@" nil t)
1717 (forward-char -1) 1887 (forward-char -1)
1718 (let ((p (point))) 1888 (let ((p (point)))
1719 (if (or 1889 (if (or
@@ -1729,7 +1899,7 @@ you can put comments here)."
1729 ;; looking if entries are balanced (a single non-escaped quote 1899 ;; looking if entries are balanced (a single non-escaped quote
1730 ;; inside braces is not detected by the former check, but 1900 ;; inside braces is not detected by the former check, but
1731 ;; bibtex-sort-entries stumbles about it 1901 ;; bibtex-sort-entries stumbles about it
1732 (goto-char (point-min)) 1902 (goto-char starting-point)
1733 (map-bibtex-entries 1903 (map-bibtex-entries
1734 (function 1904 (function
1735 (lambda (current) 1905 (lambda (current)
@@ -1737,10 +1907,9 @@ you can put comments here)."
1737 (forward-sexp 2)))) 1907 (forward-sexp 2))))
1738 ;; looking for correct sort order and duplicates 1908 ;; looking for correct sort order and duplicates
1739 (if bibtex-maintain-sorted-entries 1909 (if bibtex-maintain-sorted-entries
1740 (let ((entry-name (make-string 10 255)) 1910 (let (previous
1741 (previous nil)
1742 point) 1911 point)
1743 (beginning-of-first-bibtex-entry) 1912 (goto-char starting-point)
1744 (map-bibtex-entries 1913 (map-bibtex-entries
1745 (function 1914 (function
1746 (lambda (current) 1915 (lambda (current)
@@ -1753,7 +1922,9 @@ you can put comments here)."
1753 (t 1922 (t
1754 (error "Entries out of order here!")))))))) 1923 (error "Entries out of order here!"))))))))
1755 (goto-char pnt) 1924 (goto-char pnt)
1756 (message "BibTeX buffer is syntactically correct"))) 1925 (if from-point
1926 (message "Part of BibTeX buffer starting at point is syntactically correct")
1927 (message "BibTeX buffer is syntactically correct"))))
1757 1928
1758(defun bibtex-next-field (arg) 1929(defun bibtex-next-field (arg)
1759 "Finds end of text of next BibTeX field; with arg, to its beginning." 1930 "Finds end of text of next BibTeX field; with arg, to its beginning."
@@ -1812,14 +1983,18 @@ you can put comments here)."
1812 (bibtex-inside-field) 1983 (bibtex-inside-field)
1813 (bibtex-enclosing-field) 1984 (bibtex-enclosing-field)
1814 (let ((start (match-beginning bibtex-text-in-field)) 1985 (let ((start (match-beginning bibtex-text-in-field))
1815 (stop (match-end bibtex-text-in-field))) 1986 (stop (match-end bibtex-text-in-field)))
1816 (goto-char stop)
1817 (forward-char -1)
1818 (if (looking-at "[}\"]")
1819 (delete-char 1))
1820 (goto-char start) 1987 (goto-char start)
1821 (if (looking-at "[{\"]") 1988 (while (re-search-forward bibtex-field-string stop t)
1822 (delete-char 1))))) 1989 (let ((beg (match-beginning 0))
1990 (end (match-end 0)))
1991 (goto-char end)
1992 (forward-char -1)
1993 (if (looking-at "[}\"]")
1994 (delete-char 1))
1995 (goto-char beg)
1996 (if (looking-at "[{\"]")
1997 (delete-char 1)))))))
1823 1998
1824(defun bibtex-kill-optional-field () 1999(defun bibtex-kill-optional-field ()
1825 "Kill the entire enclosing optional BibTeX field." 2000 "Kill the entire enclosing optional BibTeX field."
@@ -1847,14 +2022,13 @@ you can put comments here)."
1847 bibtex-field-right-delimiter)) 2022 bibtex-field-right-delimiter))
1848 (bibtex-find-text t)) 2023 (bibtex-find-text t))
1849 2024
1850(defun bibtex-pop-previous (arg) 2025(defun bibtex-pop (arg direction)
1851 "Replace text of current field with the text of similar field in previous entry. 2026 ;; generic function to be used by bibtex-pop-previous and bibtex-pop-next
1852With arg, go up ARG entries. Repeated, goes up so many times. May be 2027 (let (bibtex-help-message)
1853intermixed with \\[bibtex-pop-next] (bibtex-pop-next)." 2028 (bibtex-find-text nil))
1854 (interactive "p")
1855 (bibtex-inside-field)
1856 (save-excursion 2029 (save-excursion
1857 ; parse current field 2030 ;; parse current field
2031 (bibtex-inside-field)
1858 (bibtex-enclosing-field) 2032 (bibtex-enclosing-field)
1859 (let ((start-old-text (match-beginning bibtex-text-in-field)) 2033 (let ((start-old-text (match-beginning bibtex-text-in-field))
1860 (stop-old-text (match-end bibtex-text-in-field)) 2034 (stop-old-text (match-end bibtex-text-in-field))
@@ -1862,7 +2036,8 @@ intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
1862 (stop-name (match-end bibtex-name-in-field)) 2036 (stop-name (match-end bibtex-name-in-field))
1863 (new-text)) 2037 (new-text))
1864 (goto-char start-name) 2038 (goto-char start-name)
1865 ; construct regexp for previous field with same name as this one 2039 ;; construct regexp for field with same name as this one,
2040 ;; ignoring possible OPT's
1866 (let ((matching-entry 2041 (let ((matching-entry
1867 (bibtex-cfield 2042 (bibtex-cfield
1868 (buffer-substring-no-properties (if (looking-at "OPT") 2043 (buffer-substring-no-properties (if (looking-at "OPT")
@@ -1870,135 +2045,84 @@ intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
1870 (point)) 2045 (point))
1871 stop-name) 2046 stop-name)
1872 bibtex-field-text))) 2047 bibtex-field-text)))
1873 ; if executed several times in a row, start each search where the 2048 ;; if executed several times in a row, start each search where
1874 ; last one finished 2049 ;; the last one was finished
1875 (cond ((or (eq last-command 'bibtex-pop-previous) 2050 (cond ((eq last-command 'bibtex-pop)
1876 (eq last-command 'bibtex-pop-next)) 2051 t
1877 t 2052 )
1878 )
1879 (t 2053 (t
1880 (bibtex-enclosing-reference-maybe-empty-head) 2054 (bibtex-enclosing-reference-maybe-empty-head)
1881 (setq bibtex-pop-previous-search-point (point)) 2055 (setq bibtex-pop-previous-search-point (point))
1882 (setq bibtex-pop-next-search-point (match-end 0)))) 2056 (setq bibtex-pop-next-search-point (match-end 0))))
1883 (goto-char bibtex-pop-previous-search-point) 2057 (if (eq direction 'previous)
1884 ; Now search for arg'th previous similar field 2058 (goto-char bibtex-pop-previous-search-point)
2059 (goto-char bibtex-pop-next-search-point))
2060 ;; Now search for arg'th previous/next similar field
1885 (cond 2061 (cond
1886 ((re-search-backward matching-entry (point-min) t arg) 2062 ((if (eq direction 'previous)
1887 (setq new-text 2063 (re-search-backward matching-entry (point-min) t arg)
2064 (re-search-forward matching-entry (point-max) t arg))
2065 ;; Found a matching field. Remember boundaries.
2066 (setq bibtex-pop-previous-search-point (match-beginning 0))
2067 (setq bibtex-pop-next-search-point (match-end 0))
2068 (setq new-text
1888 (buffer-substring-no-properties 2069 (buffer-substring-no-properties
1889 (match-beginning bibtex-text-in-cfield) 2070 (match-beginning bibtex-text-in-field)
1890 (match-end bibtex-text-in-cfield))) 2071 (match-end bibtex-text-in-field)))
1891 ;; change delimiters, if any changes needed 2072 ;; change delimiters, if any changes needed
1892 (cond 2073 (let ((start 0)
1893 ((and 2074 old-open
1894 (equal bibtex-field-left-delimiter "{") 2075 new-open
1895 (eq (aref new-text 0) ?\") 2076 old-close
1896 (eq (aref new-text (1- (length new-text))) ?\")) 2077 new-close)
1897 (aset new-text 0 ?\{) 2078 (if (equal bibtex-field-left-delimiter "{")
1898 (aset new-text (1- (length new-text)) ?\})) 2079 (setq old-open ?\"
1899 ((and 2080 new-open ?\{
1900 (equal bibtex-field-left-delimiter "\"") 2081 old-close ?\"
1901 (eq (aref new-text 0) ?\{) 2082 new-close ?\})
1902 (eq (aref new-text (1- (length new-text))) ?\})) 2083 (setq old-open ?\{
1903 (aset new-text 0 ?\") 2084 new-open ?\"
1904 (aset new-text (1- (length new-text)) ?\")) 2085 old-close ?\}
1905 ((or 2086 new-close ?\"))
1906 (not (eq (aref new-text 0) 2087 (while (string-match bibtex-field-string new-text start)
1907 (aref bibtex-field-left-delimiter 0))) 2088 (let ((beg (match-beginning 0))
1908 (not (eq (aref new-text (1- (length new-text))) 2089 (end (1- (match-end 0))))
1909 (aref bibtex-field-right-delimiter 0)))) 2090 (if (and
1910 (setq new-text (concat bibtex-field-left-delimiter 2091 (eq (aref new-text beg) old-open)
1911 new-text 2092 (eq (aref new-text end) old-close))
1912 bibtex-field-right-delimiter)))) 2093 (progn
1913 ; Found a matching field. Remember boundaries. 2094 (aset new-text beg new-open)
1914 (setq bibtex-pop-next-search-point (match-end 0)) 2095 (aset new-text end new-close))))
1915 (setq bibtex-pop-previous-search-point (match-beginning 0)) 2096 (setq start (match-end 0))))
1916 (bibtex-flash-head) 2097 (bibtex-flash-head)
1917 ; Go back to where we started, delete old text, and pop new. 2098 ;; Go back to where we started, delete old text, and pop new.
1918 (goto-char stop-old-text) 2099 (goto-char stop-old-text)
1919 (delete-region start-old-text stop-old-text) 2100 (delete-region start-old-text stop-old-text)
1920 (insert new-text)) 2101 (insert new-text))
1921 (t ; search failed 2102 (t
1922 (error "No previous matching BibTeX field.")))))) 2103 ;; search failed
1923 (setq this-command 'bibtex-pop-previous)) 2104 (error (concat "No "
2105 (if (eq direction 'previous)
2106 "previous"
2107 "next")
2108 " matching BibTeX field.")))))))
2109 (let (bibtex-help-message)
2110 (bibtex-find-text nil))
2111 (setq this-command 'bibtex-pop))
2112
2113(defun bibtex-pop-previous (arg)
2114 "Replace text of current field with the text of similar field in previous entry.
2115With arg, goes up ARG entries. Repeated, goes up so many times. May be
2116intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
2117 (interactive "p")
2118 (bibtex-pop arg 'previous))
1924 2119
1925(defun bibtex-pop-next (arg) 2120(defun bibtex-pop-next (arg)
1926 "Replace text of current field with the text of similar field in next entry. 2121 "Replace text of current field with the text of similar field in next entry.
1927With arg, go up ARG entries. Repeated, goes up so many times. May be 2122With arg, goes down ARG entries. Repeated, goes down so many times. May be
1928intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)." 2123intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
1929 (interactive "p") 2124 (interactive "p")
1930 (bibtex-inside-field) 2125 (bibtex-pop arg 'next))
1931 (save-excursion
1932 ; parse current field
1933 (bibtex-enclosing-field)
1934 (let ((start-old-text (match-beginning bibtex-text-in-field))
1935 (stop-old-text (match-end bibtex-text-in-field))
1936 (start-name (match-beginning bibtex-name-in-field))
1937 (stop-name (match-end bibtex-name-in-field))
1938 (new-text))
1939 (goto-char start-name)
1940 ; construct regexp for next field with same name as this one,
1941 ; ignoring possible OPT's
1942 (let ((matching-entry
1943 (bibtex-cfield
1944 (buffer-substring-no-properties (if (looking-at "OPT")
1945 (+ (point) (length "OPT"))
1946 (point))
1947 stop-name)
1948 bibtex-field-text)))
1949
1950 ; if executed several times in a row, start each search where the
1951 ; last one finished
1952 (cond ((or (eq last-command 'bibtex-pop-next)
1953 (eq last-command 'bibtex-pop-previous))
1954 t
1955 )
1956 (t
1957 (bibtex-enclosing-reference-maybe-empty-head)
1958 (setq bibtex-pop-previous-search-point (point))
1959 (setq bibtex-pop-next-search-point (match-end 0))))
1960 (goto-char bibtex-pop-next-search-point)
1961
1962 ; Now search for arg'th next similar field
1963 (cond
1964 ((re-search-forward matching-entry (point-max) t arg)
1965 (setq new-text
1966 (buffer-substring-no-properties
1967 (match-beginning bibtex-text-in-cfield)
1968 (match-end bibtex-text-in-cfield)))
1969 ;; change delimiters, if any changes needed
1970 (cond
1971 ((and
1972 (equal bibtex-field-left-delimiter "{")
1973 (eq (aref new-text 0) ?\")
1974 (eq (aref new-text (1- (length new-text))) ?\"))
1975 (aset new-text 0 ?\{)
1976 (aset new-text (1- (length new-text)) ?\}))
1977 ((and
1978 (equal bibtex-field-left-delimiter "\"")
1979 (eq (aref new-text 0) ?\{)
1980 (eq (aref new-text (1- (length new-text))) ?\}))
1981 (aset new-text 0 ?\")
1982 (aset new-text (1- (length new-text)) ?\"))
1983 ((or
1984 (not (eq (aref new-text 0)
1985 (aref bibtex-field-left-delimiter 0)))
1986 (not (eq (aref new-text (1- (length new-text)))
1987 (aref bibtex-field-right-delimiter 0))))
1988 (setq new-text (concat bibtex-field-left-delimiter
1989 new-text
1990 bibtex-field-right-delimiter))))
1991 ; Found a matching field. Remember boundaries.
1992 (setq bibtex-pop-next-search-point (match-end 0))
1993 (setq bibtex-pop-previous-search-point (match-beginning 0))
1994 (bibtex-flash-head)
1995 ; Go back to where we started, delete old text, and pop new.
1996 (goto-char stop-old-text)
1997 (delete-region start-old-text stop-old-text)
1998 (insert new-text))
1999 (t ; search failed
2000 (error "No next matching BibTeX field."))))))
2001 (setq this-command 'bibtex-pop-next))
2002 2126
2003(defun bibtex-clean-entry (&optional arg) 2127(defun bibtex-clean-entry (&optional arg)
2004 "Finish editing the current BibTeX entry and clean it up. 2128 "Finish editing the current BibTeX entry and clean it up.
@@ -2023,10 +2147,7 @@ given, calculate a new entry label."
2023 (if (looking-at "\\(OPTcrossref\\)\\|\\(crossref\\)") 2147 (if (looking-at "\\(OPTcrossref\\)\\|\\(crossref\\)")
2024 (progn 2148 (progn
2025 (goto-char begin-text) 2149 (goto-char begin-text)
2026 (if (not (looking-at 2150 (if (not (looking-at "\\(\"\"\\)\\|\\({}\\)"))
2027 (concat
2028 bibtex-field-left-delimiter
2029 bibtex-field-right-delimiter)))
2030 (setq crossref-there t)))))) 2151 (setq crossref-there t))))))
2031 (bibtex-enclosing-reference-maybe-empty-head) 2152 (bibtex-enclosing-reference-maybe-empty-head)
2032 (re-search-forward bibtex-reference-type) 2153 (re-search-forward bibtex-reference-type)
@@ -2046,10 +2167,7 @@ given, calculate a new entry label."
2046 (looking-at "OPT") 2167 (looking-at "OPT")
2047 bibtex-clean-entry-zap-empty-opts) 2168 bibtex-clean-entry-zap-empty-opts)
2048 (goto-char begin-text) 2169 (goto-char begin-text)
2049 (if (looking-at 2170 (if (looking-at "\\(\"\"\\)\\|\\({}\\)")
2050 (concat
2051 bibtex-field-left-delimiter
2052 bibtex-field-right-delimiter))
2053 ;; empty: delete whole field if really optional 2171 ;; empty: delete whole field if really optional
2054 ;; (missing crossref handled) or complain 2172 ;; (missing crossref handled) or complain
2055 (if (and 2173 (if (and
@@ -2087,26 +2205,25 @@ given, calculate a new entry label."
2087 (search-forward "=") 2205 (search-forward "=")
2088 (delete-horizontal-space) 2206 (delete-horizontal-space)
2089 (indent-to-column bibtex-text-alignment)) 2207 (indent-to-column bibtex-text-alignment))
2090 (goto-char begin-field) ; and loop to go through next test 2208 (goto-char begin-field)
2209 ;; and loop to go through next test
2091 )) 2210 ))
2092 (t 2211 (t
2093 (goto-char begin-text) 2212 (goto-char begin-text)
2094 (cond ((looking-at (concat 2213 (cond ((looking-at "\\(\"[0-9]+\"\\)\\|\\({[0-9]+}\\)")
2095 bibtex-field-left-delimiter
2096 "[0-9]+"
2097 bibtex-field-right-delimiter))
2098 ;; if numerical, 2214 ;; if numerical,
2099 (goto-char end-text) 2215 (goto-char end-text)
2100 (delete-char -1) ; delete enclosing double-quotes 2216 (delete-char -1)
2101 (goto-char begin-text) 2217 (goto-char begin-text)
2102 (delete-char 1) 2218 (delete-char 1)
2103 (goto-char end-field) ; go to end for next search 2219 ;; delete enclosing delimiters
2104 (forward-char -2) ; to compensate for the 2 quotes deleted 2220 (goto-char end-field)
2221 ;; go to end for next search
2222 (forward-char -2)
2223 ;; to compensate for the 2 delimiters deleted
2105 ) 2224 )
2106 ((looking-at (concat 2225 ((looking-at "\\(\"\"\\)\\|\\({}\\)")
2107 bibtex-field-left-delimiter 2226 ;; if empty field, complain
2108 bibtex-field-right-delimiter))
2109 ;; if empty quotes, complain
2110 (forward-char 1) 2227 (forward-char 1)
2111 (if (not (or (equal (buffer-substring-no-properties 2228 (if (not (or (equal (buffer-substring-no-properties
2112 begin-name 2229 begin-name
@@ -2190,32 +2307,49 @@ If point is not after the part of a word, all strings are listed."
2190 (string-list (copy-sequence bibtex-completion-candidates)) 2307 (string-list (copy-sequence bibtex-completion-candidates))
2191 (case-fold-search t) 2308 (case-fold-search t)
2192 (completion (save-excursion 2309 (completion (save-excursion
2193 (progn 2310 (while (re-search-backward
2194 (while (re-search-backward 2311 bibtex-string (point-min) t)
2195 bibtex-string (point-min) t)
2196 (setq string-list
2197 (cons
2198 (list
2199 (buffer-substring-no-properties
2200 (match-beginning bibtex-key-in-string)
2201 (match-end bibtex-key-in-string)))
2202 string-list)))
2203 (setq string-list 2312 (setq string-list
2204 (sort string-list 2313 (cons
2205 (lambda(x y) 2314 (list
2206 (string-lessp 2315 (buffer-substring-no-properties
2207 (car x) 2316 (match-beginning bibtex-key-in-string)
2208 (car y))))) 2317 (match-end bibtex-key-in-string)))
2209 (try-completion part-of-word string-list))))) 2318 string-list)))
2319 (setq string-list
2320 (sort string-list
2321 (lambda(x y)
2322 (string-lessp
2323 (car x)
2324 (car y)))))
2325 (try-completion part-of-word string-list))))
2210 (cond ((eq completion t) 2326 (cond ((eq completion t)
2211 (bibtex-remove-double-quotes-or-braces)) 2327 ;; remove double-quotes or braces if field is no concatenation
2328 (save-excursion
2329 (bibtex-inside-field)
2330 (bibtex-enclosing-field)
2331 (let ((end (match-end bibtex-text-in-field)))
2332 (goto-char (match-beginning bibtex-text-in-field))
2333 (if (and
2334 (looking-at bibtex-field-string)
2335 (equal (match-end 0) end))
2336 (bibtex-remove-double-quotes-or-braces)))))
2212 ((null completion) 2337 ((null completion)
2213 (error "Can't find completion for \"%s\"" part-of-word)) 2338 (error "Can't find completion for \"%s\"" part-of-word))
2214 ((not (string= part-of-word completion)) 2339 ((not (string= part-of-word completion))
2215 (delete-region beg end) 2340 (delete-region beg end)
2216 (insert completion) 2341 (insert completion)
2217 (if (assoc completion string-list) 2342 (if (assoc completion string-list)
2218 (bibtex-remove-double-quotes-or-braces))) 2343 ;; remove double-quotes or braces if field is no concatenation
2344 (save-excursion
2345 (bibtex-inside-field)
2346 (bibtex-enclosing-field)
2347 (let ((end (match-end bibtex-text-in-field)))
2348 (goto-char (match-beginning bibtex-text-in-field))
2349 (if (and
2350 (looking-at bibtex-field-string)
2351 (equal (match-end 0) end))
2352 (bibtex-remove-double-quotes-or-braces))))))
2219 (t 2353 (t
2220 (message "Making completion list...") 2354 (message "Making completion list...")
2221 (let ((list (all-completions part-of-word string-list))) 2355 (let ((list (all-completions part-of-word string-list)))
@@ -2294,11 +2428,9 @@ If point is not after the part of a word, all strings are listed."
2294 (forward-line -1) 2428 (forward-line -1)
2295 (forward-char 10)) 2429 (forward-char 10))
2296 2430
2297
2298 2431
2299;; Make BibTeX a Feature 2432;; Make BibTeX a Feature
2300 2433
2301(provide 'bibtex) 2434(provide 'bibtex)
2302 2435
2303
2304;;; bibtex.el ends here 2436;;; bibtex.el ends here