#!/usr/bin/env python import sys, re, os, os.path, fnmatch, codecs, locale from optparse import OptionParser desc = """Walk the current directory and its subdirectories, opening '*.txt' files and reporting the changes needed for the new, post version 845, format. If the option '-m' is used, changes will be made and and the results saved with the file extension changed to '.text' provided this file does not already exist.""" encoding = "UTF-8" file_encoding = locale.getdefaultlocale()[1] def make_xlat(d): adict = d rx = re.compile('|'.join(adict)) def one_xlat(match): return adict[match.group(0)] def xlat(text): return rx.sub(one_xlat, text) return xlat def walkdir(make_changes=False): global numfiles, numlines, numchanges numfiles = 0 numlines = 0 numchanges = 0 amper = re.compile(r'^&') under = re.compile(r'^(_+)') period = re.compile(r'^(\.+)') # to remove any any white space following '@e +' extent = re.compile(r'@e \+\s+') sdict = { '@l' : '@+', # include list '@x' : '@-', # exclude list '@p' : '@e +', # action period -> +extent } translate = make_xlat(sdict) cwd = os.getcwd() all_changes = [] num_skipped = 0 num_changed = 0 for path, subdirs, names in os.walk(cwd): for name in names: level = 1 if fnmatch.fnmatch(name, '[!.]*.txt'): file_changes = [] numfiles += 1 changed = False f = os.path.join(path,name) newf = "%s.text" % os.path.splitext(f)[0] if make_changes and os.path.isfile(newf): print """ Skipping %s to avoid overwriting an existing file. Remove or rename %s before running this program to process this file. """ % (f, newf) num_skipped += 1 continue sf = f[len(path)+1:] # use the relative path as the key fo = codecs.open(f, 'r', file_encoding) lines = fo.readlines() fo.close() for i in range(len(lines)): numlines += 1 old_line = lines[i].rstrip() if not old_line: continue new_line = translate(old_line) new_line = extent.sub('@e +', new_line) new_line = amper.sub('*', new_line) # old rem -> event m = under.match(new_line) if m: new_line = under.sub('+'*len(m.group(0)), new_line) m = period.match(new_line) if m: new_line = period.sub('-'*len(m.group(0)), new_line) if new_line != old_line: numchanges += 1 changed = True file_changes.append(" line %s: " % i) file_changes.append(" [-] '%s'" % old_line) file_changes.append(" [+] '%s'" % new_line) if make_changes: lines[i] = "%s\n" % new_line if changed: num_changed += 1 file_changes.insert(0, "file: '%s'" % f) all_changes.extend(file_changes) if make_changes: newf = "%s.text" % os.path.splitext(f)[0] fo = codecs.open(newf, 'w', file_encoding) fo.writelines(lines) fo.close() if num_skipped: print """ %s files with the extension '.txt' were found. Of these %s were skipped because matching files with the extension '.text' were found. The remaining %s files were examined for needed changes. """ % (numfiles, num_skipped, numfiles - num_skipped) else: print """ %s files with the extension '.txt' were found and examined for needed changes. """ % numfiles if numchanges: if make_changes: v = "Made" p = '' else: v = "You need to make" p = "\nAppend '-m' to the command line to make these changes and save the results\nto new files with the extension '.text'.\n\nANY EXISTING FILES WITH THE EXTENSION '.text' WILL NOT BE OVERWRITTEN.\n" print("%s the following %s changes in %s file(s):\n" % (v, numchanges, num_changed)) print("\n".join(all_changes)) print(p) else: print("There are no changes to be made in the %s files which were examined." % (numfiles - num_skipped)) def main(): usage = "%prog [options]" parser = OptionParser(usage=usage, description = desc) parser.add_option("-m", "--make_changes", action="store_true", dest="make_changes", help="Actually make changes and save the result with the file's extension changed to .text." ) options, args= parser.parse_args() walkdir(options.make_changes) if __name__ == '__main__': main()