from __future__ import generators import re import time _date_pat = re.compile('^(\d\d\d\d)-(\d\d)-(\d\d)\s+(.*)\s*$') def _parse_header(line): if line[0].isspace(): return None match = _date_pat.match(line) if match: when = (int(match.group(1)), int(match.group(2)), int(match.group(3)), 0,0,0, 0,0,0) who = match.group(4) return (when, who) parts = line.split(None, 5) if len(parts) == 6: try: timeval = ' '.join(parts[:5]) when = time.strptime(timeval, '%a %b %d %H:%M:%S %Y') who = parts[5] return (when, who) except ValueError: pass return None def parse(fp): '''parse a changelog in the standard format Yields tuples of the form (when, who, changes).''' when = None who = None changes = [] for line in fp: header = _parse_header(line) if header: if when: yield (when, who, changes) when, who = header changes = [] else: changes.append(line) if when: yield (when, who, changes) def _escape(s): s = s.replace('&', '&') s = s.replace('<', '<') s = s.replace('>', '>') return s def _break_into_paragraphs(lines): paragraphs = [[]] for line in lines: line = _escape(line.strip()) if not line: if paragraphs[-1]: paragraphs.append([]) continue if line[0] == '*': # bullets start new paragraphs if paragraphs[-1]: paragraphs.append([]) paragraphs[-1].append(line) if not paragraphs[-1]: del paragraphs[-1] return paragraphs def _splitword(s): parts = s.split(None, 1) parts.append('') return parts[0], parts[1] email_pat = re.compile(r'(<(.*@[-a-zA-Z0-9.]+)>)') bug_pat = re.compile(r'((?:bug\s+#?|#)(\d\d\d\d*))', re.I) def _linkify(s, bugsroot=None): s = email_pat.sub(r'\1', s) if bugsroot: s = bug_pat.sub(r'\1' % bugsroot, s) return s function_pat = re.compile(r'^(\s*\()([^\)]+)(\):.*)$') def changes_to_html(changes, webcvsroot=None, bugsroot=None): ret = [ '\n') return ''.join(ret)