Changes coming to Text::Table::Tiny

tables Tue 6 August 2019

Text::Table::Tiny is a simple module for generating ASCII tables from array data. I use it in lots of places, which is why I adopted it, and have evolved it. This post describes changes I'm working on, to give people a chance to comment, before the changes are locked in.

Note: I plan to keep this module conceptually simple: you pass an array which is then put into a simple 2D grid, with no cells spanning columns or rows. There are plenty of other table modules if you want something more complex.

Current features

The module provides a single function, which takes an arrayref of rows, and a few optional parameters:

use Text::Table::Tiny qw/ generate_table /;

my @rows = (
    ['Country', 'Capital', 'Population'],
    ['UK', 'London', 59.67],
    ['Switzerland', 'Bern', 7.25],
    ['China', 'Beijing', 1315.84],
);

print generate_table(rows => \@rows, header_row => 1);

This results in the following table:

+-------------+---------+------------+
| Country     | Capital | Population |
+-------------+---------+------------+
| UK          | London  | 59.67      |
| Switzerland | Bern    | 7.25       |
| China       | Beijing | 1315.84    |
+-------------+---------+------------+

You can ask for divider lines between all rows, by setting separate_rows to a true value, which results in a funky line between the header and the body, if you had a header:

+-------------+---------+------------+
| Country     | Capital | Population |
O=============O=========O============O
| UK          | London  |      59.67 |
+-------------+---------+------------+
| Switzerland |  Bern   |       7.25 |
+-------------+---------+------------+
| China       | Beijing |    1315.84 |
+-------------+---------+------------+

I have never used this, and imagine that very few people do. It's too visually noisy, and generally vertical space is at a premium.

And finally, you can ask for the top and bottom borders to be left off, by setting top_and_tail to a true value:

| Country     | Capital | Population |
+-------------+---------+------------+
| UK          | London  |      59.67 |
| Switzerland |  Bern   |       7.25 |
| China       | Beijing |    1315.84 |

The rest of this post describes the changes I've implemented so far.

Alignment

A few times I've wanted right-aligned columns, and Andy Lester recently requested this capability as well, which is what nudged me into action.

So now you can pass an align parameter, which takes an arrayref of alignment indicators:

align => [qw/ l c r /],

Which results in:

+-------------+---------+------------+
| Country     | Capital | Population |
+-------------+---------+------------+
| UK          | London  |      59.67 |
| Switzerland |  Bern   |       7.25 |
| China       | Beijing |    1315.84 |
+-------------+---------+------------+

For the next release, I'll probably just support left-, centre-, and right-alignment, but in the future might support right-alignment at decimal point (and other characters, like comma or colon).

Box rule characters

The new style parameter defaults to "classic", but "boxrule" switches to using the box rule characters:

style => "boxrule",

This results in:

┌─────────────┬─────────┬────────────┐
│ Country     │ Capital │ Population │
├─────────────┼─────────┼────────────┤
│ UK          │ London  │      59.67 │
│ Switzerland │  Bern   │       7.25 │
│ China       │ Beijing │    1315.84 │
└─────────────┴─────────┴────────────┘

At first that table wasn't coming out right in my blog. Looks like Google's Inconsolata typeface doesn't get the box rule characters right, so watch out if you use Inconsolata. I switched my blog to use Source Code Pro (from Google Fonts), and now the tables look right.

Here's what boxrule looks like if you set separate_rows as well:

┌─────────────┬─────────┬────────────┐
│ Country     │ Capital │ Population │
╞═════════════╪═════════╪════════════╡
│ UK          │ London  │      59.67 │
├─────────────┼─────────┼────────────┤
│ Switzerland │  Bern   │       7.25 │
├─────────────┼─────────┼────────────┤
│ China       │ Beijing │    1315.84 │
└─────────────┴─────────┴────────────┘

This takes up too much vertical space, but I guess if you have wide data but not too many rows, then you might use this?

Compact columns

I've got some tools that display a lot of columns, so I wanted the option to remove the padding around the text in each column:

compact => 1

Combined with boxrule, we get:

┌───────────┬───────┬──────────┐
│Country    │Capital│Population│
├───────────┼───────┼──────────┤
│UK         │London │     59.67│
│Switzerland│ Bern  │      7.25│
│China      │Beijing│   1315.84│
└───────────┴───────┴──────────┘

Columnar display

The "norule" style results in a columnar display:

 Country       Capital   Population

 UK            London         59.67
 Switzerland    Bern           7.25
 China         Beijing      1315.84

You can combine this with compact to get columns that are closer together:

 Country     Capital Population

 UK          London       59.67
 Switzerland  Bern         7.25
 China       Beijing    1315.84

I suspect that in most situations this wouldn't work, but it illustrates that I've got to make sure that all of these options work sensibly together.

Markdown tables

I've had a PR on this to add support for generating markdown tables. I need to look into markdown tables, and see how best to fit that in. Should it be a separate function, or a style? If it's a style, then the other options all need to make sense when combined with it.

Do you use Text::Table::Tiny?

If you use this module, or now think you might, do you have any opinions on the above, or other features you'd like to see? You can either add comments below, or email me at neil at bowers dot com.

comments powered by Disqus