~joshua-r-smith/pybtex/dev

« back to all changes in this revision

Viewing changes to pybtex/bibtex/names.py

  • Committer: Andrey Golovizin
  • Date: 2011-12-19 07:30:23 UTC
  • Revision ID: golovizin@gmail.com-20111219073023-vzw2lucmd7yfjqd5
Add tests for name format parsing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
class Text(object):
44
44
    def __init__(self, text):
45
 
        self.text = text[0]
 
45
        self.text = text
 
46
 
 
47
    def __repr__(self):
 
48
        return u'{0}({1})'.format(type(self).__name__, repr(self.text))
 
49
 
 
50
    def __eq__(self, other):
 
51
        return type(self) == type(other) and self.text == other.text
 
52
 
46
53
    def format(self, person):
47
54
        return self.text
 
55
 
48
56
    def to_python(self):
49
57
        return repr(self.text)
50
58
 
51
59
 
52
60
class NamePart(object):
53
61
    def __init__(self, format_list):
54
 
        self.pre_text, format_chars, self.delimiter, self.post_text = format_list[0]
 
62
        self.pre_text, format_chars, self.delimiter, self.post_text = format_list
55
63
 
56
64
        if self.post_text.endswith('~~'):
57
65
            self.tie = '~~'
71
79
            raise BibTeXNameFormatError('invalid format string')
72
80
        self.format_char = format_chars[0]
73
81
 
 
82
    def __repr__(self):
 
83
        format_chars = self.format_char * (1 if self.abbreviate else 2)
 
84
        format_list = [self.pre_text, format_chars, self.delimiter, self.post_text]
 
85
        return u'{0}({1})'.format(type(self).__name__, repr(format_list))
 
86
 
 
87
    def __eq__(self, other):
 
88
        return (
 
89
            type(self) == type(other)
 
90
            and self.pre_text == other.pre_text
 
91
            and self.format_char == other.format_char
 
92
            and self.abbreviate == other.abbreviate
 
93
            and self.delimiter == other.delimiter
 
94
            and self.post_text == other.post_text
 
95
        )
 
96
 
74
97
    types = {
75
98
            'f': 'bibtex_first',
76
99
            'l': 'last',
126
149
        
127
150
 
128
151
class NameFormat(object):
 
152
    """
 
153
    BibTeX name format string.
 
154
    
 
155
    >>> f = NameFormat('{ff~}{vv~}{ll}{, jj}')
 
156
    >>> f.parts == [
 
157
    ...     NamePart(['', 'ff', None, '']),
 
158
    ...     NamePart(['', 'vv', None, '']),
 
159
    ...     NamePart(['', 'll', None, '']),
 
160
    ...     NamePart([', ', 'jj', None, ''])
 
161
    ... ]
 
162
    True
 
163
    >>> f = NameFormat('{{ }ff~{ }}{vv~{- Test text here -}~}{ll}{, jj}')
 
164
    >>> f.parts == [
 
165
    ...     NamePart(['{ }', 'ff', None, '~{ }']),
 
166
    ...     NamePart(['', 'vv', None, '~{- Test text here -}']),
 
167
    ...     NamePart(['', 'll', None, '']),
 
168
    ...     NamePart([u', ', 'jj', None, ''])
 
169
    ... ]
 
170
    True
 
171
    >>> f = NameFormat('abc def {f~} xyz {f}?')
 
172
    >>> f.parts == [
 
173
    ...     Text('abc def '),
 
174
    ...     NamePart(['', 'f', None, '']),
 
175
    ...     Text(' xyz '),
 
176
    ...     NamePart(['', 'f', None, '']),
 
177
    ...     Text('?'),
 
178
    ... ]
 
179
    True
 
180
    >>> f = NameFormat('{{abc}{def}ff~{xyz}{#@$}}')
 
181
    >>> f.parts == [NamePart(['{abc}{def}', 'ff', None, '~{xyz}{#@$}'])]
 
182
    True
 
183
 
 
184
    """
 
185
 
129
186
    def __init__(self, format):
130
187
        self.format_string = format
131
 
        self.parts = name_format_grammar.parseString(format)
 
188
        self.parts = list(name_format_grammar.parseString(format))
132
189
 
133
190
    def format(self, name):
134
191
        person = Person(name)
191
248
delimiter = braced_string.copy().setParseAction(removeQuotes)
192
249
group = Group(Suppress(lbrace) + verbatim + format_chars + Optional(delimiter, None) +
193
250
        verbatim + Suppress(rbrace))
194
 
group.setParseAction(lambda toks: NamePart(toks))
195
 
toplevel_text = CharsNotIn('{}').setParseAction(lambda toks: Text(toks))
 
251
group.setParseAction(lambda toks: NamePart(toks[0]))
 
252
toplevel_text = CharsNotIn('{}').setParseAction(lambda toks: Text(toks[0]))
196
253
name_format_grammar = ZeroOrMore(toplevel_text | group) + StringEnd()
197
254
name_format_grammar.leaveWhitespace()