#!/usr/bin/env python def usage(): print ''' sedfilt.py takes all the files in the current directory with the ending inext, runs the commands in the files listed in inext-sedfilt on them, and produces processed copies with their ends changed to outext. A dot will be prefixed to the extensions you enter. No globbing. usage: sedfilt.py inext outext example outcome: clar.nly ===inext-sedfilt==> clar.ly The sed command file list, inext-sedfilt, is unformatted. The complete path must be given for all files not in the working directory. One file name per line, no comments. inext-sedfilt: /home/me/bin/seds/pre.sed /home/me/bin/seds/prep.sed local.seds /home/me/bin/seds/fine.sed /home/me/bin/seds/fin.sed (c)2004 David Raleigh Arnold under GNU. openguitar.com. Enjoy! daveA ''' sys.exit(0) def help(): print ''' ********** Help for sedfilt.py +++++++++++ All this little script does is apply this in batches: sed -f sedcommandfile infile > outfile A file full of sed commands is supposed to be called a sed command file, but I tend to call them filters, incorrectly I suppose. If you wish to apply filters to text already in complete lilypond files, the thing to do is to make the filters work between a range, such as from %lyrics!% to %lyrics.% . I think it is easiest to address files by extension, because you have to give the files names anyway. A whole sed language reference fits easily on six pages, and you need very little of it. The main thing is substitution: s/ change this / to this /g The 'g' is for global, which means the whole line. If you do this: s/_this_/_that_ /g to this: this_this_this_this You get this: this_that_this_this but put in more underscores: _this__this__this__this_ and you get: _that__that__that__that_ It's spaces, of course, not underscores. Start by putting spaces in and end by taking them out. The files that you put in the list all behave as command file. There is no sense in having each component filter repeat these operations. Invoking sedfilt.py in your "up" script in your working directory is the way to go. sedfilt.py is slow compared to sly or slyce, but all that means is that you notice it taking .ess than second if you have a lot of files to process. Do you use an "up" script? To call it: $ ./up name #!/bin/bash sly $1-orig.sly # process sly file sedfilt.py nly ly # apply filterlist nly-sedfilt sedfilt.py cly ly # apply other filterlist lilypond -etc $1.ly gv $1.pdf A batch file wouldn't be much different, except you don't need that first line, you use %1 instead of $1, and you comment with REM. To call it: C:> up.bat name, or C:> .\up name to be safest. For lilypond-book, write a ./bookup script. How do you use sly with slyce? Use sly _before_ slyce. Slyce removes all embedded sly files, because it removes all %{long comments%}. ########## In Conclusion ############ For the inext and outext, again, don't type the dots. There are many versions of sed. Most of them should work. Try GNU sed. To read this output, pipe it to a pager: $ slyce.py --help | more or redirect to a file: $ slyce.py --help > help.txt or scroll up if you can. ''' sys.exit(0) def getfilts(): '''Test for filter file, open, concatenate files therein. It's the last arg. Bail if none.''' if not sys.argv[1:]: usage() if sys.argv[1]=='--help': help() if not sys.argv[2:]: usage() else: inext = sys.argv[1] outext = sys.argv[2] if inext=='ly': print ''' To prevent overwriting essential files, you may not process all of the .ly files in the directory. Quitting. ''' if inext=='sly': print ''' To prevent overwriting essential files, you may not process all of the .sly files in the directory. Quitting. ''' sys.exit(0) if inext==outext: print "The first two params must not be the same. Quitting." sys.exit(0) name = inext + '-sedfilt' if not os.path.isfile(name): print "There is no file", name, "to process with. Quitting." sys.exit(0) else: sedcoms = open(name) allfilts = '' for line in sedcoms.readlines(): # first line read already if line.strip()=='': print "Blank line in", name, "-- continuing." continue filt = line.strip() if not os.path.isfile(filt): print "File in", name, 'named', filt, 'does not exist.' sys.exit(0) print "Opening sed command file", filt fil = open(filt) for lin in fil: allfilts = allfilts + lin ''' It is possible to have no content because no file names in xx-sedfilt so no lines read in sedcoms. ''' if allfilts=='': print "No file names in". name, "at all. Quitting." sys.exit(0) print 'Your listed sed files are concatenated in "concat.sed".' open('concat.sed', 'w').write(allfilts) inext = '.' + inext outext = '.' + outext return inext, outext, allfilts # allfilts = commands string def headlist(inext): heads = [] for name in os.listdir(os.getcwd()): head = name[:-len(inext)] end = name[-len(inext):] if end==inext: heads.append(head) return heads import sys, os, string try: inext, outext, allfilts = getfilts() heads = headlist(inext) for head in heads: infile = head + inext outfile = head + outext print "Sed is applying \"concat.sed\" to", infile, "and writing", outfile os.system("sed -f %s %s > %s" % ("concat.sed", infile, outfile)) except: #sys.exit(0) #usage() '''Reachable if Usage commented out: ''' print "python errors:" print sys.exc_type, sys.exc_value