bibtex-mode: Permit user-defined schemes for sorting entries.
* lisp/textmodes/bibtex.el (bibtex-maintain-sorted-entries): New allowed value (INDEX-FUN PREDICATE). (bibtex-entry-index, bibtex-lessp): Use it. (bibtex-init-sort): Rename from bibtex-init-sort-entry-class-alist.
This commit is contained in:
parent
c7fdc17c16
commit
9f7e0a3e7d
2 changed files with 66 additions and 38 deletions
4
etc/NEWS
4
etc/NEWS
|
@ -1481,6 +1481,10 @@ completions with more information in completion prefix and suffix.
|
|||
This new option allows the user to customize how case is converted
|
||||
when unifying entries.
|
||||
|
||||
---
|
||||
*** The user option `bibtex-maintain-sorted-entries' now permits
|
||||
user-defined sorting schemes.
|
||||
|
||||
+++
|
||||
*** 'format-seconds' can now be used for sub-second times.
|
||||
The new optional "," parameter has been added, and
|
||||
|
|
|
@ -204,20 +204,34 @@ narrowed to just the entry."
|
|||
(defcustom bibtex-maintain-sorted-entries nil
|
||||
"If non-nil, BibTeX mode maintains all entries in sorted order.
|
||||
Allowed non-nil values are:
|
||||
plain or t All entries are sorted alphabetically.
|
||||
crossref All entries are sorted alphabetically unless an entry has a
|
||||
plain or t Sort entries alphabetically by keys.
|
||||
crossref Sort entries alphabetically by keys unless an entry has a
|
||||
crossref field. These crossrefed entries are placed in
|
||||
alphabetical order immediately preceding the main entry.
|
||||
entry-class The entries are divided into classes according to their
|
||||
entry type, see `bibtex-sort-entry-class'. Within each class
|
||||
the entries are sorted alphabetically.
|
||||
sort entries alphabetically by keys.
|
||||
(INDEX-FUN PREDICATE)
|
||||
(INDEX-FUN PREDICATE INIT-FUN) Sort entries using INDEX-FUN and PREDICATE.
|
||||
Function INDEX-FUN is called for each entry with point at the
|
||||
end of the head of the entry. Its return values are used to
|
||||
sort the entries using PREDICATE. Function PREDICATE takes two
|
||||
arguments INDEX1 and INDEX2 as returned by INDEX-FUN.
|
||||
It should return non-nil if INDEX1 should sort before INDEX2.
|
||||
If INIT-FUN is non-nil, it should be a function that is called
|
||||
with no arguments to initialize the sorting.
|
||||
See also `bibtex-sort-ignore-string-entries'."
|
||||
:group 'bibtex
|
||||
:version "28.1"
|
||||
:type '(choice (const nil)
|
||||
(const t)
|
||||
(const plain)
|
||||
(const crossref)
|
||||
(const entry-class)
|
||||
(const t))
|
||||
(group :tag "Custom scheme"
|
||||
(function :tag "Index-Fun")
|
||||
(function :tag "Predicate")
|
||||
(option (function :tag "Init-Fun"))))
|
||||
:safe (lambda (a) (memq a '(nil t plain crossref entry-class))))
|
||||
|
||||
(defcustom bibtex-sort-entry-class
|
||||
|
@ -3998,28 +4012,15 @@ If mark is active count entries in region, if not in whole buffer."
|
|||
(narrow-to-region (bibtex-beginning-of-entry)
|
||||
(bibtex-end-of-entry))))
|
||||
|
||||
(defun bibtex-entry-index ()
|
||||
"Return index of BibTeX entry head at or past position of point.
|
||||
The index is a list (KEY CROSSREF-KEY ENTRY-TYPE) that is used for sorting
|
||||
the entries of the BibTeX buffer. CROSSREF-KEY is nil unless the value
|
||||
of `bibtex-maintain-sorted-entries' is `crossref'. Move point to the end
|
||||
of the head of the entry found. Return nil if no entry found."
|
||||
(let ((case-fold-search t))
|
||||
(if (re-search-forward bibtex-entry-maybe-empty-head nil t)
|
||||
(let ((key (bibtex-key-in-head))
|
||||
;; all entry types should be downcase (for ease of comparison)
|
||||
(entry-type (downcase (bibtex-type-in-head))))
|
||||
;; Don't search CROSSREF-KEY if we don't need it.
|
||||
(if (eq bibtex-maintain-sorted-entries 'crossref)
|
||||
(let ((bounds (bibtex-search-forward-field
|
||||
"\\(OPT\\)?crossref" t)))
|
||||
(list key
|
||||
(if bounds (bibtex-text-in-field-bounds bounds t))
|
||||
entry-type))
|
||||
(list key nil entry-type))))))
|
||||
|
||||
(defun bibtex-init-sort-entry-class-alist ()
|
||||
"Initialize `bibtex-sort-entry-class-alist' (buffer-local)."
|
||||
(define-obsolete-function-alias 'bibtex-init-sort-entry-class-alist
|
||||
#'bibtex-init-sort "28.1")
|
||||
(defun bibtex-init-sort (&optional parse)
|
||||
"Initialize sorting of BibTeX entries.
|
||||
If PARSE is non-nil, also parse BibTeX keys."
|
||||
(if (or parse
|
||||
(and (eq bibtex-maintain-sorted-entries 'crossref)
|
||||
(functionp bibtex-reference-keys)))
|
||||
(bibtex-parse-keys))
|
||||
(unless (local-variable-p 'bibtex-sort-entry-class-alist)
|
||||
(setq-local bibtex-sort-entry-class-alist
|
||||
(let ((i -1) alist)
|
||||
|
@ -4029,7 +4030,36 @@ of the head of the entry found. Return nil if no entry found."
|
|||
;; All entry types should be downcase (for ease of comparison).
|
||||
(push (cons (if (stringp entry) (downcase entry) entry) i)
|
||||
alist)))
|
||||
alist))))
|
||||
alist)))
|
||||
;; Custom sorting scheme
|
||||
(if (and (consp bibtex-maintain-sorted-entries)
|
||||
(nth 2 bibtex-maintain-sorted-entries))
|
||||
(funcall (nth 2 bibtex-maintain-sorted-entries))))
|
||||
|
||||
(defun bibtex-entry-index ()
|
||||
"Return index of BibTeX entry head at or past position of point.
|
||||
The index is a list (KEY CROSSREF-KEY ENTRY-TYPE) that is used for sorting
|
||||
the entries of the BibTeX buffer. CROSSREF-KEY is nil unless the value of
|
||||
`bibtex-maintain-sorted-entries' is `crossref'.
|
||||
If `bibtex-maintain-sorted-entries' is (INDEX-FUN ...), the index is the return
|
||||
value of INDEX-FUN. Return nil if no entry found.
|
||||
Move point to the end of the head of the entry found."
|
||||
(let ((case-fold-search t))
|
||||
(if (re-search-forward bibtex-entry-maybe-empty-head nil t)
|
||||
(if (consp bibtex-maintain-sorted-entries)
|
||||
;; Custom sorting scheme
|
||||
(funcall (car bibtex-maintain-sorted-entries))
|
||||
(let ((key (bibtex-key-in-head))
|
||||
;; ENTRY-TYPE should be downcase (for ease of comparison)
|
||||
(entry-type (downcase (bibtex-type-in-head)))
|
||||
bounds)
|
||||
(list key
|
||||
;; Don't search CROSSREF-KEY if we don't need it.
|
||||
(and (eq bibtex-maintain-sorted-entries 'crossref)
|
||||
(setq bounds (bibtex-search-forward-field
|
||||
"\\(OPT\\)?crossref" t))
|
||||
(bibtex-text-in-field-bounds bounds t))
|
||||
entry-type))))))
|
||||
|
||||
(defun bibtex-lessp (index1 index2)
|
||||
"Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
|
||||
|
@ -4038,6 +4068,8 @@ The predicate depends on the variable `bibtex-maintain-sorted-entries'.
|
|||
If its value is nil use plain sorting."
|
||||
(cond ((not index1) (not index2)) ; indices can be nil
|
||||
((not index2) nil)
|
||||
((consp bibtex-maintain-sorted-entries)
|
||||
(funcall (cadr bibtex-maintain-sorted-entries) index1 index2))
|
||||
((eq bibtex-maintain-sorted-entries 'crossref)
|
||||
;; CROSSREF-KEY may be nil or it can point to an entry
|
||||
;; in another BibTeX file. In both cases we ignore CROSSREF-KEY.
|
||||
|
@ -4074,10 +4106,7 @@ affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
|
|||
are ignored."
|
||||
(interactive)
|
||||
(bibtex-beginning-of-first-entry) ; Needed by `sort-subr'
|
||||
(bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
|
||||
(if (and (eq bibtex-maintain-sorted-entries 'crossref)
|
||||
(functionp bibtex-reference-keys))
|
||||
(bibtex-parse-keys)) ; Needed by `bibtex-lessp'.
|
||||
(bibtex-init-sort) ; Needed by `bibtex-lessp'.
|
||||
(sort-subr nil
|
||||
'bibtex-skip-to-valid-entry ; NEXTREC function
|
||||
'bibtex-end-of-entry ; ENDREC function
|
||||
|
@ -4228,10 +4257,7 @@ If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
|
|||
search to look for place for KEY. This requires that buffer is sorted,
|
||||
see `bibtex-validate'.
|
||||
Return t if preparation was successful or nil if entry KEY already exists."
|
||||
(bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
|
||||
(if (and (eq bibtex-maintain-sorted-entries 'crossref)
|
||||
(functionp bibtex-reference-keys))
|
||||
(bibtex-parse-keys)) ; Needed by `bibtex-lessp'.
|
||||
(bibtex-init-sort) ; Needed by `bibtex-lessp'.
|
||||
(let ((key (nth 0 index))
|
||||
key-exist)
|
||||
(cond ((or (null key)
|
||||
|
@ -4322,9 +4348,7 @@ Return t if test was successful, nil otherwise."
|
|||
(setq syntax-error t)
|
||||
|
||||
;; Check for duplicate keys and correct sort order
|
||||
(bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
|
||||
(bibtex-parse-keys) ; Possibly needed by `bibtex-lessp'.
|
||||
; Always needed by subsequent global key check.
|
||||
(bibtex-init-sort t) ; Needed by `bibtex-lessp' and global key check.
|
||||
(let (previous current key-list)
|
||||
(bibtex-progress-message "Checking for duplicate keys")
|
||||
(bibtex-map-entries
|
||||
|
|
Loading…
Add table
Reference in a new issue