~spacexplorer/+junk/myenv

« back to all changes in this revision

Viewing changes to vim/vim/ftplugin/latex-suite/bibtools.py

  • Committer: Kim Allamandola
  • Date: 2011-05-02 05:39:17 UTC
  • Revision ID: spacexplorer@gmail.com-20110502053917-x0yl2lr9ri4yskr2
InitĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Author: Srinath Avadhanula
 
2
# This file is distributed as part of the vim-latex project
 
3
# http://vim-latex.sf.net
 
4
 
 
5
import re
 
6
 
 
7
class Bibliography(dict):
 
8
    def __init__(self, txt, macros={}):
 
9
        """
 
10
        txt:
 
11
            a string which represents the entire bibtex entry. A typical
 
12
            entry is of the form:
 
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},
 
17
                  year = {1984},
 
18
                  volume = {305},
 
19
                  pages = {41-78},
 
20
                  number = {1122},
 
21
                  owner = {Srinath},
 
22
                  pdf = {C:\srinath\research\papers\Ellington-3-Kinematics.pdf},
 
23
                  timestamp = {2006.01.02},
 
24
                }
 
25
        """
 
26
        
 
27
        if macros:
 
28
            for k, v in macros.iteritems():
 
29
                txt = txt.replace(k, '{'+v+'}')
 
30
        
 
31
        m = re.match(r'\s*@(\w+){((\S+),)?(.*)}\s*', txt, re.MULTILINE | re.DOTALL)
 
32
        if not m:
 
33
            return None
 
34
 
 
35
        self['bibtype'] = m.group(1).capitalize()
 
36
        self['key'] = m.group(3)
 
37
        self['body'] = m.group(4)
 
38
 
 
39
        body = self['body']
 
40
        self['bodytext'] = ''
 
41
        while 1:
 
42
            m = re.search(r'(\S+?)\s*=\s*(.)', body)
 
43
            if not m:
 
44
                break
 
45
 
 
46
            field = m.group(1)
 
47
 
 
48
            body = body[(m.start(2)+1):]
 
49
            if m.group(2) == '{':
 
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
 
54
                # following {.
 
55
                mniter = re.finditer(r'{|}', body)
 
56
 
 
57
                count = 1
 
58
                while 1:
 
59
                    try:
 
60
                        mn = mniter.next()
 
61
                    except StopIteration:
 
62
                        return None
 
63
 
 
64
                    if mn.group(0) == '{':
 
65
                        count += 1
 
66
                    else:
 
67
                        count -= 1
 
68
 
 
69
                    if count == 0:
 
70
                        value = body[:(mn.start(0))]
 
71
                        break
 
72
 
 
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)
 
78
                if not mn:
 
79
                    return None
 
80
 
 
81
                value = body[:(mn.start(0))]
 
82
 
 
83
            else:
 
84
                # $ always matches. So we do not need to do any
 
85
                # error-checking.
 
86
                mn = re.search(r',|$', body)
 
87
                value = m.group(2) + body[:(mn.start(0))].rstrip()
 
88
 
 
89
            self[field] = re.sub(r'\s+', ' ', value)
 
90
            body = body[(mn.start(0)+1):]
 
91
 
 
92
            self['bodytext'] += ('  %s: %s\n' % (field, value))
 
93
            if self['bibtype'].lower() == 'string':
 
94
                self['macro'] = {field: value}
 
95
 
 
96
        self['bodytext'] = self['bodytext'].rstrip()
 
97
        
 
98
 
 
99
    def __getitem__(self, key):
 
100
        try:
 
101
            return dict.__getitem__(self, key)
 
102
        except KeyError:
 
103
            return ''
 
104
        
 
105
    def __str__(self):
 
106
        if self['bibtype'].lower() == 'string':
 
107
            return 'String: %(macro)s' % self
 
108
 
 
109
        elif self['bibtype'].lower() == 'article':
 
110
            return ('Article [%(key)s]\n' +
 
111
                    'TI "%(title)s"\n' +
 
112
                    'AU %(author)s\n' +
 
113
                    'IN In %(journal)s, %(year)s') % self
 
