From: "Francesco Potortì" <pot@gnu.org>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: 44597@debbugs.gnu.org
Subject: bug#44597: 26.3; bibtex should allow reverse sorting
Date: Sun, 06 Dec 2020 17:16:42 +0100 [thread overview]
Message-ID: <E1klwiI-004kvG-Le@tucano.isti.cnr.it> (raw)
In-Reply-To: <87sg99vviz.fsf@gnus.org> (larsi@gnus.org)
>> 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)))))
next prev parent reply other threads:[~2020-12-06 16:16 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-12 18:30 bug#44597: 26.3; bibtex should allow reverse sorting Francesco Potortì
2020-11-14 16:41 ` Lars Ingebrigtsen
2020-11-14 17:31 ` Francesco Potortì
2020-11-16 21:31 ` Lars Ingebrigtsen
2020-12-06 16:16 ` Francesco Potortì [this message]
2020-12-07 13:22 ` Lars Ingebrigtsen
2020-12-07 18:00 ` Francesco Potortì
2020-12-09 14:20 ` Roland Winkler
2020-12-09 9:59 ` Francesco Potortì
2020-12-09 12:59 ` Lars Ingebrigtsen
2020-12-12 16:09 ` Roland Winkler
2020-12-13 16:57 ` Francesco Potortì
2020-12-18 22:48 ` Roland Winkler
2020-12-19 0:16 ` Francesco Potortì
2020-12-19 5:05 ` Roland Winkler
2020-12-19 10:37 ` Francesco Potortì
2022-12-30 6:29 ` Roland Winkler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1klwiI-004kvG-Le@tucano.isti.cnr.it \
--to=pot@gnu.org \
--cc=44597@debbugs.gnu.org \
--cc=larsi@gnus.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.