Acme-CPANModules-TextTable
view release on metacpan or search on metacpan
lib/Acme/CPANModules/TextTable.pm view on Meta::CPAN
package Acme::CPANModules::TextTable;
use 5.010001;
use strict;
use warnings;
use utf8;
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2023-10-31'; # DATE
our $DIST = 'Acme-CPANModules-TextTable'; # DIST
our $VERSION = '0.016'; # VERSION
sub _make_table {
my ($cols, $rows, $celltext) = @_;
my $res = [];
push @$res, [];
for (0..$cols-1) { $res->[0][$_] = "col" . ($_+1) }
for my $row (1..$rows) {
push @$res, [ map { $celltext // "row$row.$_" } 1..$cols ];
}
$res;
}
our $LIST = {
summary => 'List of modules that generate text tables',
description => <<'_',
Currently excluded from this list are:
- <pm:Text::SimpleTable::AutoWidth> (wrapper to <pm:Text::SimpleTable>);
- <pm:Text::ASCIITable::EasyTable> (wrapper to <pm:Text::ASCIITable>);
_
entry_features => {
wide_char => {summary => 'Whether the use of wide characters (e.g. Kanji) in cells does not cause the table to be misaligned'},
color_data => {summary => 'Whether module supports ANSI colors (i.e. text with ANSI color codes can still be aligned properly)'},
multiline_data => {summary => 'Whether module supports aligning data cells that contain newlines'},
box_char => {summary => 'Whether module can utilize box-drawing characters'},
custom_border => {summary => 'Whether module allows customizing border in some way'},
align_row => {summary => "Whether module supports aligning text horizontally in a row (left/right/middle)"},
align_column => {summary => "Whether module supports aligning text horizontally in a column (left/right/middle)"},
align_cell => {summary => "Whether module supports aligning text horizontally in individual cells (left/right/middle)"},
valign_row => {summary => "Whether module supports aligning text vertically in a row (top/bottom/middle)"},
valign_column => {summary => "Whether module supports aligning text vertically in a column (top/bottom/middle)"},
valign_cell => {summary => "Whether module supports aligning text vertically in individual cells (top/bottom/middle)"},
rowspan => {summary => "Whether module supports row spans"},
colspan => {summary => "Whether module supports column spans"},
custom_color => {summary => 'Whether the module produces colored table and supports customizing color in some way'},
color_theme => {summary => 'Whether the module supports color theme/scheme'},
speed => {summary => "Rendering speed", schema=>'str*'},
column_width => {summary => 'Whether module allows setting the width of columns'},
per_column_width => {summary => 'Whether module allows setting column width on a per-column basis'},
row_height => {summary => 'Whether module allows setting the height of rows'},
per_row_height => {summary => 'Whether module allows setting row height on a per-row basis'},
pad => {summary => 'Whether module allows customizing cell horizontal padding'},
vpad => {summary => 'Whether module allows customizing cell vertical padding'},
},
entries => [
{
module => 'Text::Table::Any',
description => <<'_',
This is a frontend for many text table modules as backends. The interface is
dead simple, following <pm:Text::Table::Tiny>. The main drawback is that it
currently does not allow passing (some, any) options to each backend.
_
bench_code => sub {
my ($table) = @_;
Text::Table::Any::table(rows=>$table, header_row=>1);
},
features => {
align_cell => {value=>undef, summary=>"Depends on backend"},
align_column => {value=>undef, summary=>"Depends on backend"},
align_row => {value=>undef, summary=>"Depends on backend"},
box_char => {value=>undef, summary=>"Depends on backend"},
color_data => {value=>undef, summary=>"Depends on backend"},
color_theme => {value=>undef, summary=>"Depends on backend"},
colspan => {value=>undef, summary=>"Depends on backend"},
custom_border => {value=>undef, summary=>"Depends on backend"},
custom_color => {value=>undef, summary=>"Depends on backend"},
multiline_data => {value=>undef, summary=>"Depends on backend"},
rowspan => {value=>undef, summary=>"Depends on backend"},
speed => {value=>undef, summary=>"Depends on backend"},
valign_cell => {value=>undef, summary=>"Depends on backend"},
valign_column => {value=>undef, summary=>"Depends on backend"},
valign_row => {value=>undef, summary=>"Depends on backend"},
wide_char_data => {value=>undef, summary=>"Depends on backend"},
},
},
{
module => 'Text::SimpleTable',
description => <<'_',
As its name implies, a simple table-generating module with minimal documentation
and a few choices or border characters. You have to set the width of all columns
manually.
_
bench_code => sub {
my ($table) = @_;
my @colspec = map {[9, $_]} @{ $table->[0] };
my $ts = Text::SimpleTable->new(@colspec);
for (1 .. $#{$table}) { $ts->row(@{ $table->[$_] }) }
$ts->draw;
},
features => {
align_cell => {value=>0},
align_column => {value=>0},
align_row => {value=>0},
box_char => {value=>0},
color_data => {value=>0},
color_theme => {value=>0},
colspan => {value=>0},
custom_border => {value=>1, summary=>"Limited choice of 1 ASCII style and 1 UTF style"},
custom_color => {value=>0},
multiline_data => {value=>0},
rowspan => {value=>0},
speed => {value=>'fast', summary=>'Slightly slower than Text::Table::Tiny'},
valign_cell => {value=>0},
valign_column => {value=>0},
valign_row => {value=>0},
wide_char_data => {value=>0},
},
},
{
module => 'Text::UnicodeBox::Table',
description => <<'_',
The main feature of this module is the various border style it provides drawn
using Unicode box-drawing characters. It allows per-row style. The rendering
speed is particularly slow compared to other modules.
_
bench_code => sub {
my ($table) = @_;
my $t = Text::UnicodeBox::Table->new;
$t->add_header(@{ $table->[0] });
$t->add_row(@{ $table->[$_] }) for 1..$#{$table};
$t->render;
},
features => {
align_cell => 0,
align_column => 1,
box_char => 0,
color_data => 1,
color_theme => 0,
colspan => 0,
custom_border => 1,
custom_color => 0,
multiline_data => 0,
rowspan => 0,
wide_char_data => 1,
speed => "slow",
},
},
{
module => 'Text::Table::Manifold',
description => <<'_',
Two main features of this module is per-column aligning and wide character
support. This module, aside from doing its rendering, can also be told to pass
rendering to HTML, CSV, or other text table module like
<pm:Text::UnicodeBox::Table>); so in this way it is similar to
<pm:Text::Table::Any>.
_
bench_code => sub {
my ($table) = @_;
my $t = Text::Table::Manifold->new;
$t->headers($table->[0]);
$t->data([ @{$table}[1 .. $#{$table}] ]);
join("\n", @{$t->render(padding => 1)}) . "\n";
},
features => {
align_cell => 0,
align_column => 1,
box_char => undef, # ?
color_data => 1,
color_theme => 0,
colspan => 0,
custom_border => {value=>0, summary=>"But this module can pass rendering to other module like Text::UnicodeBox::Table"},
custom_color => 0,
multiline_data => 0,
rowspan => 0,
wide_char_data => 1,
},
},
{
module => 'Text::ANSITable',
description => <<'_',
This 2013 project was my take in creating a text table module that can handle
color, multiline text, wide characters. I also threw in various formatting
options, e.g. per-column/row/cell align/valign/pad/vpad, conditional formatting,
and so on. I even added a couple of features I never used: hiding rows and
specifying columns to display which can be in different order from the original
specified columns or can contain the same original columns multiple times. I
think this module offers the most formatting options on CPAN.
In early 2021, I needed colspan/rowspan and I implemented this in a new module:
<pm:Text::Table::Span> (later renamed to <pm:Text::Table::More>). I plan to add
this feature too to Text::ANSITable, but in the meantime I'm also adding more
formatting options which I need to Text::Table::More.
_
bench_code => sub {
my ($table) = @_;
my $t = Text::ANSITable->new(
use_utf8 => 0,
use_box_chars => 0,
use_color => 0,
columns => $table->[0],
border_style => 'ASCII::SingleLine',
);
$t->add_row($table->[$_]) for 1..@$table-1;
$t->draw;
},
features => {
align_cell => 1,
align_column => 1,
align_row => 1,
box_char => 1,
color_data => 1,
color_theme => 1,
colspan => 0,
column_width => 1,
custom_border => 1,
custom_color => 1,
multiline_data => 1,
pad => 1,
per_column_width => 1,
per_row_height => 1,
row_height => 1,
rowspan => 0,
speed => "slow",
valign_cell => 1,
valign_column => 1,
valign_row => 1,
vpad => 1,
wide_char_data => 1,
},
},
{
module => 'Text::ASCIITable',
bench_code => sub {
my ($table) = @_;
my $t = Text::ASCIITable->new();
$t->setCols(@{ $table->[0] });
$t->addRow(@{ $table->[$_] }) for 1..@$table-1;
"$t";
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => 0,
multiline_data => 1,
},
},
{
module => 'Text::FormatTable',
bench_code => sub {
my ($table) = @_;
my $t = Text::FormatTable->new(join('|', ('l') x @{ $table->[0] }));
$t->head(@{ $table->[0] });
$t->row(@{ $table->[$_] }) for 1..@$table-1;
$t->render;
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => 0,
multiline_data => 1,
},
},
{
module => 'Text::MarkdownTable',
bench_code => sub {
my ($table) = @_;
my $out = "";
my $t = Text::MarkdownTable->new(file => \$out);
my $fields = $table->[0];
foreach (1..@$table-1) {
my $row = $table->[$_];
$t->add( {
map { $fields->[$_] => $row->[$_] } 0..@$fields-1
});
}
$t->done;
$out;
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => 0,
multiline_data => {value=>0, summary=>'Newlines stripped'},
},
},
{
module => 'Text::Table',
bench_code => sub {
my ($table) = @_;
my $t = Text::Table->new(@{ $table->[0] });
$t->load(@{ $table }[1..@$table-1]);
$t;
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => {value=>undef, summary=>'Does not draw borders'},
multiline_data => 1,
},
},
{
module => 'Text::Table::Tiny',
description => <<'_',
The simple and tiny table-generating module which I liked back in 2012 (v0.03).
It employs an sprintf() trick to generate a single row. This module started my
personal experiments creating other table-generating modules (at last count I've
created no fewer than 15 of them!).
_
bench_code => sub {
my ($table) = @_;
Text::Table::Tiny::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => 1,
box_char => 1,
multiline_data => 0,
},
},
{
module => 'Text::Table::TinyBorderStyle',
bench_code => sub {
my ($table) = @_;
Text::Table::TinyBorderStyle::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => 1,
multiline_data => 0,
},
},
{
module => 'Text::Table::More',
description => <<'_',
A module I wrote in early 2021. Main distinguishing feature is support for
rowspan/clospan. I plan to add more features to this module on an as-needed
basic. This module is now preferred to <pm:Text::ANSITable>, although currently
it does not offer nearly as many formatting options as Text::ANSITable.
_
bench_code => sub {
my ($table) = @_;
Text::Table::More::generate_table(rows=>$table, header_row=>1);
},
features => {
align_cell => 1,
align_column => 1,
align_row => 1,
box_char => 1,
color_data => 1,
color_theme => 0,
colspan => 1,
custom_border => 1,
custom_color => 0,
multiline_data => 1,
rowspan => 1,
speed => "slow",
valign_cell => 1,
valign_column => 1,
valign_row => 1,
wide_char_data => 1,
column_width => 0, # todo
per_column_width => 0, # todo
row_height => 0, # todo
per_row_height => 0, # todo
pad => 0, # todo
vpad => 0, # todo
},
},
{
module => 'Text::Table::Sprintf',
description => <<'_',
A performant (see benchmark result) and lightweight (a page of code, no use of
modules at all), but with minimal extra features.
_
bench_code => sub {
my ($table) = @_;
Text::Table::Sprintf::table(rows=>$table, header_row=>1);
},
features => {
box_char => 0,
color_data => 0,
multiline_data => 0,
speed => {value=>"fast", summary=>"The fastest among the others in this list"},
wide_char_data => 0,
},
},
{
module => 'Text::Table::TinyColor',
bench_code => sub {
my ($table) = @_;
Text::Table::TinyColor::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 0,
color_data => 1,
box_char => 0,
multiline_data => 0,
},
},
{
module => 'Text::Table::TinyColorWide',
bench_code => sub {
my ($table) = @_;
Text::Table::TinyColorWide::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => 1,
box_char => 0,
multiline_data => 0,
},
},
{
module => 'Text::Table::TinyWide',
bench_code => sub {
my ($table) = @_;
Text::Table::TinyWide::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => 0,
box_char => 0,
},
},
{
module => 'Text::Table::Org',
bench_code => sub {
my ($table) = @_;
Text::Table::Org::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 0,
color_data => 0,
box_char => 0,
multiline_data => 0,
},
},
{
module => 'Text::Table::CSV',
bench_code => sub {
my ($table) = @_;
Text::Table::CSV::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => 0,
box_char => {value=>undef, summary=>"Irrelevant"},
multiline_data => {value=>1, summary=>"But make sure your CSV parser can handle multiline cell"},
},
},
{
module => 'Text::Table::HTML',
bench_code => sub {
my ($table) = @_;
Text::Table::HTML::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => {value=>0, summary=>'Not converted to HTML color elements'},
box_char => 0,
multiline_data => 1,
},
},
{
module => 'Text::Table::HTML::DataTables',
bench_code => sub {
my ($table) = @_;
Text::Table::HTML::DataTables::table(rows=>$table, header_row=>1);
},
features => {
wide_char_data => 1,
color_data => {value=>0, summary=>'Not converted to HTML color elements'},
box_char => 0,
multiline_data => 1,
},
},
{
module => 'Text::TabularDisplay',
bench_code => sub {
my ($table) = @_;
my $t = Text::TabularDisplay->new(@{ $table->[0] });
$t->add(@{ $table->[$_] }) for 1..@$table-1;
$t->render; # doesn't add newline
},
features => {
wide_char_data => 1,
color_data => 0,
box_char => {value=>undef, summary=>"Irrelevant"},
multiline_data => 1,
},
},
],
bench_datasets => [
{name=>'tiny (1x1)' , argv => [_make_table( 1, 1)],},
{name=>'small (3x5)' , argv => [_make_table( 3, 5)],},
{name=>'wide (30x5)' , argv => [_make_table(30, 5)],},
{name=>'long (3x300)' , argv => [_make_table( 3, 300)],},
{name=>'large (30x300)' , argv => [_make_table(30, 300)],},
{name=>'multiline data (2x1)', argv => [ [["col1", "col2"], ["foobar\nbaz\nqux\nquux","corge"]] ], include_by_default=>0 },
{name=>'wide char data (1x2)', argv => [ [["col1"], ["no wide character"], ["宽å"]] ], include_by_default=>0 },
{name=>'color data (1x2)' , argv => [ [["col1"], ["no color"], ["\e[31m\e[1mwith\e[0m \e[32m\e[1mcolor\e[0m"]] ], include_by_default=>0 },
],
};
1;
# ABSTRACT: List of modules that generate text tables
__END__
=pod
=encoding UTF-8
=head1 NAME
Acme::CPANModules::TextTable - List of modules that generate text tables
=head1 VERSION
This document describes version 0.016 of Acme::CPANModules::TextTable (from Perl distribution Acme-CPANModules-TextTable), released on 2023-10-31.
=head1 SYNOPSIS
To run benchmark with default option:
% bencher --cpanmodules-module TextTable
To run module startup overhead benchmark:
% bencher --module-startup --cpanmodules-module TextTable
For more options (dump scenario, list/include/exclude/add participants, list/include/exclude/add datasets, etc), see L<bencher> or run C<bencher --help>.
=head1 DESCRIPTION
Currently excluded from this list are:
=over
=item * L<Text::SimpleTable::AutoWidth> (wrapper to L<Text::SimpleTable>);
=item * L<Text::ASCIITable::EasyTable> (wrapper to L<Text::ASCIITable>);
=back
=head1 ACME::CPANMODULES ENTRIES
=over
=item L<Text::Table::Any>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
This is a frontend for many text table modules as backends. The interface is
dead simple, following L<Text::Table::Tiny>. The main drawback is that it
currently does not allow passing (some, any) options to each backend.
=item L<Text::SimpleTable>
Author: L<MRAMBERG|https://metacpan.org/author/MRAMBERG>
As its name implies, a simple table-generating module with minimal documentation
and a few choices or border characters. You have to set the width of all columns
manually.
=item L<Text::UnicodeBox::Table>
Author: L<EWATERS|https://metacpan.org/author/EWATERS>
The main feature of this module is the various border style it provides drawn
using Unicode box-drawing characters. It allows per-row style. The rendering
speed is particularly slow compared to other modules.
=item L<Text::Table::Manifold>
Author: L<RSAVAGE|https://metacpan.org/author/RSAVAGE>
Two main features of this module is per-column aligning and wide character
support. This module, aside from doing its rendering, can also be told to pass
rendering to HTML, CSV, or other text table module like
L<Text::UnicodeBox::Table>); so in this way it is similar to
L<Text::Table::Any>.
=item L<Text::ANSITable>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
This 2013 project was my take in creating a text table module that can handle
color, multiline text, wide characters. I also threw in various formatting
options, e.g. per-column/row/cell align/valign/pad/vpad, conditional formatting,
and so on. I even added a couple of features I never used: hiding rows and
specifying columns to display which can be in different order from the original
specified columns or can contain the same original columns multiple times. I
think this module offers the most formatting options on CPAN.
In early 2021, I needed colspan/rowspan and I implemented this in a new module:
L<Text::Table::Span> (later renamed to L<Text::Table::More>). I plan to add
this feature too to Text::ANSITable, but in the meantime I'm also adding more
formatting options which I need to Text::Table::More.
=item L<Text::ASCIITable>
Author: L<LUNATIC|https://metacpan.org/author/LUNATIC>
=item L<Text::FormatTable>
Author: L<TREY|https://metacpan.org/author/TREY>
=item L<Text::MarkdownTable>
Author: L<VOJ|https://metacpan.org/author/VOJ>
=item L<Text::Table>
Author: L<SHLOMIF|https://metacpan.org/author/SHLOMIF>
=item L<Text::Table::Tiny>
Author: L<NEILB|https://metacpan.org/author/NEILB>
The simple and tiny table-generating module which I liked back in 2012 (v0.03).
It employs an sprintf() trick to generate a single row. This module started my
personal experiments creating other table-generating modules (at last count I've
created no fewer than 15 of them!).
=item L<Text::Table::TinyBorderStyle>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::More>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
A module I wrote in early 2021. Main distinguishing feature is support for
rowspan/clospan. I plan to add more features to this module on an as-needed
basic. This module is now preferred to L<Text::ANSITable>, although currently
it does not offer nearly as many formatting options as Text::ANSITable.
=item L<Text::Table::Sprintf>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
A performant (see benchmark result) and lightweight (a page of code, no use of
modules at all), but with minimal extra features.
=item L<Text::Table::TinyColor>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::TinyColorWide>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::TinyWide>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::Org>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::CSV>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::HTML>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::Table::HTML::DataTables>
Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>
=item L<Text::TabularDisplay>
Author: L<DARREN|https://metacpan.org/author/DARREN>
=back
=head1 ACME::CPANMODULES FEATURE COMPARISON MATRIX
+-------------------------------+----------------+------------------+---------------+--------------+----------------+-----------------+-------------+-------------------+------------------+---------------------+--------------+------------+-----------...
| module | align_cell *1) | align_column *2) | align_row *3) | box_char *4) | color_data *5) | color_theme *6) | colspan *7) | custom_border *8) | custom_color *9) | multiline_data *10) | rowspan *11) | speed *12) | valign_cel...
+-------------------------------+----------------+------------------+---------------+--------------+----------------+-----------------+-------------+-------------------+------------------+---------------------+--------------+------------+-----------...
| Text::Table::Any | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) | N/A *22) ...
| Text::SimpleTable | no | no | no | no | no | no | no | yes *23) | no | no | no | fast *24) | no ...
| Text::UnicodeBox::Table | no | yes | N/A | no | yes | no | no | yes | no | no | no | slow | N/A ...
| Text::Table::Manifold | no | yes | N/A | N/A | yes | no | no | no *25) | no | no | no | N/A | N/A ...
| Text::ANSITable | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | no | slow | yes ...
| Text::ASCIITable | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | yes | N/A | N/A | N/A ...
| Text::FormatTable | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | yes | N/A | N/A | N/A ...
| Text::MarkdownTable | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | no *26) | N/A | N/A | N/A ...
| Text::Table | N/A | N/A | N/A | N/A *27) | no | N/A | N/A | N/A | N/A | yes | N/A | N/A | N/A ...
| Text::Table::Tiny | N/A | N/A | N/A | yes | yes | N/A | N/A | N/A | N/A | no | N/A | N/A | N/A ...
| Text::Table::TinyBorderStyle | N/A | N/A | N/A | yes | no | N/A | N/A | N/A | N/A | no | N/A | N/A | N/A ...
| Text::Table::More | yes | yes | yes | yes | yes | no | yes | yes | no | yes | yes | slow | yes ...
| Text::Table::Sprintf | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | no | N/A | fast *28) | N/A ...
| Text::Table::TinyColor | N/A | N/A | N/A | no | yes | N/A | N/A | N/A | N/A | no | N/A | N/A | N/A ...
| Text::Table::TinyColorWide | N/A | N/A | N/A | no | yes | N/A | N/A | N/A | N/A | no | N/A | N/A | N/A ...
| Text::Table::TinyWide | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A ...
| Text::Table::Org | N/A | N/A | N/A | no | no | N/A | N/A | N/A | N/A | no | N/A | N/A | N/A ...
| Text::Table::CSV | N/A | N/A | N/A | N/A *29) | no | N/A | N/A | N/A | N/A | yes *30) | N/A | N/A | N/A ...
| Text::Table::HTML | N/A | N/A | N/A | no | no *31) | N/A | N/A | N/A | N/A | yes | N/A | N/A | N/A ...
lib/Acme/CPANModules/TextTable.pm view on Meta::CPAN
This Acme::CPANModules module contains benchmark instructions. You can run a
benchmark for some/all the modules listed in this Acme::CPANModules module using
the L<bencher> CLI (from L<Bencher> distribution):
% bencher --cpanmodules-module TextTable
This Acme::CPANModules module also helps L<lcpan> produce a more meaningful
result for C<lcpan related-mods> command when it comes to finding related
modules for the modules listed in this Acme::CPANModules module.
See L<App::lcpan::Cmd::related_mods> for more details on how "related modules"
are found.
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/Acme-CPANModules-TextTable>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-Acme-CPANModules-TextTable>.
=head1 SEE ALSO
Related lists: L<Acme::CPANModules::HTMLTable>,
L<Acme::CPANModules::BrowsingTableInteractively>.
L<Acme::CPANModules> - about the Acme::CPANModules namespace
L<cpanmodules> - CLI tool to let you browse/view the lists
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 CONTRIBUTING
To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.
Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:
% prove -l
If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2023, 2021, 2020, 2019 by perlancar <perlancar@cpan.org>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Acme-CPANModules-TextTable>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=cut
( run in 0.531 second using v1.01-cache-2.11-cpan-5b529ec07f3 )