The attached patch addresses a reported problem with the citation
dialog, but the problem was much more extensive than the bug made
apparent. See:
     http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg117655.html
for a bit more on the nature of the bug.

The fix involves re-working the internal representation of BibTeX data
so that it is not just a
    map<string, docstring>
with the string being the key and the docstring being everything else but a
    map<string, map<docstring, docstring> >
with the string being the key and the second map associating BibTeX
fields with their values. This simplifies a lot of what goes on
internally and was already suggested by Bernhard Roider in the new
parser code.

It's a biggish patch, but there's a lot less going on here than it seems
at first. Most of it is just a matter of changing the signature of some
method calls, and a lot of it is deleting, since this simplifies a lot
of code. The most substantial changes are in
src/frontends/controllers/frontend_helpers.cpp, with a bit more in
InsetBibtex::fillWithBibKeys().

I've tested this and it seems to work fine. But others should have a
look, too.

Note that this would make it quite trivial to improve the search
functionality of the citation dialog, say, by allowing something similar
to what JabRef does (title=...) or perhaps by including a separate text
field for the key, so you could, say, enter "title" and "^Frege" to do a
regex search on the title field. That would presumably be for later,
though I'd love to go ahead and do this. It'd be great to have.

By the way, are we sure we want the "search as you go" functionality
currently in the citation dialog? There is notable slowness on my
machine (Athlon 2400+, 1GB), as I've got 500+ BibTeX keys in the dialog
and they all have to be searched on every keypress.

Richard

-- 
==================================================================
Richard G Heck, Jr
Professor of Philosophy
Brown University
http://frege.brown.edu/heck/
==================================================================
Get my public key from http://sks.keyserver.penguin.de
Hash: 0x1DE91F1E66FFBDEC
Learn how to sign your email using Thunderbird and GnuPG at:
http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto

Index: src/Buffer.h
===================================================================
--- src/Buffer.h	(revision 18444)
+++ src/Buffer.h	(working copy)
@@ -12,10 +12,11 @@
 #ifndef BUFFER_H
 #define BUFFER_H
 
+#include "DocIterator.h"
 #include "ErrorList.h"
 #include "InsetList.h"
 
-#include "DocIterator.h"
+#include "frontends/controllers/frontend_helpers.h"
 
 #include "support/FileName.h"
 #include "support/limited_stack.h"
@@ -285,7 +286,7 @@
 	void validate(LaTeXFeatures &) const;
 
 	/// return all bibkeys from buffer and its childs
-	void fillWithBibKeys(std::vector<std::pair<std::string, docstring> > & keys) const;
+	void fillWithBibKeys(biblio::BibKeyList & keys) const;
 	/// Update the cache with all bibfiles in use (including bibfiles
 	/// of loaded child documents).
 	void updateBibfilesCache();
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(revision 18445)
+++ src/Buffer.cpp	(working copy)
@@ -1317,7 +1317,7 @@
 
 
 // This is also a buffer property (ale)
-void Buffer::fillWithBibKeys(vector<pair<string, docstring> > & keys)
+void Buffer::fillWithBibKeys(biblio::BibKeyList & keys)
 	const
 {
 	/// if this is a child document and the parent is already loaded
@@ -1343,11 +1343,12 @@
 				static_cast<InsetBibitem const &>(*it);
 			// FIXME UNICODE
 			string const key = to_utf8(inset.getParam("key"));
-			docstring const label = inset.getParam("label");
+			biblio::KeyValMap keyvalmap;
+			keyvalmap[from_ascii("label")] = inset.getParam("label");
 			DocIterator doc_it(it); doc_it.forwardPos();
-			docstring const ref = doc_it.paragraph().asString(*this, false);
-			docstring const info = label + "TheBibliographyRef" + ref;
-			keys.push_back(pair<string, docstring>(key, info));
+			keyvalmap [from_ascii("ref")] = doc_it.paragraph().asString(*this, false);
+			keyvalmap[biblio::TheBibliographyRef] = biblio::TheBibliographyRef;
+			keys[key] = keyvalmap;
 		}
 	}
 }
