diff options
Diffstat (limited to 'Demo/parser/pprint.py')
-rw-r--r-- | Demo/parser/pprint.py | 143 |
1 files changed, 143 insertions, 0 deletions
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 |