summaryrefslogtreecommitdiffstats
path: root/msguntypot
diff options
context:
space:
mode:
Diffstat (limited to 'msguntypot')
-rw-r--r--msguntypot237
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__;