pibootctl.formatter

The pibootctl.formatter module contains some generic text formatting routines, including the TableWrapper class (akin to TextWrapper but specific to table output), TransMap for partially formatting templates, and the render() function: a crude markup renderer.

class pibootctl.formatter.TableWrapper(width=70, header_rows=1, footer_rows=0, cell_separator=' ', internal_line='-', internal_separator=' ', borders=('', '', '', ''), corners=('', '', '', ''), internal_borders=('', '', '', ''), align=None, format=None)[source]

Similar to TextWrapper, this class provides facilities for wrapping text to a particular width, but with a focus on table-based output.

The constructor takes numerous arguments, but typically you don’t need to specify them all (or at all). A series of dictionaries are provided with “common” configurations: pretty_table, curvy_table, unicode_table, and curvy_unicode_table. For example:

>>> from pibootctl.formatter import *
>>> wrapper = TableWrapper(width=80, **curvy_table)
>>> data = [
... ('Name', 'Length', 'Position'),
... ('foo', 3, 1),
... ('bar', 3, 2),
... ('baz', 3, 3),
... ('quux', 4, 4)]
>>> print(wrapper.fill(data))
,------+--------+----------.
| Name | Length | Position |
|------+--------+----------|
| foo  | 3      | 1        |
| bar  | 3      | 2        |
| baz  | 3      | 3        |
| quux | 4      | 4        |
`------+--------+----------'

The TableWrapper instance attributes (and keyword arguments to the constructor) are as follows:

width

(default 70) The maximum number of characters that the table can take up horizontally. TableWrapper guarantees that no output line will be longer than width characters.

header_rows

(default 1) The number of rows at the top of the table that will be separated from the following rows by a horizontal border (internal_line).

footer_rows

(default 0) The number of rows at the bottom of the table that will be separated from the preceding rows by a horizontal border (internal_line).

cell_separator

(default ' ') The string used to separate columns of cells.

internal_line

(default '-') The string used to draw horizontal lines inside the table for header_rows and footer_rows.

internal_separator

(default ' ') The string used within runs of internal_line to separate columns.

borders

(default ('', '', '', '')) A 4-tuple of strings which specify the characters used to create the left, top, right, and bottom borders of the table respectively.

corners

(default ('', '', '', '')) A 4-tuple of strings which specify the characters used for the top-left, top-right, bottom-right, and bottom-left corners of the table respectively.

internal_borders

(default ('', '', '', '')) A 4-tuple of strings which specify the characters used to interrupt runs of the borders characters to draw row and column separators. Like borders these are the left, top, right, and bottom characters respectively.

align

A callable accepting three parameters: 0-based row index, 0-based column index, and the cell data. The callable must return a character indicating the intended alignment of data within the cell. “<” for left justification, “^” for centered alignment, and “>” for right justification (as in str.format()). The default is to left align everything.

format

A callable accepting three parameters: 0-based row index, 0-based column index, and the cell data. The callable must return the desired string representation of the cell data. The default simply calls str on everything.

TableWrapper also provides similar public methods to TextWrapper:

wrap(data)[source]

Wraps the table data returning a list of output lines without final newlines. data must be a sequence of row tuples, each of which is assumed to be the same length.

If the current width does not permit at least a single character per column (after taking account of the width of borders, internal separators, etc.) then ValueError will be raised.

fill(data)[source]

Wraps the table data returning a string containing the wrapped output.

pibootctl.formatter.pretty_table

Uses simple ASCII characters to produce a typical “box-like” table appearance:

>>> from pibootctl.formatter import *
>>> wrapper = TableWrapper(width=80, **pretty_table)
>>> data = [
... ('Name', 'Length', 'Position'),
... ('foo', 3, 1),
... ('bar', 3, 2),
... ('baz', 3, 3),
... ('quux', 4, 4)]
>>> print(wrapper.fill(data))
+------+--------+----------+
| Name | Length | Position |
|------+--------+----------|
| foo  | 3      | 1        |
| bar  | 3      | 2        |
| baz  | 3      | 3        |
| quux | 4      | 4        |
+------+--------+----------+
pibootctl.formatter.curvy_table

Uses simple ASCII characters to produce a “round-edged” table appearance:

>>> from pibootctl.formatter import *
>>> wrapper = TableWrapper(width=80, **curvy_table)
>>> data = [
... ('Name', 'Length', 'Position'),
... ('foo', 3, 1),
... ('bar', 3, 2),
... ('baz', 3, 3),
... ('quux', 4, 4)]
>>> print(wrapper.fill(data))
,------+--------+----------.
| Name | Length | Position |
|------+--------+----------|
| foo  | 3      | 1        |
| bar  | 3      | 2        |
| baz  | 3      | 3        |
| quux | 4      | 4        |
`------+--------+----------'
pibootctl.formatter.unicode_table

Uses unicode box-drawing characters to produce a typical “box-like” table appearance:

