Add in initial renderer code for CLI table formatting.

This commit is contained in:
Mike Auty
2019-04-01 00:07:50 +01:00
parent d44049121f
commit 301fac91ac
2 changed files with 60 additions and 4 deletions
+59 -3
View File
@@ -20,6 +20,8 @@
import datetime
import logging
import random
import string
import sys
from typing import Callable, Any
@@ -115,9 +117,6 @@ class QuickTextRenderer(interfaces.renderers.Renderer):
'default': Optional(lambda x: "{}".format(x))
}
def __init__(self, options = None) -> None:
super().__init__(options)
def get_render_options(self):
pass
@@ -155,3 +154,60 @@ class QuickTextRenderer(interfaces.renderers.Renderer):
grid.populate(visitor, outfd)
outfd.write("\n")
class PrettyTextRenderer(interfaces.renderers.Renderer):
type_renderers = QuickTextRenderer.type_renderers
def get_render_options(self):
pass
def render(self, grid: interfaces.renderers.TreeGrid) -> None:
"""
Renders each column immediately to stdout.
This does not format each line's width appropriately, it merely tab separates each field
Args:
grid: The TreeGrid object to render
"""
# TODO: Docstrings
# TODO: Improve text output
outfd = sys.stdout
outfd.write("Formatting...\r")
display_alignment = ">"
column_separator = " | "
tree_indent_column = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(20))
max_column_widths = dict([(column, len(column.name)) for column in grid.columns])
def visitor(node, accumulator):
# Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case
max_column_widths[tree_indent_column] = max(max_column_widths.get(tree_indent_column, 0), node.path_depth)
line = {}
for column in grid.columns:
renderer = self.type_renderers.get(column.type, self.type_renderers['default'])
data = renderer(node.values[column.index])
max_column_widths[column] = max(max_column_widths.get(column, 0), len(data))
line[column] = data
accumulator.append((node.path_depth, line))
return accumulator
final_output = []
grid.populate(visitor, final_output)
# Always align the tree to the left
format_string = ["{0:<" + str(max_column_widths[tree_indent_column]) + "s}"]
for column in grid.columns:
format_string.append("{" + str(column.index + 1) + ":" + display_alignment +
str(max_column_widths[column]) + "s}")
format_string = column_separator.join(format_string) + "\n"
column_titles = [""] + [column.name for column in grid.columns]
outfd.write(format_string.format(*column_titles))
for (depth, line) in final_output:
outfd.write(format_string.format("*" * depth, *[line[x] for x in line]))
+1 -1
View File
@@ -34,7 +34,7 @@ RenderOption = Any
class Renderer(metaclass = ABCMeta):
"""Class that defines the interface that all output renderers must support"""
def __init__(self, options: List[RenderOption]) -> None:
def __init__(self, options: Optional[List[RenderOption]] = None) -> None:
"""Accepts an options object to configure the renderers"""
# FIXME: Once the config option objects are in place, put the _type_check in place