def generate_key (entry, table): if entry.has_key ('author'): aut = entry ['author'] elif entry.has_key ('editor'): aut = entry ['editor'] else: aut = () if len (aut) == 0: global __entry key = 'entry-%d' % __entry __entry = __entry + 1 else: if len (aut) > 1: key = '' for a in aut: honorific, first, last, lineage = a.format () key = key + join (map (lambda x: x [0], split (last, ' ')), '') if len (key) >= 3: if len (aut) > 3: key = key + '+' break else: honorific, first, last, lineage = aut [0].format () parts = split (last, ' ') if len (parts) == 1: key = parts [0][0:3] else: key = join (map (lambda x: x [0], parts), '') if entry.has_key ('date'): year = entry ['date'].year if year: key = key + str (year) [2:] base = _flat (key) key = Key.Key (table, base) if table.has_key (key): suff = ord ('a') while table.has_key (key): suff = suff + 1 if suff > ord ('z'): suff = ord ('a') base = base + 'a' key = Key.Key (table, base + chr (suff)) return Key.Key (table, key)
def find_entries(auxfile, bibtex): """ Parse an auxiliary file and extract the entries from the given BibTeX databases """ entries, data, style = list_entries(auxfile) if not bibtex: bibtex = data # we have to create a Reference database to hold the entries contained in the # current database. r = Base.DataBase(None) keys = copy.copy(entries) # is there something to do ? if len(entries) == 0: return r, style, entries # use the bibliographic databases in order of declaration # to solve the references for bib in bibtex: (root, ext) = os.path.splitext(bib) if not ext: ext = '.bib' # open the database db = Open.bibopen(root + ext) # as we are modifying the list of entries in this loop, we make a copy # of it in order to avoir strange behaviors orig = copy.copy(entries) # loop over the expected entries for e in orig: # create a key in the current database key = Key.Key(db, e) # does the database provide the key ? if db.has_key(key): # yes, add it to the reference r[Key.Key(None, e)] = db[key] # and remove it from the list entries.remove(e) # is it finished ? if len(entries) == 0: break # return the reference on all the entries, plus the missing ones keys = filter(lambda x, entries=entries: not entries.count(x), keys) keys = map(lambda x, r=r: Key.Key(r, x), keys) return r, keys, style, entries
def __init__ (self, keylist, database = None): if type (keylist) is types.StringType: self.list = map (lambda k, db = database: Key.Key (db, string.strip (k)), string.split (keylist, ',')) else: self.list = keylist return
def update(self, database, entry): modified = False key = string.strip(self.key.get_text()) if key == '': self.entry.key = None modified = True else: if not key_re.match(key): Utils.error_dialog_s(self.w.get_toplevel(), _("Invalid key format")) return None key = Key.Key(database, key) if key != self.entry.key: if database.has_key(key): Utils.error_dialog_s( self.w.get_toplevel(), _(u"Key “%s” already exists") % str(key.key)) return None self.entry.key = key modified = True modified = self.type != self.entry.type or modified for item in self.content: try: result = item.update(self.entry) except UnicodeError: f = Types.get_field(item.field) Utils.error_dialog_s( self.w.get_toplevel(), _(u"The “%s” field contains a non Latin-1 symbol") % f.name) return None if result == -1: return None modified = result or modified modified |= self.lt_update() if not modified: fields = self.entry.keys() fields.sort() if fields != self.fields: modified = 1 if modified: return self.entry return entry
def add(self, entry): '''Adds an (eventually) anonymous entry.''' if entry.key is None: entry.key = self.generate_key(entry) else: entry.key.base = self.key if self.has_key(entry.key): prefix = entry.key.key suffix = ord ('a') while True: key = Key.Key(self, prefix + '-' + chr(suffix)) if not self.has_key (key): break suffix += 1 entry.key = key self[entry.key] = entry return entry
def drag_received(self, *arg): selection = arg[4] info = arg[5] if not info == Mime.KEY: return keys = string.split(selection.data, '\n') reflist = [] for k in keys: (base, key) = string.split(k, '\0') if not base: base = None reflist.append(Key.Key(base, key)) self.current = Fields.Reference(reflist) text = string.join(map(lambda x: x.key, self.current.list), ', ') self.edit.set_text(text) return
def next(self): while True: try: retval = _bibtex.next_unfiltered(self.parser) except IOError, error: raise Exceptions.ParserError((str(error), )) if retval == None: self.db.set_metadata('bibtex-preamble', self.preamble) return None elif retval[0] == 'entry': retval = retval[1] name, fieldtype, offset, line, object = retval if name: key = Key.Key(self.db, name) else: key = None fieldtype = Types.get_entry(fieldtype) return Entry(key, fieldtype, object, self.parser, line) elif retval[0] == 'preamble': self.preamble.append(retval[1]) continue else: continue
def would_have_key(self, key): '''Test for a key that would be set on the database ''' return self.has_key(Key.Key(self, key.key))
db = bibopen(bib) # as we are modifying the list of entries in this loop, we make a copy # of it in order to avoir strange behaviors orig = copy.copy(entries) # we have to create a new database to hold the entries contained in the # current database. r = Base.DataBase(None) # loop over the expected entries for e in orig: # create a key in the current database key = Key.Key(db, e) # does the database provide the key ? if db.has_key(key): # yes, add it to the reference v = db[key] r[key] = v # ...including possible crossrefs if v.has_key(crossref): for ck in v[crossref].list: ck.base = db.key if db.has_key(ck):
# to solve the references for bib in bibfile: # open the database db = bibopen(bib) # as we are modifying the list of entries in this loop, we make a copy # of it in order to avoid strange behaviors orig = copy.copy(entries) # loop over the expected entries for e in orig: # create a key in the current database key = Key.Key(db, e) # does the database provide the key ? if db.has_key(key): # yes, add it to the reference r[key] = db[key] # and remove it from the list entries.remove(e) # if we found some entries in the current database... if len(r) > 0: pass # is it finished ?
def next(self): data = '' fields = {} type = None label = None while 1: line = self.file.readline() if line == '' and not fields: return None line = string.strip(line) if line == '' and fields: # store the current field if type: if type == "label": label = string.join(string.split(data), ' ') elif fields.has_key(type): fields[type].append( string.join(string.split(data), ' ')) else: fields[type] = [string.join(string.split(data), ' ')] # determine the real type while 1: if fields.has_key('journal'): type = 'article' break if fields.has_key('booktitle'): type = 'inbook' break if fields.has_key('volume') or fields.has_key('number'): type = 'inproceedings' break if fields.has_key('publisher'): type = 'book' break if fields.has_key('author') and fields.has_key('title'): type = 'unpublished' break type = 'misc' break entry = Types.get_entry(type) for f in fields.keys(): type = Types.get_field(f).type if type == Fields.AuthorGroup: group = Fields.AuthorGroup() for auth in fields[f]: group.append(Fields.Author(auth)) fields[f] = group else: if len(fields[f]) > 1: sys.stderr.write( "warning: field `%s' is defined more than once" % f) continue fields[f] = type(fields[f][0]) if label: key = Key.Key(None, label) return Base.Entry(key, entry, fields) else: return Base.Entry(None, entry, fields) t = tag_re.match(line) # we matched a new field start if t: if type: if type == "label": label = string.join(string.split(data), ' ') elif fields.has_key(type): fields[type].append( string.join(string.split(data), ' ')) else: fields[type] = [string.join(string.split(data), ' ')] type = t.group(1) if not self.mapping.has_key(type): print "warning: key `%s' has been skipped" % (type) type = None data = '' else: # store the current field type = self.mapping[type][0] data = t.group(2) continue # in the general case, append the new text data = data + ' ' + line