[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#44597: 26.3; bibtex should allow reverse sorting
From: |
Francesco Potortì |
Subject: |
bug#44597: 26.3; bibtex should allow reverse sorting |
Date: |
Sun, 06 Dec 2020 17:16:42 +0100 |
>> Ideally, bibtex.el should provide a hook where one can install any
>> function for sorting. The hook should get some arguments (the type of
>> entry, the name of entry, the date, a bibtex custom field and maybe
>> others). That would make bibtex.el more generally flexible.
>
>Yes, I think introducing a variable to control the sorting would be a
>good idea. It'd default to `bibtex-lessp' (or rather, something that
>does the same), but (as you say) have an input that makes implementing
>other sorting functions easier.
>
>Patches welcome. :-)
This is a patch that improves things, in my opinion. This is not the
ideal situation I mentioned above, but "il meglio è il nemico del bene"
(best is enemy of good). So here you are, this one satisfies my needs
and is hoefully a step towards a more general solution.
diff -pub /home/pot/elisp/bibtex-trunk.el /home/pot/elisp/bibtex.el
--- /home/pot/elisp/bibtex-trunk.el 2020-12-03 18:52:11.000000000 +0100
+++ /home/pot/elisp/bibtex.el 2020-12-06 17:02:06.000000000 +0100
@@ -202,7 +202,10 @@ 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.
+plain or t Entries are sorted alphabetically.
+reverse Entries are sorted in reverse alphabetic order.
+date Entries are sorted by date.
+reversedate Entries are reverse sorted by date, starting with newest.
crossref All entries are sorted alphabetically unless an entry has a
crossref field. These crossrefed entries are placed in
alphabetical order immediately preceding the main entry.
@@ -213,10 +216,13 @@ See also `bibtex-sort-ignore-string-entr
:group 'bibtex
:type '(choice (const nil)
(const plain)
+ (const reverse)
+ (const date)
+ (const reversedate)
(const crossref)
(const entry-class)
(const t))
- :safe (lambda (a) (memq a '(nil t plain crossref entry-class))))
+ :safe (lambda (a) (memq a '(nil t plain reverse date reversedate crossref
entry-class))))
(defcustom bibtex-sort-entry-class
'(("String")
@@ -3993,23 +3999,25 @@ If mark is active count entries in regio
(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."
+The index is a list (KEY CROSSREF-KEY ENTRY-TYPE DATE) 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))))
+ (crossref-key nil)
+ (entry-type (downcase (bibtex-type-in-head)))
+ (date (bibtex-get-date)))
;; Don't search CROSSREF-KEY if we don't need it.
- (if (eq bibtex-maintain-sorted-entries 'crossref)
+ (when (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))))))
+ (when bounds
+ (setq crossref-key (bibtex-text-in-field-bounds bounds t)))))
+ (list key crossref-key entry-type date)))))
(defun bibtex-init-sort-entry-class-alist ()
"Initialize `bibtex-sort-entry-class-alist' (buffer-local)."
@@ -4024,6 +4032,28 @@ of the head of the entry found. Return
alist)))
alist))))
+(defun bibtex-get-date (&optional latest)
+ "Return date of current entry as a string in yyyy-mm-dd format.
+If any part of date is missing, use the earliest possible missing
+value, unless LATEST is not nil, in which case use the latest possible
+missing value."
+ (let ((date (bibtex-autokey-get-field "date")))
+ (if (string> date "")
+ date
+ (let ((year (bibtex-autokey-get-field "year"))
+ (month (bibtex-autokey-get-field
+ "month" '(("^jan.*". "01") ("^feb.*". "02") ("^mar.*". "03")
+ ("^apr.*". "04") ("^may.*". "05") ("^jun.*". "06")
+ ("^jul.*". "07") ("^aug.*". "08") ("^sep.*". "09")
+ ("^oct.*". "10") ("^nov.*". "11") ("^dec.*".
"12"))))
+ (day (bibtex-autokey-get-field "days" '(("-.*" . "")))))
+ (when (string= year "") (setq year (if latest "9999" "1900")))
+ (when (string= month "") (setq month (if latest "12" "01")))
+ (when (string= day "") (setq day (if latest "31" "01")))
+ (concat year "-" month "-" (if (= (string-width day) 1)
+ (concat "0" day)
+ (substring day 0 2)))))))
+
(defun bibtex-lessp (index1 index2)
"Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
Each index is a list (KEY CROSSREF-KEY ENTRY-TYPE).
@@ -4056,6 +4086,12 @@ If its value is nil use plain sorting."
(or (< n1 n2)
(and (= n1 n2)
(string-lessp (car index1) (car index2))))))
+ ((eq bibtex-maintain-sorted-entries 'reversedate)
+ (string-lessp (nth 3 index2) (nth 3 index1)))
+ ((eq bibtex-maintain-sorted-entries 'date)
+ (string-lessp (nth 3 index1) (nth 3 index2)))
+ ((eq bibtex-maintain-sorted-entries 'reverse)
+ (string-lessp (car index2) (car index1)))
(t ; (eq bibtex-maintain-sorted-entries 'plain)
(string-lessp (car index1) (car index2)))))
- bug#44597: 26.3; bibtex should allow reverse sorting,
Francesco Potortì <=