From 83c6eccaee060b989695281f312a623fc4b9aaca Mon Sep 17 00:00:00 2001 From: David Lukes Date: Fri, 25 Feb 2022 14:21:44 +0100 Subject: [PATCH] oc-basic: Better handling of CSL-JSON dates * lisp/oc-basic.el (org-cite-basic--parse-json): Make date-parsing and year extraction more resilient. Provide more informative errors when it fails. A string-based date is not only indicated by the key 'raw, but also possibly by the key 'literal. String-based dates come in various formats, not necessarily yyyy-mm-dd. So extracting the first sequence of 4 digits is arguably a better heuristic for getting the publication year than splitting the string on - and getting the car of that. On error, include `value' in the message, which contains the original value with actionable information, whereas the previously included `date' is always nil in that case. TINYCHANGE --- lisp/oc-basic.el | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lisp/oc-basic.el b/lisp/oc-basic.el index d82406aff..81b7e4471 100644 --- a/lisp/oc-basic.el +++ b/lisp/oc-basic.el @@ -178,21 +178,29 @@ Return a hash table with citation references as keys and fields alist as values. " and "))) ('issued ;; Date are expressed as an array - ;; (`date-parts') or a "string (`raw'). - ;; In both cases, extract the year and - ;; associate it to `year' field, for - ;; compatibility with BibTeX format. + ;; (`date-parts') or a "string (`raw' + ;; or `literal'). In both cases, + ;; extract the year and associate it + ;; to `year' field, for compatibility + ;; with BibTeX format. (let ((date (or (alist-get 'date-parts value) + (alist-get 'literal value) (alist-get 'raw value)))) (cons 'year (cond ((consp date) (caar date)) ((stringp date) - (car (split-string date "-"))) + (replace-regexp-in-string + (rx + (minimal-match (zero-or-more anything)) + (group-n 1 (repeat 4 digit)) + (zero-or-more anything)) + (rx (backref 1)) + date)) (t (error "Unknown CSL-JSON date format: %S" - date)))))) + value)))))) (_ (cons field value)))) item)