Demos for Fred's parser module
diff --git a/Demo/parser/pprint.py b/Demo/parser/pprint.py
new file mode 100644
index 0000000..c4b8158
--- /dev/null
+++ b/Demo/parser/pprint.py
@@ -0,0 +1,143 @@
+#  pprint.py
+#
+#  Author:	Fred L. Drake, Jr.
+#		fdrake@vt.edu
+#
+#  This is a simple little module I wrote to make life easier.  I didn't
+#  see anything quite like it in the library, though I may have overlooked
+#  something.  I wrote this when I was trying to read some heavily nested
+#  tuples with fairly non-descriptive content.  This is modelled very much
+#  after Lisp/Scheme - style pretty-printing of lists.  If you find it
+#  useful, thank small children who sleep at night.
+#
+
+"""Support to pretty-print lists, tuples, & dictionaries recursively.
+Very simple, but at least somewhat useful, especially in debugging
+data structures.
+
+INDENT_PER_LEVEL	--  Amount of indentation to use for each new
+			    recursive level.  The default is 1.  This
+			    must be a non-negative integer, and may be
+			    set by the caller before calling pprint().
+
+MAX_WIDTH		--  Maximum width of the display.  This is only
+			    used if the representation *can* be kept
+			    less than MAX_WIDTH characters wide.  May
+			    be set by the user before calling pprint().
+
+TAB_WIDTH		--  The width represented by a single tab.  This
+			    value is typically 8, but 4 is the default
+			    under MacOS.  Can be changed by the user if
+			    desired, but is probably not a good idea.
+
+pprint(seq [, stream])	--  The pretty-printer.  This takes a Python
+			    object (presumably a sequence, but that
+			    doesn't matter) and an optional output
+			    stream.  See the function documentation
+			    for details.
+"""
+
+
+INDENT_PER_LEVEL = 1
+
+MAX_WIDTH = 80
+
+import os
+TAB_WIDTH = (os.name == 'mac' and 4) or 8
+del os
+
+
+
+def _indentation(cols):
+    "Create tabbed indentation string COLS columns wide."
+
+    #  This is used to reduce the byte-count for the output, allowing
+    #  files created using this module to use as little external storage
+    #  as possible.  This is primarily intended to minimize impact on
+    #  a user's quota when storing resource files, or for creating output
+    #  intended for transmission.
+
+    return ((cols / TAB_WIDTH) * '\t') + ((cols % TAB_WIDTH) * ' ')
+
+
+
+def pprint(seq, stream = None, indent = 0, allowance = 0):
+    """Pretty-print a list, tuple, or dictionary.
+
+    pprint(seq [, stream]) ==> None
+
+    If STREAM is provided, output is written to that stream, otherwise
+    sys.stdout is used.  Indentation is done according to
+    INDENT_PER_LEVEL, which may be set to any non-negative integer
+    before calling this function.  The output written on the stream is
+    a perfectly valid representation of the Python object passed in,
+    with indentation to suite human-readable interpretation.  The
+    output can be used as input without error, given readable
+    representations of all sequence elements are available via repr().
+    Output is restricted to MAX_WIDTH columns where possible.  The
+    STREAM parameter must support the write() method with a single
+    parameter, which will always be a string.  The output stream may be
+    a StringIO.StringIO object if the result is needed as a string.
+    """
+
+    if stream is None:
+	import sys
+	stream = sys.stdout
+
+    from types import DictType, ListType, TupleType
+
+    rep = `seq`
+    typ = type(seq)
+    sepLines = len(rep) > (MAX_WIDTH - 1 - indent - allowance)
+
+    if sepLines and (typ is ListType or typ is TupleType):
+	#  Pretty-print the sequence.
+	stream.write(((typ is ListType) and '[') or '(')
+
+	length = len(seq)
+	if length:
+	    indent = indent + INDENT_PER_LEVEL
+	    pprint(seq[0], stream, indent, allowance + 1)
+
+	    if len(seq) > 1:
+		for ent in seq[1:]:
+		    stream.write(',\n' + _indentation(indent))
+		    pprint(ent, stream, indent, allowance + 1)
+
+	    indent = indent - INDENT_PER_LEVEL
+
+	stream.write(((typ is ListType) and ']') or ')')
+
+    elif typ is DictType and sepLines:
+	stream.write('{')
+
+	length = len(seq)
+	if length:
+	    indent = indent + INDENT_PER_LEVEL
+	    items  = seq.items()
+	    items.sort()
+	    key, ent = items[0]
+	    rep = `key` + ': '
+	    stream.write(rep)
+	    pprint(ent, stream, indent + len(rep), allowance + 1)
+
+	    if len(items) > 1:
+		for key, ent in items[1:]:
+		    rep = `key` + ': '
+		    stream.write(',\n' + _indentation(indent) + rep)
+		    pprint(ent, stream, indent + len(rep), allowance + 1)
+
+	    indent = indent - INDENT_PER_LEVEL
+
+	stream.write('}')
+
+    else:
+	stream.write(rep)
+
+    #  Terminate the 'print' if we're not a recursive invocation.
+    if not indent:
+	stream.write('\n')
+
+
+#
+#  end of pprint.py