1
# Author: Srinath Avadhanula
2
# This file is distributed as part of the vim-latex project
3
# http://vim-latex.sf.net
7
class Bibliography(dict):
8
def __init__(self, txt, macros={}):
11
a string which represents the entire bibtex entry. A typical
13
@ARTICLE{ellington:84:part3,
14
author = {Ellington, C P},
15
title = {The Aerodynamics of Hovering Insect Flight. III. Kinematics},
16
journal = {Philosophical Transactions of the Royal Society of London. Series B, Biological Sciences},
22
pdf = {C:\srinath\research\papers\Ellington-3-Kinematics.pdf},
23
timestamp = {2006.01.02},
28
for k, v in macros.iteritems():
29
txt = txt.replace(k, '{'+v+'}')
31
m = re.match(r'\s*@(\w+){((\S+),)?(.*)}\s*', txt, re.MULTILINE | re.DOTALL)
35
self['bibtype'] = m.group(1).capitalize()
36
self['key'] = m.group(3)
37
self['body'] = m.group(4)
42
m = re.search(r'(\S+?)\s*=\s*(.)', body)
48
body = body[(m.start(2)+1):]
50
# search for the next closing brace. This is not simply a
51
# matter of searching for the next closing brace since
52
# braces can be nested. The following code basically goes
53
# to the next } which has not already been closed by a
55
mniter = re.finditer(r'{|}', body)
64
if mn.group(0) == '{':
70
value = body[:(mn.start(0))]
73
elif m.group(2) == '"':
74
# search for the next unquoted double-quote. To be more
75
# precise, a double quote which is preceded by an even
76
# number of double quotes.
77
mn = re.search(r'(?!\\)(\\\\)*"', body)
81
value = body[:(mn.start(0))]
84
# $ always matches. So we do not need to do any
86
mn = re.search(r',|$', body)
87
value = m.group(2) + body[:(mn.start(0))].rstrip()
89
self[field] = re.sub(r'\s+', ' ', value)
90
body = body[(mn.start(0)+1):]
92
self['bodytext'] += (' %s: %s\n' % (field, value))
93
if self['bibtype'].lower() == 'string':
94
self['macro'] = {field: value}
96
self['bodytext'] = self['bodytext'].rstrip()
99
def __getitem__(self, key):
101
return dict.__getitem__(self, key)
106
if self['bibtype'].lower() == 'string':
107
return 'String: %(macro)s' % self
109
elif self['bibtype'].lower() == 'article':
110
return ('Article [%(key)s]\n' +
113
'IN In %(journal)s, %(year)s') % self
115
elif self['bibtype'].lower() == 'conference':
116
return ('Conference [%(key)s]\n' +
119
'IN In %(booktitle)s, %(year)s') % self
121
elif self['bibtype'].lower() == 'mastersthesis':
122
return ('Masters [%(key)s]\n' +
125
'IN In %(school)s, %(year)s') % self
127
elif self['bibtype'].lower() == 'phdthesis':
128
return ('PhD [%(key)s]\n' +
131
'IN In %(school)s, %(year)s') % self
133
elif self['bibtype'].lower() == 'book':
134
return ('Book [%(key)s]\n' +
137
'IN %(publisher)s, %(year)s') % self
140
s = '%(bibtype)s [%(key)s]\n' % self
142
s += 'TI "%(title)s"\n' % self
144
s += 'AU %(author)s\n' % self
145
for k, v in self.iteritems():
146
if k not in ['title', 'author', 'bibtype', 'key', 'id', 'file', 'body', 'bodytext']:
147
s += 'MI %s: %s\n' % (k, v)
151
def satisfies(self, filters):
152
for field, regexp in filters:
153
if not re.search(regexp, self[field], re.I):
160
def __init__(self, filelist=''):
166
for f in filelist.splitlines():
169
def addfile(self, file):
170
fields = open(file).read().split('@')
172
if not (f and re.match('string', f, re.I)):
175
b = Bibliography('@' + f)
176
self.macros.update(b['macro'])
179
if not f or re.match('string', f, re.I):
182
b = Bibliography('@' + f, self.macros)
185
b['id'] = len(self.bibentries)
186
self.bibentries += [b]
189
def addfilter(self, filterspec):
190
self.filters += [filterspec.split()]
197
for b in self.bibentries:
198
if b['key'] and b.satisfies(self.filters):
202
def addsortfield(self, field):
203
self.sortfields += [field]
205
def rmsortfields(self):
210
for f in self.sortfields:
211
c = cmp(b1[f], b2[f])
215
self.bibentries.sort(cmp=cmpfun)
217
if __name__ == "__main__":
220
bf = BibFile(sys.argv[1])