App-CSVUtils

 view release on metacpan or  search on metacpan

lib/App/CSVUtils/csv2paras.pm  view on Meta::CPAN

    notes: Has no last name\nMight be adopted sometime by Jimmy

    name: matthew
    email: matthew@example.com
    phone: 555-1239
    notes: Quit\n\n  or fired?

If a CSV value contains literal "\" (backslash) it will be escaped as "\\".

Long lines are also by default folded at 78 columns (but you can customize with
the `--width` option); if a line is folded a literal backslash is added to the
end of each physical line and the next line will be indented by two spaces:

    notes: This is a long note. This is a long note. This is a long note. This is
      a long note. This is a long note.

A long word is also folded and the next line will be indented by one space:

    notes: Thisisalongwordthisisalongwordthisisalongwordthisisalongwordthisisalongw
     ord

Newline and backslash are also escaped in header; additionally a literal ":"
(colon) is escaped into "\:".

There is option to skip displaying empty fields (`--hide-empty-values`) and to
align the ":" header separator.

Keywords: paragraphs, cards, pages, headers

_
    add_args => {
        width => {
            summary => 'The width at which to fold long lines, -1 means to never fold',
            schema => ['int*', 'clset|'=>[{is=>-1, "is.err_msg"=>"Must be >0 or -1"}, {min=>1}]],
            default => 78,
        },
        hide_empty_values => {
            summary => 'Whether to skip showing empty values',
            schema => 'bool*',
        },
        align => {
            summary => 'Whether to align header separator across lines',
            schema => 'bool*',
            description => <<'_',

Note that if you want to convert the paragraphs back to CSV later using
<prog:paras2csv>, the padding spaces added by this option will become part of
header value, unless you use its `--trim-header` or `--rtrim-header` option.

_
        },
    },
    links => [
        {url=>'prog:paras2csv'},
    ],
    tags => ['category:converting'],

    examples => [
        {
            summary => 'Convert to paragraphs format, show fields alphabetically, do not fold, hide empty values',
            src => 'csv-sort-fields INPUT.csv | [[prog]] --width=-1 --hide-empty-values',
            src_plang => 'bash',
            test => 0,
            'x.doc.show_result' => 0,
        },
    ],

    on_input_header_row => sub {
        my $r = shift;

        # these are the keys we add to the stash
        $r->{escaped_headers} = [];
        $r->{longest_header_len} = 0;

        for my $field (@{ $r->{input_fields} }) {
            push @{ $r->{escaped_headers} }, _escape_header($field);
            my $l = length($r->{escaped_headers}[-1]);
            $r->{longest_header_len} = $l if $r->{longest_header_len} < $l;
        }
    },

    on_input_data_row => sub {
        my $r = shift;

        print "\n" if $r->{input_data_rownum} > 1;

        for my $i (0 .. $#{ $r->{input_fields} }) {
            my $val = $r->{input_row}[$i];
            next if $r->{util_args}{hide_empty_values} && length $val == 0;
            my $line =
                ($r->{util_args}{align} ? pad($r->{escaped_headers}[$i], $r->{longest_header_len}, "r") : $r->{escaped_headers}[$i]).
                ": ".
                _escape_value($val);
            if ($r->{util_args}{width} == -1 || length($line) <= $r->{util_args}{width}) {
                print $line, "\n";
            } else {
                require Text::Wrap::NoStrip;
                local $Text::Wrap::NoStrip::columns = $r->{util_args}{width};
                my $wrapped_line = Text::Wrap::NoStrip::wrap("", " ", $line);
                print $wrapped_line, "\n";
            }
        }
    },

    writes_csv => 0,
);

1;
# ABSTRACT: Convert CSV to paragraphs

__END__

=pod

=encoding UTF-8

=head1 NAME

App::CSVUtils::csv2paras - Convert CSV to paragraphs

=head1 VERSION



( run in 0.832 second using v1.01-cache-2.11-cpan-39bf76dae61 )