| 1 | #!/usr/bin/perl |
|---|
| 2 | |
|---|
| 3 | # Movable Type (r) Open Source (C) 2005-2009 Six Apart, Ltd. |
|---|
| 4 | # This program is distributed under the terms of the |
|---|
| 5 | # GNU General Public License, version 2. |
|---|
| 6 | # |
|---|
| 7 | # $Id$ |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | |
|---|
| 11 | use lib './lib'; |
|---|
| 12 | use lib './extlib'; |
|---|
| 13 | $| = 1; |
|---|
| 14 | |
|---|
| 15 | use Getopt::Long; |
|---|
| 16 | |
|---|
| 17 | my $L10N_FILE = 'lib/MT/L10N/ja.pm'; |
|---|
| 18 | |
|---|
| 19 | GetOptions( |
|---|
| 20 | 't:s' => \$L10N_FILE, |
|---|
| 21 | ); |
|---|
| 22 | |
|---|
| 23 | my %conv; |
|---|
| 24 | my %lconv; |
|---|
| 25 | |
|---|
| 26 | eval { |
|---|
| 27 | require "$L10N_FILE"; |
|---|
| 28 | }; |
|---|
| 29 | if ($@) { |
|---|
| 30 | die "Failed to load $L10N_FILE: $@"; |
|---|
| 31 | } |
|---|
| 32 | |
|---|
| 33 | my $lang = $L10N_FILE; |
|---|
| 34 | $lang =~ s!^lib/MT/L10N/!!; |
|---|
| 35 | $lang =~ s!\.pm$!!; |
|---|
| 36 | no strict 'refs'; |
|---|
| 37 | %conv = %{'MT::L10N::' . $lang . '::Lexicon'}; |
|---|
| 38 | foreach (keys %conv) { |
|---|
| 39 | $lconv{lc $_} = $conv{$_}; |
|---|
| 40 | my $key = $_; |
|---|
| 41 | my $key_esc = $key; |
|---|
| 42 | my $value_esc = $conv{$key}; |
|---|
| 43 | $key_esc =~ s/\'/\\'/sg; |
|---|
| 44 | $conv{$key_esc}=$value_esc; |
|---|
| 45 | $key_esc = $key; |
|---|
| 46 | $key_esc =~ s/\n/\\n/sg; |
|---|
| 47 | $conv{$key_esc}=$value_esc; |
|---|
| 48 | $key_esc = $key; |
|---|
| 49 | $key_esc =~ s/\"/\\"/sg; |
|---|
| 50 | $conv{$key_esc}=$value_esc; |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | my (%phrase, %is_used, $args); |
|---|
| 54 | my $text = <>; |
|---|
| 55 | my $tmpl = $ARGV; |
|---|
| 56 | exit unless $text; |
|---|
| 57 | do { |
|---|
| 58 | if (($tmpl ne $ARGV) || eof()) { |
|---|
| 59 | #printf "\n\t## %s\n", $tmpl; |
|---|
| 60 | printf "\n## %s\n", $tmpl; |
|---|
| 61 | $tmpl = $ARGV; |
|---|
| 62 | if ( $tmpl =~ m|plugins/([\-\w]+)/\w+| ) { |
|---|
| 63 | my $plugin = $1; |
|---|
| 64 | eval { |
|---|
| 65 | unshift @INC, "plugins/$plugin/lib"; |
|---|
| 66 | }; |
|---|
| 67 | eval { |
|---|
| 68 | require "plugins/$plugin/lib/$plugin/L10N/$lang.pm"; |
|---|
| 69 | }; |
|---|
| 70 | if ($@) { |
|---|
| 71 | # Deep dive into sub directories to find L10N |
|---|
| 72 | my $path = "plugins/$plugin/lib"; |
|---|
| 73 | $path = find_l10n_dir($path); |
|---|
| 74 | if ( $path && ($path =~ /L10N$/) ) { |
|---|
| 75 | eval { |
|---|
| 76 | require "$path/$lang.pm"; |
|---|
| 77 | }; |
|---|
| 78 | if ($@) { |
|---|
| 79 | $plugin = undef; |
|---|
| 80 | } |
|---|
| 81 | else { |
|---|
| 82 | $path =~ s|plugins/$plugin/lib/||g; |
|---|
| 83 | $path =~ s|/|::|g; |
|---|
| 84 | $plugin = $path; |
|---|
| 85 | } |
|---|
| 86 | } |
|---|
| 87 | else { |
|---|
| 88 | $plugin = undef; |
|---|
| 89 | } |
|---|
| 90 | } |
|---|
| 91 | else { |
|---|
| 92 | $plugin .= '::L10N'; |
|---|
| 93 | } |
|---|
| 94 | if ($plugin) { |
|---|
| 95 | %conv = ( |
|---|
| 96 | %conv, |
|---|
| 97 | %{$plugin . '::' . $lang . '::Lexicon'}, |
|---|
| 98 | ); |
|---|
| 99 | } |
|---|
| 100 | } |
|---|
| 101 | elsif ( $tmpl =~ m|addons/(\w+)\.pack/\w+| ) { |
|---|
| 102 | my $addon = $1; |
|---|
| 103 | eval { |
|---|
| 104 | unshift @INC, "addons/$addon.pack/lib"; |
|---|
| 105 | require "addons/$addon.pack/lib/MT/$addon/L10N/$lang.pm" |
|---|
| 106 | }; |
|---|
| 107 | unless ($@) { |
|---|
| 108 | %conv = ( |
|---|
| 109 | %conv, |
|---|
| 110 | %{'MT::' . $addon . '::L10N::' . $lang . '::Lexicon'}, |
|---|
| 111 | ); |
|---|
| 112 | } |
|---|
| 113 | } |
|---|
| 114 | %phrase = (); |
|---|
| 115 | my $t; |
|---|
| 116 | while ($text =~ m!(<(?:_|MT)_TRANS(?:\s+((?:\w+)\s*=\s*(["'])(?:<[^>]+?>|[^\3]+?)*?\3))+?\s*/?>)!igm) { |
|---|
| 117 | my($msg, %args) = ($1); |
|---|
| 118 | while ($msg =~ /\b(\w+)\s*=\s*(["'])((?:<[^>]+?>|[^\2])*?)?\2/g) { #' |
|---|
| 119 | $args{$1} = $3; |
|---|
| 120 | } |
|---|
| 121 | my $trans = ''; |
|---|
| 122 | if (exists $args{phrase}) { |
|---|
| 123 | if ($trans eq '' && $conv{$args{phrase}}) { |
|---|
| 124 | $trans = $conv{$args{phrase}}; |
|---|
| 125 | $is_used{$args{phrase}} = 1; |
|---|
| 126 | } |
|---|
| 127 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 128 | $args{phrase} =~ s/([^\\])'/$1\\'/g; |
|---|
| 129 | $args{phrase} =~ s/\\"/"/g; |
|---|
| 130 | |
|---|
| 131 | unless ($phrase{$args{phrase}}) { |
|---|
| 132 | $phrase{$args{phrase}} = 1; |
|---|
| 133 | |
|---|
| 134 | my $q = "'"; |
|---|
| 135 | if ($args{phrase} =~ /\\n/) { |
|---|
| 136 | $q = '"'; |
|---|
| 137 | } |
|---|
| 138 | if ($args{phrase} =~ /[^\\]'/) { |
|---|
| 139 | $q = '"'; |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | if ($trans) { |
|---|
| 143 | printf "\t$q%s$q => '%s',\n", $args{phrase}, $trans; # Print out translation if there was an existing one |
|---|
| 144 | } else { |
|---|
| 145 | $trans = $lconv{lc $args{phrase}}; |
|---|
| 146 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 147 | my $reason = $trans?'Case':'New'; # Really new translation or just different case |
|---|
| 148 | printf "\t$q%s$q => '%s', # Translate - $reason\n", $args{phrase}, $trans; # Print out translation if there was an existing one based on the lowercase string, empty otherwise |
|---|
| 149 | } |
|---|
| 150 | } |
|---|
| 151 | } |
|---|
| 152 | } |
|---|
| 153 | while ($text =~ /(?:translate|errtrans|trans_error|trans|translate_escape|maketext)\s*\(((?:\s*(?:"(?:[^"\\]+|\\.)*"|'(?:[^'\\]+|\\.)*')\s*\.?\s*){1,})[,\)]/gs) { |
|---|
| 154 | my($msg, %args); |
|---|
| 155 | my $p = $1; |
|---|
| 156 | while ($p =~ /"((?:[^"\\]+|\\.)*)"|'((?:[^'\\]+|\\.)*)'/gs) { |
|---|
| 157 | $args{'phrase'} .= ($1 || $2); |
|---|
| 158 | } |
|---|
| 159 | my $trans = ''; |
|---|
| 160 | $args{phrase} =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 161 | $args{phrase} =~ s/['"]\s*.\s*\n\s*['"]//gs; |
|---|
| 162 | $args{phrase} =~ s/['"]\s*\n\s*.\s*['"]//gs; |
|---|
| 163 | my $phrase = $args{phrase}; |
|---|
| 164 | $phrase =~ s/\\?\\'/'/g; |
|---|
| 165 | if ($trans eq '' && $conv{$phrase}) { |
|---|
| 166 | $trans = $conv{$phrase}; |
|---|
| 167 | $is_used{$phrase} = 1; |
|---|
| 168 | } |
|---|
| 169 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 170 | next if ($phrase{$args{phrase}}); |
|---|
| 171 | $phrase{$args{phrase}} = 1; |
|---|
| 172 | my $q = "'"; |
|---|
| 173 | if ($args{phrase} =~ /\\n|[^\\]'/) { |
|---|
| 174 | $q = '"'; |
|---|
| 175 | } |
|---|
| 176 | $args{phrase} =~ s/\\\\'/\\'/g; |
|---|
| 177 | if ($trans) { |
|---|
| 178 | printf "\t$q%s$q => $q%s$q,\n", $args{phrase}, $trans; # Print out the translation if there was an existing one |
|---|
| 179 | } else { |
|---|
| 180 | $trans = $lconv{lc $args{phrase}} || ''; |
|---|
| 181 | my $reason = $trans ? "Case" : "New"; # New translation, or just different case? |
|---|
| 182 | printf "\t$q%s$q => $q%s$q, # Translate - $reason\n", $args{phrase}, $trans; # Print out the translation if there was an existing one based on the lowercase string, else empty |
|---|
| 183 | } |
|---|
| 184 | } |
|---|
| 185 | while ($text =~ /\s*label\s*=>\s*(["'])(.*?)([^\\])\1/gs) { |
|---|
| 186 | my($msg, %args); |
|---|
| 187 | my $trans = ''; |
|---|
| 188 | $args{phrase} = $2.$3; |
|---|
| 189 | |
|---|
| 190 | if ($trans eq '' && $conv{$args{phrase}}) { |
|---|
| 191 | $trans = $conv{$args{phrase}}; |
|---|
| 192 | $is_used{$args{phrase}} = 1; |
|---|
| 193 | } |
|---|
| 194 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 195 | next if ($phrase{$args{phrase}}); |
|---|
| 196 | $phrase{$args{phrase}} = 1; |
|---|
| 197 | my $q = "'"; |
|---|
| 198 | if ($args{phrase} =~ /\\n/) { |
|---|
| 199 | $q = '"'; |
|---|
| 200 | } |
|---|
| 201 | if ($trans) { |
|---|
| 202 | printf "\t$q%s$q => '%s',\n", $args{phrase}, $trans; # Print out the translation if there was an existing one |
|---|
| 203 | } else { |
|---|
| 204 | $trans = $lconv{lc $args{phrase}} || ''; |
|---|
| 205 | my $reason = $trans ? "Case" : "New"; # New translation, or just different case? |
|---|
| 206 | printf "\t$q%s$q => '%s', # Translate - $reason\n", $args{phrase}, $trans; # Print out the translation if there was an existing one based on the lowercase string, else empty |
|---|
| 207 | } |
|---|
| 208 | } |
|---|
| 209 | if ($tmpl =~ /(services|streams)\.yaml$/) { |
|---|
| 210 | while ($text =~ /\s*(?:description|ident_hint|label|name):\s*(.+)/g) { |
|---|
| 211 | my($msg, %args); |
|---|
| 212 | my $trans = ''; |
|---|
| 213 | $args{phrase} = $1; |
|---|
| 214 | $args{phrase} =~ s/(^'+|'+$)//; |
|---|
| 215 | $args{phrase} =~ s/'/\\'/g; |
|---|
| 216 | if ($trans eq '' && $conv{$args{phrase}}) { |
|---|
| 217 | $trans = $conv{$args{phrase}}; |
|---|
| 218 | $is_used{$args{phrase}} = 1; |
|---|
| 219 | } |
|---|
| 220 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 221 | next if ($phrase{$args{phrase}}); |
|---|
| 222 | $phrase{$args{phrase}} = 1; |
|---|
| 223 | my $q = "'"; |
|---|
| 224 | if ($args{phrase} =~ /\\n/) { |
|---|
| 225 | $q = '"'; |
|---|
| 226 | } |
|---|
| 227 | if ($trans) { |
|---|
| 228 | printf "\t$q%s$q => '%s',\n", $args{phrase}, $trans; # Print out the translation if there was an existing one |
|---|
| 229 | } else { |
|---|
| 230 | $trans = $lconv{lc $args{phrase}} || ''; |
|---|
| 231 | my $reason = $trans ? "Case" : "New"; # New translation, or just different case? |
|---|
| 232 | printf "\t$q%s$q => '%s', # Translate - $reason\n", $args{phrase}, $trans; # Print out the translation if there was an existing one based on the lowercase string, else empty |
|---|
| 233 | } |
|---|
| 234 | } |
|---|
| 235 | } |
|---|
| 236 | elsif ($tmpl =~ /\.yaml$/) { |
|---|
| 237 | while ($text =~ /\s*label:\s*(.+)/g) { |
|---|
| 238 | my($msg, %args); |
|---|
| 239 | my $trans = ''; |
|---|
| 240 | $args{phrase} = $1; |
|---|
| 241 | $args{phrase} =~ s/(^'+|'+$)//; |
|---|
| 242 | $args{phrase} =~ s/'/\\'/g; |
|---|
| 243 | if ($trans eq '' && $conv{$args{phrase}}) { |
|---|
| 244 | $trans = $conv{$args{phrase}}; |
|---|
| 245 | $is_used{$args{phrase}} = 1; |
|---|
| 246 | } |
|---|
| 247 | $trans =~ s/([^\\]?)'/$1\\'/g; |
|---|
| 248 | next if ($phrase{$args{phrase}}); |
|---|
| 249 | $phrase{$args{phrase}} = 1; |
|---|
| 250 | my $q = "'"; |
|---|
| 251 | if ($args{phrase} =~ /\\n/) { |
|---|
| 252 | $q = '"'; |
|---|
| 253 | } |
|---|
| 254 | if ($trans) { |
|---|
| 255 | printf "\t$q%s$q => '%s',\n", $args{phrase}, $trans; # Print out the translation if there was an existing one |
|---|
| 256 | } else { |
|---|
| 257 | $trans = $lconv{lc $args{phrase}} || ''; |
|---|
| 258 | my $reason = $trans ? "Case" : "New"; # New translation, or just different case? |
|---|
| 259 | printf "\t$q%s$q => '%s', # Translate - $reason\n", $args{phrase}, $trans; # Print out the translation if there was an existing one based on the lowercase string, else empty |
|---|
| 260 | } |
|---|
| 261 | } |
|---|
| 262 | } |
|---|
| 263 | $text = ''; |
|---|
| 264 | } |
|---|
| 265 | $text .= $_ if $_; |
|---|
| 266 | } while (<>); |
|---|
| 267 | exit; |
|---|
| 268 | |
|---|
| 269 | print "\n\n\t## not used\n"; |
|---|
| 270 | foreach my $p (keys %conv) { |
|---|
| 271 | $p =~ s/([^\\])'/$1\\'/g; |
|---|
| 272 | unless ($is_used{$p}) { |
|---|
| 273 | my $trans = ''; |
|---|
| 274 | if ($conv{$p}) { |
|---|
| 275 | $trans = $conv{$p}; |
|---|
| 276 | $is_used{$p} = 0; |
|---|
| 277 | } |
|---|
| 278 | my $q = "'"; |
|---|
| 279 | if ($p =~ /\\[a-z]/) { |
|---|
| 280 | $q = '"'; |
|---|
| 281 | } |
|---|
| 282 | $trans =~ s/([^\\])'/$1\\'/g; |
|---|
| 283 | printf "\t$q%s$q => '%s',\n", $p, '';#$trans; |
|---|
| 284 | #printf "\nmsgid \"%s\"\nmsgstr \"%s\"\n", $p, $trans; |
|---|
| 285 | } |
|---|
| 286 | } |
|---|
| 287 | |
|---|
| 288 | sub find_l10n_dir { |
|---|
| 289 | my ($path) = @_; |
|---|
| 290 | return 0 unless -d $path; |
|---|
| 291 | if ( opendir my $dh, $path ) { |
|---|
| 292 | my @items = readdir $dh; |
|---|
| 293 | closedir $dh; |
|---|
| 294 | for my $item (@items) { |
|---|
| 295 | next if ( $item =~ /^\.\.?$/ || $item =~ /~$/ ); |
|---|
| 296 | require File::Spec; |
|---|
| 297 | my $full_path = File::Spec->catfile( $path, $item ); |
|---|
| 298 | next if ( -f $full_path ); |
|---|
| 299 | if ( ( $item eq 'L10N' ) && -d $full_path ) { |
|---|
| 300 | return $full_path; |
|---|
| 301 | } |
|---|
| 302 | if ( my $found = find_l10n_dir($full_path) ) { |
|---|
| 303 | return $found; |
|---|
| 304 | } |
|---|
| 305 | } |
|---|
| 306 | } |
|---|
| 307 | return 0; |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | 1; |
|---|