diff --git a/debian/changelog b/debian/changelog index 184a1e65..e5ab198b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,8 +6,10 @@ choose-mirror (0.046) UNRELEASED; urgency=low - Update Installer-Menu-Item. * Joey Hess - Make sort-countries clean up after itself. + * Christian Perrier + - code for better handling of countries. Not used yet - -- Bastian Blank Mon, 21 Jun 2004 14:26:16 +0200 + -- Christian Perrier Fri, 2 Jul 2004 20:15:07 +0200 choose-mirror (0.045) unstable; urgency=low diff --git a/debian/po/fa.po b/debian/po/fa.po index 867116d8..02f3708f 100644 --- a/debian/po/fa.po +++ b/debian/po/fa.po @@ -36,13 +36,18 @@ msgstr " پروتکل بارگیری فایلها:" msgid "" "Please select the file download protocol. If unsure, select \"http\"; it is " "less prone to problems involving firewalls." -msgstr "لطفا پروتکل دلخواهتان را برای بارگیری فایلها انتخاب کنید. اگر شک دارید \"http\" را اتخاب کنید. این پروتکل در رویارویی با دیواره‌های آتش کمتر دچار اشکال میشود." +msgstr "" +"لطفا پروتکل دلخواهتان را برای بارگیری فایلها انتخاب کنید. اگر شک دارید " +"\"http\" را اتخاب کنید. این پروتکل در رویارویی با دیواره‌های آتش کمتر دچار " +"اشکال میشود." #. Type: string #. Description #: ../choose-mirror.templates:34 -msgid "Please enter the hostname of the mirror from which Debian will be downloaded." -msgstr "لطفا نام میزبان شعبه ای را که میخواهید دبیان از آنجا بارگیری شود وارد کنید." +msgid "" +"Please enter the hostname of the mirror from which Debian will be downloaded." +msgstr "" +"لطفا نام میزبان شعبه ای را که میخواهید دبیان از آنجا بارگیری شود وارد کنید." #. Type: string #. Description @@ -56,7 +61,9 @@ msgstr "اطلاعات پراکسی HTTP(اگر پروکسی ندارید خال msgid "" "If you need to use a HTTP proxy to access the outside world, enter the proxy " "information here. Otherwise, leave this blank." -msgstr "اگر برای ارتباط با اینترنت احتیاج به تنظیم پراکسی دارید؛ این اطلاعات را اینجا وارد کنید در غیر این صورت خالی بگذازید" +msgstr "" +"اگر برای ارتباط با اینترنت احتیاج به تنظیم پراکسی دارید؛ این اطلاعات را " +"اینجا وارد کنید در غیر این صورت خالی بگذازید" #. Type: string #. Description @@ -64,7 +71,9 @@ msgstr "اگر برای ارتباط با اینترنت احتیاج به تن msgid "" "The proxy information should be given in the standard form of \"http://" "[[user][:pass]@]host[:port]/\"" -msgstr "اطلاعات پراکسی باید به صورت استاندارد \"http://[[user][:pass]@]host[:port]/\" وارد گردد." +msgstr "" +"اطلاعات پراکسی باید به صورت استاندارد \"http://[[user][:pass]@]host[:port]/" +"\" وارد گردد." #. Type: select #. Description @@ -79,7 +88,9 @@ msgid "" "Please select a Debian archive mirror. You should use a mirror in your " "country or region if you do not know which mirror has the best Internet " "connection to you." -msgstr " لطفا یکی از شعبه‌های آرشیو دبیان را انتخاب کنید. اگر نمیدانید کدامیک از آنها برای شما بهتر است باید شعبه ای را در منطقه یا کشور خود انتخاب کنید." +msgstr "" +" لطفا یکی از شعبه‌های آرشیو دبیان را انتخاب کنید. اگر نمیدانید کدامیک از آنها " +"برای شما بهتر است باید شعبه ای را در منطقه یا کشور خود انتخاب کنید." #. Type: select #. Description @@ -127,7 +138,9 @@ msgstr "اطلاعات پراکسی FTP(اگر پروکسی ندارید خال msgid "" "If you need to use a FTP proxy to access the outside world, please enter the " "proxy information here. Otherwise, leave this blank." -msgstr "اگر برای ارتباط با اینترنت توسط FTP احتیاج به تنظیم پراکسی دارید؛ این اطلاعات را اینجا وارد کنید در غیر این صورت خالی بگذازید." +msgstr "" +"اگر برای ارتباط با اینترنت توسط FTP احتیاج به تنظیم پراکسی دارید؛ این " +"اطلاعات را اینجا وارد کنید در غیر این صورت خالی بگذازید." #. Type: string #. Description @@ -136,8 +149,8 @@ msgid "" "The proxy information should be the standard form of \"http://[[user][:pass]" "@]host[:port]/\"." msgstr "" -" اطلاعات پراکسی FTP باید به صورت استاندارد: " -"\"http://[[user][:pass]@]host[:port]/\". باشد." +" اطلاعات پراکسی FTP باید به صورت استاندارد: \"http://[[user][:pass]@]host[:" +"port]/\". باشد." #. Type: select #. Choices @@ -159,7 +172,11 @@ msgid "" "Unstable is untested and frequently changing. Testing is a middle ground, " "that receives many of the new versions from unstable if they are not too " "buggy." -msgstr "دبیان در چند نوع مختلف قابل دسترسی است: \"پایدار\" نسخه‌ایست که به خوبی آزمایش شده و به ندرت تغییر میکند. \"ناپایدار\" نسخه ایست که آزمایش نشده و به طور مداوم در حال تغییر است. \" آزمایشی\" نسخه ای بینابینی است که بسیاری از ویرایش‌های جدید را در صورتی که زیاد مشکل نداشته باشند از نسخه ناپایدار میگیرد." +msgstr "" +"دبیان در چند نوع مختلف قابل دسترسی است: \"پایدار\" نسخه‌ایست که به خوبی " +"آزمایش شده و به ندرت تغییر میکند. \"ناپایدار\" نسخه ایست که آزمایش نشده و به " +"طور مداوم در حال تغییر است. \" آزمایشی\" نسخه ای بینابینی است که بسیاری از " +"ویرایش‌های جدید را در صورتی که زیاد مشکل نداشته باشند از نسخه ناپایدار میگیرد." #. Type: string #. Description @@ -556,5 +573,7 @@ msgid "" "The goal is to find a mirror of the Debian archive that is close to you on " "the network -- be aware that nearby countries, or even your own, may not be " "the best choice." -msgstr "هدف انتخاب شعبه‌ای از آرشیو دبیان است که بر روی اینترنت به شما نزدیکتر باشد -- باید توجه داشته باشید که کشورهای نزدیک و یا حتی کشور خودتان ممکن است بهترین انتخاب نباشد.س" - +msgstr "" +"هدف انتخاب شعبه‌ای از آرشیو دبیان است که بر روی اینترنت به شما نزدیکتر باشد " +"-- باید توجه داشته باشید که کشورهای نزدیک و یا حتی کشور خودتان ممکن است " +"بهترین انتخاب نباشد.س" diff --git a/debian/po/ko.po b/debian/po/ko.po index 22e97cf9..002e8fa2 100644 --- a/debian/po/ko.po +++ b/debian/po/ko.po @@ -23,7 +23,9 @@ msgstr "파일 내려받을 때 사용할 프로토콜:" msgid "" "Please select the file download protocol. If unsure, select \"http\"; it is " "less prone to problems involving firewalls." -msgstr "파일 내려받기 프로토콜을 선택하십시오. 잘 모르겠으면, \"http\"를 선택하십시오; http가 방화벽 관련한 문제에 가장 덜 민감합니다." +msgstr "" +"파일 내려받기 프로토콜을 선택하십시오. 잘 모르겠으면, \"http\"를 선택하십시" +"오; http가 방화벽 관련한 문제에 가장 덜 민감합니다." #. Type: string #. Description diff --git a/debian/rules b/debian/rules index 7ae99e85..fe91f47e 100755 --- a/debian/rules +++ b/debian/rules @@ -4,6 +4,22 @@ build: build-stamp build-stamp: dh_testdir $(MAKE) small + + # C. Perrier 2/7/2004 + # DO NOT actually uncomment these + # the scripts have not been tested enough + # we'd better include this for post-rc1 + # Grab ISO codes from iso-codes package + #chmod u+x ./get-iso-codes + #./get-iso-codes + # Yes, we use this one, embarked, because it has been + # hacked for using partial translations in lists + #chmod u+x ./intltool-merge + # Build the templates + #chmod u+x ./mktemplates + #./mktemplates + # END of do not uncomment + touch build-stamp clean: diff --git a/intltool-merge b/intltool-merge new file mode 100755 index 00000000..6bfc807b --- /dev/null +++ b/intltool-merge @@ -0,0 +1,1369 @@ +#!/usr/bin/perl -w + +# +# The Intltool Message Merger +# +# Copyright (C) 2000, 2003 Free Software Foundation. +# Copyright (C) 2000, 2001 Eazel, Inc +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Maciej Stachowiak +# Kenneth Christiansen +# Darin Adler +# +# Proper XML UTF-8'ification written by Cyrille Chepelov +# + +## Release information +my $PROGRAM = "intltool-merge"; +my $PACKAGE = "intltool"; +my $VERSION = "0.30"; + +## Loaded modules +use strict; +use Getopt::Long; +use Text::Wrap; +use File::Basename; + +my $must_end_tag = -1; +my $last_depth = -1; +my $translation_depth = -1; +my @tag_stack = (); +my @entered_tag = (); +my @translation_strings = (); +my $leading_space = ""; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $BA_STYLE_ARG = 0; +my $XML_STYLE_ARG = 0; +my $KEYS_STYLE_ARG = 0; +my $DESKTOP_STYLE_ARG = 0; +my $SCHEMAS_STYLE_ARG = 0; +my $RFC822DEB_STYLE_ARG = 0; +my $QUIET_ARG = 0; +my $PASS_THROUGH_ARG = 0; +my $UTF8_ARG = 0; +my $MULTIPLE_OUTPUT = 0; +my $cache_file; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "quiet|q" => \$QUIET_ARG, + "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility + "ba-style|b" => \$BA_STYLE_ARG, + "xml-style|x" => \$XML_STYLE_ARG, + "keys-style|k" => \$KEYS_STYLE_ARG, + "desktop-style|d" => \$DESKTOP_STYLE_ARG, + "schemas-style|s" => \$SCHEMAS_STYLE_ARG, + "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG, + "pass-through|p" => \$PASS_THROUGH_ARG, + "utf8|u" => \$UTF8_ARG, + "multiple-output|m" => \$MULTIPLE_OUTPUT, + "cache|c=s" => \$cache_file + ) or &error; + +my $PO_DIR; +my $FILE; +my $OUTFILE; + +my %po_files_by_lang = (); +my %translations = (); +my $iconv = $ENV{"INTLTOOL_ICONV"} || "iconv"; + +# Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +# XML quoted string contents +my $q = "[^\\\"]*"; + +## Check for options. + +if ($VERSION_ARG) +{ + &print_version; +} +elsif ($HELP_ARG) +{ + &print_help; +} +elsif ($BA_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &ba_merge_translations; + &finalize; +} +elsif ($XML_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + + &xml_merge_output; + + &finalize; +} +elsif ($KEYS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &keys_merge_translations; + &finalize; +} +elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &desktop_merge_translations; + &finalize; +} +elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &schemas_merge_translations; + &finalize; +} +elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &rfc822deb_merge_translations; + &finalize; +} +else +{ + &print_help; +} + +exit; + +## Sub for printing release information +sub print_version +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) ${VERSION} +Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +Copyright (C) 2000-2001 Eazel, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub print_help +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE +Generates an output file that includes some localized attributes from an +untranslated source file. + +Mandatory options: (exactly one must be specified) + -b, --ba-style includes translations in the bonobo-activation style + -d, --desktop-style includes translations in the desktop style + -k, --keys-style includes translations in the keys style + -s, --schemas-style includes translations in the schemas style + -r, --rfc822deb-style includes translations in the RFC822 style + -x, --xml-style includes translations in the standard xml style + +Other options: + -u, --utf8 convert all strings to UTF-8 before merging + -p, --pass-through use strings as found in .po files, without + conversion (STRONGLY unrecommended with -x) + -m, --multiple-output output one localized file per locale, instead of + a single file containing all localized elements + -c, --cache=FILE specify cache file name + (usually \$top_builddir/po/.intltool-merge-cache) + -q, --quiet suppress most messages + --help display this help and exit + --version output version information and exit + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + + +## Sub for printing error messages +sub print_error +{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + + +sub print_message +{ + print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; +} + + +sub preparation +{ + $PO_DIR = $ARGV[0]; + $FILE = $ARGV[1]; + $OUTFILE = $ARGV[2]; + + &gather_po_files; + &get_translation_database; +} + +# General-purpose code for looking up translations in .po files + +sub po_file2lang +{ + my ($tmp) = @_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub gather_po_files +{ + for my $po_file (glob "$PO_DIR/*.po") { + $po_files_by_lang{po_file2lang($po_file)} = $po_file; + } +} + +sub get_local_charset +{ + my ($encoding) = @_; + my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "/usr/local/lib/charset.alias"; + + # seek character encoding aliases in charset.alias (glib) + + if (open CHARSET_ALIAS, $alias_file) + { + while () + { + next if /^\#/; + return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i) + } + + close CHARSET_ALIAS; + } + + # if not found, return input string + + return $encoding; +} + +sub get_po_encoding +{ + my ($in_po_file) = @_; + my $encoding = ""; + + open IN_PO_FILE, $in_po_file or die; + while () + { + ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" + if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) + { + $encoding = $1; + last; + } + } + close IN_PO_FILE; + + if (!$encoding) + { + print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG; + $encoding = "ISO-8859-1"; + } + + system ("$iconv -f $encoding -t UTF-8 /dev/null"); + if ($?) { + $encoding = get_local_charset($encoding); + } + + return $encoding +} + +sub utf8_sanity_check +{ + if (!$UTF8_ARG) + { + if (!$PASS_THROUGH_ARG) + { + $PASS_THROUGH_ARG="1"; + } + } +} + +sub get_translation_database +{ + if ($cache_file) { + &get_cached_translation_database; + } else { + &create_translation_database; + } +} + +sub get_newest_po_age +{ + my $newest_age; + + foreach my $file (values %po_files_by_lang) + { + my $file_age = -M $file; + $newest_age = $file_age if !$newest_age || $file_age < $newest_age; + } + + $newest_age = 0 if !$newest_age; + + return $newest_age; +} + +sub create_cache +{ + print "Generating and caching the translation database\n" unless $QUIET_ARG; + + &create_translation_database; + + open CACHE, ">$cache_file" || die; + print CACHE join "\x01", %translations; + close CACHE; +} + +sub load_cache +{ + print "Found cached translation database\n" unless $QUIET_ARG; + + my $contents; + open CACHE, "<$cache_file" || die; + { + local $/; + $contents = ; + } + close CACHE; + %translations = split "\x01", $contents; +} + +sub get_cached_translation_database +{ + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) + { + if ($cache_file_age <= &get_newest_po_age) + { + &load_cache; + return; + } + print "Found too-old cached translation database\n" unless $QUIET_ARG; + } + + &create_cache; +} + +sub create_translation_database +{ + for my $lang (keys %po_files_by_lang) + { + my $po_file = $po_files_by_lang{$lang}; + + if ($UTF8_ARG) + { + my $encoding = get_po_encoding ($po_file); + + if (lc $encoding eq "utf-8") + { + open PO_FILE, "<$po_file"; + } + else + { + print STDERR "WARNING: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;; + + open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; + } + } + else + { + open PO_FILE, "<$po_file"; + } + + my $nextfuzzy = 0; + my $inmsgid = 0; + my $inmsgstr = 0; + my $msgid = ""; + my $msgstr = ""; + + while () + { + $nextfuzzy = 1 if /^#, fuzzy/; + + if (/^msgid "((\\.|[^\\])*)"/ ) + { + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + $msgid = ""; + $msgstr = ""; + + if ($nextfuzzy) { + $inmsgid = 0; + } else { + $msgid = unescape_po_string($1); + $inmsgid = 1; + } + $inmsgstr = 0; + $nextfuzzy = 0; + } + + if (/^msgstr "((\\.|[^\\])*)"/) + { + $msgstr = unescape_po_string($1); + $inmsgstr = 1; + $inmsgid = 0; + } + + if (/^"((\\.|[^\\])*)"/) + { + $msgid .= unescape_po_string($1) if $inmsgid; + $msgstr .= unescape_po_string($1) if $inmsgstr; + } + } + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + } +} + +sub finalize +{ +} + +sub unescape_one_sequence +{ + my ($sequence) = @_; + + return "\\" if $sequence eq "\\\\"; + return "\"" if $sequence eq "\\\""; + return "\n" if $sequence eq "\\n"; + + # gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal), + # \xXX (hex) and has a comment saying they want to handle \u and \U. + + return $sequence; +} + +sub unescape_po_string +{ + my ($string) = @_; + + $string =~ s/(\\.)/unescape_one_sequence($1)/eg; + + return $string; +} + +## NOTE: deal with < - < but not > - > because it seems its ok to have +## > in the entity. For further info please look at #84738. +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/</ 127 || $_ == 34 || $_ == 38 || $_ == 39 || $_ == 60) + { + # the ($_ > 127) should probably be removed + return "&#" . $_ . ";"; + } + else + { + return chr $_; + } +} + +sub entity_encoded_translation +{ + my ($lang, $string) = @_; + + my $translation = $translations{$lang, $string}; + return $string if !$translation; + return entity_encode ($translation); +} + +## XML (bonobo-activation specific) merge code + +sub ba_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; + + while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) + { + print OUTPUT $1; + + my $node = $2 . "\n"; + + my @strings = (); + $_ = $node; + while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { + push @strings, entity_decode($3); + } + print OUTPUT; + + my %langs; + for my $string (@strings) + { + for my $lang (keys %po_files_by_lang) + { + $langs{$lang} = 1 if $translations{$lang, $string}; + } + } + + for my $lang (sort keys %langs) + { + $_ = $node; + s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; + s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; + print OUTPUT; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + + +## XML (non-bonobo-activation) merge code + +sub parseTree +{ + my $fh = shift; + my $ref = shift; + my $depth = shift || 0; + my $language = shift || ""; + my $not_cdata = 0; + my $has_children; + + $entered_tag[$depth + 1] = 0; + + # Check to see if this is not a CDATA element. + # + foreach my $sub (@{ $ref }) { + if (ref $sub eq 'ARRAY') { + $not_cdata = 1; + } + } + + foreach my $sub (@{ $ref }) { + + # Handle empty nodes. + # + if (! $sub) { + next; + } + + if (ref $sub eq 'ARRAY') { + + # Process subnodes + # + $has_children = 0; + + # Check to see if current tag has any elements that need to be translated. + # + if ($translation_depth == -1) { + foreach my $subsub (@{ $sub } ) { + if (ref $subsub eq 'HASH') { + foreach my $e (reverse(keys %{ $subsub })) { + if ($e =~ /^_/) { + $translation_depth = $depth; + } + } + } elsif (ref $subsub eq 'ARRAY') { + $has_children = 1; + } + } + } + + my $current_tag = pop(@tag_stack); + push @tag_stack, $current_tag; + @translation_strings = (); + + $must_end_tag = $depth; + print $fh "<", $current_tag; + + parseTree($fh, $sub, $depth + 1, $language); + + # Close any open tags + # + if ($must_end_tag != -1) { + if ($must_end_tag < $depth) { + print $fh ">"; + } else { + print $fh " />"; + pop(@tag_stack); + if ($depth == $translation_depth) { + $translation_depth = -1; + } + } + $must_end_tag = -1; + } + + # Add ending tag(s), if needed + # + if ($entered_tag[$depth + 1] == 1) { + while ($last_depth > $depth) { + $last_depth--; + + print $fh ""; + } + } + $last_depth = $depth; + + # If beginning a translation block, then process for each language. + # + if ($translation_depth == $depth) { + my $do_language; + + # Skip languages that do not have translations. Since we only + # do this check when $translation_depth == $depth, it will never + # happen for nodes inside a node with a translated element. + # + for my $lang (sort keys %po_files_by_lang) { + if ($has_children == 1) { + $do_language = 1; + } else { + # Skip this language if there is no translation + # + $do_language = 0; + foreach my $string (@translation_strings) { + my $decode_string = entity_decode($string); + my $translation = $translations{$lang, $decode_string}; + if ($translation) { + $do_language = 1; + last; + } + } + } + + if ($do_language == 0) { + next; + } + + print $fh "\n"; + $leading_space =~ s/.*\n//g; + print $fh $leading_space; + if ($MULTIPLE_OUTPUT && $lang ne "$language") { + next; + } + + print $fh "<", $current_tag, " xml:lang=\"", $lang, "\""; + $must_end_tag = $depth; + + parseTree($fh, $sub, $depth + 1, $lang); + + # Close any open tags + # + if ($must_end_tag != -1) { + if ($must_end_tag < $depth) { + print $fh ">"; + } else { + print $fh " />"; + pop(@tag_stack); + if ($depth == $translation_depth) { + $translation_depth = -1; + } + } + $must_end_tag = -1; + } + + # Add ending tag(s), if needed + # + if ($entered_tag[$depth + 1] == 1) { + while ($last_depth > $depth + 1) { + $last_depth--; + + print $fh ""; + } + print $fh ""; + } + } + $translation_depth = -1; + $last_depth = $depth; + } + $leading_space = ""; + + } elsif (ref $sub eq 'HASH') { + + # Process tag elements + # + foreach my $e (reverse(keys %{ $sub })) { + my $key = $e; + my $string = $sub->{$e}; + my $quote = '"'; + + $string =~ s/^[\s]+//; + $string =~ s/[\s]+$//; + + if ($string =~ /^'.*'$/) + { + $quote = "'"; + } + $string =~ s/^['"]//g; + $string =~ s/['"]$//g; + + if ($key =~ /^_/) { + $key =~ s|^_||g; + + if ($language) { + + # Handle translation + # + my $decode_string = entity_decode($string); + my $translation = $translations{$language, $decode_string}; + if ($translation) { + $translation = entity_encode($translation); + $string = $translation; + } + } + } + + print $fh " $key=$quote$string$quote"; + } + + } else { + + # Handle tags and CDATA values + + # Mark parent tag as having been entered. + # + $entered_tag[$depth] = 1; + + # The last_depth flag allows us to determine if this tag should be + # closed with "/>" or ">" + # + $last_depth = $depth; + + # Close any open tags + # + if ($must_end_tag != -1) { + if ($must_end_tag < $depth) { + print $fh ">"; + } else { + print $fh " />"; + pop(@tag_stack); + } + $must_end_tag = -1; + } + + if ($sub =~ /^[\s]*$/) { + $leading_space .= $sub; + print $fh $sub; + } elsif ($not_cdata) { + + # Handle tags + # + my $temp_tag = $sub; + + # Display key + # + if ($sub =~ /^_/) { + + $temp_tag =~ s|^_||g; + + if ($translation_depth == -1) { + $translation_depth = $depth; + } + } + + # Push the tag on the stack, it will get handled when the ARRAY + # for this tag is processed. + # + push(@tag_stack, $temp_tag); + + } else { + + # Handle CDATA + # + my $string = $sub; + + $string =~ s/^[\s]+//; + $string =~ s/[\s]+$//; + + push(@translation_strings, $string); + + # Display CDATA + # + if ($language) { + + # Handle translation + # + my $decode_string = entity_decode($string); + my $translation = $translations{$language, $decode_string}; + if ($translation) { + $translation = entity_encode($translation); + $string = $translation; + } + } + + print $fh $string; + } + } + } +} + +sub intltool_tree_char +{ + my $expat = shift; + my $text = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + # Use original_string so that we retain escaped entities + # in CDATA sections. + # + if ($pos > 0 and $clist->[$pos - 1] eq '0') { + $clist->[$pos] .= $expat->original_string(); + } else { + push @$clist, 0 => $expat->original_string(); + } +} + +sub intltool_tree_start +{ + my $expat = shift; + my $tag = shift; + my @origlist = (); + + # Use original_string so that we retain escaped entities + # in attribute values. We must convert the string to an + # @origlist array to conform to the structure of the Tree + # Style. + # + my @original_array = split /\x/, $expat->original_string(); + my $source = $expat->original_string(); + + # Remove leading tag. + # + $source =~ s|^\s*<\s*(\S+)||s; + + # Grab attribute key/value pairs and push onto @origlist array. + # + while ($source) + { + if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; + push @origlist, $1; + push @origlist, '"' . $2 . '"'; + } + elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; + push @origlist, $1; + push @origlist, "'" . $2 . "'"; + } + else + { + last; + } + } + + my $ol = [ { @origlist } ]; + + push @{ $expat->{Lists} }, $expat->{Curlist}; + push @{ $expat->{Curlist} }, $tag => $ol; + $expat->{Curlist} = $ol; +} + +sub readXml +{ + my $filename = shift || return; + if(!-f $filename) { + die "ERROR Cannot find filename: $filename\n"; + } + + my $ret = eval 'require XML::Parser'; + if(!$ret) { + die "You must have XML::Parser installed to run $0\n\n"; + } + my $xp = new XML::Parser(Style => 'Tree'); + $xp->setHandlers(Char => \&intltool_tree_char); + $xp->setHandlers(Start => \&intltool_tree_start); + my $tree = $xp->parsefile($filename); + +# Hello thereHowdydo +# would be: +# [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{}, +# 0, "Howdy", ref, [{}]], 0, "do" ] ] + + return $tree; +} + +sub print_header +{ + my $infile = shift; + my $fh = shift; + my $source; + + if(!-f $infile) { + die "ERROR Cannot find filename: $infile\n"; + } + + print $fh qq{\n}; + { + local $/; + open DOCINPUT, "<${FILE}" or die; + $source = ; + close DOCINPUT; + } + if ($source =~ /()/s) + { + print $fh "$1\n"; + } + elsif ($source =~ /(]*>)/s) + { + print $fh "$1\n"; + } +} + +sub xml_merge_output +{ + my $source; + + eval 'require XML::Parser'; + die "You must have XML::Parser installed to run $0\n\n" + if($@); + + ## Add dir to own perl modules + my $dir = dirname($0); + push @INC, "NONE/share/intltool"; + push @INC, "$dir/modules"; + push @INC, "$dir/intltool-modules"; + + eval 'require XML::Parser::Style::OrigTree'; + die "The OrigTree module doesn't seem to be properly installed $0\n\n" + if($@); + + if ($MULTIPLE_OUTPUT) { + for my $lang (sort keys %po_files_by_lang) { + if ( ! -e $lang ) { + mkdir $lang or die "Cannot create subdirectory $lang: $!\n"; + } + open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree, 0, $lang); + close OUTPUT; + print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG; + } + } + open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n"; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree, 0); + close OUTPUT; + print "CREATED $OUTFILE\n" unless $QUIET_ARG; +} + +sub keys_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/[$lang]$1=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub desktop_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/${1}[$lang]=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub schemas_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + while ($source =~ s/ + (.*?) + (\s+)((\s*) + (\s*(.*?)\s*<\/default>)?(\s*) + (\s*(.*?)\s*<\/short>)?(\s*) + (\s*(.*?)\s*<\/long>)?(\s*) + <\/locale>) + //sx) + { + print OUTPUT $1; + + my $locale_start_spaces = $2 ? $2 : ''; + my $default_spaces = $4 ? $4 : ''; + my $short_spaces = $7 ? $7 : ''; + my $long_spaces = $10 ? $10 : ''; + my $locale_end_spaces = $13 ? $13 : ''; + my $c_default_block = $3 ? $3 : ''; + my $default_string = $6 ? $6 : ''; + my $short_string = $9 ? $9 : ''; + my $long_string = $12 ? $12 : ''; + + print OUTPUT "$locale_start_spaces$c_default_block"; + + $default_string =~ s/\s+/ /g; + $default_string = entity_decode($default_string); + $short_string =~ s/\s+/ /g; + $short_string = entity_decode($short_string); + $long_string =~ s/\s+/ /g; + $long_string = entity_decode($long_string); + + for my $lang (sort keys %po_files_by_lang) + { + my $default_translation = $translations{$lang, $default_string}; + my $short_translation = $translations{$lang, $short_string}; + my $long_translation = $translations{$lang, $long_string}; + + next if (!$default_translation && !$short_translation && + !$long_translation); + + print OUTPUT "\n$locale_start_spaces"; + + print OUTPUT "$default_spaces"; + + if ($default_translation) + { + $default_translation = entity_encode($default_translation); + print OUTPUT "$default_translation"; + } + + print OUTPUT "$short_spaces"; + + if ($short_translation) + { + $short_translation = entity_encode($short_translation); + print OUTPUT "$short_translation"; + } + + print OUTPUT "$long_spaces"; + + if ($long_translation) + { + $long_translation = entity_encode($long_translation); + print OUTPUT "$long_translation"; + } + + print OUTPUT "$locale_end_spaces"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub rfc822deb_merge_translations +{ + my %encodings = (); + for my $lang (keys %po_files_by_lang) { + $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang})); + } + + my $source; + + $Text::Wrap::huge = 'overflow'; + $Text::Wrap::break = qr/\n|\s(?=\S)/; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">${OUTFILE}" or die; + + # Remove comments + $source =~ s/^#[^\n]*(\n|$)//s; + $source =~ s/\n#[^\n]*//g; + while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg) + { + my $sep = $1; + my $non_translated_line = $3.$4; + my $string = $5; + my $underscore = length($2); + # Remove [] dummy strings + my $stripped = $string; + $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2; + $stripped =~ s/\[\s[^\[\]]*\]$//; + $non_translated_line .= $stripped; + + print OUTPUT $sep.$non_translated_line; + + if ($underscore) + { + my @str_list = rfc822deb_split($underscore, $string); + + for my $lang (sort keys %po_files_by_lang) + { + my $is_translated = 1; + my $str_translated = ''; + my $first = 1; + + for my $str (@str_list) + { + my $translation = $translations{$lang, $str}; + + if (!$translation) + { + # $is_translated = 0; + # last; + $translation = $str; + } + + # $translation may also contain [] dummy + # strings, mostly to indicate an empty string + $translation =~ s/\[\s[^\[\]]*\]$//; + + # Escape commas + $translation =~ s/,/\\,/g if $underscore eq 2; + + if ($first) + { + if ($underscore eq 2) + { + $str_translated .= $translation; + } + else + { + $str_translated .= + Text::Tabs::expand($translation) . + "\n"; + } + } + else + { + if ($underscore eq 2) + { + $str_translated .= ', ' . $translation; + } + else + { + $str_translated .= Text::Tabs::expand( + Text::Wrap::wrap(' ', ' ', $translation)) . + "\n .\n"; + } + } + $first = 0; + + # To fix some problems with Text::Wrap::wrap + $str_translated =~ s/(\n )+\n/\n .\n/g; + $str_translated =~ s/(^|\n)( +)\n( \S{$Text::Wrap::columns})/$1$2$3/g; + } + next unless $is_translated; + + $str_translated =~ s/\n \.\n$//; + $str_translated =~ s/\s+$//; + + $_ = $non_translated_line; + s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s; + print OUTPUT; + } + } + } + print OUTPUT "\n"; + + close OUTPUT; + close INPUT; +} + +sub rfc822deb_split +{ + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + # When first argument is 2, the string is a comma separated list of + # values. + my $type = shift; + my $text = shift; + $text =~ s/^[ \t]//mg; + if ($type ne 1) + { + my @values = (); + for my $value (split(/(?debian/templates.tmp +printf " Done.\n" + +# Create a temporary "pobuild" directory +rm -rf debian/pobuild >/dev/null 2>&1 +mkdir debian/pobuild + +# Create the appropriate POTFILES.in file there +cat >debian/pobuild/POTFILES.in <debian/pobuild/output <this will create pobuild/templates.pot +debconf-updatepo --podir debian/pobuild + +printf "Include country names translations into the templates file:\n" +# The following takes place for each language +# (each existing file in debian/po) +for pofile in debian/po/*.po ; do + pofilename=`basename $pofile` + langname=`basename $pofilename .po` + printf " $langname..." + # If the country names are translated, we need to merge + # the translation with the templates translations + if [ -f $ISO3166TRANSLATIONS/$pofilename ] + then + # Output is verbose, don't worry + # Copy other templates translations + cp debian/po/$pofilename debian/pobuild/$pofilename.copied + # Update it with templates.pot + msgmerge -U debian/pobuild/$pofilename.copied \ + debian/pobuild/templates.pot 2>/dev/null + # merge with iso-codes translations + # if charsets differ, this may output some "error" messages we ignore + msgmerge debian/iso-codes/$pofilename \ + debian/pobuild/$pofilename.copied \ + > debian/pobuild/$pofilename 2>/dev/null + # clean out the generated file + msgmerge -U debian/pobuild/$pofilename \ + debian/pobuild/templates.pot 2>/dev/null + # Else we just use what's translated + else + cp $pofile debian/pobuild/$pofilename && true + fi + printf "Done.\n" +done + +# and now we generate the templates file from all this +PODEBCONF_LIB=. po2debconf --podir debian/pobuild debian/templates.tmp >debian/choose-mirror.templates + diff --git a/sort-countries.new b/sort-countries.new new file mode 100755 index 00000000..aa8667ae --- /dev/null +++ b/sort-countries.new @@ -0,0 +1,46 @@ +#!/bin/sh +set -e + +[ -d debian/locales ] || mkdir debian/locales +[ -d debian/sort-tmp ] || mkdir debian/sort-tmp +cd debian/sort-tmp +for protocol in http ftp +do + sed -n -e "/^Template: mirror\\/$protocol\\/countries/,/^Description:/p" ../choose-mirror/DEBIAN/templates | + sed -e "/^Choices-/s/\\\\,/--/g" | + perl -p -e ' + chomp; + if (m/Choices-([^.]*)\.UTF-8:/) { + open (OUT, "> list.$1"); + @t = split(/, /); + shift(@t); + my $cnt = 1; + foreach my $name (@t) {$cnt++; print OUT "$cnt $name\n";} + close OUT; + } + $_="";' + echo "Sorting mirror country list for protocol $protocol:" + for file in list.* + do + lang=${file#list.} + unilang=$(grep "^$lang.*\\.UTF-8" /usr/share/i18n/SUPPORTED | sed -e 1q | sed -e 's/[@. ].*//' ) + echo -n " $lang... " + if [ -z "$unilang" ]; then + echo "skipped because no UTF-8 variant found." 1>&2 + else + [ -d ../locales/$unilang.UTF-8 ] || localedef -c -f UTF-8 -i $unilang ../locales/$unilang.UTF-8 + LOCPATH=`pwd` LC_ALL=../locales/$unilang.UTF-8 sort -k 2.1 $file | sed -e 's/ .*/, /' | tr -d '\n' | sed -e "s/^/Indices-$lang.UTF-8: 1, /" -e 's/, $//' > sorted$file + echo "Done." + echo "" >>sorted$file + fi + done + # Now ../choose-mirror/DEBIAN/templates must be patched: all sortedlist.* + # files have to be added to the mirror/$protocol/countries template. + sed -e "/$protocol.*countries/{n;q;}" ../choose-mirror/DEBIAN/templates |\ + sed -e "/^Choices-/s/--/\\,/g" >templates.tmp + cat sorted* >>templates.tmp + sed -e "/$protocol.*countries/!d;/$protocol.*countries/{:end;n;b end}" ../choose-mirror/DEBIAN/templates | sed '1,2d'>>templates.tmp + mv templates.tmp ../choose-mirror/DEBIAN/templates || true +done +cd ../.. +rm -r debian/locales debian/sort-tmp || true