#!/usr/bin/env perl

use strict;
use warnings;

use  App::ansicolumn;
exit App::ansicolumn->new->run(splice @ARGV);

__END__

=encoding utf-8

=head1 NAME

ansicolumn - ANSI terminal sequence aware column command

=head1 SYNOPSIS

ansicolumn [options] [file ...]

    -c#                  output width
    -s#                  separator string
    -t                   table style output
    -l#                  maximum number of table columns
    -x                   exchange rows and columns
    -o#                  output separator
    -R#                  right adjust table columns

    -P[#], --page=#      page mode, with optional page length
    -U[#], --up=#        show in N-up format (-WC# --linestyle=wrap)
    --2up .. --9up       same as -U2 .. -U9
    -D                   document mode
    -C#                  number of panes
    -S#                  pane width
    -W                   widen to terminal width
    -p                   paragraph mode

    -B, --border[=#]     print border with optiona style
    -F, --fillup[=#]     fill-up unit (pane|page|none)

    --height=#           page height
    --column-unit=#      column unit (default 8)
    --linestyle=#        folding style (none|truncate|wrap|wordwrap)
    --boundary=#         line-end boundary
    --linebreak=#        line-break mode (none|all|runin|runout)
    --runin=#            run-in width
    --runout=#           run-out width
    --[no-]pagebreak     allow page break
    --border-style=#     border style
    --[no-]ignore-space  ignore space in table output
    --[no-]white-space   allow white spaces at the top of each panes
    --[no-]isolation     page-end line isolation
    --tabstop=#          tab-stop character
    --tabhead=#          tab-head character
    --tabspace=#         tab-space width
    --tabstyle=#         tab style
    --ambiguous=#        ambiguous character width (narrow|wide)

=head1 VERSION

Version 1.19

=head1 DESCRIPTION

B<ansicolumn> is a L<column(1)> command clone which can handle ANSI
terminal sequences.  It supports traditional options and some of Linux
extended, and other original options.  Empty lines are B<not> ignored,
though.

=head2 COMPATIBLE OPTIONS

The column utility formats its input into multiple columns.  Rows are
filled before columns.  Input is taken from I<file> operands, or, by
default, from the standard input.

=over 7

=item B<-c>#, B<--width>=#, B<--output-width>=#

Output is formatted for a display columns wide.  See L</CALCULATION>
section.

=item B<-s>#, B<--separator>=#

Specify a set of characters to be used to delimit columns for the
-t option.

=item B<-t>, B<--table>

Determine the number of columns the input contains and create a
table.  Columns are delimited with whitespace, by default, or
with the characters supplied using the -s option.  Useful for
pretty-printing displays.

=item B<-l>I<#>, B<--table-columns-limit> I<number>

Specify maximal number of the input columns.  The last column will
contain all remaining line data if the limit is smaller than the
number of the columns in the input data.

=item B<-x>, B<--fillrows>

Fill columns before filling rows.

=item B<-o>#, B<--output-separator>=#

When used B<--table> or B<-t> option, each columns are joined by two
space characters (' ') by default.  This option will change it.

=item B<-R>I<columns>, B<--table-right>=I<columns>

Right align text in these columns.
Support only numbers.

=back

=head2 EXTENDED OPTION

=over 7

=item B<-P>[I<#>], B<--page>[=I<#>]

Page mode.  Set these options.

    --height=# or 1-
    --linestyle=wrap
    --border
    --fillup

If optional number is given, it is used as a page height unless option
B<--height> exists.  Otherwise page height is set to terminal height
minus one.

=item B<-U>#, B<--up>=#, B<--2up> .. B<--9up>

Show in N-up format.  Almost same as B<-P> but does not set page
height.  This is convenient when you want multi-column output without
page control.

=item B<-D>, B<--document>

Document mode.  Set these options.

    --widen
    --linebreak=all
    --linestyle=wrap
    --boundary=word
    --no-white-space
    --no-isolation

Next command display DOCX text in 3-up format using
L<App::optex::textconv>.

    optex -Mtextconv ansicolumn -DPC3 foo.docx | less

=item B<-C>#, B<--pane>=#

Output is formatted in the specified number of panes.  Setting number
of panes implies B<--widen> option enabled.  See L</CALCULATION>
section.

=item B<-S>#, B<--pane-width>=#, B<--pw>=#

Specify pane width.  This includes border spaces.  See L</CALCULATION>
section.

=item B<-W>, B<--widen>

Use full width of the terminal.  Each panes are expanded to fill
terminal width, unless B<--pane-width> is specified.

=item B<-p>, B<--paragraph>

Insert empty line between every successive non-empty lines.

=item B<-B>, B<--border>[=I<style>]

Print border.  Enabled by B<--page> option automatically.  If the
optional I<style> is given, it is used as a border style and precedes
to B<--border-style> option.  Use B<--border=none> to disable it.

Border style is specified by B<--border-style> option.

=item B<-F>, B<--fillup>[=C<pane>|C<page>|C<none>]

Fill up final pane or page by empty lines.  Parameter is optional and
considered as 'pane' by default.  Set by B<--page> option
automatically.  Use B<--fillup=none> if you want to explicitly disable
it.

Option B<-U> is a shortcut for B<--border=pane>.

=item B<--height>=#

Set page height and page mode on.  See L</CALCULATION> section.

=item B<--column-unit>=#, B<--cu>=#

Each columns are placed at the unit of 8 by default.  This option
changes the number of the unit.

=item B<--linestyle>=C<none>|C<truncate>|C<wrap>|C<wordwrap>, B<--ls>=C<...>

Set the style of treatment for longer lines.
Default is C<none>.

B<--linestyle=wordrap> is equivalent to B<--linestyle=wrap>
B<--boundary=word>.

=item B<--boundary>=C<none>|C<word>|C<space>

Set text wrap boundary.  If set as C<word> or C<space>, text is not
wrapped in the middle of alphanumeric word or non-space sequence.
Option B<--document> set this as C<word>.  See L<Text::ANSI::Fold> for
detail.

=item B<--linebreak>=C<none>|C<all>|C<runin>|C<runout>, B<--lb>=...

Set the linebreak mode.

=item B<--runin>=#, B<--runout>=#

Set the number of runin/runout column.
Default is both 2.

=item B<-->[B<no->]B<pagebreak>

Move to next pane when form feed character found.
Default true.

=item B<--border-style>=I<style>, B<--bs>=...

Set the border style.  Current default style is C<vbar>, which is
light vertical line filling the page height.

Sample styles:
none,
space,
vbar,          heavy-vbar,       fat-vbar,
line,          heavy-line,
stick,         heavy-stick,
ascii-frame,
ascii-box,
c-box,
box,           heavy-box,        fat-box,   very-fat-box,
round-box,     heavy-round-box,
frame,         heavy-frame,      fat-frame, very-fat-frame,
page-frame,    heavy-page-frame,
shadow,
shadow-box,    heavy-shadow-box,
comb,          heavy-comb,
rake,          heavy-rake,
mesh,          heavy-mesh,
dumbbell,      heavy-dumbbell,
ribbon,        heavy-ribbon,
round-ribbon,
double-ribbon,
etc.

These are experimental and subject to change, and this document is not
always up-to-date.  See `perldoc -m App::ansicolumn::Border` for
actual data.

You can define your own style in module or startup file.  Put next
lines in your C<$HOME/.ansicolumnrc> file, for example.

    option default --border-style myheart
    __PERL__
    App::ansicolumn::Border->add_style(
        myheart  => {
        left   => [ "\N{WHITE HEART SUIT} ", "\N{BLACK HEART SUIT} " ],
    	center => [ "\N{WHITE HEART SUIT} ", "\N{BLACK HEART SUIT} " ],
    	right  => [ "\N{WHITE HEART SUIT}" , "\N{BLACK HEART SUIT}"  ],
    },
    );

=item B<-->[B<no->]B<ignore-space>, B<-->[B<no->]B<is>

When used B<-t> option, leading spaces are ignored by default.  Use
B<--no-ignore-space> option to disable it.

=item B<-->[B<no->]B<white-space>

Allow white spaces at the top of each panes, or clean them up.
Default true.  Negated by B<--document> option.

=item B<-->[B<no->]B<isolation>

Allow the first line of a paragraph (continuous non-space lines) is
placed at the bottom of a pane.  Default true.  If false, move it to
the top of next pane.  Negated by B<--document> option.

=item B<--tabstop>=#

Set tab width.

=item B<--tabhead>=#

=item B<--tabspace>=#

Set head and following space characters.  Both are space by default.
If the option value is longer than single characger, it is evaluated
as unicode name.

=item B<--tabstyle>=#

Set the style how tab is expanded.  Select from C<dot>, C<symbol> or
C<shade>.  Styles are defined in L<Text::ANSI::Fold> library.

=item B<--ambiguous>=C<wide>|C<narrow>

Specifies how to treat Unicode ambiguous width characters.  Take a
value of 'narrow' or 'wide.  Default is 'narrow'.

=begin comment

=item B<-->[B<no->]B<discard-el>

Discard ANSI Erase Line sequence.  Default true.

=item B<--padchar>=I<char>

Set padding chracter.

=end comment

=back

=head1 CALCULATION

As for B<--height>, B<--width>, B<--pane> and B<--pane-width> options,
besides giving numeric digits, you can calculate the number using
terminal size.  If the expression contains non-digit character, it is
evaluated as a Reverse Polish Notation with the terminal size pushed
on the stack.  Initial value for B<--height> options is terminal
height, and terminal width for others.

    OPTION              VALUE
    =================   =========================
    --height 1-         height - 1
    --height 2/         height / 2
    --height 1-2/       (height - 1) / 2
    --height dup2%-2/   (height - height % 2) / 2

Space and comma characters are ignored in the expression.  So C<1-2/>
and C<< S<1 - 2 /> >> and C<1,-,2,/> are all same.  See `perldoc
Math::RPN` for the expression detail.

Next example select number of panes by dividing terminal width by 85:

    ansicolumn --pane 85/

If you consider the case the terminal width is less than 85:

    ansicolumn --pane 85/,DUP,1>,EXCH,1,IF

=head1 STARTUP

This command is implemented with L<Getopt::EX> module.  So

    ~/.ansicolumnrc

file is read at start up.  If you want use B<--no-white-space> always,
put this line in your F<~/.ansicolumnrc>.

    option default --no-white-space

Also command can be extended by original modules with B<-M>
option. See `perldoc Getopt::EX` for detail.

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::ansicolumn

To get the latest code, use this:

    $ cpanm https://github.com/kaz-utashiro/App-ansicolumn.git

=head1 EXAMPLES

L<https://github.com/kaz-utashiro/App-ansicolumn/tree/master/images>

=head1 SEE ALSO

L<column(1)>,
L<https://man7.org/linux/man-pages/man1/column.1.html>

L<App::ansicolumn>,
L<https://github.com/kaz-utashiro/App-ansicolumn>

L<Text::ANSI::Printf>,
L<https://github.com/kaz-utashiro/Text-ANSI-Printf>

=head1 AUTHOR

Kazumasa Utashiro

=head1 LICENSE

Copyright 2020-2022 Kazumasa Utashiro.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

#  LocalWords:  ansicolumn fillrows tabstop columnunit widen DOCX
#  LocalWords:  linestyle linebreak docx runin runout perldoc cpanm
#  LocalWords:  CPANMINUS perl CPAN Kazumasa Utashiro optex wordwrap
#  LocalWords:  Unicode ansicolumnrc
