App-Greple-msdoc
view release on metacpan or search on metacpan
lib/App/Greple/msdoc.pm view on Meta::CPAN
L<App::optex::textconv>,
L<https://github.com/kaz-utashiro/optex-textconv>
L<App::ansicolumn>,
L<https://qiita.com/kaz-utashiro/items/30594c16ed6d931324f9>
(in Japanese)
=head1 AUTHOR
Kazumasa Utashiro
=head1 LICENSE
Copyright 2018-2024 Kazumasa Utashiro.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
package App::Greple::msdoc;
our $VERSION = '1.07';
use strict;
use warnings;
use v5.14;
use Carp;
use utf8;
use Encode;
use Exporter 'import';
our @EXPORT = ();
our %EXPORT_TAGS = ();
our @EXPORT_OK = ();
use App::Greple::Common qw(&FILELABEL);
use Data::Dumper;
our $indent_mark = "| ";
our $opt_space = undef;
our $opt_separator = undef;
our $opt_type;
our $default_format = 'text';
sub separate_xml {
s{ (?<=>) ([^<]*) }{ $1 ? "\n$1\n" : "\n" }gex;
}
sub indent_xml {
my %arg = @_;
my $file = delete $arg{&FILELABEL} or die;
my %nonewline = do {
map { $_ => 1 }
map { @{$_->[1]} }
grep { $file =~ $_->[0] } (
[ qr/\.doc[xm]$/, [ qw(w:t w:delText w:instrText wp:posOffset) ] ],
[ qr/\.ppt[xm]$/, [ qw(a:t) ] ],
[ qr/\.xls[xm]$/, [ qw(t v f formula1) ] ],
);
};
my $level = 0;
s{
(?<mark>
(?<single>
< (?<tag>[\w:]+) [^>]* />
)
|
(?<open>
< (?<tag>[\w:]+) [^>]* (?<!/) >
)
|
(?<close>
< / (?<tag>[\w:]+) >
)
)
}{
if (not $+{single} and $nonewline{$+{tag}}) {
join("", $+{open} ? $indent_mark x $level : "",
$+{mark},
$+{close} ? "\n" : "");
}
else {
$+{close} and $level--;
($indent_mark x ($+{open} ? $level++ : $level)) . $+{mark} . "\n";
}
}gex;
}
use Archive::Zip;
use App::optex::textconv::msdoc qw(to_text get_list);
my %formatter = (
'indent-xml' => \&indent_xml,
'separate-xml' => \&separate_xml,
);
sub extract_content {
my %arg = @_;
my $file = $arg{&FILELABEL} or die;
my $type = ($file =~ /\.((?:doc|xls|ppt)[xm])$/)[0] or die;
my $pid = open(STDIN, '-|') // croak "process fork failed: $!";
binmode STDIN, ':encoding(utf8)';
if ($pid) {
return $pid;
}
my $format = $arg{format} // $default_format;
if ($format eq 'text') {
print decode 'utf8', to_text($file);
exit;
} elsif ($format =~ /xml$/) {
my $zip = Archive::Zip->new($file);
my @xml;
for my $entry (get_list($zip, $type)) {
my $member = $zip->memberNamed($entry) or next;
my $xml = $member->contents or next;
push @xml, $xml;
( run in 0.838 second using v1.01-cache-2.11-cpan-cd2fffc590a )