44# related (though complimentary) formatting operations on Python
55# programs. When called as "pindent -c", it takes a valid Python
66# program as input and outputs a version augmented with block-closing
7- # comments. When called as "pindent -e ", it assumes its input is a
7+ # comments. When called as "pindent -d ", it assumes its input is a
88# Python program with block-closing comments and outputs a commentless
99# version. When called as "pindent -r" it assumes its input is a
1010# Python program with block-closing comments but with its indentation
4646# Other options:
4747# -s stepsize: set the indentation step size (default 8)
4848# -t tabsize : set the number of spaces a tab character is worth (default 8)
49+ # -e : expand TABs into spaces
4950# file ... : input file(s) (default standard input)
5051# The results always go to standard output
5152
7879# Defaults
7980STEPSIZE = 8
8081TABSIZE = 8
82+ EXPANDTABS = 0
8183
8284import os
8385import re
9698class PythonIndenter :
9799
98100 def __init__ (self , fpi = sys .stdin , fpo = sys .stdout ,
99- indentsize = STEPSIZE , tabsize = TABSIZE ):
101+ indentsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
100102 self .fpi = fpi
101103 self .fpo = fpo
102104 self .indentsize = indentsize
103105 self .tabsize = tabsize
104106 self .lineno = 0
105- self .write = fpo .write
107+ self .expandtabs = expandtabs
108+ self ._write = fpo .write
106109 self .kwprog = re .compile (
107110 r'^\s*(?P<kw>[a-z]+)'
108111 r'(\s+(?P<id>[a-zA-Z_]\w*))?'
@@ -114,6 +117,14 @@ def __init__(self, fpi = sys.stdin, fpo = sys.stdout,
114117 self .wsprog = re .compile (r'^[ \t]*' )
115118 # end def __init__
116119
120+ def write (self , line ):
121+ if self .expandtabs :
122+ self ._write (string .expandtabs (line , self .tabsize ))
123+ else :
124+ self ._write (line )
125+ # end if
126+ # end def write
127+
117128 def readline (self ):
118129 line = self .fpi .readline ()
119130 if line : self .lineno = self .lineno + 1
@@ -196,7 +207,7 @@ def reformat(self):
196207 # end if
197208 # end def reformat
198209
199- def eliminate (self ):
210+ def delete (self ):
200211 begin_counter = 0
201212 end_counter = 0
202213 while 1 :
@@ -222,7 +233,7 @@ def eliminate(self):
222233 elif begin_counter - end_counter > 0 :
223234 sys .stderr .write ('Warning: input contained less end tags than expected\n ' )
224235 # end if
225- # end def eliminate
236+ # end def delete
226237
227238 def complete (self ):
228239 self .indentsize = 1
@@ -325,20 +336,20 @@ def complete(self):
325336# - xxx_file(filename): process file in place, return true iff changed
326337
327338def complete_filter (input = sys .stdin , output = sys .stdout ,
328- stepsize = STEPSIZE , tabsize = TABSIZE ):
329- pi = PythonIndenter (input , output , stepsize , tabsize )
339+ stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
340+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
330341 pi .complete ()
331342# end def complete_filter
332343
333- def eliminate_filter (input = sys .stdin , output = sys .stdout ,
334- stepsize = STEPSIZE , tabsize = TABSIZE ):
335- pi = PythonIndenter (input , output , stepsize , tabsize )
336- pi .eliminate ()
337- # end def eliminate_filter
344+ def delete_filter (input = sys .stdin , output = sys .stdout ,
345+ stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
346+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
347+ pi .delete ()
348+ # end def delete_filter
338349
339350def reformat_filter (input = sys .stdin , output = sys .stdout ,
340- stepsize = STEPSIZE , tabsize = TABSIZE ):
341- pi = PythonIndenter (input , output , stepsize , tabsize )
351+ stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
352+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
342353 pi .reformat ()
343354# end def reformat_filter
344355
@@ -386,33 +397,33 @@ def getvalue(self):
386397 # end def getvalue
387398# end class StringWriter
388399
389- def complete_string (source , stepsize = STEPSIZE , tabsize = TABSIZE ):
400+ def complete_string (source , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
390401 input = StringReader (source )
391402 output = StringWriter ()
392- pi = PythonIndenter (input , output , stepsize , tabsize )
403+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
393404 pi .complete ()
394405 return output .getvalue ()
395406# end def complete_string
396407
397- def eliminate_string (source , stepsize = STEPSIZE , tabsize = TABSIZE ):
408+ def delete_string (source , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
398409 input = StringReader (source )
399410 output = StringWriter ()
400- pi = PythonIndenter (input , output , stepsize , tabsize )
401- pi .eliminate ()
411+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
412+ pi .delete ()
402413 return output .getvalue ()
403- # end def eliminate_string
414+ # end def delete_string
404415
405- def reformat_string (source , stepsize = STEPSIZE , tabsize = TABSIZE ):
416+ def reformat_string (source , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
406417 input = StringReader (source )
407418 output = StringWriter ()
408- pi = PythonIndenter (input , output , stepsize , tabsize )
419+ pi = PythonIndenter (input , output , stepsize , tabsize , expandtabs )
409420 pi .reformat ()
410421 return output .getvalue ()
411422# end def reformat_string
412423
413- def complete_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE ):
424+ def complete_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
414425 source = open (filename , 'r' ).read ()
415- result = complete_string (source , stepsize , tabsize )
426+ result = complete_string (source , stepsize , tabsize , expandtabs )
416427 if source == result : return 0
417428 # end if
418429 import os
@@ -425,9 +436,9 @@ def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
425436 return 1
426437# end def complete_file
427438
428- def eliminate_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE ):
439+ def delete_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
429440 source = open (filename , 'r' ).read ()
430- result = eliminate_string (source , stepsize , tabsize )
441+ result = delete_string (source , stepsize , tabsize , expandtabs )
431442 if source == result : return 0
432443 # end if
433444 import os
@@ -438,11 +449,11 @@ def eliminate_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
438449 f .write (result )
439450 f .close ()
440451 return 1
441- # end def eliminate_file
452+ # end def delete_file
442453
443- def reformat_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE ):
454+ def reformat_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE , expandtabs = EXPANDTABS ):
444455 source = open (filename , 'r' ).read ()
445- result = reformat_string (source , stepsize , tabsize )
456+ result = reformat_string (source , stepsize , tabsize , expandtabs )
446457 if source == result : return 0
447458 # end if
448459 import os
@@ -458,21 +469,28 @@ def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
458469# Test program when called as a script
459470
460471usage = """
461- usage: pindent (-c|-e |-r) [-s stepsize] [-t tabsize] [file] ...
472+ usage: pindent (-c|-d |-r) [-s stepsize] [-t tabsize] [-e ] [file] ...
462473-c : complete a correctly indented program (add #end directives)
463- -e : eliminate #end directives
474+ -d : delete #end directives
464475-r : reformat a completed program (use #end directives)
465476-s stepsize: indentation step (default %(STEPSIZE)d)
466477-t tabsize : the worth in spaces of a tab (default %(TABSIZE)d)
478+ -e : expand TABs into spaces (defailt OFF)
467479[file] ... : files are changed in place, with backups in file~
468480If no files are specified or a single - is given,
469481the program acts as a filter (reads stdin, writes stdout).
470482""" % vars ()
471483
484+ def error_both (op1 , op2 ):
485+ sys .stderr .write ('Error: You can not specify both ' + op1 + ' and -' + op2 [0 ]+ ' at the same time\n ' )
486+ sys .stderr .write (usage )
487+ sys .exit (2 )
488+ # end def error_both
489+
472490def test ():
473491 import getopt
474492 try :
475- opts , args = getopt .getopt (sys .argv [1 :], 'cers :t:' )
493+ opts , args = getopt .getopt (sys .argv [1 :], 'cdrs :t:e ' )
476494 except getopt .error , msg :
477495 sys .stderr .write ('Error: %s\n ' % msg )
478496 sys .stderr .write (usage )
@@ -481,32 +499,41 @@ def test():
481499 action = None
482500 stepsize = STEPSIZE
483501 tabsize = TABSIZE
502+ expandtabs = EXPANDTABS
484503 for o , a in opts :
485504 if o == '-c' :
505+ if action : error_both (o , action )
506+ # end if
486507 action = 'complete'
487- elif o == '-e' :
488- action = 'eliminate'
508+ elif o == '-d' :
509+ if action : error_both (o , action )
510+ # end if
511+ action = 'delete'
489512 elif o == '-r' :
513+ if action : error_both (o , action )
514+ # end if
490515 action = 'reformat'
491516 elif o == '-s' :
492517 stepsize = string .atoi (a )
493518 elif o == '-t' :
494519 tabsize = string .atoi (a )
520+ elif o == '-e' :
521+ expandtabs = 1
495522 # end if
496523 # end for
497524 if not action :
498525 sys .stderr .write (
499- 'You must specify -c(omplete), -e(eliminate ) or -r(eformat)\n ' )
526+ 'You must specify -c(omplete), -d(elete ) or -r(eformat)\n ' )
500527 sys .stderr .write (usage )
501528 sys .exit (2 )
502529 # end if
503530 if not args or args == ['-' ]:
504531 action = eval (action + '_filter' )
505- action (sys .stdin , sys .stdout , stepsize , tabsize )
532+ action (sys .stdin , sys .stdout , stepsize , tabsize , expandtabs )
506533 else :
507534 action = eval (action + '_file' )
508535 for file in args :
509- action (file , stepsize , tabsize )
536+ action (file , stepsize , tabsize , expandtabs )
510537 # end for
511538 # end if
512539# end def test
0 commit comments