App-CSVUtils
view release on metacpan or search on metacpan
lib/App/CSVUtils/paras2csv.pm view on Meta::CPAN
package App::CSVUtils::paras2csv;
use 5.010001;
use strict;
use warnings;
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2025-02-04'; # DATE
our $DIST = 'App-CSVUtils'; # DIST
our $VERSION = '1.036'; # VERSION
use App::CSVUtils qw(gen_csv_util);
sub _unescape_field {
my $val = shift;
$val =~ s/(\\:|\\n|\\\\|[^\\:]+)/$1 eq "\\\\" ? "\\" : $1 eq "\\n" ? "\n" : $1 eq "\\:" ? ":" : $1/eg;
$val;
}
sub _unescape_value {
my $val = shift;
$val =~ s/(\\n|\\\\|[^\\]+)/$1 eq "\\\\" ? "\\" : $1 eq "\\n" ? "\n" : $1/eg;
$val;
}
sub _parse_line {
my $line = shift;
$line =~ s/\R //g;
$line =~ /((?:[^\\:]+|\\n|\\\\|\\:)+): (.*)/ or return;
my $field = _unescape_field($1);
my $value = _unescape_value($2);
($field, $value);
}
sub _parse_para {
my ($r, $para, $idx) = @_;
my @h;
while ($para =~ s/\A(.+(?:\R .*)*)(?:\R|\z)//g) {
#say "D:line=<$1>, para=<$para>";
my ($field, $val) = _parse_line($1);
defined $field or die [400, "Paragraph[$idx]: Can't parse line $1"];
if ($r->{util_args}{trim_header}) {
$field =~ s/\A\s+//;
$field =~ s/\s+\z//;
} elsif ($r->{util_args}{ltrim_header}) {
$field =~ s/\A\s+//;
} elsif ($r->{util_args}{rtrim_header}) {
$field =~ s/\s+\z//;
}
push @h, $field, $val;
}
@h;
}
gen_csv_util(
name => 'paras2csv',
summary => 'Convert paragraphs to CSV',
description => <<'_',
This utility is the counterpart of the <prog:csv2paras> utility. See its
documentation for more details.
Keywords: paragraphs, cards, pages, headers
_
add_args => {
input_file => {
schema => 'filename*',
default => '-',
pos => 0,
},
trim_header => {
schema => 'bool*',
},
rtrim_header => {
schema => 'bool*',
},
ltrim_header => {
schema => 'bool*',
},
},
add_args_rels => {
'choose_one&' => [ [qw/trim_header rtrim_header ltrim_header/] ],
},
links => [
{url=>'prog:csv2paras'},
],
tags => ['category:converting'],
examples => [
{
summary => 'Convert paragraphs format to CSV',
src => '[[prog]] - OUTPUT.csv',
src_plang => 'bash',
test => 0,
'x.doc.show_result' => 0,
},
],
reads_csv => 0,
after_read_input => sub {
my $r = shift;
my $fh;
if ($r->{util_args}{input_file} eq '-') {
$fh = \*STDIN;
} else {
open $fh, "<", $r->{util_args}{input_file}
or die [500, "Can't read file '$r->{util_args}{input_file}: $!"];
}
local $/ = "";
my $i = 0;
while (my $para = <$fh>) {
$para =~ s/\R{2}\z//;
#say "D:para=<$para>";
my @h = _parse_para($r, $para, $i);
$i++;
if ($i == 1) {
my @h2 = @h;
my $j = 0;
while (my ($field, $value) = splice @h2, 0, 2) {
$r->{output_fields}[$j] = $field;
$r->{output_fields_idx}{$field} = $j;
$j++;
}
}
my @vals;
while (my ($field, $value) = splice @h, 0, 2) {
push @vals, $value;
}
$r->{code_print_row}->(\@vals);
}
},
);
1;
# ABSTRACT: Convert paragraphs to CSV
__END__
=pod
=encoding UTF-8
=head1 NAME
App::CSVUtils::paras2csv - Convert paragraphs to CSV
=head1 VERSION
This document describes version 1.036 of App::CSVUtils::paras2csv (from Perl distribution App-CSVUtils), released on 2025-02-04.
=head1 FUNCTIONS
=head2 paras2csv
Usage:
paras2csv(%args) -> [$status_code, $reason, $payload, \%result_meta]
Convert paragraphs to CSV.
This utility is the counterpart of the L<csv2paras> utility. See its
documentation for more details.
Keywords: paragraphs, cards, pages, headers
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<input_file> => I<filename> (default: "-")
( run in 0.309 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )