Subject: bug#36252: 26.1; bibtex-generate-autokey does not use use date field

From: Patrick M. Niedzielski <[email-masked]>
Date: Sat, 05 Dec 2020 09:20:52 +0000

Lars Ingebrigtsen <[email-masked]> skribis:
> Lars Ingebrigtsen <[email-masked]> writes: 
> 
> This was five weeks ago, and there was no response, so I'm 
> closing this bug report.  If progress can be made here, please 
> respond to the debbugs mail address, and we'll reopen the bug 
> report. 

I’d like to reopen this bug, and submit the attached patch which I 
believe fixes the issue. This patch teaches 
‘bibtex-generate-autokey’ to prefer an ISO8601-formatted ‘date’ 
field when present, and fall back to a ‘year’, and is implemented 
using Lars’ ISO8601 parsing functions.

Just some implementation notes: I don’t believe Ryan’s original 
patch works as documented when ‘bibtex-autokey-use-crossref’ is 
non-nil.  In this case, his patch would seem to prefer a 
crossref’d entry’s ‘year’ field to a local entry’s ‘date’ field. 
More concretely, with the following BibLaTeX,

  @misc{doe1995some,
    title = {Some work},
    author = {John Doe},
    year = {1995},
    date = {1995-01-01},
  } 

  @misc{,
    title = {Another work},
    author = {Anon Y. Mous},
    date = {1990-03-12},
    crossref = {entry1},
  }

When generating a key for entry2, the original patch would prefer 
using the year 1995 to the year 1990, which is unintuitive. The 
attached patch implements a different behavior instead, in which 
an entry’s own ‘year/date’ field are prefered to the crossref’d 
entry’s ‘year/date’ field. In the above case, 
‘bibtex-generate-autokey’ will generate a entry key with the year 
1990 rather than 1995.

Additionally, we prefer to use the ‘date’ field when present over 
the ‘year’ field. This behavior is probably more correct, since 
BibLaTeX deprecated the ‘year’ field in favor of its own ‘date’ 
field, which only should occur in BibLaTeX-flavor files. Note that 
this is a breaking change from the prior behavior, but only when 
an entry has incompatible ‘date’ and ‘year’ fields.  If a file is 
meant to support both BibTeX and BibLaTeX, the ‘date’ and ‘year’ 
fields should contain the same information.

The attached patch implements the above behavior.

Best,
Patrick

>From 26cb162d42e7fd234506a5f847fbfb73adb68105 Mon Sep 17 00:00:00 2001
From: "Patrick M. Niedzielski" <[email-masked]>
Date: Sun, 29 Nov 2020 02:09:47 +0000
Subject: [PATCH] Prefer date field to year field in BibTex entry

The bibtex.el package contains functionality to automatically generate
a key for a BibTeX entry using author/editor, year, and title
information in the entry.  The BibLaTeX dialect has deprecated the
'year' field (and 'month') in favor of an ISO8601-formatted 'date'
field.  This patch teaches the 'bibtex-generate-autokey' function to
prefer a 'date' field when present, and fall back to a 'year' field
for bibtex compatibility.
---
 lisp/textmodes/bibtex.el | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index c9e21e58f6..fe468d261d 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -2751,10 +2751,16 @@ and `bibtex-autokey-names-stretch'."
              (bibtex-autokey-abbrev name bibtex-autokey-name-length))))
 
 (defun bibtex-autokey-get-year ()
-  "Return year field contents as a string obeying `bibtex-autokey-year-length'."
-  (let ((yearfield (bibtex-autokey-get-field "year")))
-    (substring yearfield (max 0 (- (length yearfield)
-                                   bibtex-autokey-year-length)))))
+  "If date field exists, return year component of the ISO8601-formatted
+date field contents as a string obeying `bibtex-autokey-year-length'.
+Otherwise, return year field contents as a string obeying
+`bibtex-autokey-year-length'."
+  (let* ((yearfield (bibtex-autokey-get-field "year\\|date"))
+         (dateyear  (if (iso8601-valid-p yearfield)
+                        (decoded-time-year (iso8601-parse yearfield))
+                      nil))
+         (year      (if dateyear (number-to-string dateyear) "")))
+    (substring year (max 0 (- (length year) bibtex-autokey-year-length)))))
 
 (defun bibtex-autokey-get-title ()
   "Get title field contents up to a terminator.
@@ -2837,12 +2843,16 @@ The name part:
 
 The year part:
  1. Build the year part of the key by truncating the content of the year
-    field to the rightmost `bibtex-autokey-year-length' digits (useful
-    values are 2 and 4).
- 2. If the year field (or any other field required to generate the key)
-    is absent, but the entry has a valid crossref field and
-    `bibtex-autokey-use-crossref' is non-nil, use the field of the
-    crossreferenced entry instead.
+    component of the ISO8601-formatted date field to the rightmost
+    `bibtex-autokey-year-length' digits (useful values are 2 and 4).
+ 2. If the date field is absent, but the entry has a year field, build the
+    year part of the key by truncating the year field to the rightmost
+    `bibtex-autokey-year-length' digits.
+ 3. If both the year field and the date field (or any other field
+    required to generate the key) are absent, but the entry has a
+    valid crossref field and `bibtex-autokey-use-crossref' is
+    non-nil, use the date or year field of the crossreferenced entry
+    instead.
 
 The title part
  1. Change the content of the title field according to
-- 
2.29.2