From d65761a9292822230a14056c166fe2e216bf869d Mon Sep 17 00:00:00 2001 From: Bruce D'Arcus Date: Mon, 29 Aug 2022 13:59:36 -0400 Subject: [PATCH] Make bib parser configurable --- citar-cache.el | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/citar-cache.el b/citar-cache.el index 15e5cb57..594d40f9 100644 --- a/citar-cache.el +++ b/citar-cache.el @@ -15,6 +15,7 @@ (require 'citar-format) (require 'seq) (require 'map) +(require 'files) (declare-function citar--get-template "citar" (template-name)) (declare-function citar--fields-to-parse "citar" ()) @@ -142,13 +143,14 @@ need them." (cachedfmtstr (and cached (citar-cache--bibliography-format-string cached))) (props (citar-cache--get-bibliography-props filename cachedprops)) (fmtstr (citar--get-template 'completion)) + (ext (file-name-extension filename)) (bib (or cached (citar-cache--make-bibliography filename)))) (prog1 bib ;; Set the format string so it's correct when updating bibliography (setf (citar-cache--bibliography-format-string bib) fmtstr) ;; Update bibliography if needed or forced (if (or force-update - (citar-cache--update-bibliography-p cachedprops props)) + (funcall (citar-cache--get-update-p ext) cachedprops props)) (citar-cache--update-bibliography bib props) ;; Otherwise, update props anyway in case mtime has changed: (setf (citar-cache--bibliography-props bib) props) @@ -209,7 +211,7 @@ re-hashing the file contents." (buffer-hash))))) `(:size ,size :mtime ,mtime :hash ,hash :fields ,fields))) -(defun citar-cache--update-bibliography-p (oldprops newprops) +(defun citar-cache--update-parsebib-bibliography-p (oldprops newprops) "Return whether bibliography needs to be updated. Compare NEWPROPS with OLDPROPS and decide whether the file contents have changed or the list of bibliography fields to be @@ -218,6 +220,36 @@ parsed is different." (equal (plist-get oldprops :hash) (plist-get newprops :hash)) (equal (plist-get oldprops :fields) (plist-get newprops :fields))))) +;; Parsers + +(defconst citar-cache--parser + (list (cons t (cons #'parsebib-parse #'citar-cache--update-parsebib-bibliography-p))) + "An alist of file extensions and update-related function symbols. + +Form should be (EXT . (PARSER . UPDATEP)), where: + +EXT is the file extension + +PARSER is the file parser function, which takes a single +required argument FILENAME, and ... + +UPDATEP is a predicate function; when non-nil, PARSER should be +run. Takes two arguments ...") + +(defun citar-cache--get-parser (filename) + "Return parser function name for FILENAME." + (let ((ext (file-name-extension filename))) + (car (or (assoc ext citar-cache--parser) + (assoc t citar-cache--parser))))) + +(defun citar-cache--get-update-p (filename) + "Return update predicate function name for FILENAME." + (let ((ext (file-name-extension filename))) + (cdr (or (assoc ext citar-cache--parser) + (assoc t citar-cache--parser))))) + +;; Update functions + (defun citar-cache--update-bibliography (bib &optional props) "Update the bibliography BIB from the original file. @@ -231,6 +263,7 @@ Only the bibliography fields listed in the :fields value of PROPS are parsed. After updating, the `props' slot of BIB is set to PROPS." (let* ((filename (citar-cache--bibliography-filename bib)) + (ext (file-name-extension filename)) (props (or props (citar-cache--get-bibliography-props filename))) (entries (citar-cache--bibliography-entries bib)) (messagestr (format "Updating bibliography %s" (abbreviate-file-name filename))) @@ -238,7 +271,7 @@ PROPS." (message "%s..." messagestr) (redisplay) ; Make sure message is displayed before Emacs gets busy parsing (clrhash entries) - (parsebib-parse filename :entries entries :fields (plist-get props :fields)) + (funcall (citar-cache--get-parser ext) filename :entries entries :fields (plist-get props :fields)) (setf (citar-cache--bibliography-props bib) props) (citar-cache--preformat-bibliography bib) (message "%s...done (%.3f seconds)" messagestr (float-time (time-since starttime)))))