>>> from pibootctl.formatter import *
>>> wrapper = TableWrapper(width=80, **unicode_table)
>>> data = [
... ('Name', 'Length', 'Position'),
... ('foo', 3, 1),
... ('bar', 3, 2),
... ('baz', 3, 3),
... ('quux', 4, 4)]
>>> print(wrapper.fill(data))
┌──────┬────────┬──────────┐
│ Name │ Length │ Position │
├──────┼────────┼──────────┤
│ foo  │ 3      │ 1        │
│ bar  │ 3      │ 2        │
│ baz  │ 3      │ 3        │
│ quux │ 4      │ 4        │
└──────┴────────┴──────────┘
pibootctl.formatter.curvy_unicode_table

Uses unicode box-drawing characters to produce a “round-edged” table appearance:

>>> from pibootctl.formatter import *
>>> wrapper = TableWrapper(width=80, **curvy_unicode_table)
>>> data = [
... ('Name', 'Length', 'Position'),
... ('foo', 3, 1),
... ('bar', 3, 2),
... ('baz', 3, 3),
... ('quux', 4, 4)]
>>> print(wrapper.fill(data))
╭──────┬────────┬──────────╮
│ Name │ Length │ Position │
├──────┼────────┼──────────┤
│ foo  │ 3      │ 1        │
│ bar  │ 3      │ 2        │
│ baz  │ 3      │ 3        │
│ quux │ 4      │ 4        │
╰──────┴────────┴──────────╯
class pibootctl.formatter.TransMap(**kw)[source]

Used with str.format_map() to substitute only a subset of values in a given template, passing the rest through for later processing. For example:

>>> '{foo}{bar}'.format_map(TransMap(foo=1))
'1{bar}'
>>> '{foo:02d}{bar:02d}{baz:02d}'.format_map(TransMap(foo=1, baz=3))
'01{bar:02d}03'

Note

One exception is that the !a conversion is not handled correctly. This is erroneously converted to !r. Unfortunately there’s no solution to this; it’s a side-effect of the means by which the !a conversion is performed.

class pibootctl.formatter.FormatDict(data, key_title='Key', value_title='Value', sort_key=None)[source]

Used to format data, a dict, in a format acceptable as input to the render() function. The key_title and value_title strings provide the cells for the single header row.

This class is intended to be used within a string for str.format(). For example:

>>> from pibootctl.formatter import FormatDict
>>> d = {'foo': 100, 'bar': 200}
>>> print('An example table:\n\n{s}'.format(s=FormatDict(d)))
An example table:

| Key | Value |
| foo | 100 |
| bar | 200 |

The format specification in the format string can be used to request different kinds of output, for instance:

>>> f = FormatDict({'foo': 100, 'bar': 200})
>>> print('An example list:\n\n{f:list}'.format(f=f))
An example list:

* foo = 100
* bar = 200
>>> print('An example reference list:\n\n{f:refs}'.format(f=f))
An example reference list:

[foo]: 100
[bar]: 200

The default format specification is “table”, naturally.

If the values are tuples that should be expanded into multiple columns, set value_title to a tuple with the corresponding column titles:

>>> from pibootctl.formatter import FormatDict
>>> d = {'foo': (1, 100), 'bar': (2, 200)}
>>> print('An example table:\n\n{s}'.format(s=FormatDict(d,
... value_title=('col1', 'col2'))))
An example table:

| Key | col1 | col2 |
| foo | 1 | 100 |
| bar | 2 | 200 |

Tuple values are only supported for table output.

Note

In Python versions before 3.7, you may need to use collections.OrderedDict to ensure output of the elements of data in a particular order. Alternatively, you may specify a sort_key value which will be applied to the key values of the dict to sort them prior to output.

pibootctl.formatter.int_ranges(values, range_sep='-', list_sep=', ')[source]

Given a set of integer values, returns a compressed string representation of all values in the set. For example:

>>> int_ranges({1, 2})
'1, 2'
>>> int_ranges({1, 2, 3})
'1-3'
>>> int_ranges({1, 2, 3, 4, 8})
'1-4, 8'
>>> int_ranges({1, 2, 3, 4, 8, 9})
'1-4, 8-9'

range_sep and list_sep can be optionally specified to customize the strings used to separate ranges and lists of ranges respectively.

pibootctl.formatter.render(text, width=70, list_space=False, table_style=None)[source]

A crude renderer for a crude markup language intended for formatting documentation for the console.

The markup recognized by this routine is as follows:

* Paragraphs must be separated by at least one blank line. They will be
  wrapped to *width*.

* Items in bulleted lists must start with an asterisk. No list nesting
  is permitted, but items may span several lines (without blank lines
  between them). Items will be wrapped to *width* and indented
  appropriately.

* Lines beginning and ending with a pipe character are assumed to be
  table rows. Pipe characters also delimit columns within the row. The
  first row is assumed to be a header row and will be separated from
  the rest.

An example table is shown below:

| Command | Description |
| cd | changes the current directory |
| ls | lists the content of a directory |
| cp | copies files |
| mv | renames files |
| rm | removes files |