#!/usr/bin/env python # Copyright (C) 2003-2007 Artifex Software, Inc. All rights reserved. # # This software is provided AS-IS with no warranty, either express or # implied. # # This software is distributed under license and may not be copied, # modified or distributed except as expressly authorized under the terms # of the license contained in the file LICENSE in this distribution. # # For more information about licensing, please refer to # http://www.ghostscript.com/licensing/. For information on # commercial licensing, go to http://www.artifex.com/licensing/ or # contact Artifex Software, Inc., 101 Lucas Valley Road #110, # San Rafael, CA 94903, U.S.A., +1(415)492-9861. # $Id: split_changelog.py 8022 2007-06-05 22:23:38Z giles $ # script to generate the split Changes/Details html changelogs # for Ghostscript from the output of 'svn log --xml' import string, re import xml.parsers.expat import sys, codecs class Entry: '''a class representing a single changelog entry''' data = {} has_details = False has_differences = False r = re.compile('^[\[ ]*DETAILS[ :\]]*$', re.I) c = re.compile('^[ ]*EXPECTED DIFFERENCES[ :]*$', re.I) d = re.compile('^[ ]*DIFFERENCES[ :]*$', re.I) codec = codecs.getencoder("utf8") def reset(self): self.data = {} self.has_details = False self.has_differences = False def add(self, key, value): if not self.data.has_key(key): self.data[key] = value else: self.data[key] = string.join((self.data[key], value)) def listadd(self, key, value): if not self.data.has_key(key): self.data[key] = [value] else: self.data[key].append(value) def addmsg(self, value): if not self.data.has_key('msg'): self.data['msg'] = [] self.data['msg'].append(value) if self.r.search(value): self.has_details = True if self.c.search(value): self.has_differences = True if self.d.search(value): self.has_differences = True def write(self, file, details=True): #stamp = self.data['date'] + ' ' + self.data['time'] stamp = self.data['date'] # construct the name anchor label = '' for c in stamp: if c == ' ': c = '_' if c == ':': continue label = label + c file.write('\n
') file.write('') file.write('\n') file.write(stamp + ' ' + self.data['author']) file.write('') if not details and self.has_details: file.write(' (details)') file.write('
\n') file.write('\n') file.write('\n') def write_header(file, details=True): file.write('\n') file.write('\n') file.write('\n') file.write('\n') # todo: html-escape the msg lines try: for line in self.data['msg']: # skip the details unless wanted if not details and self.r.search(line): break if self.c.search(line): break if self.d.search(line): break file.write(line.encode('utf8')) except KeyError: line = '(empty)' file.write(line.encode('utf8')) file.write('\n') file.write('[') #file.write(string.join(map(string.join, zip(self.data['name'],self.data['revision'])),', ')) #file.write(string.join(self.data['name'])) file.write(string.join(self.data['path'])) file.write(']
\n') file.write('