Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
 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
Exemplo n.º 8
0
 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))
Exemplo n.º 9
0
    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):
Exemplo n.º 10
0
# 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 ?
Exemplo n.º 11
0
    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