[Pythonmac-SIG] cheol 0.5.1 and chtab 0.1
Gordon Worley
redbird@rbisland.cx
Fri, 20 Jul 2001 22:13:07 -0400
Okay, below is the diff file between cheol 0.5 and 0.5.1 so you can
patch the source I sent out earlier. Basically, it just adds support
for long options (like --help) after reading up on getopt a little
more. Also, chtab is out. It's basically cheol with the important
parts changed to convert tabs/spaces instead of line endings.
Also, sorry about the largeness of these posts. I'll just do diff
files from now on and sometime next week I'll have both these scripts
posted on my Web site. Actually, now that I think about it, chtab
could probably be a diff on cheol. :-) Oh well.
If anyone has feature ideas, please, send them my way (but keep in
mind these are Unixy utility programs, so don't ask for them to clean
the kitchen sink). I think there may be a feature or two that could
be added to chtab, but I'm not sure what, since I got it to do the
conversions I would want it to do.
cheol0.5-0.5.1.diff:
22a23
> 0.5.1 - added support for long (--) options
31c32
< __version__ = "cheol 0.5, Copyright 2000-2001 Gordon Worley via the
Python License, version 2.1.\nType -h for help"
---
> __version__ = "cheol 0.5.1, Copyright 2000-2001 Gordon Worley via
>the Python License, version 2.1.\nType -h for help"
195,198c196,199
< -m : macify line endings
< -u : unixify line endings
< -d : dosify line endings
< -h : print help
---
> -m, --mac : macify line endings
> -u, --unix : unixify line endings
> -d, --dos : dosify line endings
> -h, --help : print help
199a201,202
>
> run with no options or args for version string
205c208
< opts, args = getopt.getopt(sys.argv[1:], "hlvmudr")
---
> opts, args = getopt.getopt(sys.argv[1:], "hlvmudr",
>("help", "mac", "unix", "dos"))
220c223
< elif opt[0] == "-m":
---
> elif opt[0] == "-m" or opt[0] == "--mac":
222c225
< elif opt[0] == "-u":
---
> elif opt[0] == "-u" or opt[0] == "--unix":
224c227
< elif opt[0] == "-d":
---
> elif opt[0] == "-d" or opt[0] == "--dos":
226c229
< elif opt[0] == "-h":
---
> elif opt[0] == "-h" or opt[0] == "--help":
232c235
< convert(arg, mode, is_recv, follow_links, verbose)
\ No newline at end of file
---
> convert(arg, mode, is_recv, follow_links, verbose)
chtab 0.1:
#!/usr/bin/env python
"""
chtab: tabs to spaces and spaces to tabs
Copyright (C) 2000-2001 Gordon Worley
This program is free software; you can redistribute it and/or modify
it under the terms of the Python License, version 2.1.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Python License, version 2.1 for more details.
For a copy of the Python License, version 2.1, visit
<http://www.python.org/>.
To contact me, please visit my Web site at <http://homepage.mac.com/
redbird/> or e-mail me at <redbird@rbisland.cx>.
#history
0.1 - fixed regexen
0.0 - based on cheol.py, but puts in regexen to convert tabs/spaces
"""
__version__ = "chtab 0.1, Copyright 2000-2001 Gordon Worley via the
Python License, version 2.1.\nType -h for help"
#fn = filename
#this first part is not by me, but put right in this code
#so that everything can stay in one file :-)
#by Jurgen Hermann, from Python Cookbook (ASPN)
import os, string
def replaceFile(oldname, newname):
""" Rename file 'oldname' to 'newname'.
"""
if os.name == 'nt' and os.path.exists(oldname):
# POSIX rename does an atomic replace, WIN32 rename
does not. :-(
try:
os.remove(newname)
except OSError, exc:
import errno
if exc.errno != errno.ENOENT: raise exc
# rename it
os.rename(oldname, newname)
class FileMorpher:
""" A class that enables a client to securely update an existing file,
including the ability to make an automated backup version.
"""
def __init__(self, filename, **kw):
""" The constructor takes the filename and some options.
backup -- boolean indicating whether you want
a backup file
(default is yes)
"""
self.filename = filename
self.do_backup = kw.get('backup', 0)
self.stream = None
self.basename, ext = os.path.splitext(self.filename)
def __del__(self):
if self.stream:
# Remove open temp file
self.__close()
os.remove(self.__tempfile())
def __tempfile(self):
return self.basename + ".tmp"
def __close(self):
""" Close temp stream, if open.
"""
if self.stream:
self.stream.close()
self.stream = None
def load(self):
""" Load the content of the original file into a string and
return it. All I/O exceptions are passed through.
"""
file = open(self.filename, "rt")
try:
content = file.read()
finally:
file.close()
return content
def save(self, content):
""" Save new content, using a temporary file.
"""
file = self.opentemp()
file.write(content)
self.commit()
def opentemp(self):
""" Open a temporary file for writing and return an
open stream.
"""
assert not self.stream, "Write stream already open"
self.stream = open(self.__tempfile(), "wt")
return self.stream
def commit(self):
""" Close the open temp stream and replace the original file,
optionally making a backup copy.
"""
assert self.stream, "Write stream not open"
# close temp file
self.__close()
# do optional backup and rename temp file to the correct name
if self.do_backup:
replaceFile(self.filename, self.basename + ".bak")
replaceFile(self.__tempfile(), self.filename)
#end part not by me
#begin part by me
import re
def convert(fn, mode, is_recv, follow_links, verbose, tab_width, all):
if is_recv:
if os.path.isdir(fn) and not os.path.islink(fn):
if verbose:
print "%s/:" % fn
os.chdir(fn)
fns = os.listdir("./")
for afn in fns:
convert(afn, mode, is_recv,
follow_links, verbose, tab_width, all)
os.chdir("..")
if verbose:
print "../:"
elif os.path.isdir(fn) and os.path.islink(fn) and
os.path.islink(fn) <= follow_links:
jfn = os.readlink(fn)
if verbose:
print "%s/ (%s/):" % (fn, jfn)
fns = os.listdir(fn)
for afn in fns:
convert(os.path.join(jfn, afn), mode,
is_recv, follow_links, verbose, tab_width, all)
if verbose:
print "../:"
if not os.path.isdir(fn):
if os.path.islink(fn) and os.path.islink(fn) <= follow_links:
tmp = fn
fn = os.readlink(fn)
if verbose:
print "converting %s (%s)" % (tmp, fn)
elif verbose:
print "converting %s" % fn
f = FileMorpher(fn)
temp = f.load()
if mode == 0:
if all:
temp = re.sub(r" {" + `tab_width` +
r"}", r"\t", temp)
else:
patt = re.compile(r"^ {" +
`tab_width` + r"}", re.M)
temp, count = patt.subn(r"\t", temp)
i = 1
while count > 0:
subpatt = re.compile(r"^\t{"
+ `i` + r"} {" + `tab_width` + r"}", re.M)
temp, count =
subpatt.subn("\t"*(i+1), temp)
i += 1
elif mode == 1:
temp = temp.expandtabs(tab_width)
stream = f.opentemp()
stream.write(temp)
f.commit()
help = """\
chtab: En/detabs files
%s [options] <path ...>
options:
-r : recursive
-l : follow links
-v : verbose
-e, --entab : turn spaces into tabs (default)
-d, --detab : turn tabs into spaces
-t <num> : number of spaces per tab (default is 4)
-a : act on all spaces (works with --entab, default is to just affect
those spaces at the beginning of lines)
-h, --help : print help
path is a file or directory
run with no options or args for version string
"""
if __name__ == '__main__':
import sys, getopt
try:
opts, args = getopt.getopt(sys.argv[1:], "ahlvedrt:",
("entab", "detab", "help"))
except:
print "That's not an option. Type -h for help."
sys.exit(1)
mode = 0 #default is to entab
all = 0 #default is to just do tabs at start of lines
tab_width = 4
is_recv = 0 #default isn't recursive
follow_links = 0 #default don't follow links
verbose = 0
for opt in opts:
if opt[0] == "-r":
is_recv = 1
elif opt[0] == "-a":
all = 1
elif opt[0] == "-l":
follow_links = 1
elif opt[0] == "-v":
verbose = 1
elif opt[0] == "-t":
tab_width = int(opt[1])
elif opt[0] == "-e" or opt[0] == "--entab":
mode = 0;
elif opt[0] == "-d" or opt[0] == "--detab":
mode = 1;
elif opt[0] == "-h" or opt[0] == "--help":
print help % sys.argv[0]
sys.exit(0)
if not args:
print __version__
for arg in args:
convert(arg, mode, is_recv, follow_links, verbose,
tab_width, all)
--
Gordon Worley `When I use a word,' Humpty Dumpty
http://homepage.mac.com/redbird/ said, `it means just what I choose
redbird@rbisland.cx it to mean--neither more nor less.'
PGP: 0xBBD3B003 --Lewis Carroll