#!/usr/bin/perl -w # # Author: Petter Reinholdtsen # Date: 2001-08-05 # Source: http://www.student.uit.no/~pere/linux/ # # Read available translations from .po files, and allow translations # already done in one file to be inserted into all the other places # where the original text occurs. # # Usage: auto_translate # # Changes: # 2001-08-05 v0.2 # Fixed bug. Unable to handle multiline 'msgid'. # 2001-08-05 v0.3 # Add 'fuzzy' tag when inserting text. # 2001-08-05 v0.4 # Only add 'fuzzy' tag in the changed files. #use strict; use Getopt::Std; my ($pofile, %translation, @problem, %msgstrs, %files); my $showfile = 1; ######################################################################### sub add_translation { my ($pofile, $msgid, $msgstr) = @_; # print " Translation: $msgid = $msgstr\n"; $msgstr = $1; $msgstrs{"$msgid\t$msgstr"}++; push(@{$files{"$msgid\t$msgstr"}}, $pofile); if ( !defined($translation{$msgid}) ) { push(@{$translation{$msgid}}, $msgstr); } else { if ( ! in_array($msgstr, $translation{$msgid}) ) { push(@{$translation{$msgid}}, $msgstr); push(@problem, $msgid) unless grep($msgid, @problem); } } $msgid = ""; } sub in_array ($$) { my ($str, $aref) = @_; my $test; for $test (@$aref) { return 1 if ($test eq $str); } return 0; } sub replace_translation { my ($filename, $msgid, $msgstr) = @_; my $count = 0; open(POTMPFILE, ">$filename.new") || die "Unable to open $filename.new"; open(POFILE, "<$filename") || die "Unable to open $filename"; while () { chomp; my @lines = (); if (m/^msgid\s+\"(.*)\"\s*$/) { my $thisid = $1; my $thisstr = ""; push(@lines, $_); while () { chomp; push(@lines, $_); if (m/^\s*\"(.+)\"\s*$/) { print "Appending \'$thisid\' \n + \'$1\'\n" if ($debug); $thisid .= $1; } if (m/^msgstr\s\"(.*)\"\s*$/) { print "ID: $thisid\n" if ($debug); $thisstr = $1; while () { chomp; push(@lines, $_); last if (/^\s*$/); if (m/^\s*\"(.+\")\s*$/) { $thisstr .= $1; } } print "Msg: $thisstr\n" if ($debug); last; } } if ("\"$thisid\"" eq $msgid && "\"$thisstr\"" ne $msgstr) { print POTMPFILE "#, fuzzy\n"; print POTMPFILE "msgid $msgid\n"; print POTMPFILE "msgstr $msgstr\n"; print POTMPFILE "\n"; $count++; } else { print POTMPFILE join("\n", @lines), "\n"; } } else { print POTMPFILE "$_\n"; } } close(POFILE) || die "unable to close $filename"; close(POTMPFILE) || die "unable to close $filename.new"; rename "$filename.new", $filename; if (0 == $count) { print "Did not find anything to replace!\n"; } } sub choose_transl { my ($msgid) = @_; print "\n$msgid\n"; my $msgstr; my $num = 0; print " $num - skip this translation\n"; my @strings = sort { $msgstrs{"$msgid\t$b"} <=> $msgstrs{"$msgid\t$a"}; } @{$translation{$msgid}}; my %curfiles; for $msgstr (@strings) { $num++; print " $num $msgstr # (" . $msgstrs{"$msgid\t$msgstr"}. ") " or die; print "[" . join(",", @{$files{"$msgid\t$msgstr"}}) . "]" or die if $showfile; print "\n" or die; my $file; for $file (@{$files{"$msgid\t$msgstr"}}) { $curfiles{$file}++; } } if ($num != 2) { print "** To many choices. **\n"; return; } print "Choice: "; $choice = ; return if (0 == $choice); $msgstr = $strings[$choice-1]; print "\n Translating $msgid as $msgstr in\n"; for $file (keys %curfiles) { print " $file\n"; replace_translation($file, $msgid, $msgstr); } } # Remove leading space and '&' before comparing sub kde_magic_sort { my $aa = $a; my $bb = $b; $aa =~ s/\&|^\s+//; $bb =~ s/\&|^\s+//; return lc($aa) cmp lc($bb); } sub translate { my ($msgid); my ($count, $icount) = (0,0); for $msgid (sort kde_magic_sort keys %translation ) { $count++; if ( 1 < scalar(@{$translation{$msgid}}) ) { $icount++; choose_transl($msgid); } } } sub read_files { my @argv = @_; for $pofile ( @argv ) { open(POFILE, "<$pofile") || next; my ($next, $msgid, $msgstr); while (1) { $_ = $next || ; last unless $_; $next = ""; chomp; s/^\#.+$//; # Remove comments next if (/^\s*$/); if (/^msgid (\".+)/) { $msgid = $1; while () { chomp; unless (/^\"/) { $next = $_; last; } $msgid .= $_; $msgid =~ s/\"\"//; } $msgstr = ""; next; } if (/^msgstr (\".+)/) { $msgstr = $1; while () { chomp; unless (/^\"/) { $next = $_; last; } $msgstr .= $_; $msgstr =~ s/\"\"//; } add_translation($pofile, $msgid, $msgstr); $msgid = ""; $msgstr = ""; } } close(POFILE); } } ######################################################################### getopt('f'); if (defined $opt_f) { $showfile = 1; print "Showing filenames\n"; } print "Reading .po files...\n"; read_files(@ARGV); print "Ready to autotranslate\n"; translate();