Markup, whitespace, docstring and comments, code

This commit is contained in:
BlauFeuer 2017-02-20 02:32:01 -05:00 committed by GitHub
parent 37984adc58
commit 0dfac7f737

View file

@ -126,6 +126,7 @@ from evennia.utils.ansi import ANSIString
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
def _to_ansi(obj): def _to_ansi(obj):
""" """
convert to ANSIString. convert to ANSIString.
@ -142,6 +143,8 @@ def _to_ansi(obj):
_unicode = unicode _unicode = unicode
_whitespace = '\t\n\x0b\x0c\r ' _whitespace = '\t\n\x0b\x0c\r '
class ANSITextWrapper(TextWrapper): class ANSITextWrapper(TextWrapper):
""" """
This is a wrapper work class for handling strings with ANSI tags This is a wrapper work class for handling strings with ANSI tags
@ -158,8 +161,8 @@ class ANSITextWrapper(TextWrapper):
becomes " foo bar baz". becomes " foo bar baz".
""" """
return text return text
##TODO: Ignore expand_tabs/replace_whitespace until ANSISTring handles them. # TODO: Ignore expand_tabs/replace_whitespace until ANSIString handles them.
## - don't remove this code. /Griatch # - don't remove this code. /Griatch
# if self.expand_tabs: # if self.expand_tabs:
# text = text.expandtabs() # text = text.expandtabs()
# if self.replace_whitespace: # if self.replace_whitespace:
@ -169,7 +172,6 @@ class ANSITextWrapper(TextWrapper):
# text = text.translate(self.unicode_whitespace_trans) # text = text.translate(self.unicode_whitespace_trans)
# return text # return text
def _split(self, text): def _split(self, text):
"""_split(text : string) -> [string] """_split(text : string) -> [string]
@ -289,6 +291,7 @@ def wrap(text, width=_DEFAULT_WIDTH, **kwargs):
w = ANSITextWrapper(width=width, **kwargs) w = ANSITextWrapper(width=width, **kwargs)
return w.wrap(text) return w.wrap(text)
def fill(text, width=_DEFAULT_WIDTH, **kwargs): def fill(text, width=_DEFAULT_WIDTH, **kwargs):
"""Fill a single paragraph of text, returning a new string. """Fill a single paragraph of text, returning a new string.
@ -311,6 +314,7 @@ def fill(text, width=_DEFAULT_WIDTH, **kwargs):
# EvCell class (see further down for the EvTable itself) # EvCell class (see further down for the EvTable itself)
class EvCell(object): class EvCell(object):
""" """
Holds a single data cell for the table. A cell has a certain width Holds a single data cell for the table. A cell has a certain width
@ -384,7 +388,7 @@ class EvCell(object):
padwidth = int(padwidth) if padwidth is not None else None padwidth = int(padwidth) if padwidth is not None else None
self.pad_left = int(kwargs.get("pad_left", padwidth if padwidth is not None else 1)) self.pad_left = int(kwargs.get("pad_left", padwidth if padwidth is not None else 1))
self.pad_right = int(kwargs.get("pad_right", padwidth if padwidth is not None else 1)) self.pad_right = int(kwargs.get("pad_right", padwidth if padwidth is not None else 1))
self.pad_top = int( kwargs.get("pad_top", padwidth if padwidth is not None else 0)) self.pad_top = int(kwargs.get("pad_top", padwidth if padwidth is not None else 0))
self.pad_bottom = int(kwargs.get("pad_bottom", padwidth if padwidth is not None else 0)) self.pad_bottom = int(kwargs.get("pad_bottom", padwidth if padwidth is not None else 0))
self.enforce_size = kwargs.get("enforce_size", False) self.enforce_size = kwargs.get("enforce_size", False)
@ -429,7 +433,7 @@ class EvCell(object):
self.align = kwargs.get("align", "l") self.align = kwargs.get("align", "l")
self.valign = kwargs.get("valign", "c") self.valign = kwargs.get("valign", "c")
#self.data = self._split_lines(unicode(data)) # self.data = self._split_lines(unicode(data))
self.data = self._split_lines(_to_ansi(data)) self.data = self._split_lines(_to_ansi(data))
self.raw_width = max(m_len(line) for line in self.data) self.raw_width = max(m_len(line) for line in self.data)
self.raw_height = len(self.data) self.raw_height = len(self.data)
@ -442,20 +446,20 @@ class EvCell(object):
if "width" in kwargs: if "width" in kwargs:
width = kwargs.pop("width") width = kwargs.pop("width")
self.width = width - self.pad_left - self.pad_right - self.border_left - self.border_right self.width = width - self.pad_left - self.pad_right - self.border_left - self.border_right
if self.width <= 0 and self.raw_width > 0: if self.width <= 0 < self.raw_width:
raise Exception("Cell width too small - no space for data.") raise Exception("Cell width too small - no space for data.")
else: else:
self.width = self.raw_width self.width = self.raw_width
if "height" in kwargs: if "height" in kwargs:
height = kwargs.pop("height") height = kwargs.pop("height")
self.height = height - self.pad_top - self.pad_bottom - self.border_top - self.border_bottom self.height = height - self.pad_top - self.pad_bottom - self.border_top - self.border_bottom
if self.height <= 0 and self.raw_height > 0: if self.height <= 0 < self.raw_height:
raise Exception("Cell height too small - no space for data.") raise Exception("Cell height too small - no space for data.")
else: else:
self.height = self.raw_height self.height = self.raw_height
# prepare data # prepare data
#self.formatted = self._reformat() # self.formatted = self._reformat()
def _crop(self, text, width): def _crop(self, text, width):
""" """
@ -512,7 +516,7 @@ class EvCell(object):
if 0 < width < m_len(line): if 0 < width < m_len(line):
# replace_whitespace=False, expand_tabs=False is a # replace_whitespace=False, expand_tabs=False is a
# fix for ANSIString not supporting expand_tabs/translate # fix for ANSIString not supporting expand_tabs/translate
adjusted_data.extend([ANSIString(part + ANSIString("{n")) adjusted_data.extend([ANSIString(part + ANSIString("|n"))
for part in wrap(line, width=width, drop_whitespace=False)]) for part in wrap(line, width=width, drop_whitespace=False)])
else: else:
adjusted_data.append(line) adjusted_data.append(line)
@ -526,7 +530,7 @@ class EvCell(object):
adjusted_data[-1] = adjusted_data[-1][:-2] + ".." adjusted_data[-1] = adjusted_data[-1][:-2] + ".."
elif excess < 0: elif excess < 0:
# too few lines. Fill to height. # too few lines. Fill to height.
adjusted_data.extend(["" for i in range(excess)]) adjusted_data.extend(["" for _ in range(excess)])
return adjusted_data return adjusted_data
@ -577,10 +581,13 @@ class EvCell(object):
hfill_char = self.hfill_char hfill_char = self.hfill_char
width = self.width width = self.width
if align == "l": if align == "l":
lines= [(line.lstrip(" ") + " " if line.startswith(" ") and not line.startswith(" ") else line) + hfill_char * (width - m_len(line)) for line in data] lines = [(line.lstrip(" ") + " " if line.startswith(" ") and not line.startswith(" ")
else line) + hfill_char * (width - m_len(line)) for line in data]
return lines return lines
elif align == "r": elif align == "r":
return [hfill_char * (width - m_len(line)) + (" " + line.rstrip(" ") if line.endswith(" ") and not line.endswith(" ") else line) for line in data] return [hfill_char * (width - m_len(line)) + (" " + line.rstrip(" ")
if line.endswith(" ") and not line.endswith(" ")
else line) for line in data]
else: # center, 'c' else: # center, 'c'
return [self._center(line, self.width, self.hfill_char) for line in data] return [self._center(line, self.width, self.hfill_char) for line in data]
@ -605,11 +612,11 @@ class EvCell(object):
return data return data
# only care if we need to add new lines # only care if we need to add new lines
if valign == 't': if valign == 't':
return data + [padline for i in range(excess)] return data + [padline for _ in range(excess)]
elif valign == 'b': elif valign == 'b':
return [padline for i in range(excess)] + data return [padline for _ in range(excess)] + data
else: # center else: # center
narrowside = [padline for i in range(excess // 2)] narrowside = [padline for _ in range(excess // 2)]
widerside = narrowside + [padline] widerside = narrowside + [padline]
if excess % 2: if excess % 2:
# uneven padding # uneven padding
@ -635,8 +642,8 @@ class EvCell(object):
left = self.hpad_char * self.pad_left left = self.hpad_char * self.pad_left
right = self.hpad_char * self.pad_right right = self.hpad_char * self.pad_right
vfill = (self.width + self.pad_left + self.pad_right) * self.vpad_char vfill = (self.width + self.pad_left + self.pad_right) * self.vpad_char
top = [vfill for i in range(self.pad_top)] top = [vfill for _ in range(self.pad_top)]
bottom = [vfill for i in range(self.pad_bottom)] bottom = [vfill for _ in range(self.pad_bottom)]
return top + [left + line + right for line in data] + bottom return top + [left + line + right for line in data] + bottom
def _border(self, data): def _border(self, data):
@ -654,18 +661,17 @@ class EvCell(object):
left = self.border_left_char * self.border_left + ANSIString('|n') left = self.border_left_char * self.border_left + ANSIString('|n')
right = ANSIString('|n') + self.border_right_char * self.border_right right = ANSIString('|n') + self.border_right_char * self.border_right
cwidth = self.width + self.pad_left + self.pad_right + \ cwidth = self.width + self.pad_left + self.pad_right + max(0, self.border_left-1) + max(0, self.border_right-1)
max(0,self.border_left-1) + max(0, self.border_right-1)
vfill = self.corner_top_left_char if left else "" vfill = self.corner_top_left_char if left else ""
vfill += cwidth * self.border_top_char vfill += cwidth * self.border_top_char
vfill += self.corner_top_right_char if right else "" vfill += self.corner_top_right_char if right else ""
top = [vfill for i in range(self.border_top)] top = [vfill for _ in range(self.border_top)]
vfill = self.corner_bottom_left_char if left else "" vfill = self.corner_bottom_left_char if left else ""
vfill += cwidth * self.border_bottom_char vfill += cwidth * self.border_bottom_char
vfill += self.corner_bottom_right_char if right else "" vfill += self.corner_bottom_right_char if right else ""
bottom = [vfill for i in range(self.border_bottom)] bottom = [vfill for _ in range(self.border_bottom)]
return top + [left + line + right for line in data] + bottom return top + [left + line + right for line in data] + bottom
@ -699,7 +705,7 @@ class EvCell(object):
natural_height (int): Height of cell. natural_height (int): Height of cell.
""" """
return len(self.formatted) #if self.formatted else 0 return len(self.formatted) # if self.formatted else 0
def get_width(self): def get_width(self):
""" """
@ -709,7 +715,7 @@ class EvCell(object):
natural_width (int): Width of cell. natural_width (int): Width of cell.
""" """
return m_len(self.formatted[0]) #if self.formatted else 0 return m_len(self.formatted[0]) # if self.formatted else 0
def replace_data(self, data, **kwargs): def replace_data(self, data, **kwargs):
""" """
@ -723,7 +729,7 @@ class EvCell(object):
`EvCell.__init__`. `EvCell.__init__`.
""" """
#self.data = self._split_lines(unicode(data)) # self.data = self._split_lines(unicode(data))
self.data = self._split_lines(_to_ansi(data)) self.data = self._split_lines(_to_ansi(data))
self.raw_width = max(m_len(line) for line in self.data) self.raw_width = max(m_len(line) for line in self.data)
self.raw_height = len(self.data) self.raw_height = len(self.data)
@ -746,7 +752,7 @@ class EvCell(object):
padwidth = int(padwidth) if padwidth is not None else None padwidth = int(padwidth) if padwidth is not None else None
self.pad_left = int(kwargs.pop("pad_left", padwidth if padwidth is not None else self.pad_left)) self.pad_left = int(kwargs.pop("pad_left", padwidth if padwidth is not None else self.pad_left))
self.pad_right = int(kwargs.pop("pad_right", padwidth if padwidth is not None else self.pad_right)) self.pad_right = int(kwargs.pop("pad_right", padwidth if padwidth is not None else self.pad_right))
self.pad_top = int( kwargs.pop("pad_top", padwidth if padwidth is not None else self.pad_top)) self.pad_top = int(kwargs.pop("pad_top", padwidth if padwidth is not None else self.pad_top))
self.pad_bottom = int(kwargs.pop("pad_bottom", padwidth if padwidth is not None else self.pad_bottom)) self.pad_bottom = int(kwargs.pop("pad_bottom", padwidth if padwidth is not None else self.pad_bottom))
self.enforce_size = kwargs.get("enforce_size", False) self.enforce_size = kwargs.get("enforce_size", False)
@ -764,22 +770,34 @@ class EvCell(object):
self.vfill_char = vfill_char[0] if vfill_char else self.vfill_char self.vfill_char = vfill_char[0] if vfill_char else self.vfill_char
borderwidth = kwargs.get("border_width", None) borderwidth = kwargs.get("border_width", None)
self.border_left = kwargs.pop("border_left", borderwidth if borderwidth is not None else self.border_left) self.border_left = kwargs.pop(
self.border_right = kwargs.pop("border_right", borderwidth if borderwidth is not None else self.border_right) "border_left", borderwidth if borderwidth is not None else self.border_left)
self.border_top = kwargs.pop("border_top", borderwidth if borderwidth is not None else self.border_top) self.border_right = kwargs.pop(
self.border_bottom = kwargs.pop("border_bottom", borderwidth if borderwidth is not None else self.border_bottom) "border_right", borderwidth if borderwidth is not None else self.border_right)
self.border_top = kwargs.pop(
"border_top", borderwidth if borderwidth is not None else self.border_top)
self.border_bottom = kwargs.pop(
"border_bottom", borderwidth if borderwidth is not None else self.border_bottom)
borderchar = kwargs.get("border_char", None) borderchar = kwargs.get("border_char", None)
self.border_left_char = kwargs.pop("border_left_char", borderchar if borderchar else self.border_left_char) self.border_left_char = kwargs.pop(
self.border_right_char = kwargs.pop("border_right_char", borderchar if borderchar else self.border_right_char) "border_left_char", borderchar if borderchar else self.border_left_char)
self.border_top_char = kwargs.pop("border_topchar", borderchar if borderchar else self.border_top_char) self.border_right_char = kwargs.pop(
self.border_bottom_char = kwargs.pop("border_bottom_char", borderchar if borderchar else self.border_bottom_char) "border_right_char", borderchar if borderchar else self.border_right_char)
self.border_top_char = kwargs.pop(
"border_topchar", borderchar if borderchar else self.border_top_char)
self.border_bottom_char = kwargs.pop(
"border_bottom_char", borderchar if borderchar else self.border_bottom_char)
corner_char = kwargs.get("corner_char", None) corner_char = kwargs.get("corner_char", None)
self.corner_top_left_char = kwargs.pop("corner_top_left", corner_char if corner_char is not None else self.corner_top_left_char) self.corner_top_left_char = kwargs.pop(
self.corner_top_right_char = kwargs.pop("corner_top_right", corner_char if corner_char is not None else self.corner_top_right_char) "corner_top_left", corner_char if corner_char is not None else self.corner_top_left_char)
self.corner_bottom_left_char = kwargs.pop("corner_bottom_left", corner_char if corner_char is not None else self.corner_bottom_left_char) self.corner_top_right_char = kwargs.pop(
self.corner_bottom_right_char = kwargs.pop("corner_bottom_right", corner_char if corner_char is not None else self.corner_bottom_right_char) "corner_top_right", corner_char if corner_char is not None else self.corner_top_right_char)
self.corner_bottom_left_char = kwargs.pop(
"corner_bottom_left", corner_char if corner_char is not None else self.corner_bottom_left_char)
self.corner_bottom_right_char = kwargs.pop(
"corner_bottom_right", corner_char if corner_char is not None else self.corner_bottom_right_char)
# this is used by the table to adjust size of cells with borders in the middle # this is used by the table to adjust size of cells with borders in the middle
# of the table # of the table
@ -793,13 +811,16 @@ class EvCell(object):
# Handle sizes # Handle sizes
if "width" in kwargs: if "width" in kwargs:
width = kwargs.pop("width") width = kwargs.pop("width")
self.width = width - self.pad_left - self.pad_right - self.border_left - self.border_right + self.trim_horizontal self.width = width - self.pad_left - self.pad_right\
if self.width <= 0 and self.raw_width > 0: - self.border_left - self.border_right + self.trim_horizontal
# if self.width <= 0 and self.raw_width > 0:
if self.width <= 0 < self.raw_width:
raise Exception("Cell width too small, no room for data.") raise Exception("Cell width too small, no room for data.")
if "height" in kwargs: if "height" in kwargs:
height = kwargs.pop("height") height = kwargs.pop("height")
self.height = height - self.pad_top - self.pad_bottom - self.border_top - self.border_bottom + self.trim_vertical self.height = height - self.pad_top - self.pad_bottom\
if self.height <= 0 and self.raw_height > 0: - self.border_top - self.border_bottom + self.trim_vertical
if self.height <= 0 < self.raw_height:
raise Exception("Cell height too small, no room for data.") raise Exception("Cell height too small, no room for data.")
# reformat (to new sizes, padding, header and borders) # reformat (to new sizes, padding, header and borders)
@ -868,7 +889,7 @@ class EvColumn(object):
col = self.column col = self.column
kwargs.update(self.options) kwargs.update(self.options)
# use fixed width or adjust to the largest cell # use fixed width or adjust to the largest cell
if not "width" in kwargs: if "width" not in kwargs:
[cell.reformat() for cell in col] # this is necessary to get initial widths of all cells [cell.reformat() for cell in col] # this is necessary to get initial widths of all cells
kwargs["width"] = max(cell.get_width() for cell in col) if col else 0 kwargs["width"] = max(cell.get_width() for cell in col) if col else 0
[cell.reformat(**kwargs) for cell in col] [cell.reformat(**kwargs) for cell in col]
@ -900,11 +921,11 @@ class EvColumn(object):
ypos = min(len(self.column)-1, max(0, int(ypos))) ypos = min(len(self.column)-1, max(0, int(ypos)))
new_cells = [EvCell(data, **self.options) for data in args] new_cells = [EvCell(data, **self.options) for data in args]
self.column = self.column[:ypos] + new_cells + self.column[ypos:] self.column = self.column[:ypos] + new_cells + self.column[ypos:]
#self._balance(**kwargs) # self._balance(**kwargs)
def reformat(self, **kwargs): def reformat(self, **kwargs):
""" """
Change the options for the collumn. Change the options for the column.
Kwargs: Kwargs:
Keywords as per `EvCell.__init__`. Keywords as per `EvCell.__init__`.
@ -930,19 +951,24 @@ class EvColumn(object):
def __repr__(self): def __repr__(self):
return "<EvColumn\n %s>" % ("\n ".join([repr(cell) for cell in self.column])) return "<EvColumn\n %s>" % ("\n ".join([repr(cell) for cell in self.column]))
def __len__(self): def __len__(self):
return len(self.column) return len(self.column)
def __iter__(self): def __iter__(self):
return iter(self.column) return iter(self.column)
def __getitem__(self, index): def __getitem__(self, index):
return self.column[index] return self.column[index]
def __setitem__(self, index, value): def __setitem__(self, index, value):
self.column[index] = value self.column[index] = value
def __delitem__(self, index): def __delitem__(self, index):
del self.column[index] del self.column[index]
## Main Evtable class # Main Evtable class
class EvTable(object): class EvTable(object):
""" """
@ -998,7 +1024,7 @@ class EvTable(object):
height (int, optional): Fixed height of table. Defaults to being unset. Width is height (int, optional): Fixed height of table. Defaults to being unset. Width is
still given precedence. If given, table cells will crop text rather still given precedence. If given, table cells will crop text rather
than expand vertically. than expand vertically.
evenwidth (bool, optional): Used with the `width` keyword. Adjusts collumns to have as even width as evenwidth (bool, optional): Used with the `width` keyword. Adjusts columns to have as even width as
possible. This often looks best also for mixed-length tables. Default is `False`. possible. This often looks best also for mixed-length tables. Default is `False`.
maxwidth (int, optional): This will set a maximum width maxwidth (int, optional): This will set a maximum width
of the table while allowing it to be smaller. Only if it grows wider than this of the table while allowing it to be smaller. Only if it grows wider than this
@ -1025,10 +1051,10 @@ class EvTable(object):
excess = len(header) - len(table) excess = len(header) - len(table)
if excess > 0: if excess > 0:
# header bigger than table # header bigger than table
table.extend([] for i in range(excess)) table.extend([] for _ in range(excess))
elif excess < 0: elif excess < 0:
# too short header # too short header
header.extend(_to_ansi(["" for i in range(abs(excess))])) header.extend(_to_ansi(["" for _ in range(abs(excess))]))
for ix, heading in enumerate(header): for ix, heading in enumerate(header):
table[ix].insert(0, heading) table[ix].insert(0, heading)
else: else:
@ -1043,7 +1069,7 @@ class EvTable(object):
border = kwargs.pop("border", "tablecols") border = kwargs.pop("border", "tablecols")
if border is None: if border is None:
border = "none" border = "none"
if not border in ("none", "table", "tablecols", if border not in ("none", "table", "tablecols",
"header", "incols", "cols", "rows", "cells"): "header", "incols", "cols", "rows", "cells"):
raise Exception("Unsupported border type: '%s'" % border) raise Exception("Unsupported border type: '%s'" % border)
self.border = border self.border = border
@ -1052,10 +1078,14 @@ class EvTable(object):
self.border_width = kwargs.get("border_width", 1) self.border_width = kwargs.get("border_width", 1)
self.corner_char = kwargs.get("corner_char", "+") self.corner_char = kwargs.get("corner_char", "+")
pcorners = kwargs.pop("pretty_corners", False) pcorners = kwargs.pop("pretty_corners", False)
self.corner_top_left_char = _to_ansi(kwargs.pop("corner_top_left_char", '.' if pcorners else self.corner_char)) self.corner_top_left_char = _to_ansi(kwargs.pop(
self.corner_top_right_char = _to_ansi(kwargs.pop("corner_top_right_char", '.' if pcorners else self.corner_char)) "corner_top_left_char", '.' if pcorners else self.corner_char))
self.corner_bottom_left_char = _to_ansi(kwargs.pop("corner_bottom_left_char", ' ' if pcorners else self.corner_char)) self.corner_top_right_char = _to_ansi(kwargs.pop(
self.corner_bottom_right_char = _to_ansi(kwargs.pop("corner_bottom_right_char", ' ' if pcorners else self.corner_char)) "corner_top_right_char", '.' if pcorners else self.corner_char))
self.corner_bottom_left_char = _to_ansi(kwargs.pop(
"corner_bottom_left_char", ' ' if pcorners else self.corner_char))
self.corner_bottom_right_char = _to_ansi(kwargs.pop(
"corner_bottom_right_char", ' ' if pcorners else self.corner_char))
self.width = kwargs.pop("width", None) self.width = kwargs.pop("width", None)
self.height = kwargs.pop("height", None) self.height = kwargs.pop("height", None)
@ -1079,7 +1109,7 @@ class EvTable(object):
self.worktable = None self.worktable = None
# balance the table # balance the table
#self._balance() # self._balance()
def _cellborders(self, ix, iy, nx, ny, **kwargs): def _cellborders(self, ix, iy, nx, ny, **kwargs):
""" """
@ -1114,7 +1144,7 @@ class EvTable(object):
headchar = self.header_line_char headchar = self.header_line_char
def corners(ret): def corners(ret):
"Handle corners of table" """Handle corners of table"""
if ix == 0 and iy == 0: if ix == 0 and iy == 0:
ret["corner_top_left_char"] = self.corner_top_left_char ret["corner_top_left_char"] = self.corner_top_left_char
if ix == nx and iy == 0: if ix == nx and iy == 0:
@ -1126,47 +1156,47 @@ class EvTable(object):
return ret return ret
def left_edge(ret): def left_edge(ret):
"add vertical border along left table edge" """add vertical border along left table edge"""
if ix == 0: if ix == 0:
ret["border_left"] = bwidth ret["border_left"] = bwidth
#ret["trim_horizontal"] = bwidth # ret["trim_horizontal"] = bwidth
return ret return ret
def top_edge(ret): def top_edge(ret):
"add border along top table edge" """add border along top table edge"""
if iy == 0: if iy == 0:
ret["border_top"] = bwidth ret["border_top"] = bwidth
#ret["trim_vertical"] = bwidth # ret["trim_vertical"] = bwidth
return ret return ret
def right_edge(ret): def right_edge(ret):
"add vertical border along right table edge" """add vertical border along right table edge"""
if ix == nx:# and 0 < iy < ny: if ix == nx: # and 0 < iy < ny:
ret["border_right"] = bwidth ret["border_right"] = bwidth
#ret["trim_horizontal"] = 0 # ret["trim_horizontal"] = 0
return ret return ret
def bottom_edge(ret): def bottom_edge(ret):
"add border along bottom table edge" """add border along bottom table edge"""
if iy == ny: if iy == ny:
ret["border_bottom"] = bwidth ret["border_bottom"] = bwidth
#ret["trim_vertical"] = bwidth # ret["trim_vertical"] = bwidth
return ret return ret
def cols(ret): def cols(ret):
"Adding vertical borders inside the table" """Adding vertical borders inside the table"""
if 0 <= ix < nx: if 0 <= ix < nx:
ret["border_right"] = bwidth ret["border_right"] = bwidth
return ret return ret
def rows(ret): def rows(ret):
"Adding horizontal borders inside the table" """Adding horizontal borders inside the table"""
if 0 <= iy < ny: if 0 <= iy < ny:
ret["border_bottom"] = bwidth ret["border_bottom"] = bwidth
return ret return ret
def head(ret): def head(ret):
"Add header underline" """Add header underline"""
if iy == 0: if iy == 0:
# put different bottom line for header # put different bottom line for header
ret["border_bottom"] = bwidth ret["border_bottom"] = bwidth
@ -1176,15 +1206,15 @@ class EvTable(object):
# use the helper functions to define various # use the helper functions to define various
# table "styles" # table "styles"
if border in ("table", "tablecols","cells"): if border in ("table", "tablecols", "cells"):
ret = bottom_edge(right_edge(top_edge(left_edge(corners(ret))))) ret = bottom_edge(right_edge(top_edge(left_edge(corners(ret)))))
if border in ("cols", "tablecols", "cells"): if border in ("cols", "tablecols", "cells"):
ret = cols(right_edge(left_edge(ret))) ret = cols(right_edge(left_edge(ret)))
if border in ("incols"): if border in "incols":
ret = cols(ret) ret = cols(ret)
if border in ("rows", "cells"): if border in ("rows", "cells"):
ret = rows(bottom_edge(top_edge(ret))) ret = rows(bottom_edge(top_edge(ret)))
if header and not border in ("none", None): if header and border not in ("none", None):
ret = head(ret) ret = head(ret)
return ret return ret
@ -1197,7 +1227,7 @@ class EvTable(object):
options = self.options options = self.options
for ix, col in enumerate(self.worktable): for ix, col in enumerate(self.worktable):
for iy, cell in enumerate(col): for iy, cell in enumerate(col):
col.reformat_cell(iy, **self._cellborders(ix,iy,nx,ny,**options)) col.reformat_cell(iy, **self._cellborders(ix, iy, nx, ny, **options))
def _balance(self): def _balance(self):
""" """
@ -1222,7 +1252,7 @@ class EvTable(object):
self.worktable[icol].reformat(**options) self.worktable[icol].reformat(**options)
if nrow < nrowmax: if nrow < nrowmax:
# add more rows to too-short columns # add more rows to too-short columns
empty_rows = ["" for i in range(nrowmax-nrow)] empty_rows = ["" for _ in range(nrowmax-nrow)]
self.worktable[icol].add_rows(*empty_rows) self.worktable[icol].add_rows(*empty_rows)
self.ncols = ncols self.ncols = ncols
self.nrows = nrowmax self.nrows = nrowmax
@ -1251,16 +1281,16 @@ class EvTable(object):
excess = width - cwmin excess = width - cwmin
if self.evenwidth: if self.evenwidth:
# make each collumn of equal width # make each column of equal width
for i in range(excess): for _ in range(excess):
# flood-fill the minimum table starting with the smallest collumns # flood-fill the minimum table starting with the smallest columns
ci = cwidths_min.index(min(cwidths_min)) ci = cwidths_min.index(min(cwidths_min))
cwidths_min[ci] += 1 cwidths_min[ci] += 1
cwidths = cwidths_min cwidths = cwidths_min
else: else:
# make each collumn expand more proportional to their data size # make each column expand more proportional to their data size
for i in range(excess): for _ in range(excess):
# fill wider collumns first # fill wider columns first
ci = cwidths.index(max(cwidths)) ci = cwidths.index(max(cwidths))
cwidths_min[ci] += 1 cwidths_min[ci] += 1
cwidths[ci] -= 3 cwidths[ci] -= 3
@ -1280,8 +1310,9 @@ class EvTable(object):
# if we are fixing the table height, it means cells must crop text instead of resizing. # if we are fixing the table height, it means cells must crop text instead of resizing.
if nrowmax: if nrowmax:
# get minimum possible cell heights for each collumn # get minimum possible cell heights for each column
cheights_min = [max(cell.get_min_height() for cell in (col[iy] for col in self.worktable)) for iy in range(nrowmax)] cheights_min = [max(cell.get_min_height()
for cell in (col[iy] for col in self.worktable)) for iy in range(nrowmax)]
chmin = sum(cheights_min) chmin = sum(cheights_min)
if chmin > self.height: if chmin > self.height:
@ -1294,9 +1325,9 @@ class EvTable(object):
excess = self.height - chmin excess = self.height - chmin
even = self.height % 2 == 0 even = self.height % 2 == 0
for i in range(excess): for position in range(excess):
# expand the cells with the most rows first # expand the cells with the most rows first
if 0 <= i < nrowmax and nrowmax > 1: if 0 <= position < nrowmax and nrowmax > 1:
# avoid adding to header first round (looks bad on very small tables) # avoid adding to header first round (looks bad on very small tables)
ci = cheights[1:].index(max(cheights[1:])) + 1 ci = cheights[1:].index(max(cheights[1:])) + 1
else: else:
@ -1318,7 +1349,7 @@ class EvTable(object):
col.reformat_cell(iy, height=cheights[iy], **options) col.reformat_cell(iy, height=cheights[iy], **options)
except Exception as e: except Exception as e:
msg = "ix=%s, iy=%s, height=%s: %s" % (ix, iy, cheights[iy], e.message) msg = "ix=%s, iy=%s, height=%s: %s" % (ix, iy, cheights[iy], e.message)
raise Exception ("Error in vertical allign:\n %s" % msg) raise Exception("Error in vertical align:\n %s" % msg)
# calculate actual table width/height in characters # calculate actual table width/height in characters
self.cwidth = sum(cwidths) self.cwidth = sum(cwidths)
@ -1387,12 +1418,12 @@ class EvTable(object):
if excess > 0: if excess > 0:
# we need to add new rows to table # we need to add new rows to table
for col in self.table: for col in self.table:
empty_rows = ["" for i in range(excess)] empty_rows = ["" for _ in range(excess)]
col.add_rows(*empty_rows, **options) col.add_rows(*empty_rows, **options)
self.nrows += excess self.nrows += excess
elif excess < 0: elif excess < 0:
# we need to add new rows to new column # we need to add new rows to new column
empty_rows = ["" for i in range(abs(excess))] empty_rows = ["" for _ in range(abs(excess))]
column.add_rows(*empty_rows, **options) column.add_rows(*empty_rows, **options)
self.nrows -= excess self.nrows -= excess
@ -1411,7 +1442,7 @@ class EvTable(object):
xpos = min(wtable-1, max(0, int(xpos))) xpos = min(wtable-1, max(0, int(xpos)))
self.table.insert(xpos, column) self.table.insert(xpos, column)
self.ncols += 1 self.ncols += 1
#self._balance() # self._balance()
def add_row(self, *args, **kwargs): def add_row(self, *args, **kwargs):
""" """
@ -1444,12 +1475,12 @@ class EvTable(object):
if excess > 0: if excess > 0:
# we need to add new empty columns to table # we need to add new empty columns to table
empty_rows = ["" for i in range(htable)] empty_rows = ["" for _ in range(htable)]
self.table.extend([EvColumn(*empty_rows, **options) for i in range(excess)]) self.table.extend([EvColumn(*empty_rows, **options) for _ in range(excess)])
self.ncols += excess self.ncols += excess
elif excess < 0: elif excess < 0:
# we need to add more cells to row # we need to add more cells to row
row.extend(["" for i in range(abs(excess))]) row.extend(["" for _ in range(abs(excess))])
self.ncols -= excess self.ncols -= excess
if ypos is None or ypos > htable - 1: if ypos is None or ypos > htable - 1:
@ -1462,7 +1493,7 @@ class EvTable(object):
for icol, col in enumerate(self.table): for icol, col in enumerate(self.table):
col.add_rows(row[icol], ypos=ypos, **options) col.add_rows(row[icol], ypos=ypos, **options)
self.nrows += 1 self.nrows += 1
#self._balance() # self._balance()
def reformat(self, **kwargs): def reformat(self, **kwargs):
""" """
@ -1523,16 +1554,17 @@ class EvTable(object):
return [line for line in self._generate_lines()] return [line for line in self._generate_lines()]
def __str__(self): def __str__(self):
"print table (this also balances it)" """print table (this also balances it)"""
return str(unicode(ANSIString("\n").join([line for line in self._generate_lines()]))) return str(unicode(ANSIString("\n").join([line for line in self._generate_lines()])))
def __unicode__(self): def __unicode__(self):
return unicode(ANSIString("\n").join([line for line in self._generate_lines()])) return unicode(ANSIString("\n").join([line for line in self._generate_lines()]))
def _test(): def _test():
"Test" """Test"""
table = EvTable("{yHeading1{n", "{gHeading2{n", table=[[1,2,3],[4,5,6],[7,8,9]], border="cells", align="l") table = EvTable("|yHeading1|n", "|gHeading2|n", table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], border="cells", align="l")
table.add_column("{rThis is long data{n", "{bThis is even longer data{n") table.add_column("|rThis is long data|n", "|bThis is even longer data|n")
table.add_row("This is a single row") table.add_row("This is a single row")
print(unicode(table)) print(unicode(table))
table.reformat(width=50) table.reformat(width=50)
@ -1540,6 +1572,3 @@ def _test():
table.reformat_column(3, width=30, align='r') table.reformat_column(3, width=30, align='r')
print(unicode(table)) print(unicode(table))
return table return table