App-Greple-xlate

 view release on metacpan or  search on metacpan

lib/App/Greple/xlate.pm  view on Meta::CPAN

    if ($xlate_engine) {
	my $mod = __PACKAGE__ . "::$xlate_engine";
	if (eval "require $mod") {
	    $mod->import;
	} else {
	    die "Engine $xlate_engine is not available.\n";
	}
	no strict 'refs';
	${"$mod\::lang_from"} = $lang_from;
	${"$mod\::lang_to"} = $lang_to;
	*XLATE = \&{"$mod\::xlate"};
	if (not defined &XLATE) {
	    die "No \"xlate\" function in $mod.\n";
	}
    }
    if (my $pat = opt('mask')) {
	$maskobj = App::Greple::xlate::Mask->new(pattern => $pat);
    }
    if (my $patfile = opt('maskfile')) {
	$maskobj = App::Greple::xlate::Mask->new(file => $patfile);
    }
}

use App::Greple::xlate::Text;

sub postgrep {
    my $grep = shift;
    my @miss;
    for my $r ($grep->result) {
	my($b, @match) = @$r;
	for my $m (@match) {
	    my($s, $e, $i) = @$m;
	    my $key = App::Greple::xlate::Text
		->new($grep->cut(@$m), paragraph => ($i % 2 == 0))
		->normalized;
	    if (not exists $cache{$key}) {
		$cache{$key} = undef;
		push @miss, $key;
	    }
	}
    }
    cache_update(@miss) if @miss;
}

sub _progress {
    my $opt = ref $_[0] ? shift : {};
    opt('progress') or return;
    if (my $label = $opt->{label}) { print STDERR "[xlate.pm] $label:\n" }
    for (my @s = @_) {
	my $i =()= /^/mg;
	my @m = ($i == 1 ? '╶' : '│') x $i ;
	@m[0,-1] = qw(┌ └) if $i > 1;
	s/^/sprintf "%7s ", shift(@m)/mge;
	s/(?<!\n)\z/\n/;
	s/( +)$/"␣" x length($1)/mge;
	print STDERR $_;
    }
}

sub cache_update {
    binmode STDERR, ':encoding(utf8)';

    my @from = @_;
    _progress({label => "From"}, @from);
    return @from if $dryrun;

    $maskobj->mask(@from) if $maskobj;
    my @chop = grep { $from[$_] =~ s/(?<!\n)\z/\n/ } keys @from;
    my @to = map { s/ +$//mgr } &XLATE(@from);
    chop @to[@chop];
    $maskobj->unmask(@to)->reset if $maskobj;

    _progress({label => "To"}, @to);
    die "Unmatched response:\n@to" if @from != @to;
    @cache{@_} = @to;
}

sub fold_lines {
    state $fold = Text::ANSI::Fold->new(
	width     => $fold_width,
	boundary  => 'word',
	linebreak => LINEBREAK_ALL,
	runin     => 4,
	runout    => 4,
    );
    local $_ = shift;
    s/(.+)/join "\n", $fold->text($1)->chops/ge;
    $_;
}

sub xlate {
    my $param = { @_ };
    my($index, $text) = $param->@{qw(index match)};
    my $obj = App::Greple::xlate::Text->new($text,
					    paragraph => ($index % 2 == 0));
    my $s = $cache{$obj->normalized} // "!!! TRANSLATION ERROR !!!\n";
    $obj->unstrip($s);
    $s = fold_lines $s if $fold_line;
    if (state $formatter = $formatter{$output_format}) {
	return $formatter->($text, $s);
    } else {
	return $s;
    }
}
sub callback { goto &xlate }

sub mask_string {
    my($s) = +{ @_ }->{match};
    if ($maskobj) {
	$maskobj->mask($s);
    }
    $s;
}

sub cache_file {
    my $file = sprintf("%s.xlate-%s-%s.json",
		       $current_file, $xlate_engine, $lang_to);
    if ($cache_method eq 'auto') {
	-f $file ? $file : undef;
    } else {
	if ($cache_method and -f $current_file) {



( run in 1.441 second using v1.01-cache-2.11-cpan-97f6503c9c8 )