def field_and_loss(self, key): # look in the cache first if self.__text.has_key(key): return self.__text[key] obj = self.dict[key] # search its declared type fieldtype = Types.get_field(key) ret = _bibtex.expand(self.parser, obj, _fieldtype(fieldtype)) fieldtype = fieldtype.type if fieldtype == AuthorGroup: # Author val = AuthorGroup() for aut in ret[3]: val.append(Author(aut)) elif fieldtype == Date: # Date val = Date((ret[3], None, None)) elif fieldtype == LongText: # Annotation text val = BibLongTextField(ret[2], self.get_latex(key)) elif fieldtype == Text: # Any other text val = BibTextField(ret[2], self.get_latex(key)) elif fieldtype == Reference: # a reference on the same database val = Reference(ret[2], self.key.base) else: # specific fields, like URL val = fieldtype(ret[2]) self.__text[key] = (val, ret[1]) return (val, ret[1])
def field_and_loss(self, key): # look in the cache first if self.__text.has_key(key): return self.__text[key] obj = self.dict[key] # search its declared type fieldtype = Types.get_field(key) ret = _bibtex.expand(self.parser, obj, _fieldtype(fieldtype)) fieldtype = fieldtype.type if fieldtype == AuthorGroup: # Author val = AuthorGroup () for aut in ret[3]: val.append (Author(aut)) elif fieldtype == Date: # Date val = Date((ret[3], None, None)) elif fieldtype == LongText: # Annotation text val = BibLongTextField(ret[2], self.get_latex(key)) elif fieldtype == Text: # Any other text val = BibTextField(ret[2], self.get_latex(key)) elif fieldtype == Reference: # a reference on the same database val = Reference(ret[2], self.key.base) else: # specific fields, like URL val = fieldtype(ret[2]) self.__text[key] = (val, ret[1]) return (val, ret[1])
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 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 __setitem__(self, key, value): # First, set the cache for free self.__text[key] = (value, 0) if isinstance(value, Date): return # then, convert as bibtex. if isinstance(value, Reference): value = string.join(map(lambda item: item.key, value.list), ', ') self.dict[key] = _bibtex.reverse(_fieldtype(Types.get_field(key)), Config.get('bibtex+/braces').data, value) return
def lt_node_list(self, item, fields): """Return a list of longtexts (annotations) associated with item """ fields = fields[:] nodes = [] self.lt_list_add1(item, nodes, item.type.mandatory, {'mandatory': True}) self.lt_list_add1(item, nodes, item.type.optional, {'mandatory': False}) remaining = list_remove(fields, [x['key'] for x in nodes]) self.lt_list_add1(item, nodes, [Types.get_field(x) for x in remaining], {'mandatory': False}) return nodes
def lt_node_list (self, item, fields): """Return a list of longtexts (annotations) associated with item """ fields = fields[:] nodes = [] self.lt_list_add1 (item, nodes, item.type.mandatory, {'mandatory': True}) self.lt_list_add1 (item, nodes, item.type.optional, {'mandatory': False}) remaining = list_remove (fields, [ x['key'] for x in nodes]) self.lt_list_add1 ( item, nodes, [Types.get_field(x) for x in remaining], {'mandatory': False}) return nodes
def update_notebook (self): if self.notebook_init: self.notebook.foreach( lambda x: self.notebook.remove_page(0)) self.notebook_init = True self.current_page = None names = (_("Mandatory"), _("Optional"), _("Notes"), _("Extra")) self.fields = map (string.lower, self.entry.keys ()) self.content = [] for i in range (len(names)): label = gtk.Label (names [i]) if i == 0: table = [x.name.lower() for x in self.entry.type.mandatory if x.type != Fields.LongText] self.add_type1_widget (label, table, i) list_remove (self.fields, table) elif i == 1: table = [x.name.lower() for x in self.entry.type.optional if x.type != Fields.LongText] self.add_type1_widget (label, table, i) list_remove (self.fields, table) elif i == 2: self.lt_nodes = self.lt_node_list ( self.entry, self.fields) self.lt_listvw = LT_Widget_1 ( self, i, self.dialogue) self.lt_detail = LT_Widget_2 ( self.notebook, i, self.dialogue) list_remove (self.fields, [x['key'] for x in self.lt_nodes]) else: table = [x for x in self.fields if Types.get_field(x).type != Fields.LongText] self.add_type1_widget (label, table, i) self.notebook.set_border_width(6) self.notebook.show () return
def create_field(self, *arg): text = string.strip(string.lower(self.newfield.get_text())) if not re.match(r"[a-z][\w_-]*$", text): if not Utils.Callback( "The fieldname '%s' looks invalid.\nReally proceed?" % text, parent=self.w.get_toplevel()).answer(): return # update the current entry current = self.update(self.database, copy.deepcopy(self.entry)) if current is None: return self.entry = current newtype = Types.get_field(text).type self.entry[text] = newtype(_newcontent[newtype]) self.update_notebook()
def update_notebook(self): if self.notebook_init: self.notebook.foreach(lambda x: self.notebook.remove_page(0)) self.notebook_init = True self.current_page = None names = (_("Mandatory"), _("Optional"), _("Notes"), _("Extra")) self.fields = map(string.lower, self.entry.keys()) self.content = [] for i in range(len(names)): label = gtk.Label(names[i]) if i == 0: table = [ x.name.lower() for x in self.entry.type.mandatory if x.type != Fields.LongText ] self.add_type1_widget(label, table, i) list_remove(self.fields, table) elif i == 1: table = [ x.name.lower() for x in self.entry.type.optional if x.type != Fields.LongText ] self.add_type1_widget(label, table, i) list_remove(self.fields, table) elif i == 2: self.lt_nodes = self.lt_node_list(self.entry, self.fields) self.lt_listvw = LT_Widget_1(self, i, self.dialogue) self.lt_detail = LT_Widget_2(self.notebook, i, self.dialogue) list_remove(self.fields, [x['key'] for x in self.lt_nodes]) else: table = [ x for x in self.fields if Types.get_field(x).type != Fields.LongText ] self.add_type1_widget(label, table, i) self.notebook.set_border_width(6) self.notebook.show() return
def writer (iter, output, **argh): entry = iter.first () mapping = Config.get ("refer/mapping").data while entry: for key in mapping.keys (): # some fields are not to be used in output, as we # lost their content if not mapping [key] [1]: continue field = mapping [key] [0] if field == "label" and entry.key: output.write ('%' + key + ' ') output.write (Utils.format (str (entry.key.key), 75, 0, 0)) output.write ('\n') continue elif entry.has_key (field): type = Types.get_field (field).type if type == Fields.AuthorGroup: # one field per author for auth in entry [field]: output.write ('%' + key + ' ') output.write (Utils.format (str (auth), 75, 0, 0)) output.write ('\n') continue # general case output.write ('%' + key + ' ') output.write (Utils.format (str (entry [field]), 75, 0, 0)) output.write ('\n') entry = iter.next () if entry: output.write ('\n') return
def writer(iter, output, **argh): entry = iter.first() mapping = Config.get("refer/mapping").data while entry: for key in mapping.keys(): # some fields are not to be used in output, as we # lost their content if not mapping[key][1]: continue field = mapping[key][0] if field == "label" and entry.key: output.write('%' + key + ' ') output.write(Utils.format(str(entry.key.key), 75, 0, 0)) output.write('\n') continue elif entry.has_key(field): type = Types.get_field(field).type if type == Fields.AuthorGroup: # one field per author for auth in entry[field]: output.write('%' + key + ' ') output.write(Utils.format(str(auth), 75, 0, 0)) output.write('\n') continue # general case output.write('%' + key + ' ') output.write(Utils.format(str(entry[field]), 75, 0, 0)) output.write('\n') entry = iter.next() if entry: output.write('\n') return
def __init__(self, parent=None): self.dialog = gtk.Dialog(_('New Annotation Name'), parent, 0, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) self.dialog.vbox.set_border_width(24) self.dialog.vbox.pack_start( gtk.Label(_('Name of the new annotation:')), True, True, 6) self.options = gtk.combo_box_new_text() self.dialog.vbox.pack_start(self.options, True, True, 6) self.fields = [ x for x in Config.get('base/fields').data if Types.get_field(x).type == Fields.LongText ] self.fields.sort() for i in self.fields: self.options.append_text(i) self.options.set_active(0) self.options.connect('changed', self.changed) self.dialog.set_default_response(gtk.RESPONSE_ACCEPT) self.value = self.fields[0]
def __init__ (self, parent=None): self.dialog = gtk.Dialog( _('New Annotation Name'), parent, 0, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) self.dialog.vbox.set_border_width (24) self.dialog.vbox. pack_start ( gtk.Label ( _('Name of the new annotation:')), True, True, 6) self.options = gtk.combo_box_new_text () self.dialog.vbox.pack_start (self.options, True, True, 6) self.fields = [ x for x in Config.get ('base/fields').data if Types.get_field(x).type == Fields.LongText] self.fields.sort() for i in self.fields: self.options.append_text (i) self.options.set_active (0) self.options.connect ('changed', self.changed) self.dialog.set_default_response(gtk.RESPONSE_ACCEPT) self.value = self.fields[0]
def entry_write(entry, output): '''Print a single entry as BiBTeX code.''' native = isinstance(entry, Entry) tp = entry.type # write the type and key output.write('@%s{%s,\n' % (tp.name, entry.key.key)) # create a hash containing all the keys, to keep track # of those who have been already written dico = {} datefields = Config.get('bibtex/datefield').data convert = Config.get('bibtex/months').data # we have to handle the special case of the dates # create the list of months monthlist = range(0, 12) for key in convert.keys(): monthlist[convert[key] - 1] = key dateformat = Config.get('bibtex+/dateformat').data if native: # loop over all the fields for field in entry.keys(): if datefields.has_key(field): # we are processing a date... date = entry[field] dico[datefields[field][0]] = str(date.year) if date.month: month = monthlist[date.month - 1] if date.day: month = dateformat % {'day': date.day, 'month': month} dico[datefields[field][1]] = month else: # we are processing a normal entry dico[field] = _bibtex.get_native(entry.dict[field]) else: for field in entry.keys(): # convert the field in a bibtex form if datefields.has_key(field): # we are processing a date... date = entry[field] dico[datefields[field][0]] = str(date.year) if date.month: month = monthlist[date.month - 1] if date.day: month = dateformat % {'day': date.day, 'month': month} dico[datefields[field][1]] = month else: # we are processing a normal entry value = entry[field] # eventually convert the crossref if isinstance(value, Reference): value = string.join(map(lambda item: item.key, value.list), ', ') fieldtype = _fieldtype(Types.get_field(field)) dico[field] = _nativify(value, fieldtype) first = True # write according to the type order for f in tp.mandatory + tp.optional: # dico contains all the available fields field = string.lower(f.name) if not dico.has_key(field): continue if not first: output.write(',\n') else: first = False output.write(' %-14s = ' % f.name) output.write(Utils.format(dico[field], 75, 19, 19)[19:]) del dico[field] keys = dico.keys() keys.sort() for f in keys: if not first: output.write(',\n') else: first = False output.write(' %-14s = ' % f) output.write(Utils.format(dico[f], 75, 19, 19)[19:]) output.write('\n}\n\n') return
def display(self, iterator): # clear the access table self.access = [] Utils.set_cursor(self.w, 'clock') self.model.clear() for entry in iterator: row = [] i = 0 for f in self.fields: row.append(i) i = i + 1 if f == '-key-': row.append((str(entry.key.key)).decode('latin-1')) elif f == '-type-': row.append(str(entry.type.name)) ## ascii elif f == '-author/editor-': row.append( userformat.author_editor_format(entry).decode( 'latin-1')) elif f == '-author/title-': row.append( userformat.author_title_format(entry).decode( 'latin-1')) elif entry.has_key(f): if Types.get_field(f).type == Fields.AuthorGroup: text = join(map(lambda a: str(a.last), entry[f]), ', ') elif Types.get_field(f).type == Fields.Date: text = str(entry[f].year) else: text = str(entry[f]) row.append(text.decode('latin-1')) else: row.append('') if True: row.append(i) if Resource.is_viewable(entry): row.append(self.gvpixbuf) else: row.append(None) iter = self.model.append() apply(self.model.set, [iter] + row) self.access.append(entry) entry = iterator.next() Utils.set_cursor(self.w, 'normal') return
def get_latex(self, key): ''' Returns latex part ''' return _bibtex.get_latex(self.parser, self.dict[key], _fieldtype(Types.get_field(key)))
def get_field (self, entry): try: return entry [self.field] except KeyError: return Types.get_field (self.field).type ('')
def next(self): dict = {} # read entry till next blank line text = [] field = '' while 1: line = self.file.readline() if line == '': break line = string.rstrip(line) # starting with a blank ? if line == '' or line[0] == ' ': # ...then we continue the current text text.append(string.lstrip(line)) continue # new entry ? if separator_re.match(line): break # else, this is a new field if field: # save the previous one if needed dict[field] = '\n'.join(text) text = [] # store the name of this new field field = string.lower(line) # don't waste the last field content if field: dict[field] = '\n'.join(text) # did we parse a field ? if len(dict) == 0: return None # create the entry content entry = Base.Entry(type=self.deftype) for key in dict.keys(): if not self.mapping.has_key(key): #print "warning: unused key `%s'" % key continue (name, type) = self.mapping[key] text_type = Types.get_field(name).type # parse a simple text field if type == SimpleField: entry[name] = text_type(string.strip(dict[key])) elif type == KeywordField: text = string.strip(dict[key]) if entry.has_key(name): text = str(entry[name]) + '\n ' + text entry[name] = text_type(text) # parse an author field elif type == AuthorField: entry[name] = self.parse_author(dict[key]) continue # parse a source field elif type == SourceField: dict_key = ' '.join(dict[key].split('\n')) m = self.source_re.match(dict_key.strip()) if m: year, month, day = None, None, None j, v, s, n, p, o, y, d = m.group('journal', 'volume', 'inseries', 'number', 'pages', 'other', 'year', 'month') if s: ### article in a monograph series entry['booktitle'] = Fields.Text(j) if d: entry['beigabevermerk'] = Fields.LongText(d) entry.type = Types.get_entry('incollection') elif j: entry['journal'] = Fields.Text(j) if d and not d.isspace(): dates = d.split() try: month = long_month[dates[0]] except KeyError: pass ## import warnings ## warnings.filterwarnings ('once', ## message='date', ## module='OvidLike') ## warnings.warn ( ## 'OVID: %s is not representable in date ' ## 'field %s' %(dates[0], d), stacklevel=2) if len(dates) > 1: day = int(dates[1]) if v: entry['volume'] = Fields.Text(v) if n: entry['number'] = Fields.Text(n) if p: entry['pages'] = Fields.Text(p) if o: entry['other-note'] = Fields.Text(o) if y: year = int(y) entry['date'] = Fields.Date((year, month, day)) else: print '>>> Error: Source field does not parse correctly:' print dict_key print entry continue return entry
def display (self, iterator): # clear the access table self.access = [] Utils.set_cursor (self.w, 'clock') self.model.clear () for entry in iterator: row = [] i = 0 for f in self.fields: row.append (i) i = i + 1 if f == '-key-': row.append ((str (entry.key.key)).decode ('latin-1')) elif f == '-type-': row.append (str (entry.type.name)) ## ascii elif f == '-author/editor-': row.append (userformat.author_editor_format (entry).decode ('latin-1')) elif f == '-author/title-': row.append (userformat.author_title_format (entry).decode ('latin-1')) elif entry.has_key (f): if Types.get_field (f).type == Fields.AuthorGroup: text = join (map (lambda a: str (a.last), entry [f]), ', ') elif Types.get_field (f).type == Fields.Date: text = str (entry [f].year) else: text = str (entry [f]) row.append (text.decode ('latin-1')) else: row.append ('') if True: row.append (i) if Resource.is_viewable (entry): row.append (self.gvpixbuf) else: row.append (None) iter = self.model.append () apply (self.model.set, [iter] + row) self.access.append (entry) entry = iterator.next () Utils.set_cursor (self.w, 'normal') return
def next (self): dict = {} # read entry till next blank line text = [] field = '' while 1: line = self.file.readline () if line == '': break line = string.rstrip (line) # starting with a blank ? if line == '' or line [0] == ' ': # ...then we continue the current text text.append (string.lstrip (line)) continue # new entry ? if separator_re.match (line): break # else, this is a new field if field: # save the previous one if needed dict [field] = '\n'.join(text) text = [] # store the name of this new field field = string.lower (line) # don't waste the last field content if field: dict [field] = '\n'.join(text) # did we parse a field ? if len (dict) == 0: return None # create the entry content entry = Base.Entry (type = self.deftype) for key in dict.keys (): if not self.mapping.has_key (key): #print "warning: unused key `%s'" % key continue (name, type) = self.mapping [key] text_type = Types.get_field (name).type # parse a simple text field if type == SimpleField: entry [name] = text_type (string.strip (dict [key])) elif type == KeywordField: text = string.strip (dict [key]) if entry.has_key (name): text = str (entry [name]) + '\n ' + text entry [name] = text_type (text) # parse an author field elif type == AuthorField: entry [name] = self.parse_author (dict[key]) continue # parse a source field elif type == SourceField: dict_key = ' '.join(dict[key].split('\n')) m = self.source_re.match (dict_key.strip()) if m: year, month, day = None, None, None j, v, s, n, p, o, y, d = m.group( 'journal', 'volume', 'inseries', 'number', 'pages', 'other', 'year', 'month') if s: ### article in a monograph series entry['booktitle'] = Fields.Text (j) if d: entry['beigabevermerk'] = Fields.LongText (d) entry.type = Types.get_entry('incollection') elif j: entry ['journal'] = Fields.Text (j) if d and not d.isspace(): dates = d.split () try: month = long_month [dates[0]] except KeyError: pass ## import warnings ## warnings.filterwarnings ('once', ## message='date', ## module='OvidLike') ## warnings.warn ( ## 'OVID: %s is not representable in date ' ## 'field %s' %(dates[0], d), stacklevel=2) if len(dates) > 1: day = int (dates[1]) if v: entry ['volume'] = Fields.Text (v) if n: entry ['number'] = Fields.Text (n) if p: entry ['pages'] = Fields.Text (p) if o: entry ['other-note'] = Fields.Text(o) if y: year = int(y) entry ['date'] = Fields.Date((year, month, day)) else: print '>>> Error: Source field does not parse correctly:' print dict_key print entry continue return entry
def next(self): current = None data = '' table = {} # Skip whitespace while 1: line = self.file.readline() if line == '': return table line = string.rstrip(line) if line != '': break while 1: head = header.match(line) if head: if current: if table.has_key(current): table[current].append(data) else: table[current] = [data] current = string.strip(head.group(1)) data = head.group(2) else: cont = contin.match(line) if cont: data = data + ' ' + cont.group(1) line = self.file.readline() if line == '': break line = string.rstrip(line) if line == '': break # don't forget the last item if current: if table.has_key(current): table[current].append(data) else: table[current] = [data] # create the entry with the actual fields norm = {} type = Types.get_entry('article') if table.has_key('PMID'): norm['url'] = Fields.URL(medurl + table['PMID'][0]) norm['medline-pmid'] = Fields.Text(table['PMID'][0]) del table['PMID'] if table.has_key('UI'): norm[one_to_one['UI']] = Fields.Text(table['UI'][0]) del table['UI'] if table.has_key('AU'): group = Fields.AuthorGroup() for au in table['AU']: # analyze the author by ourself. first, last, lineage = [], [], [] for part in string.split(au, ' '): if part.isupper(): # in upper-case, this is a first name if len(last) > 0: first.append(part) else: # if there is no last name, there can't be a first name last.append(part) else: if len(first) > 0: # there was a first name, this must be a lineage lineage.append(part) else: last.append(part) if len(first) > 1: print "medline: long first name found. skipping." first = first[0:1] if len(first) > 0: first = string.join(first[0], '. ') + '.' else: first = None if len(last) > 0: last = string.join(last, ' ') else: last = None if len(lineage) > 0: lineage = string.join(lineage, ' ') else: lineage = None group.append(Fields.Author((None, first, last, lineage))) norm[one_to_one['AU']] = group del table['AU'] if table.has_key('DP'): fields = string.split(table['DP'][0], ' ') norm[one_to_one['DP']] = Fields.Date(fields[0]) del table['DP'] # The simple fields... for f in table.keys(): f_mapped = one_to_one.get(f, 'medline-%s' % (f.lower())) text_type = Types.get_field(f_mapped).type norm[f_mapped] = text_type(string.join(table[f], " ; ")) return Base.Entry(None, type, norm)
def next (self): lines = {} in_table = {} file_notes, file_time, file_version, file_format = ('','','','') while 1: line = self.file.readline() if line == '': return lines # what does that mean ?? head = xheader.match(line) if not head : pass elif head.group(1) == 'Date:': file_time = time.strftime( "%Y-%m-%d %H:%M", rfc822.parsedate(head.group(2))) elif head.group(1) == 'Notes:': file_notes = string.strip(head.group(2)) elif head.group(1) == 'FN': file_format = head.group(2) elif head.group(1) == 'VR': file_version = head.group(2) elif len(head.group(1)) == 2 : break else : pass self.extraneous.append(line) self.isifileformat = self.isifileformat or "Isifile format %s(%s)" % ( file_format, file_version) self.isifileinfo = self.isifileinfo or "ISI %s (%s) %s" %( file_time, file_notes, login_name) while 1: if line == 'ER':break if head : key = head.group(1) if key == 'ER': break val = head.group(3) if lines.has_key(key): lines[key].append(val) else: lines[key] = [val] else: cont = contin.match(line) if cont : val = cont.group(1) lines[key].append(val) else: break line = self.file.readline() if line == '': break # error situation head = header.match (line) key = 'PT' if lines.has_key(key): if string.strip(lines[key][0])[0] == 'J': del lines [key] else: print 'Warning: Unknown type of entry (%s) -- may need editing.' %( lines[key]) type = Types.get_entry ('article') for key in ( 'AU', 'ED'): if lines.has_key(key): group = Fields.AuthorGroup() for item in lines[key]: if string.strip(item) =='[Anon]' : auth = [item] else: name, firstn = string.split (item, ',') auth = ["%s, " % name] for i in string.strip (firstn): auth.append ("%s. " % i) group.append (Fields.Author("".join(auth))) if key == 'AU': in_table['author'] = group elif key == 'ED': in_table['editor'] = group del lines[key] key, key1, key2 = 'PG', 'BP', 'EP' if lines.has_key(key1) and lines.has_key(key2): if len(lines[key1]) == len(lines[key2]): pages = [] for i in range(len(lines[key1])): firstpg = lines[key1] [i] lastpg = lines[key2] [i] pages.append(('%s -- %s' % (firstpg, lastpg))) in_table['pages'] = Fields.Text (string.join(pages, '; ')) del lines[key1]; del lines[key2] else: print 'inconsistent BP, EP fields found' if lines.has_key(key): in_table['size'] = Fields.Text ('%s p.' %(lines[key][0])) del lines[key] key = 'PY' if lines.has_key(key): val = lines[key][0] in_table['date'] = Fields.Date(val) del lines[key] key = 'ID' if lines. has_key(key): val = "[ISI:] %s ;;" %(string.lower(string.join(lines[key], ' '))) if lines.has_key('DE'): lines['DE'].append ('; ' + val) else : lines['DE'] = [val] del lines[key] # journal titles come in various forms if lines.has_key ('SO'): uc_title = ' '.join(lines['SO']) in_table ['journal'] = Fields.Text (uc_title) if lines.has_key('JI'): uc_title = re.split(r"([- .,/]+)", uc_title) ca_title = re.split(r"[- .,/]+", ' '.join(lines['JI'])) i , Title = 0, [] for word in uc_title: Word = string.capitalize(word) if word == ca_title [i]: Title.append (word) i += 1 elif Word.startswith(ca_title[i]): Title.append(Word) i += 1 else: Title.append(string.lower(word)) del lines['JI'] in_table['journal'] = Fields.Text ("".join(Title)) del lines['SO'] for key in lines.keys(): mapped_key, joiner = key_map.get( key, ('isifile-%s' %(key.lower()), ' ; ')) text_type = Types.get_field (mapped_key).type in_table [mapped_key] = text_type (joiner.join(lines[key])) return Base.Entry ( None, type, in_table)
def entry_write(entry, output): '''Print a single entry as BiBTeX code.''' native = isinstance(entry, Entry) tp = entry.type # write the type and key output.write('@%s{%s,\n' % (tp.name, entry.key.key)) # create a hash containing all the keys, to keep track # of those who have been already written dico = {} datefields = Config.get('bibtex/datefield').data convert = Config.get('bibtex/months').data # we have to handle the special case of the dates # create the list of months monthlist = range(0, 12) for key in convert.keys(): monthlist[convert[key]-1] = key dateformat = Config.get('bibtex+/dateformat').data if native: # loop over all the fields for field in entry.keys(): if datefields.has_key(field): # we are processing a date... date = entry[field] dico[datefields[field][0]] = str(date.year) if date.month: month = monthlist[date.month - 1] if date.day: month = dateformat % {'day': date.day, 'month' : month} dico[datefields[field][1]] = month else: # we are processing a normal entry dico[field] = _bibtex.get_native(entry.dict[field]) else: for field in entry.keys(): # convert the field in a bibtex form if datefields.has_key(field): # we are processing a date... date = entry[field] dico[datefields[field][0]] = str(date.year) if date.month: month = monthlist[date.month - 1] if date.day: month = dateformat % {'day': date.day, 'month' : month} dico[datefields[field][1]] = month else: # we are processing a normal entry value = entry[field] # eventually convert the crossref if isinstance(value, Reference): value = string.join(map(lambda item: item.key, value.list), ', ') fieldtype = _fieldtype(Types.get_field(field)) dico[field] = _nativify(value, fieldtype) first = True # write according to the type order for f in tp.mandatory + tp.optional: # dico contains all the available fields field = string.lower(f.name) if not dico.has_key(field): continue if not first: output.write (',\n') else: first = False output.write(' %-14s = ' % f.name) output.write(Utils.format (dico[field], 75, 19, 19)[19:]) del dico[field] keys = dico.keys() keys.sort() for f in keys: if not first: output.write (',\n') else: first = False output.write(' %-14s = ' % f) output.write(Utils.format(dico[f], 75, 19, 19)[19:]) output.write ('\n}\n\n') return
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
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
def next (self): current = None data = '' table = {} # Skip whitespace while 1: line = self.file.readline () if line == '': return table line = string.rstrip (line) if line != '': break while 1: head = header.match (line) if head: if current: if table.has_key (current): table [current].append (data) else: table [current] = [data] current = string.strip (head.group (1)) data = head.group (2) else: cont = contin.match (line) if cont: data = data + ' ' + cont.group (1) line = self.file.readline () if line == '': break line = string.rstrip (line) if line == '': break # don't forget the last item if current: if table.has_key (current): table [current].append (data) else: table [current] = [data] # create the entry with the actual fields norm = {} type = Types.get_entry ('article') if table.has_key ('PMID'): norm ['url'] = Fields.URL (medurl + table ['PMID'] [0]) norm ['medline-pmid'] = Fields.Text (table ['PMID'] [0]) del table ['PMID'] if table.has_key ('UI'): norm [one_to_one ['UI']] = Fields.Text (table ['UI'] [0]) del table ['UI'] if table.has_key ('AU'): group = Fields.AuthorGroup () for au in table ['AU']: # analyze the author by ourself. first, last, lineage = [], [], [] for part in string.split (au, ' '): if part.isupper (): # in upper-case, this is a first name if len (last) > 0: first.append (part) else: # if there is no last name, there can't be a first name last.append (part) else: if len (first) > 0: # there was a first name, this must be a lineage lineage.append (part) else: last.append (part) if len (first) > 1: print "medline: long first name found. skipping." first = first [0:1] if len (first) > 0: first = string.join (first [0], '. ') + '.' else: first = None if len (last) > 0: last = string.join (last, ' ') else: last = None if len (lineage) > 0: lineage = string.join (lineage, ' ') else: lineage = None group.append (Fields.Author ((None, first, last, lineage))) norm [one_to_one ['AU']] = group del table ['AU'] if table.has_key ('DP'): fields = string.split (table ['DP'][0], ' ') norm [one_to_one ['DP']] = Fields.Date (fields [0]) del table ['DP'] # The simple fields... for f in table.keys (): f_mapped = one_to_one.get(f, 'medline-%s' %(f.lower())) text_type = Types.get_field(f_mapped).type norm [f_mapped] = text_type (string.join (table [f], " ; ")) return Base.Entry (None, type, norm)
def next (self): current = None data = '' table = {} # Skip whitespace while 1: line = self.file.readline () if line == '': return table line = string.rstrip (line) if line != '': break while 1: head = header.match (line) if head: if current: if table.has_key (current): table [current].append (data) else: table [current] = [data] current = string.strip (head.group (1)) data = head.group (2) else: cont = contin.match (line) if cont: data = data + ' ' + cont.group (1) line = self.file.readline () if line == '': break line = string.rstrip (line) if line == '': break # don't forget the last item if current: if table.has_key (current): table [current].append (data) else: table [current] = [data] # create the entry with the actual fields norm = {} type = Types.get_entry ('article') if table.has_key ('PMID'): norm ['url'] = Fields.URL (medurl + table ['PMID'] [0]) norm ['medline-pmid'] = Fields.Text (table ['PMID'] [0]) del table ['PMID'] if table.has_key ('UI'): norm [one_to_one ['UI']] = Fields.Text (table ['UI'] [0]) del table ['UI'] if table.has_key ('AU'): group = Fields.AuthorGroup () for au in table ['AU']: # analyze the author names first, last, lineage = [], [], [] parts = string.split (au, ' ') # if the last part is not uppercase, it is a lineage ('Jr', '3rd', etc.) if not parts [-1] . isupper(): lineage.append (parts.pop ()) else: lineage = None # after removing lineage from list, last part should be the first initial(s) if len (parts) > 1: first = parts.pop () first = string.join (first, '. ') + '.' else: first = None # join remaining parts to form the last name. if it's one initial, give it a '.' for part in parts: if len (part) == 1: last.append (part + '.') else: last.append (part) if len (parts) > 0: last = string.join(last, ' ') else: last = None group.append (Fields.Author ((None, first, last, lineage))) norm [one_to_one ['AU']] = group del table ['AU'] if table.has_key ('DP'): fields = string.split (table ['DP'][0], ' ') norm [one_to_one ['DP']] = Fields.Date (fields [0]) del table ['DP'] # The simple fields... for f in table.keys (): f_mapped = one_to_one.get(f, 'medline-%s' %(f.lower())) text_type = Types.get_field(f_mapped).type norm [f_mapped] = text_type (string.join (table [f], " ; ")) return Base.Entry (None, type, norm)