class Entry(object): """A bibliography entry.""" key = None """Entry key (for example, ``'fukushima1980neocognitron'``).""" def __init__(self, type_, fields=None, persons=None, collection=None): if fields is None: fields = {} if persons is None: persons = {} self.type = type_.lower() """Entry type (``'book'``, ``'article'``, etc.).""" self.original_type = type_ self.fields = FieldDict(self, fields) """A dictionary of entry fields. The dictionary is ordered and case-insensitive.""" self.persons = OrderedCaseInsensitiveDict(persons) """A dictionary of entry persons, by their roles. The most often used roles are ``'author'`` and ``'editor'``. """ self.collection = collection # for BibTeX interpreter self.vars = {} def __eq__(self, other): if not isinstance(other, Entry): return super(Entry, self) == other return (self.type == other.type and self.fields == other.fields and self.persons == other.persons) def __repr__(self): # representing fields as FieldDict causes problems with representing # fields.parent, so represent it as a list of tuples repr_fields = repr(self.fields.items()) return 'Entry({type_}, fields={fields}, persons={persons})'.format( type_=repr(self.type), fields=repr_fields, persons=repr(self.persons), ) def get_crossref(self): return self.collection.entries[self.fields['crossref']] def add_person(self, person, role): self.persons.setdefault(role, []).append(person) def lower(self): return type(self)( self.type, fields=self.fields.lower(), persons=self.persons.lower(), collection=self.collection, )
class Entry(object): """Bibliography entry. Important members are: - persons (a dict of Person objects) - fields (all dict of string) """ def __init__(self, type_, fields=None, persons=None, collection=None): if fields is None: fields = {} if persons is None: persons = {} self.type = type_.lower() self.original_type = type_ self.fields = FieldDict(self, fields) self.persons = OrderedCaseInsensitiveDict(persons) self.collection = collection # for BibTeX interpreter self.vars = {} def __eq__(self, other): if not isinstance(other, Entry): return super(Entry, self) == other return ( self.type == other.type and self.fields == other.fields and self.persons == other.persons ) def __repr__(self): return 'Entry({type_}, fields={fields}, persons={persons})'.format( type_=repr(self.type), fields=repr(self.fields), persons=repr(self.persons), ) def get_crossref(self): return self.collection.entries[self.fields['crossref']] def add_person(self, person, role): self.persons.setdefault(role, []).append(person) def lower(self): return type(self)( self.type, fields=self.fields.lower(), persons=self.persons.lower(), collection=self.collection, )
class Entry(object): """A bibliography entry.""" type = None """Entry type (``'book'``, ``'article'``, etc.).""" key = None """Entry key (for example, ``'fukushima1980neocognitron'``).""" fields = None """A dictionary of entry fields. The dictionary is ordered and case-insensitive.""" persons = None """ A dictionary of entry persons, by their roles. The most often used roles are ``'author'`` and ``'editor'``. """ """A reference to the containing :py:class:`.BibliographyData` object. Used to resolve crossrefs.""" def __init__(self, type_, fields=None, persons=None): if fields is None: fields = {} if persons is None: persons = {} self.type = type_.lower() self.original_type = type_ self.fields = OrderedCaseInsensitiveDict(fields) self.persons = OrderedCaseInsensitiveDict(persons) def __eq__(self, other): if not isinstance(other, Entry): return super(Entry, self) == other return (self.type == other.type and self.fields == other.fields and self.persons == other.persons) def __repr__(self): # represent the fields as a list of tuples for simplicity repr_fields = repr(list(self.fields.items())) keys = self.fields.keys() for key in keys: ind = repr_fields.index(key) - 2 # find first instance repr_fields = repr_fields[:ind] + "\n" + repr_fields[ind:] repr_fields = indent(repr_fields, prefix=" ") repr_fields = repr_fields[4:] # drop 1st indent return ("Entry({0},\n" " fields={1},\n" " persons={2})".format(repr(self.type), repr_fields, repr(self.persons))) def add_person(self, person, role): self.persons.setdefault(role, []).append(person) def lower(self): return type(self)( self.type, fields=self.fields.lower(), persons=self.persons.lower(), ) def _find_person_field(self, role): persons = self.persons[role] return ' and '.join(six.text_type(person) for person in persons) def _find_crossref_field(self, name, bib_data): if bib_data is None or 'crossref' not in self.fields: raise KeyError(name) referenced_entry = bib_data.entries[self.fields['crossref']] return referenced_entry._find_field(name, bib_data) def _find_field(self, name, bib_data=None): """ Find the field with the given ``name`` according to this rules: - If the given field ``name`` in in ``self.fields``, just return self.fields[name]. - Otherwise, if ``name`` is ``"authors"`` or ``"editors"`` (or any other person role), return the list of names as a string, separated by ``" and "``. - Otherwise, if this entry has a ``crossreff`` field, look up for the cross-referenced entry and try to find its field with the given ``name``. """ try: return self.fields[name] except KeyError: try: return self._find_person_field(name) except KeyError: return self._find_crossref_field(name, bib_data) def to_string(self, bib_format, **kwargs): """ Return the data as a unicode string in the given format. :param bib_format: Data format ("bibtex", "yaml", etc.). """ writer = find_plugin('pybtex.database.output', bib_format)(**kwargs) return writer.to_string(BibliographyData(entries={self.key: self})) @classmethod def from_string(cls, value, bib_format, entry_number=0, **kwargs): """ Return the data from a unicode string in the given format. :param bib_format: Data format ("bibtex", "yaml", etc.). :param entry_number: entry number if the string has more than one. .. versionadded:: 0.22.2 """ # get bibliography bibdata = BibliographyData.from_string(value, bib_format, **kwargs) # grab specific instance key = tuple(bibdata.entries.keys())[entry_number] return bibdata.entries[key]
class Entry(object): """A bibliography entry.""" type = None """Entry type (``'book'``, ``'article'``, etc.).""" key = None """Entry key (for example, ``'fukushima1980neocognitron'``).""" fields = None """A dictionary of entry fields. The dictionary is ordered and case-insensitive.""" rich_fields = None """A dictionary of entry fields, converted to :ref:`rich text <rich-text>`.""" persons = None """ A dictionary of entry persons, by their roles. The most often used roles are ``'author'`` and ``'editor'``. """ collection = None """A reference to the containing :py:class:`.BibliographyData` object. Used to resolve crossrefs.""" def __init__(self, type_, fields=None, persons=None, collection=None): if fields is None: fields = {} if persons is None: persons = {} self.type = type_.lower() self.original_type = type_ self.fields = FieldDict(self, fields) self.rich_fields = RichFieldProxyDict(self.fields) self.persons = OrderedCaseInsensitiveDict(persons) self.collection = collection # for BibTeX interpreter self.vars = {} def __eq__(self, other): if not isinstance(other, Entry): return super(Entry, self) == other return ( self.type == other.type and self.fields == other.fields and self.persons == other.persons ) def __repr__(self): # representing fields as FieldDict causes problems with representing # fields.parent, so represent it as a list of tuples repr_fields = repr(self.fields.items()) return 'Entry({type_}, fields={fields}, persons={persons})'.format( type_=repr(self.type), fields=repr_fields, persons=repr(self.persons), ) def get_crossref(self): return self.collection.entries[self.fields['crossref']] def add_person(self, person, role): self.persons.setdefault(role, []).append(person) def lower(self): return type(self)( self.type, fields=self.fields.lower(), persons=self.persons.lower(), collection=self.collection, )
class Entry(object): """A bibliography entry.""" type = None """Entry type (``'book'``, ``'article'``, etc.).""" key = None """Entry key (for example, ``'fukushima1980neocognitron'``).""" fields = None """A dictionary of entry fields. The dictionary is ordered and case-insensitive.""" persons = None """ A dictionary of entry persons, by their roles. The most often used roles are ``'author'`` and ``'editor'``. """ """A reference to the containing :py:class:`.BibliographyData` object. Used to resolve crossrefs.""" def __init__(self, type_, fields=None, persons=None): if fields is None: fields = {} if persons is None: persons = {} self.type = type_.lower() self.original_type = type_ self.fields = OrderedCaseInsensitiveDict(fields) self.persons = OrderedCaseInsensitiveDict(persons) def __eq__(self, other): if not isinstance(other, Entry): return super(Entry, self) == other return ( self.type == other.type and self.fields == other.fields and self.persons == other.persons ) def __repr__(self): # represent the fields as a list of tuples for simplicity repr_fields = repr(self.fields.items()) return 'Entry({type_}, fields={fields}, persons={persons})'.format( type_=repr(self.type), fields=repr_fields, persons=repr(self.persons), ) def add_person(self, person, role): self.persons.setdefault(role, []).append(person) def lower(self): return type(self)( self.type, fields=self.fields.lower(), persons=self.persons.lower(), ) def _find_person_field(self, role): persons = self.persons[role] return ' and '.join(six.text_type(person) for person in persons) def _find_crossref_field(self, name, bib_data): if bib_data is None or 'crossref' not in self.fields: raise KeyError(name) referenced_entry = bib_data.entries[self.fields['crossref']] return referenced_entry._find_field(name, bib_data) def _find_field(self, name, bib_data=None): """ Find the field with the given ``name`` according to this rules: - If the given field ``name`` in in ``self.fields``, just return self.fields[name]. - Otherwise, if ``name`` is ``"authors"`` or ``"editors"`` (or any other person role), return the list of names as a string, separated by ``" and "``. - Otherwise, if this entry has a ``crossreff`` field, look up for the cross-referenced entry and try to find its field with the given ``name``. """ try: return self.fields[name] except KeyError: try: return self._find_person_field(name) except KeyError: return self._find_crossref_field(name, bib_data)