def __init__(self, citation=None): """ Sets up internal dictionary of BibTeX fields, and initializes if argument is given. """ self.bibtype = None self.citekey = None if isinstance(citation, BibTexEntry): self._entry_dict = OrderedCaselessDict(citation._entry_dict) elif isinstance(citation, dict): self._entry_dict = OrderedCaselessDict() for k, v in citation.items(): self._entry_dict[k.lower()] = v self.bibtype = self._entry_dict.get("bibtype", None) self.citekey = self._entry_dict.get("citekey", None) else: self._entry_dict = OrderedCaselessDict() self.parse_text(citation)
def __init__(self): self.formats = OrderedCaselessDict()
class BibTexEntry(object): """ Tracks a single BibTeX entry. """ decompose_pattern = re.compile(r'^@(\w*)\s*{\s*([\w|\:|\-]*),(.*)}') # works, but misses last field field_pattern = re.compile( r'\s*([\w|\-]*?)\s*=\s*(.*?),(?=\s*[\w|\-]*\s*\=)') # get the last field last_field_pattern = re.compile(r'\s*([\w|\-]*?)\s*=\s*(.*?)\s*[,]*\s*$') def __init__(self, citation=None): """ Sets up internal dictionary of BibTeX fields, and initializes if argument is given. """ self.bibtype = None self.citekey = None if isinstance(citation, BibTexEntry): self._entry_dict = OrderedCaselessDict(citation._entry_dict) elif isinstance(citation, dict): self._entry_dict = OrderedCaselessDict() for k, v in citation.items(): self._entry_dict[k.lower()] = v self.bibtype = self._entry_dict.get("bibtype", None) self.citekey = self._entry_dict.get("citekey", None) else: self._entry_dict = OrderedCaselessDict() self.parse_text(citation) def __getattr__(self, name): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': return entry_dict elif name == '__dict__': return object.__getattribute__(self, '__dict__') elif name == 'bibtype' and hasattr(self, 'bibtype'): return object.__getattribute__(self, '__dict__')['bibtype'] elif name == 'citekey' and hasattr(self, 'citekey'): return object.__getattribute__(self, '__dict__')['citekey'] elif name in entry_dict: return entry_dict[name] elif name in BIBTEX_FIELDS: return "" else: raise AttributeError(name) def __setattr__(self, name, value): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': entry_dict = value elif name == 'bibtype' or name == 'citekey': object.__setattr__(self, name, value) else: self._entry_dict[name] = value def __delattr__(self, name): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': object.__delattr__(self, '_entry_dict') elif name in entry_dict: del (entry_dict[name]) elif name in BIBTEX_FIELDS: pass elif name in object.__getattribute__(self, '__dict__'): object.__delattr__(name) else: raise AttributeError(name) def __str__(self): """ String representation of self. """ return self.as_bibtex() def __repr__(self): """ Internal representation of self. """ repr_dict = {} repr_dict['bibtype'] = self.bibtype repr_dict['citekey'] = self.citekey repr_dict.update(self.fields_as_dict()) return repr_dict def _get_entry_dict(self): """ Returns the internal field dictionary, creating it first if neccessary. """ if not hasattr(self, '_entry_dict'): object.__setattr__(self, '_entry_dict', {}) return object.__getattribute__(self, '_entry_dict') def _get_fields(self): """ Returns list of populated fields in order (does not include bibtype and citekey). """ fields = [] for field in BIBTEX_FIELDS: if field in self._entry_dict: fields.append(field) for key in self._entry_dict: if key not in fields: fields.append(key) return fields fields = property(_get_fields) def parse_text(self, text): """ Parses a BibTeX text entry. """ text = text.replace("\n", "") self.bibtype = None self.citekey = None text = text.strip() decompose_match = self.decompose_pattern.match(text) try: self.bibtype = decompose_match.group(1) except AttributeError, exception: raise ValueError("Failed to parse bibtype: %s" % text) try: self.citekey = decompose_match.group(2) except AttributeError, exception: raise ValueError("Failed to parse citekey: %s" % text)
class BibTexEntry(object): """ Tracks a single BibTeX entry. """ decompose_pattern = re.compile(r'^@(\w*)\s*{\s*([\w|\:|\-]*),(.*)}') # works, but misses last field field_pattern = re.compile(r'\s*([\w|\-]*?)\s*=\s*(.*?),(?=\s*[\w|\-]*\s*\=)') # get the last field last_field_pattern = re.compile(r'\s*([\w|\-]*?)\s*=\s*(.*?)\s*[,]*\s*$') def __init__(self, citation=None): """ Sets up internal dictionary of BibTeX fields, and initializes if argument is given. """ self.bibtype = None self.citekey = None if isinstance(citation, BibTexEntry): self._entry_dict = OrderedCaselessDict(citation._entry_dict) elif isinstance(citation, dict): self._entry_dict = OrderedCaselessDict() for k, v in citation.items(): self._entry_dict[k.lower()] = v self.bibtype = self._entry_dict.get("bibtype", None) self.citekey = self._entry_dict.get("citekey", None) else: self._entry_dict = OrderedCaselessDict() self.parse_text(citation) def __getattr__(self, name): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': return entry_dict elif name == '__dict__': return object.__getattribute__(self, '__dict__') elif name == 'bibtype' and hasattr(self, 'bibtype'): return object.__getattribute__(self, '__dict__')['bibtype'] elif name == 'citekey' and hasattr(self, 'citekey'): return object.__getattribute__(self, '__dict__')['citekey'] elif name in entry_dict: return entry_dict[name] elif name in BIBTEX_FIELDS: return "" else: raise AttributeError(name) def __setattr__(self, name, value): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': entry_dict = value elif name == 'bibtype' or name == 'citekey': object.__setattr__(self, name, value) else: self._entry_dict[name] = value def __delattr__(self, name): """ Allows bibtex fields (and any additional ones) to be treated like object attributes. """ entry_dict = self._get_entry_dict() if name == '_entry_dict' or name == '_BibTexEntry_entry_dict': object.__delattr__(self, '_entry_dict') elif name in entry_dict: del(entry_dict[name]) elif name in BIBTEX_FIELDS: pass elif name in object.__getattribute__(self, '__dict__'): object.__delattr__(name) else: raise AttributeError(name) def __str__(self): """ String representation of self. """ return self.as_bibtex() def __repr__(self): """ Internal representation of self. """ repr_dict = {} repr_dict['bibtype'] = self.bibtype repr_dict['citekey'] = self.citekey repr_dict.update(self.fields_as_dict()) return repr_dict def _get_entry_dict(self): """ Returns the internal field dictionary, creating it first if neccessary. """ if not hasattr(self, '_entry_dict'): object.__setattr__(self, '_entry_dict', {}) return object.__getattribute__(self, '_entry_dict') def _get_fields(self): """ Returns list of populated fields in order (does not include bibtype and citekey). """ fields = [] for field in BIBTEX_FIELDS: if field in self._entry_dict: fields.append(field) for key in self._entry_dict: if key not in fields: fields.append(key) return fields fields = property(_get_fields) def parse_text(self, text): """ Parses a BibTeX text entry. """ text = text.replace("\n", "") self.bibtype = None self.citekey = None text = text.strip() decompose_match = self.decompose_pattern.match(text) try: self.bibtype = decompose_match.group(1) except AttributeError, exception: raise ValueError("Failed to parse bibtype: %s" % text) try: self.citekey = decompose_match.group(2) except AttributeError, exception: raise ValueError("Failed to parse citekey: %s" % text)