]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-ly.py
* make/lilypond-vars.make (PYTHONPATH): Add python's outdir to
[lilypond.git] / scripts / convert-ly.py
1 #!@PYTHON@
2 #
3 # convert-ly.py -- Update old LilyPond input files (fix name?)
4
5 # source file of the GNU LilyPond music typesetter
6
7 # (c) 1998--2002  Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 #                 Jan Nieuwenhuizen <janneke@gnu.org>
9
10
11 # TODO
12 #   use -f and -t for -s output
13
14 # NEWS
15 # 0.2
16 #  - rewrite in python
17
18 program_name = 'convert-ly'
19 version = '@TOPLEVEL_VERSION@'
20
21 import os
22 import sys
23 import __main__
24 import getopt
25 import  string
26 import re
27 import time
28
29 # Did we ever have \mudela-version?  I doubt it.
30 # lilypond_version_re_str = '\\\\version *\"(.*)\"'
31 lilypond_version_re_str = '\\\\(mudela-)?version *\"(.*)\"'
32 lilypond_version_re = re.compile (lilypond_version_re_str)
33 add_version = 1
34
35
36 def program_id ():
37         return '%s (GNU LilyPond) %s' %(program_name,  version);
38
39 def identify ():
40         sys.stderr.write (program_id () + '\n')
41
42 def usage ():
43         sys.stdout.write (
44                 r"""Usage: %s [OPTION]... [FILE]... 
45 Try to convert to newer lilypond-versions.  The version number of the
46 input is guessed by default from \version directive
47
48 Options:
49   -a, --assume-old       apply all conversions to unversioned files
50   -h, --help             print this help
51   -e, --edit             in place edit
52   -f, --from=VERSION     start from version. Overrides \version found in file.
53   -s, --show-rules       print all rules.
54   -t, --to=VERSION       target version
55   -n, --no-version       don't add new version stamp.
56       --version          print program version
57
58 Report bugs to bugs-gnu-music@gnu.org
59
60 """ % program_name)
61         
62         
63         sys.exit (0)
64
65 def print_version ():
66         
67         sys.stdout.write (r"""%s
68
69 This is free software.  It is covered by the GNU General Public
70 License, and you are welcome to change it and/or distribute copies of
71 it under certain conditions.  invoke as `%s --warranty' for more
72 information.
73
74 """ % (program_id() , program_name))
75         
76 def gulp_file(f):
77         try:
78                 i = open(f)
79                 i.seek (0, 2)
80                 n = i.tell ()
81                 i.seek (0,0)
82         except:
83                 print 'can\'t open file: ' + f + '\n'
84                 return ''
85         s = i.read (n)
86         if len (s) <= 0:
87                 print 'gulped empty file: ' + f + '\n'
88         i.close ()
89         return s
90
91 def str_to_tuple (s):
92         return tuple (map (string.atoi, string.split (s,'.')))
93
94 def tup_to_str (t):
95         return string.join (map (lambda x: '%s' % x, list (t)), '.')
96
97 def version_cmp (t1, t2):
98         for x in [0,1,2]:
99                 if t1[x] - t2[x]:
100                         return t1[x] - t2[x]
101         return 0
102
103 def guess_lilypond_version (filename):
104         s = gulp_file (filename)
105         m = lilypond_version_re.search (s)
106         if m:
107                 return m.group (2)
108         else:
109                 return ''
110
111 class FatalConversionError:
112         pass
113
114 conversions = []
115
116 def show_rules (file):
117         for x in conversions:
118                 file.write  ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
119
120 ############################
121                 
122 if 1:
123         def conv(str):
124                 if re.search ('\\\\multi', str):
125                         sys.stderr.write ('\nNot smart enough to convert \\multi')
126                 return str
127         
128         conversions.append (((0,1,9), conv, '\\header { key = concat + with + operator }'))
129
130 if 1:                                   # need new a namespace
131         def conv (str):
132                 if re.search ('\\\\octave', str):
133                         sys.stderr.write ('\nNot smart enough to convert \\octave')
134                 #       raise FatalConversionError()
135                 
136                 return str
137
138         conversions.append ((
139                 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically')))
140
141
142 if 1:                                   # need new a namespace
143         def conv (str):
144                 str = re.sub ('\\\\textstyle([^;]+);',
145                                          '\\\\property Lyrics . textstyle = \\1', str)
146                 # harmful to current .lys
147                 # str = re.sub ('\\\\key([^;]+);', '\\\\accidentals \\1;', str)
148                         
149                 return str
150
151         conversions.append ((
152                 ((0,1,20), conv, 'deprecated \\textstyle, new \key syntax')))
153
154
155 if 1:
156         def conv (str):
157                 str = re.sub ('\\\\musical_pitch', '\\\\musicalpitch',str)
158                 str = re.sub ('\\\\meter', '\\\\time',str)
159                         
160                 return str
161
162         conversions.append ((
163                 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
164                  '\\meter -> \\time')))
165
166 if 1:
167         def conv (str):
168                 return str
169
170         conversions.append ((
171                 ((1,0,0), conv, '0.1.21 -> 1.0.0 ')))
172
173
174 if 1:
175         def conv (str):
176                 str = re.sub ('\\\\accidentals', '\\\\keysignature',str)
177                 str = re.sub ('specialaccidentals *= *1', 'keyoctaviation = 0',str)
178                 str = re.sub ('specialaccidentals *= *0', 'keyoctaviation = 1',str)
179                         
180                 return str
181
182         conversions.append ((
183                 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
184                  'specialaccidentals -> keyoctaviation')))
185
186 if 1:
187         def conv(str):
188                 if re.search ('\\\\header', str):
189                         sys.stderr.write ('\nNot smart enough to convert to new \\header format')
190                 return str
191         
192         conversions.append (((1,0,2), conv, '\\header { key = concat + with + operator }'))
193
194 if 1:
195         def conv(str):
196                 str =  re.sub ('\\\\melodic([^a-zA-Z])', '\\\\notes\\1',str)
197                 return str
198         
199         conversions.append (((1,0,3), conv, '\\melodic -> \\notes'))
200
201 if 1:
202         def conv(str):
203                 str =  re.sub ('default_paper *=', '',str)
204                 str =  re.sub ('default_midi *=', '',str)
205                 return str
206         
207         conversions.append (((1,0,4), conv, 'default_{paper,midi}'))
208
209 if 1:
210         def conv(str):
211                 str =  re.sub ('ChoireStaff', 'ChoirStaff',str)
212                 str =  re.sub ('\\\\output', 'output = ',str)
213                         
214                 return str
215         
216         conversions.append (((1,0,5), conv, 'ChoireStaff -> ChoirStaff'))
217
218 if 1:
219         def conv(str):
220                 if re.search ('[a-zA-Z]+ = *\\translator',str):
221                         sys.stderr.write ('\nNot smart enough to change \\translator syntax')
222                 #       raise FatalConversionError()
223                 return str
224         
225         conversions.append (((1,0,6), conv, 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }'))
226
227
228 if 1:
229         def conv(str):
230                 str =  re.sub ('\\\\lyrics*', '\\\\lyrics',str)
231                         
232                 return str
233         
234         conversions.append (((1,0,7), conv, '\\lyric -> \\lyrics'))
235
236 if 1:
237         def conv(str):
238                 str =  re.sub ('\\\\\\[/3+', '\\\\times 2/3 { ',str)
239                 str =  re.sub ('\\[/3+', '\\\\times 2/3 { [',str)
240                 str =  re.sub ('\\\\\\[([0-9/]+)', '\\\\times \\1 {',str)
241                 str =  re.sub ('\\[([0-9/]+)', '\\\\times \\1 { [',str)
242                 str =  re.sub ('\\\\\\]([0-9/]+)', '}', str)
243                 str =  re.sub ('\\\\\\]', '}',str)
244                 str =  re.sub ('\\]([0-9/]+)', '] }', str)
245                 return str
246         
247         conversions.append (((1,0,10), conv, '[2/3 ]1/1 -> \\times 2/3 '))
248
249 if 1:
250         def conv(str):
251                 return str
252         conversions.append (((1,0,12), conv, 'Chord syntax stuff'))
253
254
255 if 1:
256         def conv(str):
257                 
258                 
259                 str =  re.sub ('<([^>~]+)~([^>]*)>','<\\1 \\2> ~', str)
260                         
261                 return str
262         
263         conversions.append (((1,0,13), conv, '<a ~ b> c -> <a b> ~ c'))
264
265 if 1:
266         def conv(str):
267                 str =  re.sub ('<\\[','[<', str)
268                 str =  re.sub ('\\]>','>]', str)
269                         
270                 return str
271         
272         conversions.append (((1,0,14), conv, '<[a b> <a b]>c -> [<a b> <a b>]'))
273
274
275 if 1:
276         def conv(str):
277                 str =  re.sub ('\\\\type([^\n]*engraver)','\\\\TYPE\\1', str)
278                 str =  re.sub ('\\\\type([^\n]*performer)','\\\\TYPE\\1', str)
279                 str =  re.sub ('\\\\type','\\\\context', str)
280                 str =  re.sub ('\\\\TYPE','\\\\type', str)
281                 str =  re.sub ('textstyle','textStyle', str)
282                         
283                 return str
284         
285         conversions.append (((1,0,16), conv, '\\type -> \\context, textstyle -> textStyle'))
286
287
288 if 1:
289         def conv(str):
290                 if re.search ('\\\\repeat',str):
291                         sys.stderr.write ('\nNot smart enough to convert \\repeat')
292                 #       raise FatalConversionError()
293                 return str
294         
295         conversions.append (((1,0,18), conv,
296                 '\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
297
298 if 1:
299         def conv(str):
300                 str =  re.sub ('SkipBars','skipBars', str)
301                 str =  re.sub ('fontsize','fontSize', str)
302                 str =  re.sub ('midi_instrument','midiInstrument', str)                 
303                         
304                 return str
305
306         conversions.append (((1,0,19), conv,
307                 'fontsize -> fontSize, midi_instrument -> midiInstrument, SkipBars -> skipBars'))
308
309
310 if 1:
311         def conv(str):
312                 str =  re.sub ('tieydirection','tieVerticalDirection', str)
313                 str =  re.sub ('slurydirection','slurVerticalDirection', str)
314                 str =  re.sub ('ydirection','verticalDirection', str)                   
315                         
316                 return str
317
318         conversions.append (((1,0,20), conv,
319                 '{,tie,slur}ydirection -> {v,tieV,slurV}erticalDirection'))
320
321
322 if 1:
323         def conv(str):
324                 str =  re.sub ('hshift','horizontalNoteShift', str)
325                         
326                 return str
327
328         conversions.append (((1,0,21), conv,
329                 'hshift -> horizontalNoteShift'))
330
331
332 if 1:
333         def conv(str):
334                 str =  re.sub ('\\\\grouping[^;]*;','', str)
335                         
336                 return str
337
338         conversions.append (((1,1,52), conv,
339                 'deprecate \\grouping'))
340
341
342 if 1:
343         def conv(str):
344                 str =  re.sub ('\\\\wheel','\\\\coda', str)
345                         
346                 return str
347
348         conversions.append (((1,1,55), conv,
349                 '\\wheel -> \\coda'))
350
351 if 1:
352         def conv(str):
353                 str =  re.sub ('keyoctaviation','keyOctaviation', str)
354                 str =  re.sub ('slurdash','slurDash', str)
355                         
356                 return str
357
358         conversions.append (((1,1,65), conv,
359                 'slurdash -> slurDash, keyoctaviation -> keyOctaviation'))
360
361 if 1:
362         def conv(str):
363                 str =  re.sub ('\\\\repeat *\"?semi\"?','\\\\repeat "volta"', str)
364                         
365                 return str
366
367         conversions.append (((1,1,66), conv,
368                 'semi -> volta'))
369
370
371 if 1:
372         def conv(str):
373                 str =  re.sub ('\"?beamAuto\"? *= *\"?0?\"?','noAutoBeaming = "1"', str)
374                         
375                 return str
376
377         conversions.append (((1,1,67), conv,
378                 'beamAuto -> noAutoBeaming'))
379
380 if 1:
381         def conv(str):
382                 str =  re.sub ('automaticMelismas', 'automaticMelismata', str)
383                         
384                 return str
385
386         conversions.append (((1,2,0), conv,
387                 'automaticMelismas -> automaticMelismata'))
388
389 if 1:
390         def conv(str):
391                 str =  re.sub ('dynamicDir\\b', 'dynamicDirection', str)
392                         
393                 return str
394
395         conversions.append (((1,2,1), conv,
396                 'dynamicDir -> dynamicDirection'))
397
398 if 1:
399         def conv(str):
400                 str =  re.sub ('\\\\cadenza *0 *;', '\\\\cadenzaOff', str)
401                 str =  re.sub ('\\\\cadenza *1 *;', '\\\\cadenzaOn', str)               
402                         
403                 return str
404
405         conversions.append (((1,3,4), conv,
406                 '\\cadenza -> \cadenza{On|Off}'))
407
408 if 1:
409         def conv (str):
410                 str = re.sub ('"?beamAuto([^"=]+)"? *= *"([0-9]+)/([0-9]+)" *;*',
411                               'beamAuto\\1 = #(make-moment \\2 \\3)',
412                               str)
413                 return str
414
415         conversions.append (((1,3,5), conv, 'beamAuto moment properties'))
416
417 if 1:
418         def conv (str):
419                 str = re.sub ('stemStyle',
420                               'flagStyle',
421                               str)
422                 return str
423
424         conversions.append (((1,3,17), conv, 'stemStyle -> flagStyle'))
425
426 if 1:
427         def conv (str):
428                 str = re.sub ('staffLineLeading',
429                               'staffSpace',
430                               str)
431                 return str
432
433         conversions.append (((1,3,18), conv, 'staffLineLeading -> staffSpace'))
434
435
436 if 1:
437         def conv(str):
438                 if re.search ('\\\\repetitions',str):
439                         sys.stderr.write ('\nNot smart enough to convert \\repetitions')
440                 #       raise FatalConversionError()
441                 return str
442         
443         conversions.append (((1,3,23), conv,
444                 '\\\\repetitions feature dropped'))
445
446
447 if 1:
448         def conv (str):
449                 str = re.sub ('textEmptyDimension *= *##t',
450                               'textNonEmpty = ##f',
451                               str)
452                 str = re.sub ('textEmptyDimension *= *##f',
453                               'textNonEmpty = ##t',
454                               str)
455                 return str
456
457         conversions.append (((1,3,35), conv, 'textEmptyDimension -> textNonEmpty'))
458
459 if 1:
460         def conv (str):
461                 str = re.sub ("([a-z]+)[ \t]*=[ \t]*\\\\musicalpitch *{([- 0-9]+)} *\n",
462                               "(\\1 . (\\2))\n", str)
463                 str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
464                               "\\\\musicalpitch #'(\\1)", str)
465                 if re.search ('\\\\notenames',str):
466                         sys.stderr.write ('\nNot smart enough to convert to new \\notenames format')
467                 return str
468
469         conversions.append (((1,3,38), conv, '\musicalpitch { a b c } -> #\'(a b c)'))
470
471 if 1:
472         def conv (str):
473                 def replace (match):
474                         return '\\key %s;' % string.lower (match.group (1))
475                 
476                 str = re.sub ("\\\\key ([^;]+);",  replace, str)
477                 return str
478         
479         conversions.append (((1,3,39), conv, '\\key A ;  ->\\key a;'))
480
481 if 1:
482         def conv (str):
483                 if re.search ('\\[:',str):
484                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
485                 return str
486
487         conversions.append (((1,3,41), conv,
488                 '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }'))
489
490 if 1:
491         def conv (str):
492                 str = re.sub ('Staff_margin_engraver' , 'Instrument_name_engraver', str)
493                 return str
494
495         conversions.append (((1,3,42), conv,
496                 'Staff_margin_engraver deprecated, use Instrument_name_engraver'))
497
498 if 1:
499         def conv (str):
500                 str = re.sub ('note[hH]eadStyle\\s*=\\s*"?(\\w+)"?' , "noteHeadStyle = #'\\1", str)
501                 return str
502
503         conversions.append (((1,3,49), conv,
504                 'noteHeadStyle value: string -> symbol'))
505
506 if 1:
507         def conv (str):
508                 if re.search ('\\\\keysignature', str):
509                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
510                 return str
511
512
513         conversions.append (((1,3,58), conv,
514                 'noteHeadStyle value: string -> symbol'))
515
516 if 1:
517         def conv (str):
518                 str = re.sub (r"""\\key *([a-z]+) *;""", r"""\\key \1 \major;""",str);
519                 return str
520         conversions.append (((1,3,59), conv,
521                 '\key X ; -> \key X major; ')) 
522
523 if 1:
524         def conv (str):
525                 str = re.sub (r'latexheaders *= *"\\\\input ',
526                               'latexheaders = "',
527                               str)
528                 return str
529         conversions.append (((1,3,68), conv, 'latexheaders = "\\input global" -> latexheaders = "global"'))
530
531
532
533
534 # TODO: lots of other syntax change should be done here as well
535 if 1:
536         def conv (str):
537                 str = re.sub ('basicCollisionProperties', 'NoteCollision', str)
538                 str = re.sub ('basicVoltaSpannerProperties' , "VoltaBracket", str)
539                 str = re.sub ('basicKeyProperties' , "KeySignature", str)
540
541                 str = re.sub ('basicClefItemProperties' ,"Clef", str)
542
543
544                 str = re.sub ('basicLocalKeyProperties' ,"Accidentals", str)
545                 str = re.sub ('basicMarkProperties' ,"Accidentals", str)
546                 str = re.sub ('basic([A-Za-z_]+)Properties', '\\1', str)
547
548                 str = re.sub ('Repeat_engraver' ,'Volta_engraver', str)
549                 return str
550         
551         conversions.append (((1,3,92), conv, 'basicXXXProperties -> XXX, Repeat_engraver -> Volta_engraver'))
552
553 if 1:
554         def conv (str):
555                 # Ugh, but meaning of \stemup changed too
556                 # maybe we should do \stemup -> \stemUp\slurUp\tieUp ?
557                 str = re.sub ('\\\\stemup', '\\\\stemUp', str)
558                 str = re.sub ('\\\\stemdown', '\\\\stemDown', str)
559                 str = re.sub ('\\\\stemboth', '\\\\stemBoth', str)
560                 
561                 str = re.sub ('\\\\slurup', '\\\\slurUp', str)
562                 str = re.sub ('\\\\slurboth', '\\\\slurBoth', str)
563                 str = re.sub ('\\\\slurdown', '\\\\slurDown', str)
564                 str = re.sub ('\\\\slurdotted', '\\\\slurDotted', str)
565                 str = re.sub ('\\\\slurnormal', '\\\\slurNoDots', str)          
566                 
567                 str = re.sub ('\\\\shiftoff', '\\\\shiftOff', str)
568                 str = re.sub ('\\\\shifton', '\\\\shiftOn', str)
569                 str = re.sub ('\\\\shiftonn', '\\\\shiftOnn', str)
570                 str = re.sub ('\\\\shiftonnn', '\\\\shiftOnnn', str)
571
572                 str = re.sub ('\\\\onevoice', '\\\\oneVoice', str)
573                 str = re.sub ('\\\\voiceone', '\\\\voiceOne', str)
574                 str = re.sub ('\\\\voicetwo', '\\\\voiceTwo', str)
575                 str = re.sub ('\\\\voicethree', '\\\\voiceThree', str)
576                 str = re.sub ('\\\\voicefour', '\\\\voiceFour', str)
577
578                 # I don't know exactly when these happened...
579                 # ugh, we loose context setting here...
580                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\stemUp\\\\slurUp\\\\tieUp', str)
581                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\stemDown\\\\slurDown\\\\tieDown', str)
582                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\stemBoth\\\\slurBoth\\\\tieBoth', str)
583
584                 str = re.sub ('verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #1', str)
585                 str = re.sub ('verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #-1', str)
586                 str = re.sub ('verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #0', str)
587                 
588                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\\\1Up', str)
589                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\\\1Down', str)
590                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\\\1Both', str)
591
592                 # (lacks capitalisation slur -> Slur)
593                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\1 \\\\override #\'direction = #1', str)
594                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\1 \\override #\'direction = #-1', str)
595                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\1 \\\\override #\'direction = #0', str)
596
597                 ## dynamic..
598                 str = re.sub ('\\\\property *[^ .]*[.]?dynamicDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\dynamicUp', str)
599                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\dynamicDown', str)
600                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?(0|(\\\\center))"?', '\\\\dynamicBoth', str)
601
602                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?(0|(""))"?', '\\\\\\1NoDots', str)
603                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?([1-9]+)"?', '\\\\\\1Dotted', str)
604
605                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?(0|(""))"?', '\\\\autoBeamOn', str)
606                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?([1-9]+)"?', '\\\\autoBeamOff', str)
607
608
609
610                 return str
611         
612         conversions.append (((1,3,93), conv,
613                 'property definiton case (eg. onevoice -> oneVoice)'))
614
615
616 if 1:
617         def conv (str):
618                 str = re.sub ('ChordNames*', 'ChordNames', str)
619                 if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
620                         sys.stderr.write ('\nNot smart enough to convert to new \\textscript markup text')
621
622                 str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
623
624                 return str
625         
626         conversions.append (((1,3,97), conv, 'ChordName -> ChordNames'))
627
628
629 # TODO: add lots of these
630         
631 if 1:
632         def conv (str):
633                 str = re.sub ('\\\\property *"?Voice"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Voice.TextScript \\\\set #\'font-style = #\'\\1', str)
634                 str = re.sub ('\\\\property *"?Lyrics"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Lyrics.LyricText \\\\set #\'font-style = #\'\\1', str)
635
636                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?timeSignatureStyle"? *= *"([^"]*)"', '\\\\property \\1.TimeSignature \\\\override #\'style = #\'\\2', str) 
637
638                 str = re.sub ('"?timeSignatureStyle"? *= *#?""', 'TimeSignature \\\\override #\'style = ##f', str)
639                 
640                 str = re.sub ('"?timeSignatureStyle"? *= *#?"([^"]*)"', 'TimeSignature \\\\override #\'style = #\'\\1', str)
641                 
642                 str = re.sub ('#\'style *= #*"([^"])"', '#\'style = #\'\\1', str)
643                 
644                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?horizontalNoteShift"? *= *"?#?([-0-9]+)"?', '\\\\property \\1.NoteColumn \\\\override #\'horizontal-shift = #\\2', str) 
645
646                 # ugh
647                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *""', '\\\\property \\1.Stem \\\\override #\'flag-style = ##f', str)
648                 
649                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *"([^"]*)"', '\\\\property \\1.Stem \\\\override #\'flag-style = #\'\\2', str) 
650                 return str
651         
652         conversions.append (((1,3,98), conv, 'CONTEXT.textStyle -> GROB.#font-style '))
653
654 if 1:
655         def conv (str):
656                 str = re.sub ('"?beamAutoEnd_([0-9]*)"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end 1 \\1 * *) = \\2', str)
657                 str = re.sub ('"?beamAutoBegin_([0-9]*)"? *= *(#\\([^)]*\))', 'autoBeamSettings \\push #\'(begin 1 \\1 * *) = \\2', str)
658                 str = re.sub ('"?beamAutoEnd"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end * * * *) = \\1', str)
659                 str = re.sub ('"?beamAutoBegin"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(begin * * * *) = \\1', str)
660
661
662                 return str
663         
664         conversions.append (((1,3,102), conv, 'beamAutoEnd -> autoBeamSettings \\push (end * * * *)'))
665
666
667 if 1:
668         def conv (str):
669                 str = re.sub ('\\\\push', '\\\\override', str)
670                 str = re.sub ('\\\\pop', '\\\\revert', str)
671
672                 return str
673         
674         conversions.append (((1,3,111), conv, '\\push -> \\override, \\pop -> \\revert'))
675
676 if 1:
677         def conv (str):
678                 str = re.sub ('LyricVoice', 'LyricsVoice', str)
679                 # old fix
680                 str = re.sub ('Chord[Nn]ames*.Chord[Nn]ames*', 'ChordNames.ChordName', str)
681                 str = re.sub ('Chord[Nn]ames([ \t\n]+\\\\override)', 'ChordName\\1', str)
682                 return str
683         
684         conversions.append (((1,3,113), conv, 'LyricVoice -> LyricsVoice'))
685
686 def regularize_id (str):
687         s = ''
688         lastx = ''
689         for x in str:
690                 if x == '_':
691                         lastx = x
692                         continue
693                 elif x in string.digits:
694                         x = chr(ord (x) - ord ('0')  +ord ('A'))
695                 elif x not in string.letters:
696                         x = 'x'
697                 elif x in string.lowercase and lastx == '_':
698                         x = string.upper (x)
699                 s = s + x
700                 lastx = x
701         return s
702
703 if 1:
704         def conv (str):
705                 
706                 def regularize_dollar_reference (match):
707                         return regularize_id (match.group (1))
708                 def regularize_assignment (match):
709                         return '\n' + regularize_id (match.group (1)) + ' = '
710                 str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
711                 str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
712                 return str
713         
714         conversions.append (((1,3,117), conv, 'identifier names: $!foo_bar_123 -> xfooBarABC'))
715
716
717 if 1:
718         def conv (str):
719                 def regularize_paper (match):
720                         return regularize_id (match.group (1))
721                 
722                 str = re.sub ('(paper_[a-z]+)', regularize_paper, str)
723                 str = re.sub ('sustainup', 'sustainUp', str)
724                 str = re.sub ('nobreak', 'noBreak', str)
725                 str = re.sub ('sustaindown', 'sustainDown', str)
726                 str = re.sub ('sostenutoup', 'sostenutoUp', str)
727                 str = re.sub ('sostenutodown', 'sostenutoDown', str)
728                 str = re.sub ('unachorda', 'unaChorda', str)
729                 str = re.sub ('trechorde', 'treChorde', str)
730         
731                 return str
732         
733         conversions.append (((1,3,120), conv, 'paper_xxx -> paperXxxx, pedalup -> pedalUp.'))
734
735 if 1:
736         def conv (str):
737                 str = re.sub ('drarnChords', 'chordChanges', str)
738                 str = re.sub ('\\musicalpitch', '\\pitch', str)
739                 return str
740         
741         conversions.append (((1,3,122), conv, 'drarnChords -> chordChanges, \\musicalpitch -> \\pitch'))
742
743 if 1:
744         def conv (str):
745                 str = re.sub ('ly-([sg])et-elt-property', 'ly-\\1et-grob-property', str)
746                 return str
747         
748         conversions.append (((1,3,136), conv, 'ly-X-elt-property -> ly-X-grob-property'))
749
750 if 1:
751         def conv (str):
752                 str = re.sub ('point-and-click +#t', 'point-and-click line-column-location', str)
753                 return str
754         
755         conversions.append (((1,3,138), conv, 'point-and-click argument changed to procedure.'))
756
757 if 1:
758         def conv (str):
759                 str = re.sub ('followThread', 'followVoice', str)
760                 str = re.sub ('Thread.FollowThread', 'Voice.VoiceFollower', str)
761                 str = re.sub ('FollowThread', 'VoiceFollower', str)
762                 return str
763         
764         conversions.append (((1,3,138), conv, 'followThread -> followVoice.'))
765
766 if 1:
767         def conv (str):
768                 str = re.sub ('font-point-size', 'font-design-size', str)
769                 return str
770         
771         conversions.append (((1,3,139), conv, 'font-point-size -> font-design-size.'))
772
773 if 1:
774         def conv (str):
775                 str = re.sub ('([a-zA-Z]*)NoDots', '\\1Solid', str)
776                 return str
777         
778         conversions.append (((1,3,141), conv, 'xNoDots -> xSolid'))
779
780 if 1:
781         def conv (str):
782                 str = re.sub ('([Cc])hord([ea])', '\\1ord\\2', str)
783                 return str
784         
785         conversions.append (((1,3,144), conv, 'Chorda -> Corda'))
786
787
788 if 1:
789         def conv (str):
790                 str = re.sub ('([A-Za-z]+)MinimumVerticalExtent', 'MinimumV@rticalExtent', str)
791                 str = re.sub ('([A-Za-z]+)ExtraVerticalExtent', 'ExtraV@rticalExtent', str)
792                 str = re.sub ('([A-Za-z]+)VerticalExtent', 'VerticalExtent', str)
793                 str = re.sub ('ExtraV@rticalExtent', 'ExtraVerticalExtent', str)
794                 str = re.sub ('MinimumV@rticalExtent', 'MinimumVerticalExtent', str)            
795                 return str
796
797         conversions.append (((1,3,145), conv,
798         'ContextNameXxxxVerticalExtent -> XxxxVerticalExtent'))
799
800 if 1:
801         def conv (str):
802                 str = re.sub ('\\\\key[ \t]*;', '\\key \\default;', str)
803                 str = re.sub ('\\\\mark[ \t]*;', '\\mark \\default;', str)
804
805                 # Make sure groups of more than one ; have space before
806                 # them, so that non of them gets removed by next rule
807                 str = re.sub ("([^ \n\t;]);(;+)", "\\1 ;\\2", str)
808                 
809                 # Only remove ; that are not after spaces, # or ;
810                 # Otherwise  we interfere with Scheme comments,
811                 # which is badbadbad.
812                 str = re.sub ("([^ \t;#]);", "\\1", str)
813
814                 return str
815         conversions.append (((1,3,146), conv, 'semicolons removed'))
816
817 if 1:
818         def conv (str):
819                 str = re.sub ('default-neutral-direction', 'neutral-direction',str)
820                 return str
821         conversions.append (((1,3,147), conv, 'default-neutral-direction -> neutral-direction'))
822
823 if 1:
824         def conv (str):
825                 str = re.sub ('\(align', '(axis', str)
826                 str = re.sub ('\(rows', '(columns', str)
827                 return str
828         conversions.append (((1,3,148), conv, '"(align" -> "(axis", "(rows" -> "(columns"'))
829
830
831 if 1:
832         def conv (str):
833                 str = re.sub ('SystemStartDelimiter', 'systemStartDelimiter', str)
834                 return str
835         conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
836
837 if 1:
838         def conv (str):
839                 str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
840                 str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)          
841                 return str
842         
843         conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
844
845
846 if 1:
847         def conv (str):
848         
849                 def func(match):
850                         break_dict = {
851                         "Instrument_name": "instrument-name",
852                         "Left_edge_item": "left-edge",
853                         "Span_bar": "span-bar",
854                         "Breathing_sign": "breathing-sign",
855                         "Staff_bar": "staff-bar",
856                         "Clef_item": "clef",
857                         "Key_item": "key-signature",
858                         "Time_signature": "time-signature",
859                         "Custos": "custos"
860                         }
861                         props =  match.group (1)
862                         for (k,v) in break_dict.items():
863                                 props = re.sub (k, v, props)
864                         return  "breakAlignOrder = #'(%s)" % props
865
866                 str = re.sub ("breakAlignOrder *= *#'\\(([a-z_\n\tA-Z ]+)\\)",
867                               func, str)
868                 return str
869
870         # 40 ? 
871         conversions.append (((1,5,40), conv, 'breakAlignOrder property names'))
872         
873
874 if 1:
875         def conv (str):
876                 str = re.sub ('noAutoBeaming *= *##f', 'autoBeaming = ##t', str)
877                 str = re.sub ('noAutoBeaming *= *##t', 'autoBeaming = ##f', str)
878                 return str
879         
880         conversions.append (((1,5,49), conv, 'noAutoBeaming -> autoBeaming'))
881
882 if 1:
883         def conv (str):
884                 str = re.sub ('tuplet-bracket-visibility', 'bracket-visibility', str)
885                 str = re.sub ('tuplet-number-visibility', 'number-visibility', str)             
886                 return str
887         
888         conversions.append (((1,5,52), conv, 'tuplet-X-visibility -> X-visibility'))
889
890 if 1:
891         def conv (str):
892                 str = re.sub ('Pitch::transpose', 'ly-transpose-pitch', str)
893
894                 return str
895         
896         conversions.append (((1,5,56), conv, 'Pitch::transpose -> ly-transpose-pitch'))
897
898 if 1:
899         def conv (str):
900                 str = re.sub ('textNonEmpty *= *##t', "TextScript \\set #'no-spacing-rods = ##f", str)
901                 str = re.sub ('textNonEmpty *= *##f', "TextScript \\set #'no-spacing-rods = ##t", str)
902                 return str
903         
904         conversions.append (((1,5,58), conv, 'deprecate textNonEmpty'))
905
906
907 if 1:
908         def conv (str):
909                 str = re.sub ('MinimumVerticalExtent', 'minimumV@rticalExtent', str)
910                 str = re.sub ('minimumVerticalExtent', 'minimumV@rticalExtent', str)            
911                 str = re.sub ('ExtraVerticalExtent', 'extraV@rticalExtent', str)
912                 str = re.sub ('extraVerticalExtent', 'extraV@rticalExtent', str)                
913                 str = re.sub ('VerticalExtent', 'verticalExtent', str)
914                 str = re.sub ('extraV@rticalExtent', 'extraVerticalExtent', str)
915                 str = re.sub ('minimumV@rticalExtent', 'minimumVerticalExtent', str)            
916                 return str
917
918         conversions.append (((1,5,59), conv,
919         'XxxxVerticalExtent -> xxxVerticalExtent'))
920
921 if 1:
922         def conv (str):
923                 str = re.sub ('visibility-lambda', 'break-visibility', str)
924                 return str
925
926         conversions.append (((1,5,62), conv,
927         'visibility-lambda -> break-visibility'))
928         
929
930 if 1:
931         def conv (str):
932                 if re.search (r'\addlyrics',str) \
933                        and re.search ('automaticMelismata', str)  == None:
934                         sys.stderr.write  ('automaticMelismata is turned on by default since 1.5.67. Please fix this by hand.')
935                         raise FatalConversionError()
936                 return str
937
938         conversions.append (((1,5,67), conv,
939                              'automaticMelismata turned on by default'))
940
941 if 1:
942         def conv (str):
943                 str = re.sub ('ly-set-grob-property([^!])', 'ly-set-grob-property!\1', str)
944                 str = re.sub ('ly-set-mus-property([^!])', 'ly-set-mus-property!\1', str)               
945                 return str
946         
947         conversions.append (((1,5,68), conv, 'ly-set-X-property -> ly-set-X-property!'))
948
949 if 1:
950         def conv (str):
951                 str = re.sub ('extent-X', 'X-extent', str)
952                 str = re.sub ('extent-Y', 'Y-extent', str)              
953                 return str
954         
955         conversions.append (((1,5,71), conv, 'extent-[XY] -> [XY]-extent'))
956
957
958 if 1:
959         def conv (str):
960                 str = re.sub ("""#\(set! +point-and-click +line-column-location\)""",
961                               """#(set-point-and-click! \'line-column)""", str)
962                 str = re.sub ("""#\(set![ \t]+point-and-click +line-location\)""",
963                               '#(set-point-and-click! \'line)', str)
964                 str = re.sub ('#\(set! +point-and-click +#f\)',
965                               '#(set-point-and-click! \'none)', str)
966                 return str
967         
968         conversions.append (((1,5,72), conv, 'set! point-and-click -> set-point-and-click!'))
969
970
971 if 1:
972         def conv (str):
973                 str = re.sub ('flag-style', 'stroke-style', str)
974                 str = re.sub (r"""Stem([ ]+)\\override #'style""", r"""Stem \\override #'flag-style""", str);
975                 str = re.sub (r"""Stem([ ]+)\\set([ ]+)#'style""", r"""Stem \\set #'flag-style""", str);
976                 return str
977         
978         conversions.append (((1,6,5), conv, 'Stems: flag-style -> stroke-style; style -> flag-style'))
979
980
981 if 1:
982         def subst_req_name (match):
983                 return "(make-music-by-name \'%sEvent)" % regularize_id (match.group(1))
984
985         def conv (str):
986                 str = re.sub ('\\(ly-make-music *\"([A-Z][a-z_]+)_req\"\\)', subst_req_name, str)
987                 str = re.sub ('Request_chord', 'EventChord', str)
988                 return str
989         
990         conversions.append (((1,7,1), conv, 'ly-make-music foo_bar_req -> make-music-by-name FooBarEvent'))
991
992
993 if 1:
994         spanner_subst ={
995                 "text" : 'TextSpanEvent',
996                 "decrescendo" : 'DecrescendoEvent',
997                 "crescendo" : 'CrescendoEvent',
998                 "Sustain" : 'SustainPedalEvent',
999                 "slur" : 'SlurEvent',
1000                 "UnaCorda" : 'UnaCordaEvent',
1001                 "Sostenuto" : 'SostenutoEvent',
1002                 }
1003         def subst_ev_name (match):
1004                 stype = 'STOP'
1005                 if re.search ('start', match.group(1)):
1006                         stype= 'START'
1007
1008                 mtype = spanner_subst[match.group(2)]
1009                 return "(make-span-event '%s %s)" % (mtype , stype)
1010
1011         def subst_definition_ev_name(match):
1012                 return ' = #%s' % subst_ev_name (match) 
1013         def subst_inline_ev_name (match):
1014                 s = subst_ev_name (match)
1015                 return '#(ly-export %s)' % s
1016         def subst_csp_definition (match):
1017                 return ' = #(make-event-chord (list %s))' % subst_ev_name (match)
1018         def subst_csp_inline (match):
1019                 return '#(ly-export (make-event-chord (list %s)))' % subst_ev_name (match)
1020                 
1021         def conv (str):
1022                 str = re.sub (r' *= *\\spanrequest *([^ ]+) *"([^"]+)"', subst_definition_ev_name, str)
1023                 str = re.sub (r'\\spanrequest *([^ ]+) *"([^"]+)"', subst_inline_ev_name, str)
1024                 str = re.sub (r' *= *\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_definition, str)
1025                 str = re.sub (r'\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_inline, str)
1026                 str = re.sub (r'ly-id ', 'ly-import ', str)
1027
1028                 str = re.sub (r' *= *\\script "([^"]+)"', ' = #(make-articulation "\\1")', str)
1029                 str = re.sub (r'\\script "([^"]+)"', '#(ly-export (make-articulation "\\1"))', str)
1030                 return str
1031
1032         conversions.append (((1,7,2), conv, '\\spanrequest -> #(make-span-event .. ), \script -> #(make-articulation .. )'))
1033
1034 if 1:
1035         def conv(str):
1036                 str = re.sub (r'\(ly-', '(ly:', str)
1037
1038                 changed = [
1039                         r'duration\?',
1040                         r'font-metric\?',
1041                         r'molecule\?',
1042                         r'moment\?',
1043                         r'music\?',
1044                         r'pitch\?',
1045                         'make-duration',
1046                         'music-duration-length',
1047                         'duration-log',
1048                         'duration-dotcount',
1049                         'intlog2',
1050                         'duration-factor',
1051                         'transpose-key-alist',
1052                         'get-system',
1053                         'get-broken-into',
1054                         'get-original',
1055                         'set-point-and-click!',
1056                         'make-moment',
1057                         'make-pitch',
1058                         'pitch-octave',
1059                         'pitch-alteration',
1060                         'pitch-notename',
1061                         'pitch-semitones',
1062                         r'pitch<\?',
1063                         r'dir\?',
1064                         'music-duration-compress',
1065                         'set-point-and-click!'
1066                         ]
1067
1068                 origre = r'\b(%s)' % string.join (changed, '|')
1069                 
1070                 str = re.sub (origre, r'ly:\1',str)
1071                 str = re.sub ('set-point-and-click!', 'set-point-and-click', str)
1072                 
1073                 return str
1074         
1075         conversions.append (((1,7,3), conv, 'ly- -> ly:'))
1076
1077 if 1:
1078         def conv(str):
1079                 str = re.sub (r'<<', '< <', str)
1080                 str = re.sub (r'>>', '> >', str)
1081
1082                 return str
1083         
1084         conversions.append (((1,7,4), conv, '<< >> -> < <  > >'))
1085
1086
1087 ################################
1088 #       END OF CONVERSIONS      
1089 ################################
1090
1091 def get_conversions (from_version, to_version):
1092         def version_b (v, f = from_version, t = to_version):
1093                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
1094         return filter (version_b, conversions)
1095
1096
1097 def latest_version ():
1098         return conversions[-1][0]
1099
1100 def do_conversion (infile, from_version, outfile, to_version):
1101         conv_list = get_conversions (from_version, to_version)
1102
1103         sys.stderr.write ('Applying conversions: ')
1104         str = infile.read ()
1105         last_conversion = ()
1106         try:
1107                 for x in conv_list:
1108                         sys.stderr.write (tup_to_str (x[0])  + ', ')
1109                         str = x[1] (str)
1110                         last_conversion = x[0]
1111
1112         except FatalConversionError:
1113                 sys.stderr.write ('Error while converting; I won\'t convert any further')
1114
1115         if last_conversion:
1116                 sys.stderr.write ('\n')
1117                 new_ver =  '\\version \"%s\"' % tup_to_str (last_conversion)
1118
1119                 if re.search (lilypond_version_re_str, str):
1120                         str = re.sub (lilypond_version_re_str,'\\'+new_ver , str)
1121                 elif add_version:
1122                         str = new_ver + '\n' + str
1123
1124                 outfile.write(str)
1125
1126         return last_conversion
1127         
1128 class UnknownVersion:
1129         pass
1130
1131 def do_one_file (infile_name):
1132         sys.stderr.write ('Processing `%s\' ... '% infile_name)
1133         outfile_name = ''
1134         if __main__.edit:
1135                 outfile_name = infile_name + '.NEW'
1136         elif __main__.outfile_name:
1137                 outfile_name = __main__.outfile_name
1138
1139         if __main__.from_version:
1140                 from_version = __main__.from_version
1141         else:
1142                 guess = guess_lilypond_version (infile_name)
1143                 if not guess:
1144                         raise UnknownVersion()
1145                 from_version = str_to_tuple (guess)
1146
1147         if __main__.to_version:
1148                 to_version = __main__.to_version
1149         else:
1150                 to_version = latest_version ()
1151
1152
1153         if infile_name:
1154                 infile = open (infile_name,'r')
1155         else:
1156                 infile = sys.stdin
1157
1158         if outfile_name:
1159                 outfile =  open (outfile_name, 'w')
1160         else:
1161                 outfile = sys.stdout
1162
1163         touched = do_conversion (infile, from_version, outfile, to_version)
1164
1165         if infile_name:
1166                 infile.close ()
1167
1168         if outfile_name:
1169                 outfile.close ()
1170
1171         if __main__.edit and touched:
1172                 try:
1173                         os.remove(infile_name + '~')
1174                 except:
1175                         pass
1176                 os.rename (infile_name, infile_name + '~')
1177                 os.rename (infile_name + '.NEW', infile_name)
1178
1179         sys.stderr.write ('\n')
1180         sys.stderr.flush ()
1181
1182 edit = 0
1183 assume_old = 0
1184 to_version = ()
1185 from_version = ()
1186 outfile_name = ''
1187
1188 (options, files) = getopt.getopt (
1189         sys.argv[1:], 'ao:f:t:senh', ['no-version', 'assume-old', 'version', 'output', 'show-rules', 'help', 'edit', 'from=', 'to='])
1190
1191 for opt in options:
1192         o = opt[0]
1193         a = opt[1]
1194         if o== '--help' or o == '-h':
1195                 usage ()
1196                 sys.exit (0)
1197         if o == '--version' or o == '-v':
1198                 print_version ()
1199                 sys.exit (0)
1200         elif o== '--from' or o=='-f':
1201                 from_version = str_to_tuple (a)
1202         elif o== '--to' or o=='-t':
1203                 to_version = str_to_tuple (a)
1204         elif o== '--edit' or o == '-e':
1205                 edit = 1
1206         elif o== '--show-rules' or o == '-s':
1207                 show_rules (sys.stdout)
1208                 sys.exit(0)
1209         elif o == '--output' or o == '-o':
1210                 outfile_name = a
1211         elif o == '--assume-old' or o == '-a':
1212                 assume_old = 1
1213         elif o == '--no-version' or o == '-n':
1214                 add_version = 0
1215         else:
1216                 print o
1217                 raise getopt.error
1218
1219 identify ()
1220 for f in files:
1221         if f == '-':
1222                 f = ''
1223         if not os.path.isfile (f):
1224                 continue
1225         try:
1226                 do_one_file (f)
1227         except UnknownVersion:
1228                 sys.stderr.write ('\n')
1229                 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
1230                 sys.stderr.write ('\n')
1231                 if assume_old:
1232                         fv = from_version
1233                         from_version = (0,0,0)
1234                         do_one_file (f)
1235                         from_version = fv
1236                 else:
1237                         sys.stderr.write ("%s: skipping: `%s' " % (program_name,  f))
1238                 pass
1239 sys.stderr.write ('\n')