diff options
| -rw-r--r-- | BibTeX.py | 52 |
1 files changed, 26 insertions, 26 deletions
@@ -87,21 +87,35 @@ class FileIter: if string: file = cStringIO.StringIO(string) if file: - it = iter(file.xreadlines()) - self.iter = it + self.iter = iter(file) assert self.iter self.lineno = 0 - self._next = it.next def next(self): self.lineno += 1 - return self._next() + return self.iter.next() def advance(self, line): while not line or line.isspace() or COMMENT_RE.match(line): line = self.next() return line +# Matches a comment line outside of an entry. +OUTER_COMMENT_RE = re.compile(r'^\s*[\#\%]') +# Matches a comment line inside of an entry. +COMMENT_RE = re.compile(r'^\s*\%') +# Matches the start of an entry. group 1 is the type of the entry. +# group 2 is the rest of the line. +ENTRY_BEGIN_RE = re.compile(r'''^\s*\@([^\s\"\%\'\(\)\,\=\{\}]+)(.*)''') +# Start of an entry. group 1 is the keyword naming the entry. +BRACE_BEGIN_RE = re.compile(r'\s*\{(.*)') +BRACE_END_RE = re.compile(r'\s*\}(.*)') +KEY_RE = re.compile(r'''\s*([^\"\#\%\'\(\)\,\=\{\}\s]+)(.*)''') + +STRING_CLOSE_RE = re.compile(r'^([^\{\}\"]*)\"(.*)') +BRACE_CLOSE_RE = re.compile(r'^([^\{\}]*)\}(.*)') +BRACE_OPEN_RE = re.compile(r'^([^\{\}]*\{)(.*)') +RAW_DATA_RE = re.compile(r'^([^\s\},]+)(.*)') class Parser: """Parser class: reads BibTeX from a file and returns a BibTeX object.""" @@ -133,6 +147,9 @@ class Parser: def advance(self, line): return self.fileiter.advance(line) + @property + def lineno(self): + return self.fileiter.lineno def _parseKey(self, line): line = self.advance(line) @@ -205,11 +222,11 @@ class Parser: data.append(" ") line = self.fileiter.next() elif line[0] == '#': - print >>sys.stderr, "Weird concat on line %s" % it.lineno + print >>sys.stderr, "Weird concat on line %s" % self.lineno elif line[0] in "},": if not data: print >>sys.stderr, "No data after field on line %s" % ( - it.lineno) + self.lineno) else: m = RAW_DATA_RE.match(line) if m: @@ -220,7 +237,7 @@ class Parser: data.append(m.group(1)) line = m.group(2) else: - raise ParseError("Questionable line at line %s" % it.lineno) + raise ParseError("Questionable line at line %s" % self.lineno) # Got a string, check for concatenation. if line.isspace() or not line: @@ -237,12 +254,12 @@ class Parser: return data, line def _parseEntry(self, line): # name, strings, entries - self.entryLine = self.fileiter.lineno + self.entryLine = self.lineno line = self.advance(line) m = BRACE_BEGIN_RE.match(line) if not m: - raise ParseError("Expected an opening brace at line %s" % it.lineno) + raise ParseError("Expected an opening brace at line %s" % self.lineno) line = m.group(1) proto = {'string': 'p', 'preamble': 'v'}.get(self.curEntType, 'kp*') @@ -334,23 +351,6 @@ class Parser: raise ParseError("Bad input at line %s (expected a new entry.)" % self.fileiter.lineno) -# Matches a comment line outside of an entry. -OUTER_COMMENT_RE = re.compile(r'^\s*[\#\%]') -# Matches a comment line inside of an entry. -COMMENT_RE = re.compile(r'^\s*\%') -# Matches the start of an entry. group 1 is the type of the entry. -# group 2 is the rest of the line. -ENTRY_BEGIN_RE = re.compile(r'''^\s*\@([^\s\"\%\'\(\)\,\=\{\}]+)(.*)''') -# Start of an entry. group 1 is the keyword naming the entry. -BRACE_BEGIN_RE = re.compile(r'\s*\{(.*)') -BRACE_END_RE = re.compile(r'\s*\}(.*)') -KEY_RE = re.compile(r'''\s*([^\"\#\%\'\(\)\,\=\{\}\s]+)(.*)''') - -STRING_CLOSE_RE = re.compile(r'^([^\{\}\"]*)\"(.*)') -BRACE_CLOSE_RE = re.compile(r'^([^\{\}]*)\}(.*)') -BRACE_OPEN_RE = re.compile(r'^([^\{\}]*\{)(.*)') -RAW_DATA_RE = re.compile(r'^([^\s\},]+)(.*)') - def parseFile(filename, result=None): """Helper function: parse a single BibTeX file""" |
