diff options
Diffstat (limited to 'msguntypot')
-rw-r--r-- | msguntypot | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/msguntypot b/msguntypot new file mode 100644 index 0000000..d900c75 --- /dev/null +++ b/msguntypot @@ -0,0 +1,237 @@ +#! /usr/bin/env perl +eval 'exec perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + +# msg untypo pot -- Update the PO files when you remove a typo in POT file not needing any translation update +# +# Copyright 2005 by Martin Quinson (mquinson#debian.fr) +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of GPL v2.0 or later (see COPYING). + +my $VERSION=$Locale::Po4a::TransTractor::VERSION; + +=head1 NAME + +msguntypot - update PO files when a typo is fixed in POT file + +=head1 SYNOPSIS + +B<msguntypot> B<-o> I<old_pot> B<-n> I<new_pot> I<pofiles> ... + +=head1 DESCRIPTION + +When you fix a trivial error which surely doesn't affect translations (e.g. +a typo) in a POT file, you should unfuzzy the corresponding msgstr in the +translated PO files to avoid so extra work to the translators. + +This task is difficult and error prone when done manually, and this tool is +there to help doing so correctly. You just need to provide the two versions +of the POT file: before the edition and after as marked in the above +synopsis, and it all becomes automatic. + +=head1 HOW TO USE IT + +In short, when you discover a typo in one of your [english] message, do the +following: + +=over + +=item - Regenerate your POT and PO files. + + make -C po/ update-po # for message program translations + debconf-updatepo # for debconf translations + po4a po4a.conf # for po4a based documentation translations + +or something else, depending on your project's building settings. You know +how to make sure your POT and PO files are uptodate, don't you?? + +=item - Make a copy of your POT file. + + cp myfile.pot myfile.pot.orig + +=item - Make a copy of all your PO files. + + mkdir po_fridge; cp *.po po_fridge + +=item - Fix your typo. + +$EDITOR the_file_in_which_there_is_a_typo + +=item - Regenerate your POT and PO files. + +See above. + +=back + +At this point, the typo fix fuzzied all the translations, and this +unfortunate change is the only one between the PO files of your main +directory and the one from the fridge. Here is how to solve this. + +=over + +=item - Discard fuzzy translation, restore the ones from the fridge. + + cp po_fridge/*.po . + +=item - Manually merge the PO files with the new POT file, but taking the useless fuzzy into account. + + msguntypot -o myfile.pot.orig -n myfile.pot *.po + +=item - Cleanups. + + rm -rf myfile.pot.orig po_fridge + +=back + +You're done. The typo was eradicated from msgstr of both your POT and PO +files, and the PO files were not fuzzyied in the process. Your translators +love you already. + +=head1 SEE ALSO + +Despite its name, this tool is not part of the gettext tool suite. It is +instead part of po4a. More precisely, it's a random Perl script using the +fine po4a modules. For more information about po4a, please see: + +L<po4a(7)> + +=head1 AUTHORS + + Martin Quinson (mquinson#debian,org) + +=head1 COPYRIGHT AND LICENSE + +Copyright 2005 by SPI, inc. + +This program is free software; you may redistribute it and/or modify it +under the terms of GPL v2.0 or later (see the COPYING file). + +=cut + +use 5.16.0; +use strict; +use warnings; + +use Getopt::Long qw(GetOptions); + +use Locale::Po4a::TransTractor; +use Locale::Po4a::Common; + +use Pod::Usage qw(pod2usage); + +use File::Temp; + +Locale::Po4a::Common::textdomain('po4a'); + +sub show_version { + Locale::Po4a::Common::show_version("msguntypot"); + exit 0; +} + +my ($help,$debug,@verbose,$quiet,$noprevious); +@verbose = (); +$debug = 0; + +my ($newfile,$oldfile)=("",""); + +Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); +GetOptions( + 'help|h' => \$help, + + 'new|n=s' => \$newfile, + 'old|o=s' => \$oldfile, + + 'verbose|v' => \@verbose, + 'debug|d' => \$debug, + 'quiet|q' => \$quiet, + 'no-previous' => \$noprevious, + 'version|V' => \&show_version +) or pod2usage(); + +# Argument check +$help && pod2usage (-verbose => 1, -exitval => 0); + +my ($verbose) = (scalar @verbose); +$verbose = 1 if $debug; +$verbose = -1 if $quiet; +my %options = ( + "verbose" => $verbose, + "debug" => $debug); + +# Argument checking +defined($oldfile) && length($oldfile) || die wrap_msg(gettext("Mandatory argument '%s' missing."), "-o"); +-e $oldfile || die wrap_msg(gettext("File %s does not exist."), $oldfile); +defined($newfile) && length($newfile) || die wrap_msg(gettext("Mandatory argument '%s' missing."), "-n"); +-e $newfile || die wrap_msg(gettext("File %s does not exist."), $newfile); + +# Parse files +my $newpot=Locale::Po4a::Po->new(); +my $oldpot=Locale::Po4a::Po->new(); +$newpot->read($newfile); +$oldpot->read($oldfile); + +die wrap_msg(gettext("The new and old POT files have different amount of strings (%d != %d).". + " Something's seriously wrong here."), + $newpot->count_entries(), $oldpot->count_entries()) + if ($newpot->count_entries() != $oldpot->count_entries()); + +# Compare them and find differences between them +my (%diff)=(); + +for (my ($o,$n)=(0,0) ; + $o<$oldpot->count_entries() && $n<$newpot->count_entries(); + $o++,$n++) { + + my ($oldstr,$newstr)=($oldpot->msgid($o),$newpot->msgid($n)); + + $diff{$oldstr} = $newstr + if ($oldstr ne $newstr); + + } +print wrap_msg(gettext("Found %d modified entries."),scalar keys %diff) if $verbose; + +my $msgmergeOpts = ($noprevious ? "" : "--previous"); + +# Get all po files and report differences in them +my ($pofile); +(undef,$pofile)=File::Temp::tempfile("po4aXXXX", + DIR => File::Spec->tmpdir(), + SUFFIX => ".po", + OPEN => 0, + UNLINK => 0) + or die wrap_msg(gettext("Cannot create a temporary PO file: %s"), $!); + +my $pocount = 0; +while (my $poarg = shift) { + $pocount ++; + print wrap_msg(gettext("Handling %s"),$poarg) if $verbose; + my $cmd = "msgmerge $msgmergeOpts -o $pofile --silent $poarg $oldfile"; + if (system($cmd)) { + my $msg = $!; + unlink ($pofile); + die wrap_msg(gettext("Could not run msgmerge: %s\nThe command was: %s"), $msg, $cmd); + } + my $po=Locale::Po4a::Po->new(); + $po->read($pofile); + + for (my $n=0 ; $n<$po->count_entries(); $n++) { + my $str=$po->msgid($n); + next unless defined $str; + my $newstr = $diff{$str}; + + if (defined $newstr) { + $po->{po}{ $newstr } = { %{ $po->{po}{ $str } } }; + $po->{po}{ $str } = (); + delete $po->{po}{ $str }; + print wrap_msg(gettext("msguntypot changed msgid \"%s\" to \"%s\" in %s\n"),$str,$newstr,$poarg) if ($verbose); + } + } + $po->write($poarg); +} +unlink($pofile); + +print wrap_msg(gettext("Modified %d entries in %d files."),scalar keys %diff,$pocount); + +exit 0; +__END__; |