# Bibliography class # - essentially a container for many BibEntry objects # - provides methods for reading/writing the bibliography # - provides iterators, sorting etc # Copyright (c) 2007, Peter Corke # # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * The name of the copyright holder may not be used to endorse or # promote products derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. import string; import BibEntry; import urllib; import urlparse; import os; import os.path; import sys; NoSuchFile = "No such file"; class Bibliography: def __init__(self): self.keyList = []; self.abbrevDict = {} def open(self, filename): if filename == '-': self.filename = "stdin"; return sys.stdin; urlbits = urlparse.urlparse('~/lib/bib/z.bib'); if urlbits[0]: # path is a URL fp = urllib.urlopen(filename); self.filename = filename; else: # path is a local file path = os.environ['BIBPATH']; for p in string.split(path, os.pathsep): f = os.path.join(p, filename); if os.path.isfile(f): break; else: raise NoSuchFile; fp = open(f, "r"); home = os.path.expanduser('~'); f2 = os.path.abspath(f); common = os.path.commonprefix([home, f2]); if common: self.filename = "~" + f2[len(common):] else: self.filename = f; return fp; def close(self, fp): fp.close(); # resolve all abbreviations found in the value fields of all entries def resolveAbbrev(self): #print >> sys.stderr, len(self.abbrevDict); for be in self: for f in be: v = be.getField(f); if isinstance(v,str): if v in self.abbrevDict: if self.abbrevDict[v]: be.setField(f, self.abbrevDict[v]); def insertEntry(self, be, ignore=False): #print >> sys.stderr, "inserting key ", be.getKey() # should check to see if be is of BibEntry type key = be.getKey(); if key in [x.key for x in self.keyList]: if not ignore: print >> sys.stderr, "key %s already in dictionary" % (key) return False; self.keyList.append(be); return True; def insertAbbrev(self, abbrev, value): #print >> sys.stderr, "inserting abbrev ", abbrev if abbrev in self.abbrevDict: #print >> sys.stderr, "abbrev %s already in list" % (abbrev) return False; self.abbrevDict[abbrev] = value; #be.brief(); return True; def __repr__(self): print >> sys.stderr def brief(self): for be in self: be.brief(); def getFilename(self): return self.filename; def getAbbrevs(self): return self.abbrevDict; def display(self): for be in self: be.display(); print >> sys.stderr def __contains__(self, key): return key in [x.key for x in self.keyList]; def __getitem__(self, i): if type(i) is str: index = [x.key for x in self.keyList].index(i); return self.keyList[index]; elif type(i) is int: return self.keyList[i]; else: raise; def __len__(self): return len(self.keyList); def sort(self, sortfunc): # turn the dictionary of entries into a list so we can sort it self.keyList.sort(sortfunc); # return list of all bibentry's that match the search spec def search(self, key, str, type="all", caseSens=0): if str == '*': return self.keyList; result = []; if string.lower(type) == "all": for be in self: if be.search(key, str, caseSens): result.append(be); else: for be in self: if be.isRefType(type) and be.search(key, str, caseSens): result.append(be); return result;