App-Greple-xlate
view release on metacpan or search on metacpan
lib/App/Greple/xlate.pm view on Meta::CPAN
s/( +)$/"â£" x length($1)/mge;
print STDERR $_;
}
}
sub clone_context {
my $ctx = shift;
return {
new_texts => [ @{$ctx->{new_texts} // []} ],
source_before => $ctx->{source_before},
source_after => $ctx->{source_after},
hits_before => [ map [ @$_ ], @{$ctx->{hits_before} // []} ],
hits_after => [ map [ @$_ ], @{$ctx->{hits_after} // []} ],
old_pairs => [ map [ @$_ ], @{$ctx->{old_pairs} // []} ],
};
}
sub change_span {
my($old, $new) = @_;
my @old = split //, $old;
my @new = split //, $new;
my $prefix = 0;
$prefix++ while $prefix < @old && $prefix < @new
&& $old[$prefix] eq $new[$prefix];
my $suffix = 0;
$suffix++ while $suffix < @old - $prefix
&& $suffix < @new - $prefix
&& $old[-1 - $suffix] eq $new[-1 - $suffix];
my $old_len = @old - $prefix - $suffix;
my $new_len = @new - $prefix - $suffix;
my $old_change = $old_len
? join('', @old[$prefix .. $prefix + $old_len - 1]) : '';
my $new_change = $new_len
? join('', @new[$prefix .. $prefix + $new_len - 1]) : '';
($prefix, $old_change, $new_change);
}
sub review_quote {
local $_ = shift // '';
s/\\/\\\\/g;
s/\n/\\n/g;
s/\t/\\t/g;
s/"/\\"/g;
qq{"$_"};
}
sub review_change {
my($old_source, $new_source, $old_translation, $new_translation) = @_;
print STDERR "[xlate.pm] Review:\n";
for my $change (
[ source => change_span($old_source, $new_source) ],
[ target => change_span($old_translation, $new_translation) ],
) {
my($label, $offset, $old, $new) = @$change;
printf STDERR " %s \@%d: %s -> %s\n",
$label, $offset, review_quote($old), review_quote($new);
}
}
sub cache_update {
binmode STDERR, ':encoding(utf8)';
my $region = ref $_[0] eq 'HASH' ? shift : { texts => [ @_ ] };
my @from = @{$region->{texts}};
my @pristine = @from;
my $context = $region->{context};
if ($context) {
my $refs = @{$context->{hits_before} // []}
+ @{$context->{hits_after} // []};
my $olds = @{$context->{old_pairs} // []};
_progress({label => "Context"},
sprintf("%d reference pair(s), %d previous pair(s)",
$refs, $olds));
}
if ($dryrun) {
my @preview = @from;
if ($anonobj) {
$anonobj->mask(@preview);
$anonobj->reset;
}
if ($maskobj) {
$maskobj->mask(@preview);
$maskobj->reset;
}
_progress({label => "From"}, @preview);
# Populate cache with original text so callback can fetch it
@cache{@{$region->{texts}}} = @from;
return @from;
}
my @result = eval {
my $masked_context = $context;
if ($anonobj) {
$anonobj->mask(@from);
if ($context) {
$masked_context = clone_context($context);
$anonobj->mask_reference(@{$masked_context->{new_texts}});
$anonobj->mask_reference(
$masked_context->{source_before},
$masked_context->{source_after});
for my $pairs (@{$masked_context}{qw(hits_before hits_after old_pairs)}) {
$anonobj->mask_reference(@$_) for @$pairs;
}
}
}
$maskobj->mask(@from) if $maskobj;
# Show the payload as it will be transmitted, consistent with
# the dryrun preview and the --xlate-mask display.
_progress({label => "From"}, @from);
warn Dumper $masked_context if $context and opt('debug');
my @chop = grep { $from[$_] =~ s/(?<!\n)\z/\n/ } keys @from;
my @to = do {
local $call_context = $masked_context;
map { s/ +$//mgr } &XLATE(@from);
};
chop @to[@chop];
$maskobj->unmask(@to)->reset if $maskobj;
if ($anonobj) {
$anonobj->unmask(@to);
$anonobj->reset;
}
( run in 0.960 second using v1.01-cache-2.11-cpan-364913b4093 )