114
 
 
115
        elif self['bibtype'].lower() == 'conference':
 
116
            return ('Conference [%(key)s]\n' +
 
117
                    'TI "%(title)s"\n' +
 
118
                    'AU %(author)s\n' +
 
119
                    'IN In %(booktitle)s, %(year)s') % self
 
120
 
 
121
        elif self['bibtype'].lower() == 'mastersthesis':
 
122
            return ('Masters [%(key)s]\n' + 
 
123
                    'TI "%(title)s"\n' + 
 
124
                    'AU %(author)s\n' + 
 
125
                    'IN In %(school)s, %(year)s') % self
 
126
 
 
127
        elif self['bibtype'].lower() == 'phdthesis':
 
128
            return ('PhD [%(key)s]\n' + 
 
129
                    'TI "%(title)s"\n' + 
 
130
                    'AU %(author)s\n' + 
 
131
                    'IN In %(school)s, %(year)s') % self
 
132
 
 
133
        elif self['bibtype'].lower() == 'book':
 
134
            return ('Book [%(key)s]\n' +
 
135
                    'TI "%(title)s"\n' + 
 
136
                    'AU %(author)s\n' + 
 
137
                    'IN %(publisher)s, %(year)s') % self
 
138
 
 
139
        else:
 
140
            s = '%(bibtype)s [%(key)s]\n' % self
 
141
            if self['title']:
 
142
                s += 'TI "%(title)s"\n' % self
 
143
            if self['author']:
 
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)
 
148
 
 
149
            return s.rstrip()
 
150
 
 
151
    def satisfies(self, filters):
 
152
        for field, regexp in filters:
 
153
            if not re.search(regexp, self[field], re.I):
 
154
                return False
 
155
 
 
156
        return True
 
157
 
 
158
class BibFile:
 
159
 
 
160
    def __init__(self, filelist=''):
 
161
        self.bibentries = []
 
162
        self.filters = []
 
163
        self.macros = {}
 
164
        self.sortfields = []
 
165
        if filelist:
 
166
            for f in filelist.splitlines():
 
167
                self.addfile(f)
 
168
 
 
169
    def addfile(self, file):
 
170
        fields = open(file).read().split('@')
 
171
        for f in fields:
 
172
            if not (f and re.match('string', f, re.I)):
 
173
                continue
 
174
 
 
175
            b = Bibliography('@' + f)
 
176
            self.macros.update(b['macro'])
 
177
 
 
178
        for f in fields:
 
179
            if not f or re.match('string', f, re.I):
 
180
                continue
 
181
 
 
182
            b = Bibliography('@' + f, self.macros)
 
183
            if b:
 
184
                b['file'] = file
 
185
                b['id'] = len(self.bibentries)
 
186
                self.bibentries += [b]
 
187
 
 
188
 
 
189
    def addfilter(self, filterspec):
 
190
        self.filters += [filterspec.split()]
 
191
 
 
192
    def rmfilters(self):
 
193
        self.filters = []
 
194
 
 
195
    def __str__(self):
 
196
        s = ''
 
197
        for b in self.bibentries:
 
198
            if b['key'] and b.satisfies(self.filters):
 
199
                s += '%s\n\n' % b
 
200
        return s
 
201
 
 
202
    def addsortfield(self, field):
 
203
        self.sortfields += [field]
 
204
 
 
205
    def rmsortfields(self):
 
206
        self.sortfields = []
 
207
 
 
208
    def sort(self):
 
209
        def cmpfun(b1, b2):
 
210
            for f in self.sortfields:
 
211
                c = cmp(b1[f], b2[f])
 
212
                if c:
 
213
                    return c
 
214
            return 0
 
215
        self.bibentries.sort(cmp=cmpfun)
 
216
 
 
217
if __name__ == "__main__":
 
218
    import sys
 
219
 
 
220
    bf = BibFile(sys.argv[1])
 
221
    print bf