NAME Text::ANSITable - Create a nice formatted table using extended ASCII and ANSI colors VERSION version 0.06 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('bold'); # if not, a nice default is picked $t->color_theme('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; 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. Border styles are searched in the %border_styles variable in each searched package. Hash keys are border style names, hash values are border style specifications. To choose border style, either set the "border_style" attribute to an available border style or a border specification directly. $t->border_style("singleh_boxchar"); $t->border_style("foo"); # 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. When there are lots of "Text::ANSITable::BorderStyle::*" modules, searching can add some overhead. To avoid searching in all modules, you can specify name using "Subpackage::Name" syntax, e.g.: # will only search in Text::ANSITable::BorderStyle::Default $t->color_theme("Default::bricko"); 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. Format for the "chars" specification key: [ [A, b, C, D], # 0 [E, F, G], # 1 [H, i, J, K], # 2 [L, M, N], # 3 [O, p, Q, R], # 4 [S, t, U, V], # 5 ] AbbbCbbbD #0 Top border characters E F G #1 Vertical separators for header row HiiiJiiiK #2 Separator between header row and first data row L M N #3 Vertical separators for data row OpppQpppR #4 Separator between data rows L M N #3 StttUtttV #5 Bottom border characters Each character must have visual width of 1. But if A is an empty string, the top border line will not be drawn. Likewise: if H is an empty string, the header-data separator line will not be drawn; if S is an empty string, bottom border line will not be drawn. 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. Color themes are searched in the %color_themes variable in each searched package. Hash keys are color theme names, hash values are color theme specifications. To choose a color theme, either set the "color_theme" attribute to an available color theme or a border specification directly. $t->color_theme("default_nogradation"); $t->color_theme("foo"); # 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. When there are lots of "Text::ANSITable::ColorTheme::*" modules, searching can add some overhead. To avoid searching in all modules, you can specify name using "Subpackage::Name" syntax, e.g.: # will only search in Text::ANSITable::ColorTheme::Default $t->color_theme("Default::default_nogradation"); 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. Color for items must be specified as 6-hexdigit RGB value (like "ff0088") or ANSI escape codes (e.g. "\e[31;1m" for bold red foregound color, or "\e[48;5;226m" for lemon yellow background color). You can also return a 2-element array containing RGB value for foreground and background, respectively. For flexibility, color can also be a coderef which should produce a color value. This allows you to do, e.g. gradation border color, random color, etc (see Text::ANSITable::ColorTheme::Demo). Code will be called with "($self, %args)" where %args contains various information, like "name" (the item name being requested). You can get the row position from "$self->{_draw}{y}". 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" attribute This 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" attribute This 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" attribute This sets left and right padding for all columns. * table-level "cell_lpad" and "cell_rpad" attributes They 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 "row_vpad" attribute This sets top and bottom padding for all rows. * table-level "row_tpad"/"row_bpad" attributes They set top/bottom padding separately for all rows. * per-row "vpad" style Example: $t->set_row_style($rownum, vpad => 1); When adding row: $t->add_row($rownum, {vpad=>1}); * per-row "tpad"/"vpad" style Example: $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" and "cell_bgcolor" attributes Sets 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" and "bgcolor" styles Example: $t->set_column_style('colname', fgcolor => 'fa8888'); $t->set_column_style('colname', bgcolor => '202020'); * per-row fgcolor and bgcolor styles Example: $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 and bgcolor styles Example: $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" and "cell_valign" attribute * per-column "align" and "valign" styles Example: $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" and "valign" styles * per-cell "align" and "valign" 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}". 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 "Color::ANSI::Util"'s "detect_color_depth()". 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 via LANG environment variable, or 1. If "use_utf8" is set to 0, an attempt to select a border style that uses Unicode characters will result in an exception. (In the future, setting "use_utf8" to 0 might opt the module to use the non-"mb_*" version of functions from Text::ANSI::Util, e.g. "ta_wrap()" instead of "ta_mbwrap()", and so on). 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->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". $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. 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. FAQ General My table looks garbled when viewed through pager like less! It's because less escapes ANSI color codes. Try using "-R" option of less to display ANSI color codes raw. Or, try not using boxchar border styles, use the utf8 or ascii version. Try not using colors. 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 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 I'm getting 'Wide character in print' error message when I use utf8 border styles! Add something like this first before printing to your output: binmode(STDOUT, ":utf8"); How to hide borders? There is currently no "show_border" attribute. Choose border styles like "space_ascii" or "none_utf8": $t->border_style("none"); 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 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. Set your "TERM" to "xterm-256color". Also make sure your terminal emulator supports 256 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{y} % 2 ? '202020' : undef }); TODO/BUGS 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 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. AUTHOR Steven Haryanto COPYRIGHT AND LICENSE This software is copyright (c) 2013 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. FUNCTIONS None are exported by default, but they are exportable.