Esempio n. 1
0
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,
        )
Esempio n. 2
0
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,
        )
Esempio n. 3
0
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]
Esempio n. 4
0
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,
        )
Esempio n. 5
0
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)