App-PickRandomLines
view release on metacpan or search on metacpan
script/pick view on Meta::CPAN
# }
# }
#
# FORMAT_CELLS:
# {
# my $tffmt = $resmeta->{'table.field_formats'};
# my $tffmt_code = $resmeta->{'table.field_format_code'};
# my $tffmt_default = $resmeta->{'table.default_field_format'};
# last unless $tffmt || $tffmt_code || $tffmt_default;
#
# my (@fmt_names, @fmt_opts); # key: column index
# for my $i (0..$#columns) {
# my $field_idx = $field_idxs[$i];
# my $fmt = $tffmt_code ? $tffmt_code->($columns[$i]) : undef;
# $fmt //= $tffmt->[$field_idx] if $field_idx >= 0;
# $fmt //= $tffmt_default;
# if (ref $fmt eq 'ARRAY') {
# $fmt_names[$i] = $fmt->[0];
# $fmt_opts [$i] = $fmt->[1] // {};
# } else {
# $fmt_names[$i] = $fmt;
# $fmt_opts [$i] = {};
# }
# }
#
# my $nf;
#
# for my $i (0..$#{$data}) {
# next if $i==0 && $header_row;
# my $row = $data->[$i];
# for my $j (0..$#columns) {
# next unless defined $row->[$j];
# my $fmt_name = $fmt_names[$j];
# #say "D:j=$j fmt_name=$fmt_name";
# next unless $fmt_name;
# my $fmt_opts = $fmt_opts [$j];
# if ($fmt_name eq 'iso8601_datetime' || $fmt_name eq 'iso8601_date' || $fmt_name eq 'datetime' || $fmt_name eq 'date') {
# if ($row->[$j] =~ /\A[0-9]+(\.[0-9]*)?\z/) {
# my $frac = $1 ? "0$1"+0 : 0;
# my @t = gmtime($row->[$j]);
# if ($fmt_name eq 'iso8601_datetime' || $fmt_name eq 'datetime') {
# $row->[$j] = sprintf(
# "%04d-%02d-%02dT%02d:%02d:".($frac ? "%06.3f" : "%02d")."Z",
# $t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]+$frac);
# } else {
# $row->[$j] = sprintf(
# "%04d-%02d-%02d",
# $t[5]+1900, $t[4]+1, $t[3]);
# }
# }
# } elsif ($fmt_name eq 'boolstr') {
# $row->[$j] = $row->[$j] ? "yes" : "no";
# } elsif ($fmt_name eq 'filesize') {
# require Format::Human::Bytes;
# $row->[$j] = Format::Human::Bytes::base2($row->[$j], 0);
# } elsif ($fmt_name eq 'sci2dec') {
# if ($row->[$j] =~ /\A(?:[+-]?)(?:\d+\.|\d*\.(\d+))[eE]([+-]?\d+)\z/) {
# my $n = length($1 || "") - $2; $n = 0 if $n < 0;
# $row->[$j] = sprintf("%.${n}f", $row->[$j]);
# }
# } elsif ($fmt_name eq 'percent') {
# my $fmt = $fmt_opts->{sprintf} // '%.2f%%';
# $row->[$j] = sprintf($fmt, $row->[$j] * 100);
# } elsif ($fmt_name eq 'number') {
# require Number::Format::BigFloat;
# $row->[$j] = Number::Format::BigFloat::format_number(
# $row->[$j], {
# thousands_sep => $fmt_opts->{thousands_sep} // ',',
# decimal_point => $fmt_opts->{decimal_point} // '.',
# decimal_digits => $fmt_opts->{precision} // 0,
# # XXX decimal_fill
# });
# }
# }
# }
# }
#
# if ($format eq 'text-pretty') {
# ALIGN_COLUMNS:
# {
# last unless @$data;
#
# # note: the logic of this block of code now also put in Number::Pad
#
# # XXX we just want to turn off 'uninitialized' and 'negative repeat
# # count does nothing' from the operator x
# no warnings;
#
# my $tfa = $resmeta->{'table.field_aligns'};
# my $tfa_code = $resmeta->{'table.field_align_code'};
# my $tfa_default = $resmeta->{'table.default_field_align'};
#
# # align numbers by default, with 'right' currently as 'number' is too slow
# unless ($tfa || $tfa_code || $tfa_default) {
# $tfa = [map { undef } 0 .. $#columns];
# COLUMN:
# for my $colidx (0 .. $#columns) {
# for my $i (0 .. $#{$data}) {
# next if $header_row && $i == 0;
# my $cell = $data->[$i][$colidx];
# next unless defined $cell;
# next COLUMN unless $cell =~ /\A[+-]?[0-9]+(?:\.[0-9]*)?(?:[Ee][+-]?[0-9]+)?(?:%)?\z/;
# }
# $tfa->[$colidx] = 'right';
# }
# }
# #use DD; dd $tfa;
# #say "D1";
#
# for my $colidx (0..$#columns) {
# my $field_idx = $field_idxs[$colidx];
# my $align = $tfa_code ? $tfa_code->($columns[$colidx]) : undef;
# $align //= $tfa->[$field_idx] if $field_idx >= 0;
# $align //= $tfa_default;
# next unless $align;
#
# # determine max widths
# my $maxw;
# my ($maxw_bd, $maxw_d, $maxw_ad); # before digit, digit, after d
# if ($align eq 'number') {
# my (@w_bd, @w_d, @w_ad);
# for my $i (0..$#{$data}) {
# my $row = $data->[$i];
# if (@$row > $colidx) {
# my $cell = $row->[$colidx];
# if ($header_row && $i == 0) {
# my $w = length($cell);
# push @w_bd, 0;
# push @w_bd, 0;
# push @w_ad, 0;
# } elsif ($cell =~ /\A([+-]?\d+)(\.?)(\d*)[%]?\z/) {
# # decimal notation number (with optional percent sign). TODO: allow arbitraty units after number, e.g. ml, mcg, etc? but should we align the unit too?
# push @w_bd, length($1);
# push @w_d , length($2);
# push @w_ad, length($3);
# } elsif ($cell =~ /\A([+-]?\d+\.?\d*)([eE])([+-]?\d+)\z/) {
# # scientific notation number
# push @w_bd, length($1);
# push @w_d , length($2);
# push @w_ad, length($3);
# } else {
# # not a number
# push @w_bd, length($cell);
# push @w_bd, 0;
# push @w_ad, 0;
# }
# } else {
# push @w_bd, 0;
# push @w_d , 0;
# push @w_ad, 0;
# }
# }
# $maxw_bd = max(@w_bd);
# $maxw_d = max(@w_d);
# $maxw_ad = max(@w_ad);
# if ($header_row) {
# my $w = length($data->[0][$colidx]);
# if ($maxw_d == 0 && $maxw_ad == 0) {
# $maxw_bd = $w;
# }
# }
# }
#
# $maxw = max(map {
# @$_ > $colidx ? length($_->[$colidx]) : 0
# } @$data);
#
# # do the alignment
# for my $i (0..$#{$data}) {
# my $row = $data->[$i];
# for my $i (0..$#{$data}) {
# my $row = $data->[$i];
# next unless @$row > $colidx;
# my $cell = $row->[$colidx];
# next unless defined($cell);
# if ($align eq 'number') {
# my ($bd, $d, $ad);
# if ($header_row && $i == 0) {
# } elsif (($bd, $d, $ad) = $cell =~ /\A([+-]?\d+)(\.?)(\d*)\z/) {
# $cell = join(
# '',
# (' ' x ($maxw_bd - length($bd))), $bd,
# $d , (' ' x ($maxw_d - length($d ))),
# $ad, (' ' x ($maxw_ad - length($ad))),
# );
# } elsif (($bd, $d, $ad) = $cell =~ /\A([+-]?\d+\.?\d*)([eE])([+-]?\d+)\z/) {
# $cell = join(
# '',
# (' ' x ($maxw_bd - length($bd))), $bd,
# $d , (' ' x ($maxw_d - length($d ))),
# $ad, (' ' x ($maxw_ad - length($ad))),
# );
script/pick view on Meta::CPAN
#result"> to "pretty text" if it can do so, e.g. the structure can be represented
#as a 2-dimensional table. Otherwise, it falls back to JSON or Perl. The table
#formats supported include CSV, TSV, LTSV, or HTML. More table formats (e.g. Org,
#Markdown) are supported via L<Text::Table::Any> when you set
#L</"FORMAT_PRETTY_TABLE_BACKEND">.
#
#This module is a more lightweight version of L<Perinci::Result::Format> but the
#long-term goal is to reunite the two formatting modules back to a
#modular/pluggable module.
#
#=for Pod::Coverage ^(firstidx)$
#
#=head1 SUPPORTED RESULT METADATA PROPERTIES/ATTRIBUTES
#
#The L<enveloped result specification|Rinci::function/"Enveloped result">
#specifies various properties/attributes that can be used as formatting hints.
#Below are the list of properties/attributes supported by this module, including
#those that are not in the specification:
#
#=over
#
#=item * table.html_class
#
#Str. Used when formatting result as HTML table.
#
#=item * table.fields
#
#Array of str. Define fields in order. Used when formatting result as text table.
#Fields that are not defined in this array will be displayed after the defined
#fields (or hidden, if you set C<table.hide_unknown_fields>).
#
#=item * table.hide_unknown_fields
#
#Bool. If set to true, then unknown fields (those not defined in C<table.fields>)
#will not be shown. Used when formatting result as text table.
#
#=item * table.field_orders
#
#Array of str. Like C<table.fields>, but with higher precedence.
#
#=item * table.field_labels
#
#Array of str. Define labels for each field (each element correspond to the field
#of the same element as defined in C<table.fields>). Used when formatting result
#as text table. Will show this in header for fields instead the actual field
#name.
#
#=item * table.field_units
#
#Array of str. Define units for each field (each element correspond to the field
#of the same element as defined in C<table.fields>). Used when formatting result
#as text table. Will show this along with field name/label. For example if a
#field's unit is defined as `cm` and field name is `length`, then the field
#header will show as `length (cm)`.
#
#=item * table.field_formats
#
#Array of str. Define format for each field (each element correspond to the field
#of the same element as defined in C<table.fields>). Used when formatting result
#as text table. Known formats: `iso8601_datetime`, `iso8601_date`, `datetime`,
#`date`, `boolstr`, `filesize`, `sci2dec`, `percent`, `number`.
#
#=item * table.field_format_code
#
#Coderef. Will be called with argument of field name. Expected to return format
#name (see C<table.field_formats>). Used when formatting result as text table.
#This option can be used when you want to dynamically determine a suitable format
#based on field name.
#
#=item * table.default_field_format
#
#Str. Instead of defining format for each field using `table.field_formats`, you
#can also specify default format for all fields.
#
#=item * table.field_aligns
#
#Array of str. Define alignment for each field (each element correspond to the
#field of the same element as defined in C<table.fields>). Used when formatting
#result as text table. Known alignment value for each field: `number` (special
#rule to align on decimal point or `E`), `right`, `middle`|`center`, `right`.
#
#=item * table.field_align_code
#
#Coderef. Will be called with argument of field name. Expected to return
#alignment name (see C<table.field_aligns>). Used when formatting result as text
#table. This option can be used when you want to dynamically determine a suitable
#alignment based on field name.
#
#=item * table.default_field_align
#
#Str. Instead of defining alignment for each field using `table.field_aligns`,
#you can also specify default alignment for all fields.
#
#=back
#
#=head1 FUNCTIONS
#
#=head2 format($res, $format[ , $is_naked=0, $cleanse=1 ]) => str
#
#=head1 ENVIRONMENT
#
#=head2 FORMAT_PRETTY_TABLE_BACKEND
#
#Str, optional. If this is set, will render text table using L<Text::Table::Any>
#(with C<backend> set to the value of this environment variable) instead of the
#default L<Text::Table::Sprintf>. This is useful if you want to output text table
#in a different format, for example to generate Org tables (make sure
#L<Text::Table::Org> backend is already installed):
#
# % FORMAT_PRETTY_TABLE_BACKEND=Text::Table::Org lcpan rdeps Getopt::Lucid
#
#For convenience, a default is chosen for you under certain condition. When
#inside Emacs (environment C<INSIDE_EMACS> is set), C<Text::Table::Org> is used
#as default.
#
#=head2 FORMAT_PRETTY_TABLE_BACKEND_OPTS
#
#Str, JSON-encoding expected. This setting is to accompany
#L</FORMAT_PRETTY_TABLE_BACKEND>, to be passed to
#L<Text::Table::Any>C<::table()>'s C<backend_opts> argument. It should be a hash
#encoded in JSON, e.g.:
( run in 0.719 second using v1.01-cache-2.11-cpan-39bf76dae61 )