terminaltables
Renders ASCII, Unicode box-drawing, and GitHub-flavored Markdown tables in the terminal from nested lists of strings.
Repository Health
Technical Analysis
terminaltables is a small, dependency-light Python library for drawing tables in terminal and console applications. Given a nested list of strings, it produces aligned, bordered output using one of several renderers: plain ASCII, Unix box-drawing characters, Windows Code Page 437 box characters, a double-lined variant, a borderless “porcelain” style for piping into other tools, and a GitHub-flavored Markdown table for use in READMEs and issues.
Under the hood it handles the parts that make terminal table rendering fiddly: measuring column widths across multi-line cells, wrapping and padding content, honoring per-column left/right/center justification, and detecting the current terminal width so callers can decide whether a table fits or needs to be resized. Each table class subclasses a shared BaseTable/AsciiTable hierarchy, so custom border styles can be built by overriding a small set of class-level character constants rather than reimplementing layout logic.
This package is a maintained fork of the original, now-archived terminaltables project (by Robpol86). It keeps the same public API — AsciiTable, SingleTable, DoubleTable, GithubFlavoredMarkdownTable, and PorcelainTable — so existing code that imports terminaltables continues to work, while the fork adds type annotations, drops Python 2 support, and responds to community pull requests that the original repository no longer accepts.
What You Get
- Five table renderers in one package:
AsciiTable,SingleTable(Unix box-drawing),DoubleTable,GithubFlavoredMarkdownTable, andPorcelainTable(no borders, pipe-friendly) - Automatic column-width and row-height calculation across multi-line cell content, including proper wrapping of embedded newlines
- Per-column justification (
left/right/center) via a simplejustify_columnsdict keyed by column index - Terminal-width awareness:
table_width,column_max_width(), and anokproperty to check whether a rendered table will fit the current console - Configurable borders and padding — toggle inner column borders, heading/footing separators, row separators, outer border, and left/right cell padding independently
- Cross-platform rendering: correct box-drawing characters for both Unix terminals and Windows consoles (Code Page 437)
Common Use Cases
- Printing structured CLI output — status summaries, config dumps, or command results — as readable aligned tables instead of raw text
- Formatting tabular data (query results, log summaries, diff reports) for terminal-based dev tools and scripts
- Generating GitHub-flavored Markdown tables programmatically for auto-generated README sections or issue/PR templates
- Producing borderless, delimiter-free output with
PorcelainTablefor piping into other command-line tools
Under The Hood
Architecture
The library is organized as a small class hierarchy rooted in BaseTable (base_table.py), which defines the generic line-generation logic — gen_table() walks each row, decides whether it needs a heading/footing/row separator, and delegates to gen_row_lines() to align and pad every cell before joining them with the correct vertical border characters. AsciiTable (ascii_table.py) builds on this with convenience properties (table_width, column_widths, ok) that call into width_and_alignment.py’s max_dimensions() and table_width() helpers. Border styling for every other table variant (SingleTable, DoubleTable, UnixTable, WindowsTable, PorcelainTable, GithubFlavoredMarkdownTable in other_tables.py and github_table.py) is expressed purely as overrides of a set of CHAR_* class constants, so adding a new visual style requires no new layout code — only a new subclass with different characters. Changing the core gen_table()/gen_row_lines() contract in base_table.py would ripple through every subclass since they all depend on the same border-character dispatch table.
Tech Stack
Pure Python with no runtime dependencies — pyproject.toml (Poetry-managed, package name terminaltables3, Python 3.8+) declares only development/test dependencies: pytest, pytest-cov, tox, mypy, ruff, black, pylint, bandit, and pre-commit for linting/formatting, plus colorama/colorclass/termcolor as optional complementary libraries for colored cell content. Terminal-size and Windows console-buffer detection in terminal_io.py uses ctypes to call the Win32 GetConsoleScreenBufferInfo API directly on Windows, falling back to standard os/shutil terminal APIs elsewhere. Tox drives the Python 3.8–3.13 test matrix.
Code Quality
The project has a dedicated tests/ tree with per-module test directories (test_base_table, test_build, test_width_and_alignment, test_terminal_io) plus end-to-end tests (test_all_tables_e2e) and example-script tests, run via pytest with coverage reporting (--cov-report term-missing --cov-report xml) and pytest-randomly/pytest-xdist for randomized, parallelized runs. Source is type-annotated (function signatures use typing.Sequence, Optional, Generator, Tuple) and checked with mypy, plus ruff, pylint, black, and bandit configured via .pre-commit-config.yaml, giving the codebase a linted, typed, and CI-checked baseline (GitHub Actions workflow in .github/workflows/build.yml).
What Makes It Unique Rather than one monolithic table renderer, the design isolates every visual style — ASCII, Unix/Windows box-drawing, double-line, GitHub Markdown, borderless “porcelain” — as thin subclasses that override only border characters, keeping layout and wrapping logic in one place. As an actively maintained fork of an archived, unmaintained original, its main value beyond the base project is drop-in API compatibility combined with an ongoing type-annotation effort and Python 2 removal, aimed squarely at keeping older codebases building against a still-supported terminal-table library.