Re: [Ebib-users] multiple keywords fields in bib files
Brought to you by:
joostkremers
From: Joost K. <joo...@fa...> - 2007-03-28 12:20:11
|
Hi Abel, On Wed, Mar 28, 2007 at 07:17:20AM -0300, Abel Morabito wrote: > I'm working with an imported bib database with multiple keywords field, with > entries like this: > [...] > keywords="irbesartan", > keywords="nephropathy", > keywords="diabetes", > keywords="Full text", > keywords="economics", > keywords="PND2007", [...] Mmm... I've never come across something like this before... Didn't even know it was possible at all in BibTeX. > Ebib just reads the last keywords field, in this case PND2007, and deletes > the previos ones. Yes. Ebib stores each entry in a hash table and uses the field names as the keys. Since each key can only appear once in a hash table, each `keywords' field replaces the previous one. > It seems ebib works with keywords written in one line, for instance Yep. That would be the way to do it. It wouldn't be easy to modify Ebib to allow multiple `keywords' fields. As I said, because I use hash tables to store the entries, and hash tables don't allow it on principle, I would have to rewrite Ebib from scratch using some other storage method (which I'm not about to do. ;-) Alternatively, it would be possible to put the different keywords values in a list and store that as the value of the keywords field in the hash table. That, too, would take some time to implement, however, as it raises questions about how to display this on the screen, etc. > How could I work this out so I can use the original bib file without editing > every keywords field? If you have no problem with storing the different keywords in a single keywords field, then the following code will do this: #v+ (defun ebib-find-bibtex-fields (entry-type limit) "Finds the fields of the BibTeX entry that starts on the line POINT is on. Returns a hash table containing all the fields and values, or NIL if none were found. ENTRY-TYPE is the type of the entry, which will be recorded in the hash table. Before the search starts, POINT is moved back to the beginning of the line." (beginning-of-line) (let ((fields (make-hash-table :size 15))) (while (progn (skip-chars-forward "^," limit) ; we must move to the next comma, (eq (char-after) ?,)) ; and make sure we are really on a comma. (skip-chars-forward "\"#%'(),={} \n\t\f" limit) (let ((beg (point))) (when (looking-at-goto-end (concat "\\(" ebib-bibtex-identifier "\\)[ \t\n\f]*=") 1) (let ((field-type (intern (downcase (buffer-substring-no-properties beg (point)))))) (unless (eq field-type 'type*) ; the 'type*' key holds the entry type, so we can't use it (let ((field-contents (ebib-get-field-contents limit))) (when field-contents (let ((existing-contents (gethash field-type fields))) (if existing-contents (puthash field-type (from-raw (concat (to-raw existing-contents) "; " (to-raw field-contents))) fields) (puthash field-type field-contents fields)))))))))) (when (> (hash-table-count fields) 0) (puthash 'type* entry-type fields) fields))) #v- Replace the function ebib-find-bibtex-fields in ebib.el with this new definition, and load your .bib file again. Ebib will concatenate all the keywords fields into one keywords field, separated by a semicolon and a space. Now, when I tested this code on the BibTeX entry you provide, I noticed another thing: the author field in your sample entry has newlines in it. In itself, that's not a problem, but it turns out that Ebib treats it as a so-called "raw" field, which it shouldn't do. I tracked down the problem, and it seems to be an inconsistency (not to say "bug"...) in Emacs. I don't have a fix for this yet. In principle, this won't be a problem as long as you don't toggle the field's "raw" status. (This problem only occurs with multiline field values that are surrounded by quotes, not when they're surrounded by braces. Ebib uses braces, so the problem won't occur with multiline values created with Ebib.) -- Joost Kremers, PhD University of Cologne Institute for German Language and Literature Albertus Magnus Platz 50923 Cologne, Germany Tel. +49 221 / 4703807 |