@@ -1705,10 +1706,10 @@
 	vector<docstring> labels;
 
 	if (code == Inset::CITE_CODE) {
-		vector<pair<string, docstring> > keys;
+		biblio::BibKeyList keys;
 		fillWithBibKeys(keys);
-		vector<pair<string, docstring> >::const_iterator bit  = keys.begin();
-		vector<pair<string, docstring> >::const_iterator bend = keys.end();
+		biblio::BibKeyList::const_iterator bit  = keys.begin();
+		biblio::BibKeyList::const_iterator bend = keys.end();
 
 		for (; bit != bend; ++bit)
 			// FIXME UNICODE
Index: src/frontends/controllers/frontend_helpers.h
===================================================================
--- src/frontends/controllers/frontend_helpers.h	(revision 18444)
+++ src/frontends/controllers/frontend_helpers.h	(working copy)
@@ -28,8 +28,17 @@
 
 /** Functions of use to citation and bibtex GUI controllers and views */
 namespace lyx {
+	
 namespace biblio {
+	
+/// First entry is field, second is value
+typedef std::map<docstring, docstring> KeyValMap;
+/// First entry is the bibliography key, second the data
+typedef std::map<std::string, std::map<docstring, docstring> > BibKeyList;
 
+static const docstring TheBibliographyRef(from_ascii("@LyXInfo"));
+static const docstring TheDataString(from_ascii("@BibTeXData"));
+
 enum CiteEngine {
 	ENGINE_BASIC,
 	ENGINE_NATBIB_AUTHORYEAR,
@@ -69,34 +78,31 @@
 std::string const asValidLatexCommand(std::string const & input,
 				      CiteEngine const engine);
 
-/// First entry is the bibliography key, second the data
-typedef std::map<std::string, docstring> InfoMap;
-
 /// Returns a vector of bibliography keys
-std::vector<std::string> const getKeys(InfoMap const &);
+std::vector<std::string> const getKeys(BibKeyList const &);
 
 /** Returns the BibTeX data associated with a given key.
-    Empty if no info exists. */
-docstring const getInfo(InfoMap const &, std::string const & key);
+    Empty if the key was not defined in the BibTeX record. */
+docstring const getInfo(BibKeyList const &, std::string const & key);
 
 /// return the year from the bibtex data record
-docstring const getYear(InfoMap const & map, std::string const & key);
+docstring const getYear(BibKeyList const & map, std::string const & key);
 
 /// return the short form of an authorlist
-docstring const getAbbreviatedAuthor(InfoMap const & map, std::string const & key);
+docstring const getAbbreviatedAuthor(BibKeyList const & map, std::string const & key);
 
 // return only the family name
 docstring const familyName(docstring const & name);
 
 /** Search a BibTeX info field for the given key and return the
     associated field. */
-docstring const parseBibTeX(docstring data, std::string const & findkey);
+docstring const getValueForKey(KeyValMap data, std::string const & findkey);
 
 /** Returns an iterator to the first key that meets the search
     criterion, or end() if unsuccessful.
 
     User supplies :
-    the InfoMap of bibkeys info,
+    the BibKeyList of bibkeys info,
     the vector of keys to be searched,
     the search criterion,
     an iterator defining the starting point of the search,
@@ -105,7 +111,7 @@
 */
 
 std::vector<std::string>::const_iterator
-searchKeys(InfoMap const & map,
+searchKeys(BibKeyList const & map,
 	   std::vector<std::string> const & keys_to_search,
 	   docstring const & search_expression,
 	   std::vector<std::string>::const_iterator start,
@@ -145,12 +151,12 @@
 
    User supplies :
    the key,
-   the InfoMap of bibkeys info,
+   the BibKeyList of bibkeys info,
    the available citation styles
 */
 std::vector<docstring> const
 getNumericalStrings(std::string const & key,
-		    InfoMap const & map,
+		    BibKeyList const & map,
 		    std::vector<CiteStyle> const & styles);
 
 /**
@@ -162,12 +168,12 @@
 
    User supplies :
    the key,
-   the InfoMap of bibkeys info,
+   the BibKeyList of bibkeys info,
    the available citation styles
 */
 std::vector<docstring> const
 getAuthorYearStrings(std::string const & key,
-		     InfoMap const & map,
+		     BibKeyList const & map,
 		     std::vector<CiteStyle> const & styles);
 
 } // namespace biblio
Index: src/frontends/controllers/frontend_helpers.cpp
===================================================================
--- src/frontends/controllers/frontend_helpers.cpp	(revision 18444)
+++ src/frontends/controllers/frontend_helpers.cpp	(working copy)
@@ -31,9 +31,6 @@
 #include "frontends/alert.h"
 #include "support/filetools.h"
 #include "support/lstrings.h"
-#include "support/Package.h"
-#include "support/filetools.h"
-#include "support/lstrings.h"
 #include "support/lyxalgo.h"
 #include "support/os.h"
 #include "support/Package.h"
@@ -124,9 +121,6 @@
 	return str;
 }
 
-
-static const docstring TheBibliographyRef(from_ascii("TheBibliographyRef"));
-
 } // namespace anon
 
 
@@ -198,38 +192,29 @@
 }
 
 
-docstring const getAbbreviatedAuthor(InfoMap const & map, string const & key)
+docstring const getAbbreviatedAuthor(BibKeyList const & map, string const & key)
 {
 	BOOST_ASSERT(!map.empty());
 
-	InfoMap::const_iterator it = map.find(key);
+	BibKeyList::const_iterator it = map.find(key);
 	if (it == map.end())
 		return docstring();
-	docstring const & data = it->second;
+	KeyValMap const & data = it->second;
 
 	// Is the entry a BibTeX one or one from lyx-layout "bibliography"?
-	docstring::size_type const pos = data.find(TheBibliographyRef);
-	if (pos != docstring::npos) {
-		if (pos <= 2) {
-			return docstring();
-		}
+	KeyValMap::const_iterator it2 = data.find(TheBibliographyRef);
+	if (it2 != data.end()) 
+		// We don't have any way to tell how the author names might have
+		// been formatted.
+		return docstring();
 
-		docstring const opt = trim(data.substr(0, pos - 1));
-		if (opt.empty())
-			return docstring();
+	docstring author = getValueForKey(data, "author");
 
-		docstring authors;
-		split(opt, authors, '(');
-		return authors;
-	}
-
-	docstring author = parseBibTeX(data, "author");
-
 	if (author.empty())
-		author = parseBibTeX(data, "editor");
+		author = getValueForKey(data, "editor");
 
 	if (author.empty()) {
-		author = parseBibTeX(data, "key");
+		author = getValueForKey(data, "key");
 		if (author.empty())
 			// FIXME UNICODE
 			return from_utf8(key);
@@ -251,36 +236,23 @@
 }
 
 
-docstring const getYear(InfoMap const & map, string const & key)
+docstring const getYear(BibKeyList const & map, string const & key)
 {
 	BOOST_ASSERT(!map.empty());
 
-	InfoMap::const_iterator it = map.find(key);
+	BibKeyList::const_iterator it = map.find(key);
 	if (it == map.end())
 		return docstring();
-	docstring const & data = it->second;
+	KeyValMap const & data = it->second;
 
 	// Is the entry a BibTeX one or one from lyx-layout "bibliography"?
-	docstring::size_type const pos = data.find(TheBibliographyRef);
-	if (pos != docstring::npos) {
-		if (pos <= 2) {
-			return docstring();
-		}
+	KeyValMap::const_iterator it2 = data.find(TheBibliographyRef);
+	if (it2 != data.end()) 
+		// We don't have any way to tell how the entry might have
+		// been formatted.
+		return docstring();
 
-		docstring const opt =
-			trim(data.substr(0, pos - 1));
-		if (opt.empty())
-			return docstring();
-
-		docstring authors;
-		docstring const tmp = split(opt, authors, '(');
-		docstring year;
-		split(tmp, year, ')');
-		return year;
-
-	}
-
-	docstring year = parseBibTeX(data, "year");
+	docstring year = getValueForKey(data, "year");
 	if (year.empty())
 		year = _("No year");
 
@@ -302,11 +274,11 @@
 } // namespace anon
 
 
-vector<string> const getKeys(InfoMap const & map)
+vector<string> const getKeys(BibKeyList const & map)
 {
 	vector<string> bibkeys;
-	InfoMap::const_iterator it  = map.begin();
-	InfoMap::const_iterator end = map.end();
+	BibKeyList::const_iterator it  = map.begin();
+	BibKeyList::const_iterator end = map.end();
 	for (; it != end; ++it) {
 		bibkeys.push_back(it->first);
 	}
@@ -316,43 +288,42 @@
 }
 
 
-docstring const getInfo(InfoMap const & map, string const & key)
+docstring const getInfo(BibKeyList const & map, string const & key)
 {
 	BOOST_ASSERT(!map.empty());
 
-	InfoMap::const_iterator it = map.find(key);
+	BibKeyList::const_iterator it = map.find(key);
 	if (it == map.end())
 		return docstring();
-	docstring const & data = it->second;
+	KeyValMap const & data = it->second;
 
-	// is the entry a BibTeX one or one from lyx-layout "bibliography"?
-	docstring::size_type const pos = data.find(TheBibliographyRef);
-	if (pos != docstring::npos) {
-		docstring::size_type const pos2 = pos + TheBibliographyRef.size();
-		docstring const info = trim(data.substr(pos2));
-		return info;
+	// Is the entry a BibTeX one or one from lyx-layout "bibliography"?
+	KeyValMap::const_iterator it2 = data.find(TheBibliographyRef);
+	if (it2 != data.end()) {
+		KeyValMap::const_iterator it3 = data.find(from_ascii("ref"));
+		return it3->second;
 	}
 
 	// Search for all possible "required" keys
-	docstring author = parseBibTeX(data, "author");
+	docstring author = getValueForKey(data, "author");
 	if (author.empty())
-		author = parseBibTeX(data, "editor");
+		author = getValueForKey(data, "editor");
 
-	docstring year      = parseBibTeX(data, "year");
-	docstring title     = parseBibTeX(data, "title");
-	docstring booktitle = parseBibTeX(data, "booktitle");
-	docstring chapter   = parseBibTeX(data, "chapter");
-	docstring number    = parseBibTeX(data, "number");
-	docstring volume    = parseBibTeX(data, "volume");
-	docstring pages     = parseBibTeX(data, "pages");
-	docstring annote    = parseBibTeX(data, "annote");
-	docstring media     = parseBibTeX(data, "journal");
+	docstring year      = getValueForKey(data, "year");
+	docstring title     = getValueForKey(data, "title");
+	docstring booktitle = getValueForKey(data, "booktitle");
+	docstring chapter   = getValueForKey(data, "chapter");
+	docstring number    = getValueForKey(data, "number");
+	docstring volume    = getValueForKey(data, "volume");
+	docstring pages     = getValueForKey(data, "pages");
+	docstring annote    = getValueForKey(data, "annote");
+	docstring media     = getValueForKey(data, "journal");
 	if (media.empty())
-		media = parseBibTeX(data, "publisher");
+		media = getValueForKey(data, "publisher");
 	if (media.empty())
-		media = parseBibTeX(data, "school");
+		media = getValueForKey(data, "school");
 	if (media.empty())
-		media = parseBibTeX(data, "institution");
+		media = getValueForKey(data, "institution");
 
 	odocstringstream result;
 	if (!author.empty())
@@ -381,7 +352,7 @@
 		return result_str;
 
 	// This should never happen (or at least be very unusual!)
-	return data;
+	return docstring();
 }
 
 
@@ -418,24 +389,28 @@
 public:
 	// re and icase are used to construct an instance of boost::RegEx.
 	// if icase is true, then matching is insensitive to case
-	RegexMatch(InfoMap const & m, string const & re, bool icase)
+	RegexMatch(BibKeyList const & m, string const & re, bool icase)
 		: map_(m), regex_(re, icase) {}
 
+	//FIXME This should probably be restored to its earlier behavior
 	bool operator()(string const & key) const {
-		// the data searched is the key + its associated BibTeX/biblio
-		// fields
-		string data = key;
-		InfoMap::const_iterator info = map_.find(key);
-		if (info != map_.end())
+		BibKeyList::const_iterator info = map_.find(key);
+ 		if (info == map_.end())
+ 			return false;
+ 
+ 		string data = key;
+		//The machinations here are required because map::operator[] 
+		//has no const version.
+		KeyValMap const kvm = info->second;
+		KeyValMap::const_iterator it = kvm.find(TheDataString);
+		if (it != kvm.end())
 			// FIXME UNICODE
-			data += ' ' + to_utf8(info->second);
-
-		// Attempts to find a match for the current RE
-		// somewhere in data.
+			data += ' ' + to_utf8(it->second);
+ 
 		return boost::regex_search(data, regex_);
 	}
 private:
-	InfoMap const map_;
+	BibKeyList const map_;
 	mutable boost::regex regex_;
 };
 
@@ -443,7 +418,7 @@
 
 
 vector<string>::const_iterator
-searchKeys(InfoMap const & theMap,
+searchKeys(BibKeyList const & theMap,
 	   vector<string> const & keys,
 	   string const & search_expr,
 	   vector<string>::const_iterator start,
@@ -490,142 +465,13 @@
 }
 
 
-docstring const parseBibTeX(docstring data, string const & findkey)
+docstring const getValueForKey(KeyValMap data, string const & findkey)
 {
-	// at first we delete all characters right of '%' and
-	// replace tabs through a space and remove leading spaces
-	// we read the data line by line so that the \n are
-	// ignored, too.
-	docstring data_;
-	int Entries = 0;
-	docstring dummy = token(data,'\n', Entries);
-	while (!dummy.empty()) {
-		// no tabs
-		dummy = subst(dummy, '\t', ' ');
-		// no leading spaces
-		dummy = ltrim(dummy);
-		// ignore lines with a beginning '%' or ignore all right of %
-		docstring::size_type const idx =
-			dummy.empty() ? docstring::npos : dummy.find('%');
-		if (idx != docstring::npos)
-			// Check if this is really a comment or just "\%"
-			if (idx == 0 || dummy[idx - 1] != '\\')
-				dummy.erase(idx, docstring::npos);
-			else
-				//  This is "\%", so just erase the '\'
-				dummy.erase(idx - 1, 1);
-		// do we have a new token or a new line of
-		// the same one? In the first case we ignore
-		// the \n and in the second we replace it
-		// with a space
-		if (!dummy.empty()) {
-			if (!contains(dummy, '='))
-				data_ += ' ' + dummy;
-			else
-				data_ += dummy;
-		}
-		dummy = token(data, '\n', ++Entries);
-	}
-
-	// replace double commas with "" for easy scanning
-	data = subst(data_, from_ascii(",,"), from_ascii("\"\""));
-
-	// unlikely!
-	if (data.empty())
+	docstring key = from_ascii(findkey);
+	KeyValMap::const_iterator it = data.find(key);
+	if (it == data.end())
 		return docstring();
-
-	// now get only the important line of the bibtex entry.
-	// all entries are devided by ',' except the last one.
-	data += ',';
-	// now we have same behaviour for all entries because the last one
-	// is "blah ... }"
-	Entries = 0;
-	bool found = false;
-	// parsing of title and booktitle is different from the
-	// others, because booktitle contains title
-	do {
-		dummy = token(data, ',', Entries++);
-		if (!dummy.empty()) {
-			found = contains(ascii_lowercase(dummy), from_ascii(findkey));
-			if (findkey == "title" &&
-			    contains(ascii_lowercase(dummy), from_ascii("booktitle")))
-				found = false;
-		}
-	} while (!found && !dummy.empty());
-	if (dummy.empty())
-		// no such keyword
-		return docstring();
-
-	// we are not sure, if we get all, because "key= "blah, blah" is
-	// allowed.
-	// Therefore we read all until the next "=" character, which follows a
-	// new keyword
-	docstring keyvalue = dummy;
-	dummy = token(data, ',', Entries++);
-	while (!contains(dummy, '=') && !dummy.empty()) {
-		keyvalue += ',' + dummy;
-		dummy = token(data, ',', Entries++);
-	}
-
-	// replace double "" with originals ,, (two commas)
-	// leaving us with the all-important line
-	data = subst(keyvalue, from_ascii("\"\""), from_ascii(",,"));
-
-	// Clean-up.
-	// 1. Spaces
-	data = rtrim(data);
-	// 2. if there is no opening '{' then a closing '{' is probably cruft.
-	if (!contains(data, '{'))
-		data = rtrim(data, "}");
-	// happens, when last keyword
-	docstring::size_type const idx =
-		!data.empty() ? data.find('=') : docstring::npos;
-
-	if (idx == docstring::npos)
-		return docstring();
-
-	data = trim(data.substr(idx));
-
-	// a valid entry?
-	if (data.length() < 2 || data[0] != '=')
-		return docstring();
-	else {
-		// delete '=' and the following spaces
-		data = ltrim(data, " =");
-		if (data.length() < 2) {
-			// not long enough to find delimiters
-			return data;
-		} else {
-			docstring::size_type keypos = 1;
-			char_type enclosing;
-			if (data[0] == '{') {
-				enclosing = '}';
-			} else if (data[0] == '"') {
-				enclosing = '"';
-			} else {
-				// no {} and no "", pure data but with a
-				// possible ',' at the end
-				return rtrim(data, ",");
-			}
-			docstring tmp = data.substr(keypos);
-			while (tmp.find('{') != docstring::npos &&
-			       tmp.find('}') != docstring::npos &&
-			       tmp.find('{') < tmp.find('}') &&
-			       tmp.find('{') < tmp.find(enclosing)) {
-
-				keypos += tmp.find('{') + 1;
-				tmp = data.substr(keypos);
-				keypos += tmp.find('}') + 1;
-				tmp = data.substr(keypos);
-			}
-			if (tmp.find(enclosing) == docstring::npos)
-				return data;
-			else {
-				keypos += tmp.find(enclosing);
-				return data.substr(1, keypos - 1);
-			}
-		}
-	}
+	return data[key];
 }
 
 
@@ -743,7 +589,7 @@
 
 vector<docstring> const
 getNumericalStrings(string const & key,
-		    InfoMap const & map, vector<CiteStyle> const & styles)
+		    BibKeyList const & map, vector<CiteStyle> const & styles)
 {
 	if (map.empty())
 		return vector<docstring>();
@@ -797,7 +643,7 @@
 
 vector<docstring> const
 getAuthorYearStrings(string const & key,
-		    InfoMap const & map, vector<CiteStyle> const & styles)
+		    BibKeyList const & map, vector<CiteStyle> const & styles)
 {
 	if (map.empty())
 		return vector<docstring>();
Index: src/frontends/controllers/ControlCitation.h
===================================================================
--- src/frontends/controllers/ControlCitation.h	(revision 18444)
+++ src/frontends/controllers/ControlCitation.h	(working copy)
@@ -63,7 +63,7 @@
 	}
 private:
 	/// The info associated with each key
-	biblio::InfoMap bibkeysInfo_;
+	biblio::BibKeyList bibkeysInfo_;
 
 	///
 	static std::vector<biblio::CiteStyle> citeStyles_;
Index: src/frontends/controllers/ControlCitation.cpp
===================================================================
--- src/frontends/controllers/ControlCitation.cpp	(revision 18444)
+++ src/frontends/controllers/ControlCitation.cpp	(working copy)
@@ -12,6 +12,7 @@
 #include <config.h>
 
 #include "ControlCitation.h"
+#include "frontend_helpers.h"
 
 #include "Buffer.h"
 #include "BufferParams.h"
@@ -48,12 +49,8 @@
 
 	bool use_styles = engine != biblio::ENGINE_BASIC;
 
-	vector<pair<string, docstring> > blist;
-	kernel().buffer().fillWithBibKeys(blist);
-	bibkeysInfo_.clear();
-	for (size_t i = 0; i < blist.size(); ++i)
-		bibkeysInfo_[blist[i].first] = blist[i].second;
-
+	kernel().buffer().fillWithBibKeys(bibkeysInfo_);
+	
 	if (citeStyles_.empty())
 		citeStyles_ = biblio::getCiteStyles(engine);
 	else {
@@ -137,23 +134,21 @@
 		// it is treated as a simple string by boost::regex.
 		expr = escape_special_chars(expr);
 
-	boost::regex reg_exp(to_utf8(expr), case_sensitive?
+	boost::regex reg_exp(to_utf8(expr), case_sensitive ?
 		boost::regex_constants::normal : boost::regex_constants::icase);
 
 	vector<string>::const_iterator it = keys_to_search.begin();
 	vector<string>::const_iterator end = keys_to_search.end();
 	for (; it != end; ++it ) {
-		biblio::InfoMap::const_iterator info = bibkeysInfo_.find(*it);
+		biblio::BibKeyList::iterator info = bibkeysInfo_.find(*it);
 		if (info == bibkeysInfo_.end())
 			continue;
 
 		string data = *it;
 		// FIXME UNICODE
-		data += ' ' + to_utf8(info->second);
+		data += ' ' + to_utf8((info->second)[biblio::TheDataString]);
 
 		try {
-			// Attempts to find a match for the current RE
-			// somewhere in data.
 			if (boost::regex_search(data, reg_exp))
 				foundKeys.push_back(*it);
 		}
Index: src/insets/InsetBibtex.h
===================================================================
--- src/insets/InsetBibtex.h	(revision 18444)
+++ src/insets/InsetBibtex.h	(working copy)
@@ -13,8 +13,9 @@
 #define INSET_BIBTEX_H
 
 
-#include <vector>
+#include <map>
 #include "InsetCommand.h"
+#include "frontends/controllers/frontend_helpers.h"
 
 #include "support/FileName.h"
 
@@ -38,8 +39,7 @@
 	///
 	int latex(Buffer const &, odocstream &, OutputParams const &) const;
 	///
-	void fillWithBibKeys(Buffer const & buffer,
-		std::vector<std::pair<std::string, docstring> > & keys) const;
+	void fillWithBibKeys(Buffer const & buffer, biblio::BibKeyList & keys) const;
 	///
 	std::vector<support::FileName> const getFiles(Buffer const &) const;
 	///
Index: src/insets/InsetBibtex.cpp
===================================================================
--- src/insets/InsetBibtex.cpp	(revision 18444)
+++ src/insets/InsetBibtex.cpp	(working copy)
@@ -34,7 +34,6 @@
 
 #include <boost/tokenizer.hpp>
 
-
 namespace lyx {
 
 using support::absolutePath;
@@ -537,9 +536,9 @@
 }
 
 
-// This method returns a comma separated list of Bibtex entries
+// This method returns a map of Bibtex entries
 void InsetBibtex::fillWithBibKeys(Buffer const & buffer,
-		std::vector<std::pair<string, docstring> > & keys) const
+		biblio::BibKeyList & keys) const
 {
 	vector<FileName> const files = getFiles(buffer);
 	for (vector<FileName>::const_iterator it = files.begin();
@@ -554,15 +553,6 @@
 		//   field values.
 		// - it accepts more characters in keys or value names than 
 		//   bibtex does.
-		//
-		// TODOS:
-		// - the entries are split into name = value pairs by the 
-		//   parser. These have to be merged again because of the 
-		//   way lyx treats the entries ( pair<...>(...) ). The citation
-		//   mechanism in lyx should be changed such that it can use
-		//   the split entries.
-		// - messages on parsing errors can be generated.
-		//
 
 		// Officially bibtex does only support ASCII, but in practice
 		// you can use the encoding of the main document as long as
@@ -571,6 +561,7 @@
 		// We don't restrict keys to ASCII in LyX, since our own
 		// InsetBibitem can generate non-ASCII keys, and nonstandard
 		// 8bit clean bibtex forks exist.
+		
 		idocfstream ifs(it->toFilesystemEncoding().c_str(),
 		                std::ios_base::in,
 		                buffer.params().encoding().iconvName());
@@ -639,22 +630,27 @@
 
 			} else {
 
-				// Citation entry. Read the key and all name = value pairs
+				// Citation entry. Try to read the key.
 				docstring key;
-				docstring fields;
-				docstring name;
-				docstring value;
-				docstring commaNewline;
 
 				if (!readTypeOrKey(key, ifs, from_ascii(",})"), keepCase) || !ifs)
 					continue;
 
+				/////////////////////////////////////////////
 				// now we have a key, so we will add an entry 
 				// (even if it's empty, as bibtex does)
+				// we now read the field = value pairs.
 				// 
 				// all items must be separated by a comma. If
 				// it is missing the scanning of this entry is
 				// stopped and the next is searched.
+				docstring fields;
+				docstring name;
+				docstring value;
+				docstring commaNewline;
+				docstring data;
+				biblio::KeyValMap keyvalmap;
+				
 				bool readNext = removeWSAndComma(ifs);
 
 				while (ifs && readNext) {
@@ -676,23 +672,14 @@
 					if (!readValue(value, ifs, strings)) 
 						break;
 
-					// append field to the total entry string.
-					//
-					// TODO: Here is where the fields can be put in 
-					//       a more intelligent structure that preserves
-					//	     the already known parts.
-					fields += commaNewline;
-					fields += name + from_ascii(" = {") + value + '}';
-
-					if (!commaNewline.length()) 
-						commaNewline = from_ascii(",\n"); 
-
+					keyvalmap[name] = value;
+					data += "\n\n" + value;
 					readNext = removeWSAndComma(ifs);
 				}
 
 				// add the new entry
-				keys.push_back(pair<string, docstring>(
-				to_utf8(key), fields));
+				keyvalmap[biblio::TheDataString] = data;
+				keys[to_utf8(key)] = keyvalmap;
 			}
 
 		} //< searching '@'
Index: src/insets/InsetCitation.cpp
===================================================================
--- src/insets/InsetCitation.cpp	(revision 18444)
+++ src/insets/InsetCitation.cpp	(working copy)
@@ -65,13 +65,13 @@
 		return docstring();
 
 	// Cache the labels
-	typedef std::map<Buffer const *, biblio::InfoMap> CachedMap;
+	typedef std::map<Buffer const *, biblio::BibKeyList> CachedMap;
 	static CachedMap cached_keys;
 
 	// and cache the timestamp of the bibliography files.
 	static std::map<FileName, time_t> bibfileStatus;
 
-	biblio::InfoMap infomap;
+	biblio::BibKeyList infomap;
 
 	vector<FileName> const & bibfilesCache = buffer.getBibfilesCache();
 	// compare the cached timestamps with the actual ones.
@@ -97,16 +97,7 @@
 
 	// build the keylist only if the bibfiles have been changed
 	if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) {
-		typedef vector<std::pair<string, docstring> > InfoType;
-		InfoType bibkeys;
-		buffer.fillWithBibKeys(bibkeys);
-
-		InfoType::const_iterator bit  = bibkeys.begin();
-		InfoType::const_iterator bend = bibkeys.end();
-
-		for (; bit != bend; ++bit)
-			infomap[bit->first] = bit->second;
-
+		buffer.fillWithBibKeys(infomap);
 		cached_keys[&buffer] = infomap;
 	} else
 		// use the cached keys
Index: src/insets/InsetInclude.h
===================================================================
--- src/insets/InsetInclude.h	(revision 18444)
+++ src/insets/InsetInclude.h	(working copy)
@@ -56,10 +56,11 @@
 			  std::vector<docstring> & list) const;
 	/** Fills \c keys
 	 *  \param buffer the Buffer containing this inset.
-	 *  \param keys the list of bibkeys in the child buffer.
-	 */
+	 *  \param keys the map of bibkeys in the child buffer.
+	 */	
+
 	void fillWithBibKeys(Buffer const & buffer,
-		std::vector<std::pair<std::string, docstring> > & keys) const;
+		std::map<std::string, std::map<docstring, docstring> > & keys) const;
 	/** Update the cache with all bibfiles in use of the child buffer
 	 *  (including bibfiles of grandchild documents).
 	 *  Does nothing if the child document is not loaded to prevent
Index: src/insets/InsetInclude.cpp
===================================================================
--- src/insets/InsetInclude.cpp	(revision 18445)
+++ src/insets/InsetInclude.cpp	(working copy)
@@ -693,7 +693,7 @@
 
 
 void InsetInclude::fillWithBibKeys(Buffer const & buffer,
-		std::vector<std::pair<string, docstring> > & keys) const
+		std::map<std::string, std::map<docstring, docstring> > & keys) const
 {
 	if (loadIfNeeded(buffer, params_)) {
 		string const included_file = includedFilename(buffer, params_).absFilename();

Reply via email to