#!/usr/bin/env python # Copyright (C) 2001-2020 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. # # Refer to licensing information at http://www.artifex.com or contact # Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, # CA 94945, U.S.A., +1(415)492-9861, for further information. # # 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, os def html_escape(string): table = { '&': '&', '"': '"', '>': '>', '<': '<', '$': '$'} new = [] for char in string: new.append(table.get(char,char)) return "".join(new) 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') if self.data['author'] in authors: self.data['author'] = authors[self.data['author']] 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') file.write('\n') 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(html_escape(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('