#!/usr/bin/env python def usage(): print ''' slasub.py does slash replacement and then substitutes anything. Usage: $ slasub.py infile > outfile (output redirected) Slash replacement: Bb7/f / / Gm / --> Bb7/f Bb7/f Bb7/f Gm Gm // / --> // // Slashes preceded by a space and not immediately followed by another character are replaced by the previous word in the line. Define in document: #$mac( replacement text... optional argument placers = % % to get per cents in output: %% %% replacement text end: #) The identifier must begin with "#" at the beginning of a line. Single per cents are replaced by arguments of targets. The easiest way to mess up is to forget to close the replacement text with "#)". You can't start a definition with "##", but any other nonwhite character may follow the first "#". Targets in document: $mic @gob Gm7b5 or: $mac(arg1 arg2 ... ) \gub(arg1 arg2 ... ) (c)2005 David Raleigh Arnold under GNU. See GNU license. 20050510 ''' sys.exit(0) def getinputfile(): '''If there is infile, do it, return open infile ''' if sys.argv[1:]: # if more than argv[0] if os.path.isfile(sys.argv[1]): infile = open(sys.argv[1]) elif sys.argv[1]=='--help': usage() else: print "Can't find file " + sys.argv[1] + "." sys.exit(0) else: usage() return infile def slashreplace(file): # A word is anything without a space. Match is: ' / ' # Function receives an open file, returns a list of lines. # Lines are right stripped. # Sub does not fail at eof w/o \n matchstr = re.compile(r"([^\s]+)?(\s*)(\s/\s)") omatch = re.compile(r"(/$)") slash = " / " allfile = [] for line in file: line = omatch.sub(r'''/ ''', line, 1) for slash in line: line = matchstr.sub(r'''\1\2 \1 ''', line, 1) #line = line.rstrip() allfile.append(line) # = allfile + line + '\n' return allfile def rawreplacementstrings(allfile, defsign, openpar, enddef): # find the macros and replacement strings # if replacement has pcts, open parenthesis attached to mac iter = 0 exprlist = [] maclist = [] newfile = '' addline = -1 expr = "" for line in allfile: stexpr = '' # var is also a flag not to survive iteration # find symbol if it begins line if line.find(defsign)==0: # openpar before space in line is no white in macro nor null # is total check on whether this is start of def # then slice off 1st char. if line.find(openpar)>1>line.find('\s'): divvy = line.split(openpar, 1) mac = divvy[0] if mac not in maclist: # new macs only please maclist.append(mac) # mac is done! # new expr is started expr = "" stexpr = divvy[1] else: mac = "" if line.find(enddef)>-1: #### last line here if stexpr and mac: # one liner #leave in line only the ending of def stexpr, line = stexpr.split(enddef) stexpr = stexpr.replace('%%', 'PerCentSign') exprlist.append(stexpr) stexpr = "" mac = "" if line=='': line = None if expr and mac: # not oneliner but last line endexpr, line = line.split(enddef) expr = expr + endexpr expr = expr.replace('%%', 'PerCentSign') exprlist.append(expr) expr = '' mac = '' if line=='': line = None # not first line but not last line of expression: elif stexpr and mac: expr = expr + stexpr #+ '\n' stexpr = "" line = None elif expr and mac: expr = expr + line #+ '\n' line = None if not line==None: newfile = newfile + line #+ '\n' # put openpar on end of macro in cases where there are pcts in the # replacement text for dex in range(len(exprlist)): maclist[dex] = maclist[dex][1:] if exprlist[dex].find('%')>-1: maclist[dex] = maclist[dex] + openpar return newfile, maclist, exprlist def insertpercents(macr, expo, line, closepar): try: pct = "%" while 1: newexpo = expo if line.find(macr)>-1: divvy = line.split(macr, 1) rest = divvy[1] divvio = rest.split(closepar, 1) argus = divvio[0].strip() arglist = argus.split(' ') for arg in arglist: if newexpo.find(pct)>-1: newexpo = newexpo.replace(pct, arg, 1) else: break line = divvy[0] + newexpo + divvio[1] else: break return line except: print "python errors:" print sys.exc_type, sys.exc_value import string, sys, os, time, re try: defsign = '#' openpar = '(' closepar = ')' enddef = defsign + closepar infile = getinputfile() allfile = slashreplace(infile) # allfile is list of lines. newfile, maclist, exprlist = rawreplacementstrings(allfile, defsign, openpar, enddef) print maclist, len(maclist) print exprlist, len(exprlist) shfile = newfile.split('\n') index = len(maclist) iter = 0 # doing each def and expression in turn. Fortunately # no targets span lines for line in shfile: for dex in range(len(maclist)): macr = maclist[dex] expo = exprlist[dex] if macr.find(openpar)>1: # to speed up? line = insertpercents(macr, expo, line, closepar) else: line = line.replace(macr, expo) line = line.replace('PerCentSign', '%') print line except: #sys.exit(0) #usage() '''Reachable if Usage commented out: ''' print "python errors:" print sys.exc_type, sys.exc_value