[IPython-dev] pycolor: read from STDIN

Paul Mueller gakusei at dakotacom.net
Sat May 12 19:49:08 EDT 2007


Hi,

Here is the patch to pycolor (& it's man page) to allow it to read from
stdin. I've redone the cmdline parsing code to use optparse, which is
less messy & brittle than the old way would have been if I had extended
it.

I've split the modifications into two patches, in order to facilitate
logically separate commits if you want to do so:

pycolor_read_from_stdin_patch1.diff:
    has the current functionality but uses optparse
pycolor_read_from_stdin_patch2.diff:
    adds STDIN support; apply after applying
    pycolor_read_from_stdin_patch1.diff

Thanks,
Paul Mueller
-------------- next part --------------
Index: IPython/PyColorize.py
===================================================================
--- IPython/PyColorize.py	(revision 2337)
+++ IPython/PyColorize.py	(working copy)
@@ -38,6 +38,7 @@
 import cStringIO
 import keyword
 import os
+import optparse
 import string
 import sys
 import token
@@ -242,42 +243,38 @@
         # send text
         owrite('%s%s%s' % (color,toktext,colors.normal))
             
-def main():
-    """Colorize a python file using ANSI color escapes and print to stdout.
+def main(argv=None):
+    """Run as a command-line script: colorize a python file using ANSI color
+    escapes and print to stdout.
 
-    Usage:
-      %s [-s scheme] filename
+    Inputs:
 
-    Options:
+      - argv(None): a list of strings like sys.argv[1:] giving the command-line
+        arguments. If None, use sys.argv[1:].
+    """
 
-      -s scheme: give the color scheme to use. Currently only 'Linux'
-      (default) and 'LightBG' and 'NoColor' are implemented (give without
-      quotes).  """  
+    usage_msg = """%prog [options] filename
 
-    def usage():
-        print >> sys.stderr, main.__doc__ % sys.argv[0]
-        sys.exit(1)
-        
-    # FIXME: rewrite this to at least use getopt
-    try:
-        if sys.argv[1] == '-s':
-            scheme_name = sys.argv[2]
-            del sys.argv[1:3]
-        else:
-            scheme_name = _scheme_default
-        
-    except:
-        usage()
+Colorize a python file using ANSI color escapes and print to stdout."""
 
-    try:
-        fname = sys.argv[1]
-    except:
-        usage()
-        
+    parser = optparse.OptionParser(usage=usage_msg)
+    newopt = parser.add_option
+    newopt('-s','--scheme',metavar='NAME',dest='scheme_name',action='store',
+           choices=['Linux','LightBG','NoColor'],default=_scheme_default,
+           help="give the color scheme to use. Currently only 'Linux'\
+ (default) and 'LightBG' and 'NoColor' are implemented (give without\
+ quotes)")
+
+    opts,args = parser.parse_args(argv)
+
+    if len(args) != 1:
+        parser.error("you must give one filename.")
+
     # write colorized version to stdout
+    fname = args[0]
     parser = Parser()
     try:
-        parser.format(file(fname).read(),scheme = scheme_name)
+        parser.format(file(fname).read(),scheme=opts.scheme_name)
     except IOError,msg:
         # if user reads through a pager and quits, don't print traceback
         if msg.args != (32,'Broken pipe'):
Index: doc/pycolor.1
===================================================================
--- doc/pycolor.1	(revision 2337)
+++ doc/pycolor.1	(working copy)
@@ -2,7 +2,7 @@
 .\" First parameter, NAME, should be all caps
 .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
 .\" other parameters are allowed: see man(7), man(1)
-.TH PYCOLOR 1 "March 21, 2003"
+.TH PYCOLOR 1 "May 12, 2007"
 .\" Please adjust this date whenever revising the manpage.
 .\"
 .\" Some roff macros, for reference:
@@ -24,7 +24,10 @@
 Prints a colorized version of the input file to standard out.
 .SH OPTIONS
 .TP
-.B \-s <scheme>
+.B \-h, \-\-help
+Output a brief help message.
+.TP
+.B \-s, \-\-scheme <scheme>
 Give the color scheme to use.  Currently only Linux (default),
 LightBG, and NOColor are implemented.
 .SH AUTHOR
-------------- next part --------------
Index: IPython/PyColorize.py
===================================================================
--- IPython/PyColorize.py
+++ IPython/PyColorize.py  (working copy)
@@ -244,8 +244,8 @@
         owrite('%s%s%s' % (color,toktext,colors.normal))
             
 def main(argv=None):
-    """Run as a command-line script: colorize a python file using ANSI color
-    escapes and print to stdout.
+    """Run as a command-line script: colorize a python file or stdin using ANSI
+    color escapes and print to stdout.

     Inputs:

@@ -253,9 +253,10 @@
         arguments. If None, use sys.argv[1:].
     """

-    usage_msg = """%prog [options] filename
+    usage_msg = """%prog [options] [filename]

-Colorize a python file using ANSI color escapes and print to stdout."""
+Colorize a python file or stdin using ANSI color escapes and print to stdout.
+If no filename is given, or if filename is -, read standard input."""

     parser = optparse.OptionParser(usage=usage_msg)
     newopt = parser.add_option
@@ -267,18 +268,34 @@

     opts,args = parser.parse_args(argv)

-    if len(args) != 1:
-        parser.error("you must give one filename.")
+    if len(args) > 1:
+        parser.error("you must give at most one filename.")
+
+    if len(args) == 0:
+        fname = '-' # no filename given; setup to read from stdin
+    else:
+        fname = args[0]
+
+    if fname == '-':
+        stream = sys.stdin
+    else:
+        stream = file(fname)

-    # write colorized version to stdout
-    fname = args[0]
     parser = Parser()
+
+    # we need nested try blocks because pre-2.5 python doesn't support unified
+    # try-except-finally
     try:
-        parser.format(file(fname).read(),scheme=opts.scheme_name)
-    except IOError,msg:
-        # if user reads through a pager and quits, don't print traceback
-        if msg.args != (32,'Broken pipe'):
-            raise
+        try:
+            # write colorized version to stdout
+            parser.format(stream.read(),scheme=opts.scheme_name)
+        except IOError,msg:
+            # if user reads through a pager and quits, don't print traceback
+            if msg.args != (32,'Broken pipe'):
+                raise
+    finally:
+        if stream is not sys.stdin:
+            stream.close() # in case a non-handled exception happened above

 if __name__ == "__main__":
     main()
Index: doc/pycolor.1
===================================================================
--- doc/pycolor.1
+++ doc/pycolor.1 (working copy)
@@ -16,12 +16,14 @@
 .\" .sp <n>    insert n+1 empty lines
 .\" for manpage-specific macros, see man(7)
 .SH NAME
-pycolor \- Colorize a python file using ANSI and print to stdout.
+pycolor \- Colorize a python file or stdin using ANSI and print to stdout.
 .SH SYNOPSIS
 .B pycolor
-.RI [ options ] " file"
+.RI [ options ]
+.RI [ file ]
 .SH DESCRIPTION
-Prints a colorized version of the input file to standard out.
+Prints a colorized version of the input file (or standard input if no file is
+given, or the file name - is given) to standard out.
 .SH OPTIONS
 .TP
 .B \-h, \-\-help


More information about the IPython-dev mailing list