Source code for filesysobjects.pprint

# -*- coding: utf-8 -*-
"""The filesysobjects.pprint module provides pretty printer for paths.
"""
from __future__ import absolute_import
from __future__ import print_function

import os


from filesysobjects import V3K, ISSTR, RTE, PrettyPrintError

#
# for some display enhancements, for now uses the initial only
#
try:
    if V3K:
        columns, rows = os.get_terminal_size(0)  # @UndefinedVariable
    else:
        import curses
        stdscr = curses.initscr()
        curses.cbreak()
        curses.noecho()
        stdscr.keypad(1)
        columns, rows = stdscr.getmaxyx()
        curses.endwin()
except:
    # common defaults
    columns = 80
    rows = 24


from filesysobjects.apppaths import splitapppathx

__author__ = 'Arno-Can Uestuensoez'
__license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints"
__copyright__ = "Copyright (C) 2010-2016 Arno-Can Uestuensoez" \
                "@Ingenieurbuero Arno-Can Uestuensoez"
__version__ = '0.1.20'
__uuid__ = "4135ab0f-fbb8-45a2-a6b1-80d96c164b72"

__docformat__ = "restructuredtext en"


[docs]class PPPathVar(object): """Pretty printer for *PATH* variables. """
[docs] def __init__(self, path, **kargs): """Pretty print search path variables. Splits and returns the formatted printable string for search path variables of type *PATH*. The input: :: posix: path = "/path/entry/0:/path/entry/1" win32: path = "\\path/entry\\0;\\path\\entry\\1" results in the output of 'format=console': :: ...MYPATH = [ ...::::"/path/entry/0", ...::::"/path/entry/1", ...] for the output parameters: :: <format>: the output format, here format='console' 'MYPATH': the prefix, here 'MYPATH' '=': the assignchar, here '=' "/path/entry/0": first path entry "/path/entry/1": second path entry '.' * n: 'n' offset, here n=3 '.': offsetchar, here '.' ':' * m: 'm' indent, here m=4 ':': indentchar, here ':' For further details and examples refer to the manual. Args: **path**: The search path to be pretty printed. :: path := ( <search-path-string> | <list-of-search-paths> | <tuple-of-search-paths> ) search-path-string := "string of PATH syntax, see 'tpf' and 'spf'" list-of-search-paths := [<path-entry-0>, <path-entry-1>, ...] tuple-of-search-paths := (<path-entry-0>, <path-entry-1>, ...) kargs: **assignchar**: The character representing the assignment. **format**: The output format.:: format := ( console # formatted for console display | ini # simple path print with normalized path | inix0 # multiline colon separated list | inix1 # multiple key repetition | json # JSON syntax module | properties # | python # same as json | xml # XML syntax module | yaml # YAML syntax module ) See manual for details. **indent**: Indention of each path item. :: indent := <#int> default := 4 **indentchar**: The character used for padding of the indention. The use of 'indentchar[0]' only is forced. :: offsetchar := <printable-character> default := ' ' # space **indentclip**: Indention clipped overflows for of each individual path item. :: indent := <#int> default := 2 **indentclipchar**: The character user for extra padding of clipped items. The use of 'indentchar[0]' only is forced. :: offsetchar := <printable-character> default := ' ' # space **keepentry**: Preserves path entries from overflow handling. :: keepentry := ( True # ignore overflow for single path entries | False # applies overflow processing within single # path entries ) **maxwidth**: The maximal line width. default := 80 **linesep**: The output line separator. default := os.linesep **linesepfinal**: Controls the print of a line separator at the end of the string. :: linesepfinal := ( True # prints a line separator as last character | False # suppress the final line separator ) default := True **offset**: The left side offset margin for all output strings. :: offset := <#int> default := 0 **offsetchar**: The character used for padding of a general offset. The use of 'offsetchar[0]' only is forced. :: offsetchar := <printable-character> default := ' ' # space **overflow**: The behavior, when line is longer than *maxwidth*. :: overflow := ( 'ignore' # ignores overflow | 'cut' # drops the overflow | 'clip' # continues with the overflow # in next line, starts new for # next item | 'clipmerge' # continues with the overflow # in next line, concatenates # next item ) default := 'ignore' **pathsepin**: The input path separator. default := os.pathsep **pathsepout**: The output path separator. default := os.pathsep **prefix**: The prefix to be printed first. :: prefix := "string without line breaks" The output is: :: <prefix> = [ "<path-entry-0>", "<path-entry-1>", ] default := 'PATH' **spf**: Source platform. **tpf**: Target platform. Returns: Object/None Raises: pass-through """ self.assignchar = kargs.get("assignchar", '=') self.format = kargs.get("format", 'console') self.indent = kargs.get("indent", 4) self.indentchar = kargs.get("indentchar", ' ') self.indentclip = kargs.get("indentclip", 2) self.indentclipchar = kargs.get("indentclipchar", ' ') self.keepentry = kargs.get("keepentry", True) self.linesep = kargs.get("linesep", os.linesep) self.linesepfinal = kargs.get("linesepfinal", True) self.maxwidth = kargs.get("maxwidth", columns) self.offset = kargs.get("offset", 0) self.offsetchar = kargs.get("offsetchar", ' ') self.overflow = kargs.get("overflow", 'ignore') self.pathsepin = kargs.get("pathsepin", os.pathsep) self.pathsepout = kargs.get("pathsepout", os.pathsep) self.prefix = kargs.get("prefix", 'PATH') # self.tpf = kargs.get("tpf", RTE) kw = {} try: self.tpf = kargs.pop("tpf") kw['tpf'] = self.tpf except KeyError: self.tpf = False try: self.spf = kargs.pop("spf") kw['spf'] = self.spf except KeyError: self.spf = False self._raw = path if type(path) in ISSTR: self.path = splitapppathx( path, apppre=False, pathsep=self.pathsepin, **kw ) elif type(path) in (list, tuple): # lists and tuples are expected to be split resource paths. self.path = path else: raise PrettyPrintError("type not supported: " +str(path))
[docs] def __str__(self): """Pretty prints as defined by the creation parameters. """ if self.format.lower() == 'console': return self.str_console() elif self.format.lower() == 'ini': return self.str_ini() elif self.format.lower() == 'inix0': return self.str_inix0() elif self.format.lower() == 'inix1': return self.str_inix1() elif self.format.lower() == 'inix2': return self.str_inix2() elif self.format.lower() == 'json': return self.str_json() elif self.format.lower() == 'properties': return self.str_properties() elif self.format.lower() == 'xml': return self.str_xml() elif self.format.lower() == 'yaml': return self.str_yaml() return self.str_console()
def str_console(self): """Creates the string for standard display output. """ res = '' offset = self.offset offsetstr = self.offset * self.offsetchar indent = offset + self.indent indentstr = offsetstr + self.indent * self.indentchar indentclip = indent + self.indentclip indentclipstr = indentstr + self.indentclip * self.indentclipchar if self.overflow == 'clipmerge': # the complete string resi = self.prefix + ' ' + self.assignchar + ' "' + self.pathsepout.join(self.path) l0 = len(resi) if l0 < self.maxwidth: # fits into current linen length return resi + '"' # # needs clipping # res += offsetstr + resi[:self.maxwidth - offset - 1] + '"'# + self.linesep plen = self.maxwidth - indent lx = plen + offset - 1 # logically pushed back for an extra quote while lx < l0: res += self.linesep res += indentstr + ( '"' + resi[lx : lx + plen-2] + '"' ) #+ self.linesep lx += plen - 2 return res + self.linesep res += offsetstr + self.prefix + ' ' + self.assignchar + ' [' + self.linesep for p in self.path: resi = '"%s' % (str(p)) l0 = len(resi) if self.overflow == 'ignore': res += indentstr + resi + '",' + self.linesep elif l0 > (self.maxwidth - indent) and not self.keepentry: plen = self.maxwidth - indent res += indentstr + resi[:plen] if self.overflow == 'cut': res = res[:-2] + '*"' + self.linesep continue elif self.overflow == 'clip': res = res[:-1] + '"' + self.linesep plen = self.maxwidth - indentclip lx = plen + 1 # extra quote plen -= self.indentclip while lx < l0: res += indentclipstr + ( '"' + resi[lx : lx + plen] + '"' ) + self.linesep lx += plen res = res[:-len(self.linesep) - 1] + '",' + self.linesep else: res += indentstr + resi + '",' + self.linesep if res.endswith(',' + self.linesep): res = res[:-len(',' + self.linesep)] + self.linesep if self.linesepfinal: res += offsetstr + ']' + self.linesep else: res += offsetstr + ']' return res def str_ini(self): """Creates the string for standard *INI* format. """ offsetstr = self.offset * self.offsetchar # the complete string if self.linesepfinal: return offsetstr + self.prefix + ' ' + self.assignchar + ' "' + self.pathsepout.join(self.path) + '"'+ self.linesep else: return offsetstr + self.prefix + ' ' + self.assignchar + ' "' + self.pathsepout.join(self.path) + '"' def str_inix0(self): """Creates the string for extended *INI* format based on colon separated multi-line lists. """ res = '' offsetstr = self.offset * self.offsetchar indentstr = offsetstr + self.indent * self.indentchar res += offsetstr + self.prefix + ' ' + self.assignchar + ' ' for p in self.path: res += self.linesep res += indentstr + ':%s' % (str(p)) if self.linesepfinal: return res + self.linesep else: return res def str_inix1(self): """Creates the string for the extended *INI* format based on multiple key repetition. """ res = '' offsetstr = self.offset * self.offsetchar for p in self.path: resi = self.prefix + ' ' + self.assignchar + ' %s' % (str(p)) res += offsetstr + resi + self.linesep if self.linesepfinal: return res else: return res[:-len(self.linesep)] def str_inix2(self): """Creates the string for the extended *INI* format based on multiple keys with incremented index extension. """ res = '' offsetstr = self.offset * self.offsetchar idx = 0 for p in self.path: resi = self.prefix + str(idx) + ' ' + self.assignchar + ' %s' % (str(p)) res += offsetstr + resi + self.linesep idx += 1 if self.linesepfinal: return res else: return res[:-len(self.linesep)] def str_json(self): """Creates the string for standard *INI* format. """ res = '' offsetstr = self.offset * self.offsetchar indentstr = offsetstr + self.indent * self.indentchar res += offsetstr + '"' + self.prefix + '": [' empty = True for p in self.path: empty = False res += self.linesep resi = '"%s' % (str(p)) res += indentstr + resi + '",' if empty: res += self.linesep + offsetstr + ']' else: res = res[:-1] + self.linesep + offsetstr + ']' if self.linesepfinal: return res + self.linesep else: return res def str_properties(self): """Creates the string for standard *INI* format. """ res = '' # self.assignchar = kargs.get("assignchar", '=') # self.format = kargs.get("format", 'print') # self.indent = kargs.get("indent", 4) # self.indent = kargs.get("indent", 4) # self.indentchar = kargs.get("indentchar", ' ') # self.indentclip = kargs.get("indentclip", 2) # self.keepentry = kargs.get("keepentry", True) # self.keepentry = kargs.get("keepentry", True) # self.linesep = kargs.get("linesep", os.linesep) # self.maxwidth = kargs.get("maxwidth", 80) # self.maxwidth = kargs.get("maxwidth", columns) # self.offset = kargs.get("offset", 4) # self.offsetchar = kargs.get("offsetchar", ' ') # self.overflow = kargs.get("overflow", 'clip') # self.overflow = kargs.get("overflow", 'ignore') # self.pathsepin = kargs.get("pathsepin", os.pathsep) # self.pathsepout = kargs.get("pathsepout", os.pathsep) # self.prefix = kargs.get("prefix", path.__name__) return res def str_xml(self): """Creates the string for standard *XML* format. """ res = '' offsetstr = self.offset * self.offsetchar indentstr = offsetstr + self.indent * self.indentchar res += offsetstr + '<' + self.prefix + '>' + self.linesep idx = 0 for p in self.path: resi = '<entry idx=' + str(idx) + '>' + '%s' % (str(p)) + '</entry>' res += indentstr + resi + self.linesep idx += 1 if self.linesepfinal: res += offsetstr + '</' + self.prefix + '>' + self.linesep else: res += offsetstr + '</' + self.prefix + '>' return res def str_yaml(self): """Creates the string for standard *INI* format. """ res = '' offsetstr = self.offset * self.offsetchar indentstr = offsetstr + self.indent * self.indentchar res += offsetstr + self.prefix + ':' for p in self.path: resi = '- ' + '%s' % (str(p)) res += self.linesep + indentstr + resi if self.linesepfinal: return res + self.linesep else: return res return res
[docs] def __repr__(self): return repr(self._raw)
def raw(self): return self._raw