NAME
Text::ANSITable - Create nice formatted tables using extended ASCII and ANSI colors
VERSION
version 0.27
SYNOPSIS
use 5.010;
use Text::ANSITable;
# don't forget this if you want to output utf8 characters
binmode(STDOUT, ":utf8");
my $t = Text::ANSITable->new;
# set styles
$t->border_style('Default::bold'); # if not, a nice default is picked
$t->color_theme('Default::sepia'); # if not, a nice default is picked
# fill data
$t->columns(["name", "color", "price"]);
$t->add_row(["chiki" , "yellow", 2000]);
$t->add_row(["lays" , "green" , 7000]);
$t->add_row(["tao kae noi", "blue" , 18500]);
# draw it!
say $t->draw;
Samples of output:
DESCRIPTION
This module is yet another text table formatter module like Text::ASCIITable or Text::SimpleTable, with the following differences:
Colors and color themes
ANSI color codes will be used by default (even 256 and 24bit colors), but will degrade to lower color depth and black/white according to terminal support.
Box-drawing characters
Box-drawing characters will be used by default, but will degrade to using normal ASCII characters if terminal does not support them.
Unicode and wide character support
Border styles using Unicode characters (double lines, bold/heavy lines, brick style, etc). Columns containing wide characters stay aligned.
Compared to Text::ASCIITable, it uses lower_case
method/attr names instead of CamelCase
, and it uses arrayref for columns
and add_row
. When specifying border styles, the order of characters are slightly different. More fine-grained options to customize appearance.
It uses Moo object system.
BORDER STYLES
To list available border styles:
say $_ for $t->list_border_styles;
Or you can also try out borders using the provided ansitable-list-border-styles script. Or, you can also view the documentation for the Text::ANSITable::BorderStyle::*
modules, where border styles are searched.
To choose border style, either set the border_style
attribute to an available border style or a border specification directly.
$t->border_style("Default::singleh_boxchar");
$t->border_style("Foo::bar"); # dies, no such border style
$t->border_style({ ... }); # set specification directly
If no border style is selected explicitly, a nice default will be chosen. You can also set the ANSITABLE_BORDER_STYLE
environment variable to set the default.
To create a new border style, create a module under Text::ANSITable::BorderStyle::
. Please see one of the existing border style modules for example, like Text::ANSITable::BorderStyle::Default. For more about border styles, refer to SHARYANTO::Role::BorderStyle.
COLOR THEMES
To list available color themes:
say $_ for $t->list_color_themes;
Or you can also run the provided ansitable-list-color-themes script. Or you can view the documentation for the Text::ANSITable::ColorTheme::*
modules where color themes are searched.
To choose a color theme, either set the color_theme
attribute to an available color theme or a color theme specification directly.
$t->color_theme("Default::default_nogradation");
$t->color_theme("Foo::bar"); # dies, no such color theme
$t->color_theme({ ... }); # set specification directly
If no color theme is selected explicitly, a nice default will be chosen. You can also set the ANSITABLE_COLOR_THEME
environment variable to set the default.
To create a new color theme, create a module under Text::ANSITable::ColorTheme::
. Please see one of the existing color theme modules for example, like Text::ANSITable::ColorTheme::Default. For more about color themes, refer to SHARYANTO::Role::ColorTheme.
COLUMN WIDTHS
By default column width is set just so it is enough to show the widest data. This can be customized in the following ways (in order of precedence, from lowest):
table-level
cell_width
attributeThis sets width for all columns.
per-column
width
style$t->set_column_style('colname', width => 20);
You can use negative number to mean minimum width.
ROW HEIGHTS
This can be customized in the following ways (in order of precedence, from lowest):
table-level
cell_height
attributeThis sets height for all rows.
per-row
height
style$t->set_row_style(1, height => 2);
You can use negative number to mean minimum height.
CELL (HORIZONTAL) PADDING
By default cell (horizontal) padding is 1. This can be customized in the following ways (in order of precedence, from lowest):
table-level
cell_pad
attributeThis sets left and right padding for all columns.
table-level
cell_lpad
andcell_rpad
attributesThey set left and right padding for all columns, respectively.
per-column
pad
style$t->set_column_style($colname, pad => 0);
per-column
lpad
/rpad
style$t->set_column_style($colname, lpad => 1); $t->set_column_style($colname, rpad => 2);
ROW VERTICAL PADDING
Default vertical padding is 0. This can be changed in the following ways (in order of precedence, from lowest):
table-level
cell_vpad
attributeThis sets top and bottom padding for all rows.
table-level
cell_tpad
/cell_bpad
attributesThey set top/bottom padding separately for all rows.
per-row
vpad
styleExample:
$t->set_row_style($rownum, vpad => 1);
When adding row:
$t->add_row($rownum, {vpad=>1});
per-row
tpad
/vpad
styleExample:
$t->set_row_style($row_num, tpad => 1); $t->set_row_style($row_num, bpad => 2);
When adding row:
$t->add_row($row, {tpad=>1, bpad=>2});
CELL COLORS
By default data format colors are used, e.g. cyan/green for text (using the default color scheme, items num_data
, bool_data
, etc). In absense of that, cell_fgcolor
and cell_bgcolor
from the color scheme are used. You can customize colors in the following ways (ordered by precedence, from lowest):
table-level
cell_fgcolor
andcell_bgcolor
attributesSets all cells' colors. Color should be specified using 6-hexdigit RGB which will be converted to the appropriate terminal color.
Can also be set to a coderef which will receive ($rownum, $colname) and should return an RGB color.
per-column
fgcolor
andbgcolor
stylesExample:
$t->set_column_style('colname', fgcolor => 'fa8888'); $t->set_column_style('colname', bgcolor => '202020');
per-row
fgcolor
andbgcolor
stylesExample:
$t->set_row_style($rownum, {fgcolor => 'fa8888', bgcolor => '202020'});
When adding row/rows:
$t->add_row($row, {fgcolor=>..., bgcolor=>...}); $t->add_rows($rows, {bgcolor=>...});
per-cell
fgcolor
andbgcolor
stylesExample:
$t->set_cell_style($rownum, $colname, fgcolor => 'fa8888'); $t->set_cell_style($rownum, $colname, bgcolor => '202020');
For flexibility, all colors can be specified as coderef. See "COLOR THEMES" for more details.
CELL (HORIZONTAL AND VERTICAL) ALIGNMENT
By default, numbers are right-aligned, dates and bools are centered, and the other data types (text including) are left-aligned. All data are top-valigned. This can be customized in the following ways (in order of precedence, from lowest):
table-level
cell_align
andcell_valign
attributeper-column
align
andvalign
stylesExample:
$t->set_column_style($colname, align => 'middle'); # or left, or right $t->set_column_style($colname, valign => 'top'); # or bottom, or middle
per-row
align
andvalign
stylesper-cell
align
andvalign
styles$t->set_cell_style($rownum, $colname, align => 'middle'); $t->set_cell_style($rownum, $colname, valign => 'top');
CELL FORMATS
The per-column and per-cell formats
styles regulate how to format data. The value for this style setting will be passed to Data::Unixish::Apply's apply()
, as the functions
argument. So it should be a single string (like date
) or an array (like ['date', ['centerpad', {width=>20}]]
).
See Data::Unixish or install App::dux and then run dux -l
to see what functions are available. Functions of interest to formatting data include: bool
, num
, sprintf
, sprintfn
, wrap
, (among others).
ATTRIBUTES
columns => ARRAY OF STR
Store column names. Note that when drawing, you can omit some columns, reorder them, or display some more than once (see column_filter
attribute).
rows => ARRAY OF ARRAY OF STR
Store row data. You can set this attribute directly, or add rows incrementally using add_row()
and add_rows()
methods.
row_filter => CODE|ARRAY OF INT
When drawing, only show rows that match this. Can be an array containing indices of rows which should be shown, or a coderef which will be called for each row with arguments ($row, $row_num)
and should return a bool value indicating whether that row should be displayed.
Internal note: During drawing, rows will be filtered and put into $t->{_draw}{frows}
.
column_filter => CODE|ARRAY OF STR
When drawing, only show columns that match this. Can be an array containing names of columns that should be displayed (column names can be in different order or duplicate, column can also be referred to with its numeric index). Can also be a coderef which will be called with ($col_name, $col_num)
for every column and should return a bool value indicating whether that column should be displayed. The coderef version is more limited in that it cannot reorder the columns or instruct for the same column to be displayed more than once.
Internal note: During drawing, column names will be filtered and put into $t->{_draw}{fcols}
.
column_wrap => BOOL
Set column wrapping for all columns. Can be overriden by per-column wrap
style. By default column wrapping will only be done for text columns and when width is explicitly set to a positive value.
use_color => BOOL
Whether to output color. Default is taken from COLOR
environment variable, or detected via (-t STDOUT)
. If use_color
is set to 0, an attempt to use a colored color theme (i.e. anything that is not the no_color
theme) will result in an exception.
(In the future, setting use_color
to 0 might opt the module to use normal/plain string routines instead of the slower ta_* functions from Text::ANSI::Util; this also means that the module won't handle ANSI escape codes in the content text.)
color_depth => INT
Terminal's color depth. Either 16, 256, or 2**24 (16777216). Default will be retrieved from COLOR_DEPTH
environment or detected using Term::Detect.
use_box_chars => BOOL
Whether to use box drawing characters. Drawing box drawing characters can be problematic in some places because it uses ANSI escape codes to switch to (and back from) line drawing mode ("\e(0"
and "\e(B"
, respectively).
Default is taken from BOX_CHARS
environment variable, or 1. If use_box_chars
is set to 0, an attempt to use a border style that uses box drawing chararacters will result in an exception.
use_utf8 => BOOL
Whether to use Unicode (UTF8) characters. Default is taken from UTF8
environment variable, or detected using Term::Detect, or guessed via LANG environment variable. If use_utf8
is set to 0, an attempt to select a border style that uses Unicode characters will result in an exception.
border_style => HASH
Border style specification to use.
You can set this attribute's value with a specification or border style name. See "BORDER STYLES"" in " for more details.
border_style_args => HASH
Some border styles can accept arguments. You can set it here. See the corresponding border style's documentation for information on what arguments it accepts.
color_theme => HASH
Color theme specification to use.
You can set this attribute's value with a specification or color theme name. See "COLOR THEMES"" in " for more details.
color_theme_args => HASH
Some color themes can accept arguments. You can set it here. See the corresponding color theme's documentation for information on what arguments it accepts.
show_header => BOOL (default: 1)
When drawing, whether to show header.
show_row_separator => INT (default: 2)
When drawing, whether to show separator lines between rows. The default (2) is to only show separators drawn using add_row_separator()
. If you set this to 1, lines will be drawn after every data row. If you set this attribute to 0, no lines will be drawn whatsoever.
cell_width => INT
Set width for all cells. Can be overriden by per-column width
style.
cell_height => INT
Set height for all cell. Can be overriden by per-row height
style.
cell_align => STR
Set (horizontal) alignment for all cells. Either left
, middle
, or right
. Can be overriden by per-column/per-row/per-cell align
style.
cell_valign => STR
Set (horizontal) alignment for all cells. Either top
, middle
, or bottom
. Can be overriden by per-column/per-row/per-cell align
style.
cell_pad => INT
Set (horizontal) padding for all cells. Can be overriden by per-column pad
style.
cell_lpad => INT
Set left padding for all cells. Overrides the cell_pad
attribute. Can be overriden by per-column lpad
style.
cell_rpad => INT
Set right padding for all cells. Overrides the cell_pad
attribute. Can be overriden by per-column rpad
style.
cell_vpad => INT
Set vertical padding for all cells. Can be overriden by per-row vpad
style.
cell_tpad => INT
Set top padding for all cells. Overrides the cell_vpad
attribute. Can be overriden by per-row tpad
style.
cell_bpad => INT
Set bottom padding for all cells. Overrides the cell_vpad
attribute. Can be overriden by per-row bpad
style.
cell_fgcolor => RGB|CODE
Set foreground color for all cells. Value should be 6-hexdigit RGB. Can also be a coderef that will receive %args (e.g. row_num, col_name, col_num) and should return an RGB color. Can be overriden by per-cell fgcolor
style.
cell_bgcolor => RGB|CODE
Like cell_fgcolor
but for background color.
header_fgcolor => RGB|CODE
Set foreground color for all headers. Overrides cell_fgcolor
for headers. Value should be a 6-hexdigit RGB. Can also be a coderef that will receive %args (e.g. col_name, col_num) and should return an RGB color.
header_bgcolor => RGB|CODE
Like header_fgcolor
but for background color.
header_align => STR
header_valign => STR
header_vpad => INT
header_tpad => INT
header_bpad => INT
METHODS
$t = Text::ANSITable->new(%attrs) => OBJ
Constructor.
$t->list_border_styles => LIST
Return the names of available border styles. Border styles will be searched in Text::ANSITable::BorderStyle::*
modules.
$t->list_color_themes => LIST
Return the names of available color themes. Color themes will be searched in Text::ANSITable::ColorTheme::*
modules.
$t->get_border_style($name) => HASH
Can also be called as a static method: Text::ANSITable->get_border_style($name)
.
$t->get_color_theme($name) => HASH
Can also be called as a static method: Text::ANSITable->get_color_theme($name)
.
$t->add_row(\@row[, \%styles]) => OBJ
Add a row. Note that row data is not copied, only referenced.
Can also add per-row styles (which can also be done using row_style()
).
$t->add_rows(\@rows[, \%styles]) => OBJ
Add multiple rows. Note that row data is not copied, only referenced.
Can also add per-row styles (which can also be done using row_style()
).
$t->add_row_separator() => OBJ
Add a row separator line.
$t->get_cell($row_num, $col) => VAL
Get cell value at row #$row_num
(starts from zero) and column named/numbered $col
.
$t->set_cell($row_num, $col, $newval) => VAL
Set cell value at row #$row_num
(starts from zero) and column named/numbered $col
. Return old value.
$t->get_column_style($col, $style) => VAL
Get per-column style for column named/numbered $col
.
$t->set_column_style($col, $style=>$val[, $style2=>$val2, ...])
Set per-column style(s) for column named/numbered $col
. Available values for $style
: align
, valign
, pad
, lpad
, rpad
, width
, formats
, fgcolor
, bgcolor
, type
, wrap
.
$t->get_row_style($row_num) => VAL
Get per-row style for row numbered $row_num
.
$t->set_row_style($row_num, $style=>$newval[, $style2=>$newval2, ...])
Set per-row style(s) for row numbered $row_num
. Available values for $style
: align
, valign
, height
, vpad
, tpad
, bpad
, fgcolor
, bgcolor
.
$t->get_cell_style($row_num, $col, $style) => VAL
Get per-cell style.
$t->set_cell_style($row_num, $col, $style=>$newval[, $style2=>$newval2, ...])
Set per-cell style(s). Available values for $style
: align
, valign
, formats
, fgcolor
, bgcolor
.
$t->draw => STR
Render table.
ENVIRONMENT
COLOR => BOOL
Can be used to set default value for the color
attribute.
COLOR_DEPTH => INT
Can be used to set default value for the color_depth
attribute.
BOX_CHARS => BOOL
Can be used to set default value for the box_chars
attribute.
UTF8 => BOOL
Can be used to set default value for the utf8
attribute.
COLUMNS => INT
Can be used to override terminal width detection.
ANSITABLE_BORDER_STYLE => STR
Can be used to set default value for border_style
attribute.
ANSITABLE_COLOR_THEME => STR
Can be used to set default value for border_style
attribute.
ANSITABLE_STYLE => JSON
Can be used to set table's most attributes. Value should be a JSON-encoded hash of attr => val
pairs. Example:
% ANSITABLE_STYLE='{"show_row_separator":1}' ansitable-list-border-styles
will display table with row separator lines after every row.
ANSITABLE_COLUMN_STYLES => JSON
Can be used to set per-column styles. Interpreted right before draw(). Value should be a JSON-encoded hash of col => {style => val, ...}
pairs. Example:
% ANSITABLE_COLUMN_STYLES='{"2":{"type":"num"},"3":{"type":"str"}}' ansitable-list-border-styles
will display the bool columns as num and str instead.
ANSITABLE_ROW_STYLES => JSON
Can be used to set per-row styles. Interpreted right before draw(). Value should be a JSON-encoded a hash of row_num => {style => val, ...}
pairs. Example:
% ANSITABLE_ROW_STYLES='{"0":{"bgcolor":"000080","vpad":1}}' ansitable-list-border-styles
will display the first row with blue background color and taller height.
ANSITABLE_CELL_STYLES => JSON
Can be used to set per-cell styles. Interpreted right before draw(). Value should be a JSON-encoded a hash of "row_num,col" => {style => val, ...}
pairs. Example:
% ANSITABLE_CELL_STYLES='{"1,1":{"bgcolor":"008000"}}' ansitable-list-border-styles
will display the second-on-the-left, second-on-the-top cell with green background color.
FAQ
General
Output is too fancy! I just want to generate some plain (Text::ASCIITable-like) output to be pasted to my document.
$t->use_utf8(0);
$t->use_box_chars(0);
$t->use_color(0);
$t->border_style('Default::single_ascii');
and you're good to go. Alternatively you can set environment UTF8=0, BOX_CHARS=0, COLOR=0, and ANSITABLE_BORDER_STYLE=Default::single_ascii.
Why am I getting 'Wide character in print' warning?
You are probably using a utf8 border style, and you haven't done something like this to your output:
binmode(STDOUT, ":utf8");
My table looks garbled when viewed through pager like less!
That's because less by default escapes ANSI color and box_char codes. Try using -R
option of less to display ANSI color codes raw.
Or, try not using colors and box_char border styles:
$t->use_color(0);
$t->use_box_chars(0);
Note that as of this writing, less -R does not interpret box_char codes so you'll need to avoid using box_char border styles if you want your output to display properly under less.
How do I hide some columns/rows when drawing?
Use the column_filter
and row_filter
attributes. For example, given this table:
my $t = Text::ANSITable->new;
$t->columns([qw/one two three/]);
$t->add_row([$_, $_, $_]) for 1..10;
Doing this:
$t->row_filter([0, 1, 4]);
print $t->draw;
will show:
one | two | three
-----+-----+-------
1 | 1 | 1
2 | 2 | 2
5 | 5 | 5
Doing this:
$t->row_filter(sub { my ($row, $idx) = @_; $row->[0] % 2 }
will display:
one | two | three
-----+-----+-------
1 | 1 | 1
3 | 3 | 3
5 | 5 | 5
7 | 7 | 7
9 | 9 | 9
Doing this:
$t->column_filter([qw/two one 0/]);
will display:
two | one | one
-----+-----+-----
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
4 | 4 | 4
5 | 5 | 5
6 | 6 | 6
7 | 7 | 7
8 | 8 | 8
9 | 9 | 9
10 | 10 | 10
Doing this:
$t->column_filter(sub { my ($colname, $idx) = @_; $colname =~ /t/ });
will display:
two | three
-----+-------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
Formatting data
How do I format data?
Use the formats
per-column style or per-cell style. For example:
$t->set_column_style('available', formats => [[bool=>{style=>'check_cross'}],
[centerpad=>{width=>10}]]);
$t->set_column_style('amount' , formats => [[num=>{decimal_digits=>2}]]);
$t->set_column_style('size' , formats => [[num=>{style=>'kilo'}]]);
See Data::Unixish::Apply and Data::Unixish for more details on the available formatting functions.
How does the module determine column data type?
Currently: if column name has the word date
or time
in it, the column is assumed to contain date data. If column name has ?
in it, the column is assumed to be bool. If a column contains only numbers (or undefs), it is num. Otherwise, it is str.
How does the module format data types?
Currently: num will be right aligned and applied num_data
color (cyan in the default theme). date will be centered and applied date_data
color (gold in the default theme). bool will be centered and formatted as check/cross symbol and applied bool_data
color (red/green depending on whether the data is false/true). str will be applied str_data
color (no color in the default theme).
Other color themes might use different colors.
How do I force column to be of a certain data type?
For example, you have a column named deleted
but want to display it as bool. You can do:
$t->set_column_style(deleted => type => 'bool');
How do I wrap long text?
The wrap
dux function can be used to wrap text (see: Data::Unixish::wrap). You'll want to set ansi
and mb
both to 1 to handle ANSI escape codes and wide characters in your text (unless you are sure that your text does not contain those):
$t->set_column_style('description', formats=>[[wrap => {width=>60, ansi=>1, mb=>1}]]);
How do I highlight text with color?
The ansi::highlight
dux function can be used to highlight text (see: Data::Unixish::ansi::highlight).
$t->set_column_style(2, formats => [[highlight => {pattern=>$pat}]]);
I want to change the default bool cross/check sign representation!
By default, bool columns are shown as cross/check sign. This can be changed, e.g.:
$t->set_column_style($colname, type => 'bool',
formats => [[bool => {style=>"Y_N"}]]);
See Data::Unixish::bool for more details.
Border
How to hide borders?
There is currently no show_border
attribute. Choose border styles like Default::space_ascii
or Default::none_utf8
:
$t->border_style("Default::none");
Why are there 'none_ascii' as well 'none_utf8' and 'none_boxchar' border styles?
Because of the row separator, that can still be drawn if add_row_separator()
is used. See next question.
I want to hide borders, and I do not want row separators to be shown!
The default is for separator lines to be drawn if drawn using add_row_separator()
, e.g.:
$t->add_row(['row1']);
$t->add_row(['row2']);
$t->add_row_separator;
$t->add_row(['row3']);
The result will be:
row1
row2
--------
row3
However, if you set show_row_separator
to 0, no separator lines will be drawn whatsoever:
row1
row2
row3
I want to separate each row with a line!
Set show_row_separator
to 1, or alternatively, set ANSITABLE_STYLE='{"show_row_separator":1}
.
Color
How to disable colors?
Set use_color
attribute or COLOR
environment to 0.
How to specify colors using names (e.g. red, 'navy blue') instead of RGB?
Use modules like Graphics::ColorNames.
I'm not seeing colors when output is piped (e.g. to a pager)!
The default is to disable colors when (-t STDOUT) is false. You can force-enable colors by setting use_color
attribute or COLOR
environment to 1.
How to enable 256 colors? I'm seeing only 16 colors.
Use terminal emulators that support 256 colors, e.g. Konsole, xterm, gnome-terminal, PuTTY/pterm (but the last one has minimal Unicode support). Better yet, use Konsole or Konsole-based emulators which supports 24bit colors.
How to enable 24bit colors (true color)?
Currently only Konsole and the Konsole-based Yakuake terminal emulator software support 24bit colors.
How to force lower color depth? (e.g. I use Konsole but want 16 colors)
Set COLOR_DEPTH
to 16.
How to change border gradation color?
The default color theme applies vertical color gradation to borders from white (ffffff) to gray (444444). To change this, set border1
and border2
theme arguments:
$t->color_theme_args({border1=>'ff0000', border2=>'00ff00'}); # red to green
I'm using terminal emulator with white background, the texts are not very visible!
Try using the "*_whitebg" themes, as the other themes are geared towards terminal emulators with black background.
How to set different background colors for odd/even rows?
Aside from doing $t->set_row_style($row_num, bgcolor=>...)
for each row, you can also do this:
$t->cell_bgcolor(sub { my ($self, %args) = @_; $args{row_num} % 2 ? '202020' : undef });
TODO/BUGS
Most color themes still look crappy on 256 colors (I develop on Konsole).
Attributes: cell_wrap? (a shorter/nicer version for formats => [[wrap => {ansi=>1, mb=>1}]]).
Column styles: show_{left,right}_border (shorter name? {l,r}border?)
Row styles: show_{top,bottom}_border (shorter name? {t,b}border?)
row span? column span?
SEE ALSO
For collections of border styles, search for Text::ANSITable::BorderStyle::*
modules.
For collections of color themes, search for Text::ANSITable::ColorTheme::*
modules.
Other table-formatting modules: Text::Table, Text::SimpleTable, Text::ASCIITable (which I usually used), Text::UnicodeTable::Simple, Table::Simple (uses Moose).
Modules used: Text::ANSI::Util, Color::ANSI::Util.
HOMEPAGE
Please visit the project's homepage at https://metacpan.org/release/Text-ANSITable.
SOURCE
Source repository is at https://github.com/sharyanto/perl-Text-ANSITable.
BUGS
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Text-ANSITable
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.
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.