Changeset 4118


Ignore:
Timestamp:
2003-04-09T16:26:31+12:00 (21 years ago)
Author:
mdewsnip
Message:

Some fairly major changes to reflect the new back-end.

Location:
trunk/gsdl/bin/script
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/bin/script/picklanguage.pl

    r4069 r4118  
    3636}
    3737
    38 use parsargv;
     38
    3939use util;
    40 use Cwd;
    41 use File::Basename;
    42 use GDBM_File;
    4340use CGI;
    44 #use utf8;
     41
    4542
    4643sub main
    4744{
    48     my $query = new CGI;
    49     my @languages;
    50 
    5145    # directory in which to put the generated html pages
    5246    my $lang_dir = util::filename_cat($ENV{'GSDLHOME'},"tmp","lang");
    53     my $forms_dir = util::filename_cat($lang_dir,"package_forms");
    54 
    55     ## replace next two blocks of code with with util::mk_all_dir() ...
    56     util::mk_all_dir($forms_dir);
    57  
    5847    my @lang_list;
    59     my $langlog_fname = util::filename_cat($forms_dir,"languages.log");
     48    my $langlog_fname = util::filename_cat($lang_dir,"languages.log");
    6049
    6150    if (!-e $langlog_fname) {
     
    7463        push(@lang_list, { 'long' => $lang_long, 'abbr' => $lang_abbr } );
    7564        }
    76 
    7765    }
    7866    close MCFILE;
     
    9684    close LANGFILE;
    9785    }
    98      
    9986
    10087    open(LANGFILE, "<$langlog_fname")
     
    10390    #reads into the languages array all languages currently in use
    10491    #and their corresponding language codes from the languages.log file
     92    my @languages;
    10593    while (<LANGFILE>) {
    10694    $lang = $_;
     
    10997    <LANGFILE>;
    11098    }
    111    
    11299    close LANGFILE;
    113100
    114101    #opens a file to write HTML content of the page to
    115 
    116     my $picklang_fname = util::filename_cat($forms_dir,"picklanguage.lang");
    117 
     102    my $picklang_fname = util::filename_cat($lang_dir, "picklanguage.lang");
    118103    open(HTMLFILE, ">$picklang_fname")
    119104    || die "Unable to open $picklang_fname: $!\n";
    120    
     105
    121106    #writes to file the instructions on how to use the interface (_textinitial)
    122107    #and then displays a table at the end with menu options from which the user
    123108    #selects their base and translation languages, and submits these choices
    124109    #to proceed into the interface translation agency
     110    my $query = new CGI;
    125111    print HTMLFILE (" _textinitial_ <br>\n",
    126112            "<table border=\"2\" cellpadding=\"8\"><tr><td><center>",
     
    141127            $query->submit("submitlanguage","_textenter_"),
    142128            "</center><p>\n",
    143             "<img src=\"_httpimg_/divb.gif\"><p>");
     129            "<center><img src=\"_httpimg_/divb.gif\"></center><p>");
    144130   
    145131    close HTMLFILE;
    146 
    147132}
    148133
     134
    149135&main();
  • trunk/gsdl/bin/script/submit_translation.pl

    r3855 r4118  
    3737}
    3838
    39 use parsargv;
    40 use util;
    41 use Cwd;
    42 use File::Basename;
     39
    4340use GDBM_File;
    44 use utf8;
     41
     42
     43my %translationdata = ();
     44my %updatedata = ();
     45
    4546
    4647sub main
    4748{
    48     #gets the name of the args file with the cgiargsclass data in it
    49     my $filename = shift(@_);
    50     #gets the name of the language currently being translated from base language
    51     my $language = shift(@_);
    52 
    53     my $baselanguage = shift(@_);
     49    # Get the name of the source (base) language
     50    my $sourcelang = shift(@_);
     51    # Get the name of the target language
     52    my $targetlang = shift(@_);
     53    # Get the name of the args file with the cgiargsclass data in it
     54    my $argsfile = shift(@_);
     55
     56    # Check that all arguments were supplied
     57    if (!$sourcelang) {
     58    die "Error: You didn't supply the name of the source language!\n";
     59    }
     60    if (!$targetlang) {
     61    die "Error: You didn't supply the name of the target language!\n";
     62    }
     63    if (!$argsfile) {
     64    die "Error: You didn't supply the name of the arguments file!\n";
     65    }
     66
     67    # Casefold both language names
     68    $sourcelang =~ tr/A-Z/a-z/;
     69    $targetlang =~ tr/A-Z/a-z/;
     70
     71    # Handles cases where the macro file name is different to the language name
     72    $sourcelang = "port" if ($sourcelang =~ m/portuguese/);
     73    $sourcelang = "indo" if ($sourcelang =~ m/indonesian/);
     74    $targetlang = "port" if ($targetlang =~ m/portuguese/);
     75    $targetlang = "indo" if ($targetlang =~ m/indonesian/);
     76
     77    my $gsdldir = "$ENV{'GSDLHOME'}/";
     78    my $translationdir = $gsdldir . "tmp/lang/" . $sourcelang . "-" . $targetlang . "/";
     79    my $translationdb = $translationdir . "translation.db";
     80    my $updatedb = $translationdir . "update.db";
     81
     82    # Open the two database files for the translation
     83    tie(%translationdata, "GDBM_File", $translationdb, 1, 0640);
     84    tie(%updatedata, "GDBM_File", $updatedb, 1, 0640);
     85
     86    # Parse the translation submissions
     87    my $submissions = &parse_user_submission($sourcelang, $targetlang,
     88                         $translationdir.$argsfile);
     89    # print "Submissions:\n";
     90    # &display_hash($submissions);
     91
     92    # Add the submissions to the translation database
     93    &add_submissions_to_database($submissions);
     94
     95    # Writes the target macro files
     96    my $macrosdir = $gsdldir . "macros/";
     97    &write_target_macro_files($sourcelang, $targetlang, $macrosdir);
     98
     99    # Clean up
     100    untie %translationdata;
     101    untie %updatedata;
     102}
     103
     104
     105sub parse_user_submission
     106{
     107    my ($sourcelang, $targetlang, $filename) = @_;
     108
     109    #opens the args file or kills program
     110    open(ARGUMENTS, "<$filename") or die("Error: Could not open $filename.\n");
    54111
    55112    #stores a hash of macronames with numbers still appended and their values
    56113    my %distinctkeys = ();
    57     #stores an hash of macronames without numbers appended and the value
    58     #being the full text of the macro
    59     my %macronames = ();
    60    
    61     my $macrotext = "";
    62     $number = 0;
    63    
    64     $langcode = &getlangcode($language);
    65 
    66     $language = "port" if ($language =~ m/portuguese/);
    67     $language = "indo" if ($language =~ m/indonesian/);
    68    
    69     my ($macronumbered) = &parsebasefile($baselanguage);
    70     my ($macronumbered2) = &parsebasefile($baselanguage . "2");
    71     ($macronumbered) = &combine_hashes($macronumbered, $macronumbered2);
    72  
    73     my ($foreign) = &parseforeignfile($language);
    74     &checktranspackg($language . "2");
    75     my ($foreign2) = &parseforeignfile($language . "2");
    76     ($foreign) = &combine_hashes($foreign, $foreign2);
    77 
    78     my ($macronames) = &parseusersubmission($filename);
    79 
    80     foreach $key (keys %$macronames) {
    81     #print STDERR "$key\n";
    82     if ($key =~ m/(_\w+_)/) {
    83         $macronames->{$key} = " [l=$langcode] {" . $macronames->{$key} . "}\n";
    84         $macro = $key;
    85         $macro =~ s/.*:://;
    86         if ($macronumbered{$macro}) {
    87         $number = $macronumbered{$macro};
    88         $foreign{$number} = $macro . $macronames->{$key};
    89         }
    90     }
    91     else {
    92         $macronames->{$key} =~ s/\&lt;br\&gt;/\n/g;
    93         $macro = $key;
    94         $macro =~ s/.*:://;
    95         if ($macronumbered{$macro}) {
    96         $number = $macronumbered{$macro};
    97         $foreign{$number} = $macronames->{$key};
    98         }
    99     }
    100     }
    101 
    102     $language2 = $language . "2";
    103 
    104     open MACROOUT, ">$ENV{'GSDLHOME'}/macros/$language.dm" or die "MURGH MACROOUT1\n";
    105 
    106     foreach $ky (sort {$a <=> $b} keys %foreign) {
    107     if ($foreign{$ky} =~ m/package\s+home(\s+|$)/) {
    108         close MACROOUT;
    109         open MACROOUT, ">$ENV{'GSDLHOME'}/macros/$language2.dm" or die "MURGH MACROOUT2\n";
    110     }
    111     print MACROOUT "$foreign{$ky}\n";
    112     print STDERR "$ky $foreign{$ky}\n";
    113     }
    114 
    115     close MACROOUT;
    116 
    117     return 0;
    118 
    119 }
    120 
    121 &main(@ARGV);
    122 
    123 sub checktranspackg {
    124 
    125     $file = shift(@_);
    126 
    127     $found = "false";
    128 
    129     open (OTHERDMIN, "<$ENV{'GSDLHOME'}/macros/$file.dm") or return;
    130 
    131     while (<OTHERDMIN>) {
    132     $found = "true" if($_ =~ m/^package translang/);
    133     }
    134 
    135     close OTHERDMIN;
    136 
    137     if ($found ne "true") {
    138     open (OTHERDMOUT, ">>$ENV{'GSDLHOME'}/macros/$file.dm") or return;
    139 
    140     print OTHERDMOUT "###################################################################\n";
    141     print OTHERDMOUT "package translang\n";
    142     print OTHERDMOUT "###################################################################\n";
    143     print OTHERDMOUT "#-------------------------------------------------------------------\n";
    144     print OTHERDMOUT "text macros\n";
    145     print OTHERDMOUT "#-------------------------------------------------------------------\n";
    146            
    147 
    148     close OTHERDMOUT;
    149     }
    150 }
    151 
    152 sub getlangcode {
    153 
    154     $language = shift (@_);
    155 
    156     open(LANGFILE, "<$ENV{'GSDLHOME'}/tmp/lang/package_forms/languages.log") or die "MURGH LANGFILE\n";
    157 
    158     while (<LANGFILE>) {
    159     $lang = $_;
    160     chomp($lang);
    161     $langcode = <LANGFILE>;
    162     chomp($langcode);
    163     $langHASH{$lang} = $langcode;
    164     }
    165    
    166     close LANGFILE;
    167  
    168     $langcode = $langHASH{$language};
    169    
    170     return ($langcode);
    171 }
    172 
    173 sub parsebasefile {
    174 
    175     $file = shift(@_);
    176 
    177     open (BASEIN, "<$ENV{'GSDLHOME'}/macros/$file.dm") or return;
    178    
    179     while (<BASEIN>) {
    180    
    181     $line = $_;
    182     chomp($line);
    183     $number++;
    184 
    185     if ($line =~ m/\Apackage /) {
    186         $currpackage = $line;
    187         $currpackage =~ s/package //;
    188         $key = $currpackage . "::package";
    189         $macronumbered{$key} = $number;
    190     }
    191     elsif ($line =~ m/\A\#\# .*/) {
    192        
    193         my @icon = split(/\s*\#\#\s*/, $line);
    194        
    195         $macro = $icon[(scalar @icon) - 1];
    196        
    197         $macronumbered{$macro} = $number;
    198        
    199         while ($line =~ m/\s+/) {
    200         $line = <BASEIN>;
    201         chomp($line);
    202         }
    203     }
    204     elsif ($line =~ m/\A(_\w+_)/) {
    205         $line = $&;
    206         $macronumbered{$line} = $number;
    207     }
    208     elsif ($line =~ m/\A(\#\stext\smacros)/) {
    209         $key = $currpackage . "::textmacro";
    210         $macronumbered{$key} = $number;
    211     }
    212     elsif ($line =~ m/\A(\#\sicons)/) {
    213         $key = $currpackage . "::icons";
    214         $macronumbered{$key} = $number;
    215     }
    216     #print STDERR "$file $line\n";
    217     }
    218    
    219     close BASEIN;
    220    
    221     return (\%macronumbered);
    222 
    223 }
    224 
    225 sub parseforeignfile {
    226 
    227     $file = shift(@_);
    228 
    229     open (MACROIN, "<$ENV{'GSDLHOME'}/macros/$file.dm") or return;
    230    
    231    
    232     while (<MACROIN>) {
    233 
    234     $number = 0;
    235 
    236     if ($_ =~ m/\A(_\w+_)/) {
    237    
    238         $macro = $&;
    239         $number = $macronumbered{$macro} if($macronumbered{$macro});
    240         $line = $_;
    241 
    242         # while there is still text of the macro to go...
    243         while ($_ !~ /.*\}/) {
    244         # ... adds it to the macrotext variable
    245         $_ = <MACROIN>;
    246         $line .= $_;
    247         }
    248         if ($number != 0) {
    249         $foreign{$number} = $line;
    250         }
    251     }
    252     elsif ($_ =~ m/\A\#\# .*/) {
    253         $line = $_;
    254        
    255         $line .= <MACROIN> unless ($line =~ m/^\#\# .*\#\#/);
    256 
    257         my @icon = split(/\s*\#\#\s*/, $line);
    258        
    259         $macro = $icon[(scalar @icon) - 1];
    260        
    261         $number = $macronumbered{$macro} if($macronumbered{$macro});
    262         $currline = $line;
    263        
    264         while ($currline =~ m/\S+/) {
    265         $currline = <MACROIN>;
    266         $line .= $currline;
    267         }
    268         if ($number != 0) {
    269         $foreign{$number} = $line;
    270         }
    271     }
    272     else {
    273         if ($_ =~ m/\S+/) {
    274         $line = $_;
    275         if ($line =~ m/\Apackage /) {
    276             $currpackage = $line;
    277             chomp($currpackage);
    278             $currpackage =~ s/package //;
    279             $key = $currpackage . "::package";
    280             $number = $macronumbered{$key} if($macronumbered{$key});
    281             $line = "###################################################################\n" . $line;
    282             $line .= "###################################################################\n";
    283             $foreign{$number} = $line;
    284         }
    285         elsif ($line =~ m/\A(\#\stext\smacros)/) {
    286             $key = $currpackage . "::textmacro";
    287             $number = $macronumbered{$key} if($macronumbered{$key});
    288             $line = "#-------------------------------------------------------------------\n" . $line;
    289             $line .= "#-------------------------------------------------------------------\n";
    290             $foreign{$number} = $line;
    291         }
    292         elsif ($line =~ m/\A(\#\sicons)/) {
    293             $key = $currpackage . "::icons";
    294             $number = $macronumbered{$key} if($macronumbered{$key});
    295             $line = "#-------------------------------------------------------------------\n" . $line;
    296             $line .= "#-------------------------------------------------------------------\n";
    297             $foreign{$number} = $line;
    298         }
    299         }
    300     }
    301     }
    302     close MACROIN;
    303 
    304     return (\%foreign);
    305 
    306 }
    307 
    308 
    309 sub parseusersubmission {
    310 
    311     $filename = shift(@_);
    312    
    313     #opens the args file or kills program
    314     open(ARGUMENTS, "<$filename") or die("MURGH USER SUBMISSION\n");
     114
    315115    #while there are still lines left to read
     116    my $macroname = "";
     117    my $macrovalue = "";
    316118    while (<ARGUMENTS>) {
    317119    #gets the line
     
    319121    #chomps off the final newline character
    320122    chomp($line);
    321 
    322         #if the line contains :: (browser converts to %3A%3A) then it has a macroname
    323     if ($line =~ m/%3A%3A/) {
    324         $macro = $line;
    325         #changes the codes back to ::
    326         $macro =~ s/%3A%3A/::/;
    327         #removes value of macro leaving just the name
    328         $macro =~ s/=.*//;
    329         #saves the value
    330         $value = $&;
    331         #removes all " and = from value
    332         $value =~ s/=//g;
    333         $value =~ s/\A\"//;
    334         $value =~ s/\"\Z//;
    335         $value =~ s/<br>/\n/g;
    336         #removes all " from macro
    337         $macro =~ s/\"//g;
    338         #removes any whitespace from macro
    339         $macro =~ s/\s+//g;
    340         #hashes the macro and it's value
    341         if ($value =~ m/\S+/) {
    342         $distinctkeys{$macro} = $value;
     123    # removes nasty carriage returns and formfeeds
     124    $line =~ s/\r$//;
     125    $line =~ s/\f$//;
     126    # print "Line: $line\n";
     127
     128    if ($line =~ m/^ \"/) {
     129        #if the line contains :: (browser converts to %3A%3A) then it has a macroname
     130        if ($line =~ m/%3A%3A/) {
     131        #hashes the previous macro and its value, provided the value is non-empty
     132        if ($macrovalue =~ m/\S+/) {
     133            $distinctkeys{$macroname} = $macrovalue;
     134        }
     135
     136        $macroname = $line;
     137        #changes the codes back to ::
     138        $macroname =~ s/%3A%3A/::/g;
     139        #removes value of macro leaving just the name
     140        $macroname =~ s/=.*//;
     141        #saves the value
     142        $macrovalue = $&;
     143        #removes all " from macro
     144        $macroname =~ s/\"//g;
     145        #removes any whitespace from macro
     146        $macroname =~ s/\s+//g;
     147
     148        #removes all " and = from value
     149        $macrovalue =~ s/=//g;
     150        $macrovalue =~ s/\A\"//;
     151        $macrovalue =~ s/\"\Z//;
     152        $macrovalue =~ s/<br>/\n/g;
     153        }
     154        else {
     155        #hashes the previous macro and its value, provided the value is non-empty
     156        if ($macroname ne "" && $macrovalue =~ m/\S+/) {
     157            $distinctkeys{$macroname} = $macrovalue;
     158        }
     159        $macroname = "";
     160        $macrovalue = "";
    343161        }
    344162    }
    345     }
    346 
    347     for $key (sort keys %distinctkeys) {
    348    
    349     $macrotext = $distinctkeys{$key};
    350 
    351     #print STDERR "$key\n";
    352     $macronames{$key} = $macrotext;
    353     $macrotext = "";
     163    else {
     164        # Check if this is part of a multi-line macro
     165        if ($macroname ne "") {
     166        $extravalue = $line;
     167        #removes all " and = from value
     168        $extravalue =~ s/=//g;
     169        $extravalue =~ s/\A\"//;
     170        $extravalue =~ s/\"\Z//;
     171        $extravalue =~ s/<br>/\n/g;
     172        # add this line to the current macro value
     173        $macrovalue = $macrovalue . "\n" . $extravalue;
     174        }
     175    }
    354176    }
    355177
    356178    close ARGUMENTS;
    357179
    358     return (\%macronames);
    359 }
    360 
    361 sub combine_hashes {
    362    
    363     my ($hash1, $hash2) = @_;
    364     my %combined = ();
    365 
    366     foreach $key (keys %$hash1) {
    367     $combined{$key} = $hash1->{$key};
    368     }
    369     foreach $key (sort keys %$hash2) {
    370     $combined{$key} = $hash2->{$key};
    371     #print STDERR "$key\n";
    372     }
    373 
    374     return (\%combined);
    375 
    376 }
    377 
    378 
    379 
     180    # Create a hash map containing the translations to add
     181    my %translations = ();
     182    my $targetcode = $translationdata{"*target_lang_code*"};
     183
     184    for $sourcekey (sort keys %distinctkeys) {
     185    my $macrotext = $distinctkeys{$sourcekey};
     186    $macrotext = "[l=$targetcode] {" . $macrotext . "}\n";
     187
     188    my $targetkey = &get_target_key_equivalent($sourcelang, $targetlang, $sourcekey);
     189    $translations{$targetkey} = $macrotext;
     190    }
     191
     192    return (\%translations);
     193}
     194
     195
     196sub get_target_key_equivalent
     197{
     198    my ($sourcelang, $targetlang, $sourcekey) = @_;
     199
     200    my $macrofile = $sourcekey;
     201    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     202    my $key = $sourcekey;
     203    $key =~ s/^([^:])+::(.*)/$2/;
     204
     205    my $targetkey;
     206    if ($macrofile eq ($sourcelang . ".dm")) {
     207    $targetkey = $targetlang . ".dm" . "::" . $key;
     208    }
     209    if ($macrofile eq ($sourcelang . "2.dm")) {
     210    $targetkey = $targetlang . "2.dm" . "::" . $key;
     211    }
     212
     213    return ($targetkey);
     214}
     215
     216
     217sub display_hash
     218{
     219    my ($hash) = @_;
     220
     221    foreach $key (sort (keys %$hash)) {
     222    print $key . "\n";
     223    print $hash->{$key} . "\n";
     224    }
     225}
     226
     227
     228sub add_submissions_to_database
     229{
     230    my ($submissions) = @_;
     231
     232    # Write each submission to the database
     233    foreach $key (sort keys(%$submissions)) {
     234    $translationdata{$key} = $submissions->{$key};
     235
     236    # If this was one of the macros needing updating, it has been
     237    if ($updatedata{$key}) {
     238        delete $updatedata{$key};
     239    }
     240    }
     241}
     242
     243
     244sub write_target_macro_files
     245{
     246    my ($sourcelang, $targetlang, $macrosdir) = @_;
     247
     248    my $targetdmfile1 = $macrosdir . $targetlang . ".dm";
     249    my $targetdmfile2 = $macrosdir . $targetlang . "2.dm";
     250
     251    my $currentfile = "1";
     252    my $currentpackage = "";
     253    my %textmacros = ();
     254    my %iconmacros = ();
     255
     256    open(TARGET_DM_FILE, ">$targetdmfile1") or die "Error: Could not write file.\n";
     257
     258    # Find all the target keys in the database
     259    foreach $key (sort (keys %translationdata)) {
     260    my $macrofile = $key;
     261    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     262
     263    # Check if this is a target macro
     264    if ($macrofile eq ($targetlang . ".dm") || $macrofile eq ($targetlang . "2.dm")) {
     265        if ($macrofile eq ($targetlang . "2.dm") && $currentfile eq "1") {
     266        # Write the macros for the package just finished
     267        &write_macros(TARGET_DM_FILE, $currentpackage, $textmacros, $iconmacros);
     268        close TARGET_DM_FILE;
     269
     270        # Start a new package
     271        $currentpackage = "";
     272        $textmacros = ();
     273        $iconmacros = ();
     274
     275        # Start the next file
     276        $currentfile = "2";
     277        open(TARGET_DM_FILE, ">$targetdmfile2") or die "Error: Could not write file.\n";
     278        }
     279
     280        my $targetpackage = $key;
     281        $targetpackage =~ s/^([^:])+::(.*)::(.*)/$2/;
     282
     283        my $macroname = $key;
     284        $macroname =~ s/^([^:])+::(.*)::(.*)/$3/;
     285
     286        if ($targetpackage ne $currentpackage) {
     287        if ($currentpackage ne "") {
     288            # Write the macros for the package just finished
     289            &write_macros(TARGET_DM_FILE, $currentpackage, $textmacros, $iconmacros);
     290        }
     291
     292        # Start a new package
     293        $currentpackage = $targetpackage;
     294        $textmacros = ();
     295        $iconmacros = ();
     296        }
     297
     298        # Determine whether this is a text or icon macro
     299        my $macrotext = $translationdata{$key};
     300        if ($macrotext =~ m/\#\# (^|.)*/) {
     301        $iconmacros->{$macroname} = $macrotext;
     302        }
     303        else {
     304        $textmacros->{$macroname} = $macrotext;
     305        }
     306    }
     307    }
     308
     309    # Write the macros for the last package of the last file
     310    &write_macros(TARGET_DM_FILE, $currentpackage, $textmacros, $iconmacros);
     311    close TARGET_DM_FILE;
     312}
     313
     314
     315sub write_macros
     316{
     317    my ($fh, $packagename, $textmacros, $iconmacros) = @_;
     318
     319    # Write package header
     320    print $fh "\n";
     321    print $fh "######################################################################\n";
     322    print $fh "package $packagename\n";
     323    print $fh "######################################################################\n";
     324
     325    # Write text macros
     326    print $fh "\n";
     327    print $fh "#------------------------------------------------------------\n";
     328    print $fh "# text macros\n";
     329    print $fh "#------------------------------------------------------------\n";
     330    print $fh "\n";
     331    foreach $textkey (sort (keys %$textmacros)) {
     332    print $fh $textkey . $textmacros->{$textkey} . "\n";
     333    }
     334
     335    # Write icon macros
     336    print $fh "#------------------------------------------------------------\n";
     337    print $fh "# icons\n";
     338    print $fh "#------------------------------------------------------------\n";
     339    print $fh "\n";
     340    foreach $iconkey (sort (keys %$iconmacros)) {
     341    print $fh $iconmacros->{$iconkey} . "\n";
     342    }
     343}
     344
     345
     346&main(@ARGV);
  • trunk/gsdl/bin/script/translator.pl

    r4068 r4118  
    3333}
    3434
    35 use parsargv;
    36 use util;
    37 use Cwd;
    38 use File::Basename;
     35
    3936use GDBM_File;
    4037use CGI;
    41 #require utf8;
    42 #use unicode;
     38
     39
     40my $translationdir;
     41my $translationdb;
     42my %translationdata = ();
     43my $updatedb;
     44my %updatedata = ();
     45
    4346
    4447sub main
    4548{
    46     #gets the name of the translation language
    47     my $file = shift(@_);
    48     #gets the name of the base language
    49     my $baselanguage = shift(@_);
    50    
    51     #checks that arguments were supplied
    52     if (!$file) {
    53     die "You didn't supply the name of the language file! Aborting...\n";
    54     }
    55     if (!$baselanguage) {
    56     die "You didn't supply the name of the base language file! Aborting...\n";
    57     }
    58 
    59     #generates a hash of the differences between the base language file and the
    60     #translation language file, of the form macroname->macrotext
    61     my ($diffhash) = &initial_hashing($file, $baselanguage);
    62 
    63     #generates HTML code to display user interface on webpage with what needs translation
    64     #returns an array of CGI data
    65     my @queries = &generate_pages($diffhash, $file, $baselanguage);
    66 
    67 }
    68 
    69 sub initial_hashing {
    70 
    71     my ($file, $baselanguage) = @_;
    72 
    73     #catches cases where the macro file name is different to the language name
    74     $file = "port" if ($file =~ m/portuguese/);
    75     $file = "indo" if ($file =~ m/indonesian/);
    76 
    77     #saves the directory path to the database files
    78     $gdbmdir  = "$ENV{'GSDLHOME'}/tmp/lang/gdbmfiles/";
    79     #creates the directory if it doesn't exist
    80     if (!-e $gdbmdir) {
    81     my $store_umask = umask(0000);
    82     if (! mkdir($gdbmdir, 0777)) {
    83         umask($store_umask);
    84         die "Couldn't create directory $gdbmdir\n";
    85     }
    86     umask($store_umask);
    87     }
    88     #saves the directory path to the macro files
    89     my $macrodir = "$ENV{'GSDLHOME'}/macros/";
    90    
    91     # hashes the macro files into form of macroname->macrotext
    92     my ($englhash) = &parse_macrofile($macrodir.$baselanguage.".dm");
    93     my ($engl2hash) =  &parse_macrofile($macrodir.$baselanguage."2.dm");
    94    
    95     #uses each of the above hashes to write the db files
    96     &file_to_db($baselanguage, $englhash);
    97     &file_to_db($baselanguage."2", $engl2hash);
    98    
    99     #uses cvs date annotation to assign date of last edit to each macro
    100     my ($base) = &dateannotation($baselanguage);
    101     my ($base2) = &dateannotation($baselanguage."2");
    102     #combines hash to end up with a full hash of the english and english2 macrofiles with
    103     #each macro having a date allocated to it
    104     $base = &combine_hashes($base,$base2);
    105    
    106     # language macro-filename and database-filename
    107     my $macrofile = $macrodir.$file.".dm";
    108     my $dbfile = $gdbmdir.$file.".db";
    109    
    110     #if we are creating a new language
    111     if (! -e $macrofile) {
    112    
    113     #hard code of all the packages that exist in the two macrofiles
    114     #DON'T LIKE THIS CAUSE WHEN A NEW PACKAGE IS ADDED, WILL CREATE ERROR!!!!!!!!!!!!!!!!!!!!!!
    115     @packages = ("Global", "about", "document", "query", "preferences", "browse", "help",
    116              "home", "homehelp", "extlink", "authen", "collector", "docs", "usersedituser",
    117              "usersdeleteuser", "bsummary", "status", "users", "gsdl", "userschangepasswd",
    118              "userschangepasswdok", "translang");
    119 
    120     #creates a new macro file and writes a framework of a macrofile to it
    121     open MCROFILE, ">$macrofile" or die "MURGH\n";
    122    
    123     foreach $packg (@packages) {
    124         print MCROFILE "package $packg\n";
    125         print MCROFILE "# text macros\n";
    126         print MCROFILE "# icons\n";
    127     }
    128 
    129     close MCROFILE;
    130 
    131     #get a code for the new language as the first two characters of the language
    132     $code = $& if($file =~ m/\w\w/);
    133 
    134     #opens the existing file containing the languages and their codes
    135     open LANGFILE, "<$ENV{'GSDLHOME'}/tmp/lang/package_forms/languages.log" or die "MURGH\n";
    136 
    137     #scrolls through file checking that the new code does not already exist
    138     while (<LANGFILE>) {
    139         #if code does exist, change to 2nd and 3rd characters of new language
    140         #THIS CHECKING IS NOT RECURSIVE, SO IF 2ND ONE DID ALREADY EXIST WOULD CAUSE PROBLEMS!!!!!!!
    141         if ($_ eq $code){
    142         $code = $& if($file =~ m/.\w\w/);
    143         $code =~ s/\A.//;
    144         }
    145     }
    146 
    147     close LANGFILE;
    148    
    149     #appends the name of the new language and its associated code to the end of the file
    150     open LANGFILE, ">>$ENV{'GSDLHOME'}/tmp/lang/package_forms/languages.log" or die "MURGH\n";
    151     print LANGFILE "\n$file";
    152     $code = $& if($file =~ m/\w\w/);
    153     print LANGFILE "\n$code";
    154     close LANGFILE;
    155     }
    156 
    157     #hashes translation language macrofiles into form of macroname->macrotext
    158     my ($langhash) = &parse_macrofile($macrofile);
    159     $macrofile = $macrodir.$file."2.dm";
    160     my ($langhash2) = &parse_macrofile($macrofile);
    161      
    162     #uses these hashes to write the db files for the translation language
    163     &file_to_db($file, $langhash);
    164     &file_to_db($file."2", $langhash2);
    165 
    166     #annotates each macro name with the date that it was last edited
    167     my $foreign = &dateannotation($file);
    168     my $foreign2 = &dateannotation($file . "2");
    169 
    170     #combines data into final hash of macroname->macrotext where each
    171     #macro has the date of last edition
    172     $foreign = &combine_hashes($foreign, $foreign2);
    173    
    174     #finds the differences between the english database (base language)
    175     #and the supplied languages database and hashes these differences
    176     #in the form macroname->macrotext
    177     my $diffhash = &db_db_diffs($gdbmdir.$baselanguage.".db", $dbfile, $base, $foreign, $baselanguage);
    178     $dbfile = $gdbmdir.$file."2.db";
    179     my $diffhash2 = &db_db_diffs($gdbmdir.$baselanguage."2.db", $dbfile, $base, $foreign, $baselanguage);
    180 
    181     #combines the differences from the first and second language files into one hash
    182     $diffhash = &combine_diffhash($diffhash,$diffhash2);
    183 
    184     return (\%$diffhash);
    185 }
    186 
    187 #combines two existing hashes of the same format together
    188 sub combine_hashes {
    189    
    190     my ($hash1, $hash2) = @_;
    191     my %combined = ();
    192 
    193     foreach $key (sort (keys %$hash1)) {
    194     $combined{$key} = $hash1->{$key};
    195     }
    196     foreach $key (sort (keys %$hash2)) {
    197     $combined{$key} = $hash2->{$key};
    198     }
    199 
    200     return (\%combined);
    201 
    202 }
    203 
    204 #combines to existing diffhashes together, retaining information regarding
    205 #whether a macro came from the first or second hash
    206 sub combine_diffhash {
    207    
    208     my ($hash1, $hash2) = @_;
    209     my %combined = ();
    210 
    211     foreach $key (sort (keys %$hash1)) {
    212     $combined{$key} = [$hash1->{$key},"1"];
    213     }
    214     foreach $key (sort (keys %$hash2)) {
    215     $combined{$key} = [$hash2->{$key},"2"];
    216     }
    217 
    218     return (\%combined);
    219 
    220 }
    221 
    222 #to parse the .dm files into a hash of macronames->macrotext
     49    # Get the name of the source (base) language
     50    my $sourcelang = shift(@_);
     51    # Get the name of the target language
     52    my $targetlang = shift(@_);
     53
     54    # Check that both arguments were supplied
     55    if (!$sourcelang) {
     56    die "Error: You didn't supply the name of the source language!\n";
     57    }
     58    if (!$targetlang) {
     59    die "Error: You didn't supply the name of the target language!\n";
     60    }
     61
     62    # Casefold both language names
     63    $sourcelang =~ tr/A-Z/a-z/;
     64    $targetlang =~ tr/A-Z/a-z/;
     65
     66    # If the source language is not English, it may not be up to date
     67    if ($sourcelang !~ m/english/) {
     68    # print STDERR "Warning: Source language is not English. You should check that" .
     69    #              " the source language is up to date before beginning.\n";
     70    }
     71
     72    # Handles cases where the macro file name is different to the language name
     73    $sourcelang = "port" if ($sourcelang =~ m/portuguese/);
     74    $sourcelang = "indo" if ($sourcelang =~ m/indonesian/);
     75    $targetlang = "port" if ($targetlang =~ m/portuguese/);
     76    $targetlang = "indo" if ($targetlang =~ m/indonesian/);
     77
     78    my $gsdldir = "$ENV{'GSDLHOME'}/";
     79    my $macrosdir = $gsdldir . "macros/";
     80
     81    # Check that the source language macro files exist, and parse them
     82    my $sourcedmfile1 = $sourcelang . ".dm";
     83    my $sourcehash1;
     84    if (-e $macrosdir.$sourcedmfile1) {
     85    $sourcehash1 = &parse_macrofile($macrosdir, $sourcedmfile1);
     86    }
     87
     88    my $sourcedmfile2 = $sourcelang . "2.dm";
     89    my $sourcehash2;
     90    if (-e $macrosdir.$sourcedmfile2) {
     91    $sourcehash2 = &parse_macrofile($macrosdir, $sourcedmfile2);
     92    }
     93
     94    # Make sure some macros exist to be translated
     95    if (!$sourcehash1 && !$sourcehash2) {
     96    die "Error: No source macro information exists.\n";
     97    }
     98
     99    # Combine the two source hashes
     100    my $sourcehash = &combine_hashes($sourcehash1, $sourcehash2);
     101    # print "Source hash:\n";
     102    # &display_hash($sourcehash);
     103
     104    # Check if this is a new translation process or the continuation of an old one
     105    $translationdir = $gsdldir . "tmp/lang/" . $sourcelang . "-" . $targetlang . "/";
     106    $translationdb = $translationdir . "translation.db";
     107    $updatedb = $translationdir . "update.db";
     108
     109    if (! -e $translationdir) {
     110    # Create a directory to store the data for the new translation
     111    if (! mkdir($translationdir, 0777)) {
     112        die "Error: Couldn't create directory $translationdir.\n";
     113    }
     114
     115    # Start a new database for the translation information
     116    tie(%translationdata, "GDBM_File", $translationdb, GDBM_WRCREAT, 0640);
     117
     118    # Work out what the target language code should be, and store it in the database
     119    my $langdir = $gsdldir . "tmp/lang/";
     120    my $langlogfile = $langdir . "languages.log";
     121    my $languagecodes = &get_language_codes();
     122    my $targetcode = &get_language_code($targetlang, $langlogfile, $languagecodes);
     123    print STDERR "Target language code: $targetcode\n";
     124    $translationdata{"*target_lang_code*"} = $targetcode;
     125
     126    # Start a new update database
     127    tie(%updatedata, "GDBM_File", $updatedb, GDBM_WRCREAT, 0640);
     128    }
     129    else {
     130    # This translation is a continuation of an old one, so open the database files for it
     131    tie(%translationdata, "GDBM_File", $translationdb, 1, 0640);
     132    tie(%updatedata, "GDBM_File", $updatedb, 1, 0640);
     133    }
     134
     135    # Create the target language macro files if they don't exist
     136    my $targetdmfile1 = $targetlang . ".dm";
     137    if (! -e $macrosdir.$targetdmfile1) {
     138    # print "Target macro file $macrosdir$targetdmfile1 does not exist... creating.\n";
     139    &create_empty_macrofile($macrosdir.$sourcedmfile1, $macrosdir.$targetdmfile1);
     140    }
     141    my $targetdmfile2 = $targetlang . "2.dm";
     142    if (! -e $macrosdir.$targetdmfile2) {
     143    # print "Target macro file $macrosdir$targetdmfile2 does not exist... creating.\n";
     144    &create_empty_macrofile($macrosdir.$sourcedmfile2, $macrosdir.$targetdmfile2);
     145    }
     146
     147    # Parse the target language macro files
     148    my $targethash1 = &parse_macrofile($macrosdir, $targetdmfile1);
     149    my $targethash2 = &parse_macrofile($macrosdir, $targetdmfile2);
     150
     151    # Combine the two target hashes
     152    my $targethash = &combine_hashes($targethash1, $targethash2);
     153    # print "Target hash:\n";
     154    # &display_hash($targethash);
     155
     156    # Determine the macros that need translating
     157    my $needstranslating = &find_macros_needing_translation($sourcelang, $sourcehash,
     158                                $targetlang, $targethash);
     159    # print "Macros needing translation:\n";
     160    # &display_hash($needstranslating);
     161
     162    # Generates HTML code to display user interface on webpage with what needs translation
     163    &generate_pages($sourcelang, $targetlang, $needstranslating);
     164
     165    # Clean up
     166    untie %translationdata;
     167    untie %updatedata;
     168}
     169
     170
     171sub get_language_code
     172{
     173    my ($language, $langlogfile, $languagecodes) = @_;
     174
     175    # Try the languages.log file
     176    open(LANG_LOG_IN, "<$langlogfile") or die "Error: Could not open $langlogfile.\n";
     177
     178    my $linenum = "odd";
     179    my $found = "false";
     180    while (<LANG_LOG_IN>) {
     181    $line = $_;
     182    chomp($line);
     183
     184    # Check if the language code appears in the languages.log file
     185    if ($linenum eq "odd") {
     186        if ($line eq $language) {
     187        $found = "true";
     188        }
     189        $linenum = "even";
     190    }
     191    else {
     192        if ($found eq "true") {
     193        return $line;
     194        }
     195        $linenum = "odd";
     196    }
     197    }
     198
     199    close LANG_LOG_IN;
     200
     201    # Try to find it using the ISO 639 language codes
     202    my $langcode;
     203    if ($languagecodes->{$language}) {
     204    $langcode = $languagecodes->{$language};
     205    }
     206    # Otherwise we just have to make something up
     207    else {
     208    $langcode = &make_up_language_code($language, $languagecodes);
     209    }
     210
     211    # Add the language code to the languages.log file
     212    open LANG_LOG_OUT, ">>$langlogfile" or die "Error: Could not append to $langlogfile.\n";
     213    print LANG_LOG_OUT "\n$language\n$langcode";
     214    close LANG_LOG_OUT;
     215
     216    return $langcode;
     217}
     218
     219
     220sub make_up_language_code
     221{
     222    my ($language, $languagecodes) = @_;
     223
     224    # !! TO FINISH !!
     225    print STDERR "Making up language code...\n";
     226    $langcode = $& if ($language =~ m/\w\w/);
     227    $language =~ s/\A.//;
     228
     229    return $langcode;
     230}
     231
     232
     233sub create_empty_macrofile
     234{
     235    my ($sourcedmfile, $targetdmfile) = @_;
     236
     237    open(SOURCE_DM_FILE_IN, "<$sourcedmfile") or die "Error: Could not open file.\n";
     238    open(TARGET_DM_FILE_OUT, ">$targetdmfile") or die "Error: Could not write file.\n";
     239
     240    # Reads in contents of macro file, line by line
     241    while (<SOURCE_DM_FILE_IN>) {
     242    # Check if a new package is being defined
     243    if (s/^package //) {
     244        $packagename = $_;
     245        chomp($packagename);
     246
     247        # It is, so write an empty package section to the target macro file
     248        print TARGET_DM_FILE_OUT "package $packagename\n";
     249        print TARGET_DM_FILE_OUT "# text macros\n";
     250        print TARGET_DM_FILE_OUT "# icons\n";       
     251    }
     252    }
     253
     254    close SOURCE_DM_FILE_IN;
     255    close TARGET_DM_FILE_OUT;
     256}
     257
     258
    223259sub parse_macrofile
    224260{
    225     #saves the path of the macro file
    226     my $filename = shift(@_);
    227     #initialises some local variables
     261    my ($macrosdir, $macrofile) = @_;
     262
     263    # Initialises some local variables
    228264    my $currpackage;
    229265    my %macros = ();
    230     my @date = localtime(time);
    231    
    232     #opens macro file or kills program
    233     open(IN, "<$filename") or return;
    234     #reads in contents of macro file, line by line
     266
     267    # Opens macro file or returns
     268    my $macropath = $macrosdir . $macrofile;
     269    open(IN, "<$macropath") or return;
     270
     271    # Reads in contents of macro file, line by line
    235272    while (<IN>) {
    236     # find out the current package that macros belong to
     273    # Check if a new package is being defined
    237274    if (s/^package //) {
    238275        $currpackage = $_;
    239276        chomp($currpackage);
    240277    }
    241     #if line contains a macro name
     278
     279    # Line contains a macro name
    242280    elsif (/^(_\w+_)/) {
    243281        # gets the name of the macro ($1 contains text matched by corresponding
    244         #set of parentheses in the last matched pattern within the dynamic scope
    245         #which here matches (_\w+_) )
     282        # set of parentheses in the last matched pattern within the dynamic scope
     283        # which here matches (_\w+_) )
    246284        my $macroname = $1;
    247         #saves the day/month/year
    248         my $macrotext = $date[3]. "/" . $date[4] . "/" . $date[5] ."\n";
    249         # key to the hash and the database
    250         my $key = $currpackage . "::" . $macroname;
     285        my $macrotext;
     286
    251287        # get the first line of the macro
    252288        $_ =~ s/^_\w+_ *//;
     
    258294        }
    259295        $macrotext .= $_;
    260         #hashes the macroname and the macrotext
     296
     297        # The key consists of macro file, package name, and macro name
     298        my $key = $macrofile . "::" . $currpackage . "::" . $macroname;
     299        # Store the macro text in the database
    261300        $macros{$key} = $macrotext;
    262 
    263     }
    264     #line in format ## "sometext" ## macro ## macroname ##
     301    }
     302
     303    # Line in format ## "sometext" ## macro ## macroname ##
    265304    elsif (/^\#\# .*/) {
    266305        my $macroname = $_;
    267         #saves the day/month/year
    268         my $macrotext = " ".$date[3]. "/" . $date[4] . "/" . $date[5] ."\n";
    269        
     306        my $macrotext;
     307
    270308        #if the macro text contains a new line will run over two lines
    271         unless ($macroname =~ m/^\#\# .*\#\#/) {
    272        
     309        unless ($macroname =~ m/^\#\# .*\#\#/) {       
    273310        $macroname = $_;
    274311        chomp($macroname);
    275312        $_ = <IN>;
    276313        $macroname .= $_;
    277        
    278314        }
    279315
     
    285321        # overwrite macroname with macroname from ## ... ## ... ## HERE ###
    286322        $macroname = $names[(scalar @names) - 1];
    287         #append package to the front of macroname
    288         my $key = $currpackage . "::" . $macroname; # key to the hash and the database
    289 
    290         #read in the rest of the text associated with the image macro (i.e height | width etc.)
     323
     324        # read in the rest of the text associated with the image macro
    291325        while ($_ !~ /^\s+/) {
    292326        $macrotext .= $_;
    293327        $_ = <IN>;
    294328        }
    295         #hashes macroname and macrotext
     329
     330        # key to the hash and the database
     331        my $key = $macrofile . "::" . $currpackage . "::" . $macroname;
     332        # hashes macroname and macrotext
    296333        $macros{$key} = $macrotext;
    297334    }
    298    
    299     }   
     335    }
    300336    close IN;
    301337
    302    
    303338    return (\%macros);
    304339}
    305340
    306 #to annotate each macro with the date that it was last edited
    307 sub dateannotation {
    308    
    309     $language = shift(@_);
    310     my %macrodated = ();
    311 
    312     #system call which returns one big string containing the whole macro file
    313     #with each line annotated with the date it was last modified
    314     $ENV{'CVS_RSH'}="ssh";
    315     $file = qx/cd $ENV{'GSDLHOME'}\/macros;cvs annotate $language.dm/;
    316     #split the file into an array of lines
    317     @file = split(/\n/,$file);
    318     #return $file variable to empty state to free up memory
    319     $file = "";
    320    
    321     for ($p = 0; $p < scalar(@file); $p++) {
    322    
    323     $line = $file[$p];
    324     chomp($line);
    325     #cuts the date of the beginning of the line and saves it
    326     $line =~ s/.*\(.*\):\s//;
    327     $date = $&;
    328    
    329     #checks that date is in the correct format
    330     $date = $& if($date =~ m/\d\d-\w\w\w-\d\d/);
    331    
    332     #if line contains an image macro
    333     if ($line =~ m/\#\# .*/) {
    334        
    335         #catch macrotexts which cover two lines
    336         unless ($line =~ m/\A\#\# .*\#\#/) {
    337         $line = $file[++$p];
    338         chomp($line);
    339         $line =~ s/.*\(.*\):\s//;
    340         }
    341         my @icon = split(/\s*\#\#\s*/, $line);
    342        
    343         $macro = $icon[(scalar @icon) - 1];
    344        
    345         #hash the macro name and the date
    346         $macrodated{$macro} = $date;
    347        
    348         #read through the rest of the image macro so that the normal macros it
    349         #may contain don't get included in the macrodated hash
    350         while ($line =~ m/\s+/) {
    351         $line = $file[++$p];
    352         chomp($line);
    353         $line =~ s/.*\(.*\):\s//;
    354         }
    355     }
    356     #if the line contains a normal macro in _this_ form
    357     elsif ($line =~ m/\A(_\w+_)/) {
    358         $line = $&;
    359         #hash the macro name and the date
    360         $macrodated{$line} = $date;
    361     }
    362    
    363        
    364     }
    365    
    366     return (\%macrodated);
    367 }
    368 
    369 #used to update the db file when changes occur in the dm file
    370 #will execute this command everytime the translator is entered
    371 #for both the base language and translation language db files
    372 sub file_to_db
    373 {
    374     my ($filename, $filehash) = @_;
    375 
    376     my $database = "$ENV{'GSDLHOME'}/tmp/lang/gdbmfiles/$filename.db";
    377     my %dbhash = ();
    378 
    379    
    380     if (-e $database) {
    381    
    382     tie(%dbhash, 'GDBM_File', $database, 1, 0640) or die "$!";
    383 
    384     foreach $filekey (sort keys(%$filehash)) {
    385        
    386         if (!($dbhash{$filekey})) {
    387         $dbhash{$filekey} = $filehash->{$filekey};
    388         }
    389         else {
    390         # strip off the dates from both entries...
    391         my $filemacro = ($filehash->{$filekey});
    392         my $dbmacro = ($dbhash{$filekey});
    393         $filemacro =~ s/^.*//;
    394         $dbmacro =~ s/^.*//;
    395 
    396         if ($dbmacro ne $filemacro) {
    397             #update the database to reflect the change...
    398             $dbhash{$filekey} = $filehash->{$filekey};
     341
     342# Combines two existing hashes of the same format together
     343sub combine_hashes
     344{
     345    my ($hash1, $hash2) = @_;
     346    my %combined = ();
     347
     348    foreach $key (sort (keys %$hash1)) {
     349    $combined{$key} = $hash1->{$key};
     350    }
     351    foreach $key (sort (keys %$hash2)) {
     352    $combined{$key} = $hash2->{$key};
     353    }
     354
     355    return (\%combined);
     356}
     357
     358
     359sub display_hash
     360{
     361    my ($hash) = @_;
     362
     363    foreach $key (sort (keys %$hash)) {
     364    print $key . "\n";
     365    print $hash->{$key} . "\n";
     366    }
     367}
     368
     369
     370sub find_macros_needing_translation
     371{
     372    my ($sourcelang, $sourcehash, $targetlang, $targethash) = @_;
     373
     374    # Find source macros whose text has changed
     375    foreach $sourcekey (sort keys(%$sourcehash)) {
     376    if ($translationdata{$sourcekey}) {
     377        if ($translationdata{$sourcekey} ne $sourcehash->{$sourcekey}) {
     378        # print "Source macro $sourcekey has changed value.\n";
     379
     380        my $targetkey = &get_target_key_equivalent($sourcelang, $targetlang,
     381                               $sourcekey);
     382        if ($targethash->{$targetkey}) {
     383            $updatedata{$targetkey} = $targethash->{$targetkey};
    399384        }
    400         }
    401     }
    402    
    403     }
    404     else { # create the database file for the particular language file...
    405     # tie the hash to the database
    406     tie(%dbhash, "GDBM_File", $database, GDBM_WRCREAT, 0640);
    407    
    408     %dbhash = %$filehash;
    409     }
    410 
    411     untie %dbhash;
    412 }
    413 
    414 #Takes two paramaters which are two database filenames, works out
    415 #the differences between the two, and returns them in %diffhash
    416 #which holds entries which are not in db_one but are in db_two and
    417 #entries which are in both, but the db_one entry has been updated since
    418 #the db_two entry was last edited
    419 sub db_db_diffs
    420 {
    421     my ($db_one, $db_two, $basedates, $foreigndates, $baselanguage) = @_;
    422 
    423     my %db1hash = ();
    424     my %db2hash = ();
    425     my %months = ("Jan",1,"Feb",2,"Mar",3,"Apr",4,"May",5,"Jun",6,
    426           "Jul",7,"Aug",8,"Sep",9,"Oct",10,"Nov",11,"Dec",12);
    427    
    428     # this hash holds the database entries that are in
    429     # english.db but not in $filename.db
    430     my %diffhash = ();
    431 
    432     #ties the hash to database so when you read from hash it fetches from external
    433     #database and when you set hash it writes to external database
    434     tie(%db1hash, "GDBM_File", $db_one, GDBM_READER, 0640);
    435     tie(%db2hash, "GDBM_File", $db_two, GDBM_READER, 0640);
    436 
    437    
    438     #the key is the name of the macro
    439     foreach $key (sort keys(%db1hash)) {
    440 
    441     #if the macro isn't there at all, then it's different
    442     if (!$db2hash{$key}) {
    443         $diffhash{$key} = [$db1hash{$key}, ""];
    444     }
    445     #else if the macro is in both, want to compare date stamps of date hashes
    446     #and if foreign date is older than base date want to add to diffhash aswell
    447     else {
    448         $macro = $key;
    449         $macro =~ s/\A.*:://;
    450         $bdate = $basedates->{$macro};
    451         $fdate = "";
    452         #check that the macro has a foreign date
    453         if ($foreigndates->{$macro}) {
    454         $fdate = $foreigndates->{$macro};
    455         @fdate = split(/-/,$fdate);
    456         @bdate = split(/-/,$bdate);
    457        
    458         #compare year then month then day
    459         if ($bdate[2] >= $fdate[2]) {
    460             if ($months{$bdate[1]} >= $months{$fdate[1]}) {
    461             if ($bdate[0] > $fdate[0]) {
    462                 #get the foreign/translation language text as it currently stands
    463                  $foreigntext = $db2hash{$key};
    464                  if ($foreigntext =~ m/\#\# /) {
    465                  $foreigntext = $& if ($foreigntext =~ m/\"(.|^)*\"/);
    466                  }
    467                  else {
    468                  $foreigntext =~ s/^.*\n//;
    469                  $foreigntext =~ s/.*\{//;
    470                  $foreigntext =~ s/\}\Z//;
    471                  $foreigntext =~ s/\n\Z//;
    472                  }
    473 
    474                 #store the macroname with the macrotext in the base and foreign languages
    475                 $diffhash{$key} = [$db1hash{$key}, $foreigntext];
    476             }
    477             }
     385        else {
     386            $updatedata{$targetkey} = "";
    478387        }
    479388        }
    480389    }
    481390    }
    482     untie %db1hash;
    483     untie %db2hash;
    484 
    485     return \%diffhash;   
    486 }
     391
     392    # Clear out the database
     393    my $targetcode = $translationdata{"*target_lang_code*"};
     394    untie %translationdata;
     395    unlink($translationdb);
     396    %translationdata = ();
     397    tie(%translationdata, "GDBM_File", $translationdb, GDBM_WRCREAT, 0640);
     398    $translationdata{"*target_lang_code*"} = $targetcode;
     399
     400    # Re-add source and target macros
     401    foreach $sourcekey (sort keys(%$sourcehash)) {
     402    $translationdata{$sourcekey} = $sourcehash->{$sourcekey};
     403    }
     404    foreach $targetkey (sort keys(%$targethash)) {
     405    $translationdata{$targetkey} = $targethash->{$targetkey};
     406    }
     407
     408    my %needstranslating = ();
     409
     410    # Macros that need translating are those that are in the source language macro file
     411    #  but no translation exists in the translation database
     412    foreach $sourcekey (sort keys(%$sourcehash)) {
     413    my $targetkey = &get_target_key_equivalent($sourcelang, $targetlang, $sourcekey);
     414    if (!$translationdata{$targetkey}) {
     415        # print "Macro $sourcekey needs translating.\n";
     416        $needstranslating{$sourcekey}[0] = $sourcehash->{$sourcekey};
     417        $needstranslating{$sourcekey}[1] = "";
     418    }
     419    }
     420
     421    # ...and those in the list of macros to update
     422    foreach $targetkey (sort keys(%updatedata)) {
     423    my $sourcekey = &get_source_key_equivalent($sourcelang, $targetlang, $targetkey);
     424    $needstranslating{$sourcekey}[0] = $sourcehash->{$sourcekey};
     425    $needstranslating{$sourcekey}[1] = $updatedata{$targetkey};
     426    }
     427
     428    return (\%needstranslating);
     429}
     430
     431
     432sub get_source_key_equivalent
     433{
     434    my ($sourcelang, $targetlang, $targetkey) = @_;
     435
     436    my $macrofile = $targetkey;
     437    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     438    my $key = $targetkey;
     439    $key =~ s/^([^:])+::(.*)/$2/;
     440
     441    my $sourcekey;
     442    if ($macrofile eq ($targetlang . ".dm")) {
     443    $sourcekey = $sourcelang . ".dm" . "::" . $key;
     444    }
     445    if ($macrofile eq ($targetlang . "2.dm")) {
     446    $sourcekey = $sourcelang . "2.dm" . "::" . $key;
     447    }
     448
     449    return ($sourcekey);
     450}
     451
     452
     453sub get_target_key_equivalent
     454{
     455    my ($sourcelang, $targetlang, $sourcekey) = @_;
     456
     457    my $macrofile = $sourcekey;
     458    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     459    my $key = $sourcekey;
     460    $key =~ s/^([^:])+::(.*)/$2/;
     461
     462    my $targetkey;
     463    if ($macrofile eq ($sourcelang . ".dm")) {
     464    $targetkey = $targetlang . ".dm" . "::" . $key;
     465    }
     466    if ($macrofile eq ($sourcelang . "2.dm")) {
     467    $targetkey = $targetlang . "2.dm" . "::" . $key;
     468    }
     469
     470    return ($targetkey);
     471}
     472
    487473
    488474# generates whole website by seperating hash of differences into groups
     
    490476sub generate_pages
    491477{
    492     my ($datahash) = shift(@_);
    493     my $lang = shift(@_);
    494     my $baselanguage = shift(@_);
     478    my ($sourcelang, $targetlang, $needstranslating) = @_;
     479
    495480    my %pagehash = ();
    496     my @query_pages = ();
    497 
    498     # directory in which to put the generated html pages
    499     my $dir = "$ENV{'GSDLHOME'}/tmp/lang/package_forms/$lang";
    500    
    501     # creates directory if it doesn't already exist
    502     if (!-e $dir) {
    503     my $store_umask = umask(0000);
    504     if (! mkdir($dir, 0777)) {
    505         umask($store_umask);
    506         die "Couldn't create directory $dir\n";
    507     }
    508     umask($store_umask);
    509     }
    510    
     481
    511482    @pageno = ();
    512483    $pageno = 1;
     
    517488    # sorted first by whether it is from the core or auxiliary macrofile then
    518489    # alphabetically by macroname
    519     foreach $key (sort {$datahash->{$a}[1] <=> $datahash->{$b}[1]
    520                 ||
    521                 $datahash->{$a}[0] cmp $datahash->{$b}[0] } keys(%$datahash)) {
    522    
     490    foreach $sourcekey (sort keys(%$needstranslating)) {
    523491    #nested hash. The pagehash contains a hash of all of the translation pages.
    524492    #Then each page is itself contains a hash of all the macros on that page, where
    525493    #each macro is associated with some macrotext and whether it was from the core
    526494    #or auxiliary macrofile
    527     $pagehash->{$pageno}->{$key} = [$datahash->{$key}[0],$datahash->{$key}[1]];
     495    # my $targetkey = &get_target_key_equivalent($sourcelang, $targetlang, $sourcekey);
     496    # print "Source key: $sourcekey Target key: $targetkey\n";
     497
     498    $pagehash->{$pageno}->{$sourcekey} = $needstranslating->{$sourcekey};
    528499    $keysperpage++;
    529    
     500
    530501    #reduce the number of macros per page in these cases
    531     $limit = 7 if($key =~ m/collector::_text.*/);
    532     $limit = 7 if($key =~ m/help::_text.*/);
    533     $limit = 1 if($key =~ m/translang::_textinitial_/);
    534     $limit = 3 if($key =~ m/home::.*/);
    535     $limit = 3 if($key =~ m/gsdl::.*/);
    536     $limit = 1 if($key =~ m/help::_(.*)texthelp.*/);
    537     $limit = $keysperpage if ($limit <= $keysperpage);
     502    # $limit = 7 if($key =~ m/collector::_text.*/);
     503    # $limit = 7 if($key =~ m/help::_text.*/);
     504    # $limit = 1 if($key =~ m/translang::_textinitial_/);
     505    # $limit = 3 if($key =~ m/home::.*/);
     506    # $limit = 3 if($key =~ m/gsdl::.*/);
     507    # $limit = 1 if($key =~ m/help::_(.*)texthelp.*/);
     508    # $limit = $keysperpage if ($limit <= $keysperpage);
    538509
    539510    #if have enough keys to generate a page with
    540511    if ($keysperpage == $limit) {
     512        #opens a file to write the HTML code to for current page
     513        open HTMLFILE, ">$translationdir/$pageno.lang";
     514
     515        #passes hash of keys for current page and filehandle, returns CGI data
     516        &generate_form($sourcelang, $targetlang, $pagehash->{$pageno}, \*HTMLFILE);
     517        close HTMLFILE;
     518
     519        #push the page number onto the array of pages
     520        push(@pageno, $pageno);
     521        $pageno++;
     522
    541523        #resets key counting variable
    542524        $keysperpage = 0;
    543525        $limit = 15;
    544         #opens a file to write the HTML code to for current page
    545         open HTMLFILE, ">$dir/$pageno.lang";
    546 
    547         #passes hash of keys for current page and filehandle, returns CGI data
    548         my $query = &generate_form($pagehash->{$pageno}, \*HTMLFILE, $lang, $baselanguage);
    549         close HTMLFILE;
    550 
    551         #push the page number onto the array of pages
    552         push(@pageno, $pageno);
    553         #increment the current page
    554         $pageno++;
    555     }
    556     }
    557    
    558     #if you exit the loop with keys still to write
     526    }
     527    }
     528
     529    # if you exit the loop with keys still to write
    559530    if ($keysperpage != 0) {
    560    
    561     #writes out the remaining keys, same format as above
    562     open HTMLFILE, ">$dir/$pageno.lang";
    563     my $query = &generate_form($pagehash->{$pageno}, \*HTMLFILE, $lang, $baselanguage);
     531    # writes out the remaining keys, same format as above
     532    open HTMLFILE, ">$translationdir/$pageno.lang";
     533    &generate_form($sourcelang, $targetlang, $pagehash->{$pageno}, \*HTMLFILE);
    564534    close HTMLFILE;
    565535    push(@pageno, $pageno);
     
    567537
    568538    #writes each page number to a file
    569     open PAGELOG, ">$dir/pageno.log" or die("MURGH\n");
     539    open PAGELOG, ">$translationdir/pageno.log";
    570540    foreach $page (@pageno) {
    571541    print PAGELOG $page, "\n";
     
    574544
    575545    #write thankyou page for language translator once translation is complete
    576     open THANKYOU, ">$dir/thankyou.lang" or die("MURGH\n");
    577     print THANKYOU "<center> _textthanks_ $lang _texttrans_ <p></center>\n";
     546    open THANKYOU, ">$translationdir/thankyou.lang" or die("MURGH\n");
     547    print THANKYOU ("<center> _textthanks_ $targetlang _texttrans_ _textgetdmfiles_ ",
     548            "<a href=\"_httpprefix_/gsdl/macros/$targetlang" . ".dm\">_texthere_</a>",
     549            " &amp; ",
     550            "<a href=\"_httpprefix_/gsdl/macros/$targetlang" . "2.dm\">_texthere_</a>.",
     551            "<p></center>\n");
    578552    close THANKYOU;
    579553
     
    582556}
    583557
     558
    584559sub generate_form
    585560{
     561    my $sourcelang = shift(@_);
     562    my $targetlang = shift(@_);
    586563    my $formhash = shift(@_);
    587564    my $fh = shift(@_);
    588     my $language = shift(@_);
    589     my $baselanguage = shift(@_);
     565
    590566    # common gateway interface for writing the stuff to the web
    591567    my $query = new CGI;
    592     my $keynamecount = 1;
     568    my $keynamecount;
    593569
    594570    $first = "true";
    595571
    596     foreach $key (sort {$formhash->{$a}[1] <=> $formhash->{$b}[1]} (keys(%$formhash))) {
    597 
    598     my $text = $formhash->{$key}[0][0];
     572    foreach $key (sort (keys(%$formhash))) {
     573
     574    my $text = $formhash->{$key}[0];
     575    my $default = $formhash->{$key}[1];
    599576
    600577    # whole lot of formatting on strings
     
    602579    # the macro names for the contents of the macro itself
    603580    my $keyname = $key;
    604      
    605581    $keyname  =~ s/_/\\_/g;
    606     # strip off the date
    607     $text =~ s/.*//;
     582
     583    $text =~ s/_/\\_/g;
    608584    $text =~ s/(\[l=.*\])//;
    609    
     585    $default =~ s/_/\\_/g;
     586    $default =~ s/(\[l=.*\] )//;
     587
    610588        # must take care of image macros single and multiple line ones
    611589    $text =~ s/(\<br\>\#\#.*\#\#\s*\<br\>).*/$1/g;
    612    
     590    $default =~ s/(\<br\>\#\#.*\#\#\s*\<br\>).*/$1/g;
     591
    613592    # format the text for displaying in the browser
    614593    $text =~ s/[\{\}]//g unless($text =~ m/\#\# /);
     594    $default =~ s/[\{\}]//g unless($text =~ m/\#\# /);
    615595
    616596    $text =~ s/(\A\n)//;
    617597    $text =~ s/(\n\Z)//;
    618    
    619    
     598    $default =~ s/(\A\n)//;
     599    $default =~ s/(\n\Z)//;
     600    # print "Key: $keyname Text: $text Default: $default\n";
     601
    620602    $keynamecount = 1;
    621603   
    622     #gets the translation language text which will exist when base macro
    623     #has been edited after the last edition of the translation macro
    624     my $default = $formhash->{$key}[0][1];
    625604    #tells whether is a core or auxiliary macro
    626     my $priority = $formhash->{$key}[1];
    627    
    628     #if is a core macro, and the first on the page, table header displays core
    629     if($priority eq "1" and $first eq "true") {
    630 
    631         print $fh ($query->hidden(-name=>"tlng",-default=>"$language"),
    632                $query->hidden(-name=>"bl",-default=>"$baselanguage"),
    633                "</center><img src=\"_httpimg_/core.gif\">",
    634                "<table cellpadding=\"10\">\n",
    635                "<tr><td><strong><center>".uc ($baselanguage)."</strong></center></td>\n",
    636                "<td><strong><center>". uc ($language)."</strong></center></td></tr>\n");
    637         #shows that have seen first macro of core type
    638         $first = "been";
    639     }
    640     #if is a auxiliary macro, and the first on the page, table header displays auxiliary
    641     if($priority eq "2" and $first eq "true") {
    642       print $fh ($query->hidden(-name=>"tlng",-default=>"$language"),
    643              $query->hidden(-name=>"bl",-default=>"$baselanguage"),
    644              "</center><img src=\"_httpimg_/auxiliary.gif\">",
    645              "<table cellpadding=\"10\">\n",
    646              "<tr><td><strong><center>". uc ($baselanguage)."</strong></center></td>\n",
    647              "<td><strong><center>". uc ($language)."</strong></center></td></tr>\n");
    648         $first = "false";
    649     }   
    650     #if another macro has already been seen, but this is the first occurence of
    651     #an auxiliary macro, will finish current table and begin new auxiliary table underneath
     605    my $priority = &core_or_auxiliary_macro($sourcelang, $keyname);
     606
     607    if ($first eq "true") {
     608        print $fh ($query->hidden(-name=>"tlng",-default=>"$targetlang"),
     609               $query->hidden(-name=>"bl",-default=>"$sourcelang"));
     610
     611        # If it is a core macro, table header displays core
     612        if ($priority eq "1") {
     613        print $fh "</center><img src=\"_httpimg_/core.gif\">";
     614
     615        #shows that have seen first macro of core type
     616        $first = "been";
     617        }
     618
     619        # If it is an auxiliary macro, table header displays auxiliary
     620        if ($priority eq "2") {
     621        print $fh "</center><img src=\"_httpimg_/auxiliary.gif\">";
     622        $first = "false";
     623        }
     624
     625        print $fh ("<table cellpadding=\"10\">\n<tr>",
     626               "<td><strong><center>". uc ($sourcelang)."</center></strong></td>\n",
     627               "<td><strong><center>". uc ($targetlang)."</center></strong></td>\n",
     628               "</tr>\n");
     629    }
     630
     631    # If this is the first auxiliary macro, but not the first macro, finish the
     632    #   current table and start a new auxiliary table underneath
    652633    if($priority eq "2" and $first eq "been") {
    653634        print $fh ("</table><br></center><img src=\"_httpimg_/auxiliary.gif\">",
    654                "<table cellpadding=\"10\">",
    655                "<tr><td><strong><center>".uc ($baselanguage)."</strong></center></td>\n",
    656                "<td><strong><center>". uc ($language)."</strong></center></td></tr>\n");
     635               "<table cellpadding=\"10\">\n<tr>",
     636               "<td><strong><center>". uc ($sourcelang)."</strong></center></td>\n",
     637               "<td><strong><center>". uc ($targetlang)."</strong></center></td>\n",
     638               "</tr>\n");
    657639        $first = "false";
    658640    }
     
    666648        my $textbox1;
    667649        if (1) {
    668             $rows = 1 if ($rows < 1);
     650            $rows = 1;  # if ($rows < 1);
    669651            $textbox1 = "<textarea name=\"whocaresh\" rows=\"$rows\" cols=\"50\" readonly=\"1\">";
    670652            $textbox1 .= "$& </textarea>\n";
     
    685667        if (1) {
    686668            $textbox2 = "<textarea name=\"$keyname$keynamecount\" rows=\"$rows\" cols=\"50\">";
    687             $textbox2 .= "$default </textarea><br>\n"; 
     669            $textbox2 .= "$default</textarea><br>\n";
    688670        }
    689671        else {
     
    699681    }
    700682    elsif ($text =~ m/\S+/) {
    701         $text =~ s/\s+/ /g;
    702        
    703         my @words = split(/ /, $text);
    704         my $words = scalar(@words);
    705         my $rows = sprintf("%.0f", $words/5);
    706         print $fh ("<tr><td align=center>\n");
    707         #determines how many rows of text are required to display the base language
    708         #macro text then use this value to determine whether we should use a text area
    709         #or a text field
    710 
    711         # Experimenting with textfield and text area
    712         # for now use exclusively textareas.
    713 
    714         # if ($rows >= 0) {
    715         if (1) {
    716             $rows = 1 if ($rows < 1);
    717 
    718             #prints to the file two text areas, the left one contains the base language
    719             #macro text, the right contains the translation language macro text if any exists
     683        $text =~ s/\s+/ /g;
     684
     685        my @words = split(/ /, $text);
     686        my $words = scalar(@words);
     687        my $rows = sprintf("%.0f", $words/5);
     688        print $fh ("<tr><td align=center>\n");
     689        #determines how many rows of text are required to display the base language
     690        #macro text then use this value to determine whether we should use a text area
     691        #or a text field
     692
     693        # Experimenting with textfield and text area
     694        # for now use exclusively textareas.
     695
     696        # if ($rows >= 0) {
     697        if (1) {
     698        $rows = 1 if ($rows < 1);
     699
     700        #prints to the file two text areas, the left one contains the base language
     701        #macro text, the right contains the translation language macro text if any exists
    720702           
    721             $text =~ s/<p>/<p>\n/g;
    722             $text =~ s/<br>/<br>\n/g;
    723             $text =~ s/<\/td>/<\/td>\n/g;
    724 
    725             print $fh ("<textarea name=\"whocaresh\" rows=\"$rows\" cols=\"50\" readonly=\"1\">",
    726                    "$text </textarea>\n",
    727                    "</td><td align=center>\n",
    728                    "<textarea name=\"$keyname\" rows=\"$rows\" cols=\"50\">",
    729                    "$default </textarea><br></td></tr>\n"); 
    730            
    731             #### print STDERR "$text \n";
    732         }
    733         else {
    734             #prints to the file two text fields, the left one contains the base language
    735             #macro text, the right contains the translation language macro text if any exists
    736             print $fh ($query->textfield(-name=>"whocares",
    737                          -default=>"$text",
    738                          -size=>50,
    739                          -readonly=>1),
    740                    "</td><td align=center>\n",
    741                    $query->textfield(-name=>"$keyname" . "$keynamecount",
    742                          -default=>"$default",
    743                          -size=>50),
    744                    "<br></td></tr>\n");
    745         }
    746         }
    747     }
     703        $text =~ s/<p>/<p>\n/g;
     704        $text =~ s/<br>/<br>\n/g;
     705        $text =~ s/<\/td>/<\/td>\n/g;
     706
     707        print $fh ("<textarea name=\"whocaresh\" rows=\"$rows\" cols=\"50\" readonly=\"1\">",
     708               "$text</textarea>\n",
     709               "</td><td align=center>\n",
     710               "<textarea name=\"$keyname\" rows=\"$rows\" cols=\"50\">",
     711               "$default</textarea><br></td></tr>\n"); 
     712        }
     713        else {
     714        #prints to the file two text fields, the left one contains the base language
     715        #macro text, the right contains the translation language macro text if any exists
     716        print $fh ($query->textfield(-name=>"whocares",
     717                         -default=>"$text",
     718                         -size=>50,
     719                         -readonly=>1),
     720               "</td><td align=center>\n",
     721               $query->textfield(-name=>"$keyname" . "$keynamecount",
     722                         -default=>"$default",
     723                         -size=>50),
     724               "<br></td></tr>\n");
     725        }
     726    }
     727    }
     728
    748729    #finishes table and adds a SUBMIT CHANGES option on the end
    749730    print $fh ("</table><br><center>\n",
     
    754735           "</td></tr><tr><td width=\"50%\"></td><td align=right width=\"50%\">",
    755736           "<br> _textsubmittext_ \n",
     737           "_textgetdmfiles_ ",
     738           "<a href=\"_httpprefix_/gsdl/macros/$targetlang" . ".dm\">_texthere_</a>",
     739           " &amp; ",
     740           "<a href=\"_httpprefix_/gsdl/macros/$targetlang" . "2.dm\">_texthere_</a>.",
    756741           "</td></tr></table>");
    757742
     
    759744    push (@queries, $query);
    760745
    761     return $query;
    762 }
     746    # return $query;
     747}
     748
     749
     750sub source_or_target_macro
     751{
     752    my ($sourcelang, $targetlang, $key) = @_;
     753
     754    my $macrofile = $key;
     755    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     756
     757    if ($macrofile eq ($sourcelang . ".dm") || $macrofile eq ($sourcelang . "2.dm")) {
     758    return "1";  # Source macro
     759    }
     760    else {
     761    return "2";  # Target macro
     762    }
     763}
     764
     765
     766sub core_or_auxiliary_macro
     767{
     768    my ($sourcelang, $sourcekey) = @_;
     769
     770    my $macrofile = $sourcekey;
     771    $macrofile =~ s/^([^:]+)::(.*)/$1/;
     772
     773    if ($macrofile eq ($sourcelang . ".dm")) {
     774    return "1";  # Core macro
     775    }
     776    if ($macrofile eq ($sourcelang . "2.dm")) {
     777    return "2";  # Auxiliary macro
     778    }
     779}
     780
    763781
    764782&main(@ARGV);
    765783
     784
     785sub get_language_codes
     786{
     787    %languagecodes = (
     788              'abkhazian', 'ab',
     789              'afar', 'aa',
     790              'afrikaans', 'af',
     791              'albanian', 'sq',
     792              'amharic', 'am',
     793              'arabic', 'ar',
     794              'armenian', 'hy',
     795              'assamese', 'as',
     796              'aymara', 'ay',
     797              'azerbaijani', 'az',
     798              'bashkir', 'ba',
     799              'basque', 'eu',
     800              'bengali', 'bn',
     801                'bangla', 'bn',
     802              'bhutani', 'dz',
     803              'bihari', 'bh',
     804              'bislama', 'bi',
     805              'breton', 'br',
     806              'bulgarian', 'bg',
     807              'burmese', 'my',
     808              'byelorussian', 'be',
     809                'belarusian', 'be',
     810              'cambodian', 'km',
     811              'catalan', 'ca',
     812              'chinese', 'zh',
     813              'corsican', 'co',
     814              'croatian', 'hr',
     815              'czech', 'cs',
     816              'danish', 'da',
     817              'dutch', 'nl',
     818              'english', 'en',
     819              'esperanto', 'eo',
     820              'estonian', 'et',
     821              'faeroese', 'fo',
     822              'farsi', 'fa',
     823              'fiji', 'fj',
     824              'finnish', 'fi',
     825              'french', 'fr',
     826              'frisian', 'fy',
     827              'galician', 'gl',
     828              'gaelic (scottish)', 'gd',
     829              'gaelic (manx)', 'gv',
     830              'georgian', 'ka',
     831              'german', 'de',
     832              'greek', 'el',
     833              'greenlandic', 'kl',
     834              'guarani', 'gn',
     835              'gujarati', 'gu',
     836              'hausa', 'ha',
     837              'hebrew', 'iw',
     838              'hindi', 'hi',
     839              'hungarian', 'hu',
     840              'icelandic', 'is',
     841              'indonesian', 'id',  # Should be 'in' for backward compatibility
     842              'interlingua', 'ia',
     843              'interlingue', 'ie',
     844              'inuktitut', 'iu',
     845              'inupiak', 'ik',
     846              'irish', 'ga',
     847              'italian', 'it',
     848              'japanese', 'ja',
     849              'javanese', 'jv',
     850              'kannada', 'kn',
     851              'kashmiri', 'ks',
     852              'kazakh', 'kk',
     853              'kinyarwanda', 'rw',
     854                'ruanda', 'rw',
     855              'kirghiz', 'ky',
     856              'kirundi', 'rn',
     857                'rundi', 'rn',
     858              'korean', 'ko',
     859              'kurdish', 'ku',
     860              'laothian', 'lo',
     861              'latin', 'la',
     862              'latvian', 'lv',
     863                'lettish', 'lv',
     864              'limburgish', 'li',
     865                'limburger', 'li',
     866              'lingala', 'ln',
     867              'lithuanian', 'lt',
     868              'macedonian', 'mk',
     869              'malagasy', 'mg',
     870              'malay', 'ms',
     871              'malayalam', 'ml',
     872              'maltese', 'mt',
     873              'maori', 'mi',
     874              'marathi', 'mr',
     875              'moldavian', 'mo',
     876              'mongolian', 'mn',
     877              'nauru', 'na',
     878              'nepali', 'ne',
     879              'norwegian', 'no',
     880              'occitan', 'oc',
     881              'oriya', 'or',
     882              'oromo', 'om',
     883                'afan', 'om',
     884                'galla', 'om',
     885              'pashto', 'ps',
     886                'pushto', 'ps',
     887              'polish', 'pl',
     888              'portuguese', 'pt',
     889              'punjabi', 'pa',
     890              'quechua', 'qu',
     891              'rhaeto-romance', 'rm',
     892              'romanian', 'ro',
     893              'russian', 'ru',
     894              'samoan', 'sm',
     895              'sangro', 'sg',
     896              'sanskrit', 'sa',
     897              'serbian', 'sr',
     898              'serbo-croatian', 'sh',
     899              'sesotho', 'st',
     900              'setswana', 'tn',
     901              'shona', 'sn',
     902              'sindhi', 'sd',
     903              'sinhalese', 'si',
     904              'siswati', 'ss',
     905              'slovak', 'sk',
     906              'slovenian', 'sl',
     907              'somali', 'so',
     908              'spanish', 'es',
     909              'sundanese', 'su',
     910              'swahili', 'sw',
     911                'kiswahili', 'sw',
     912              'swedish', 'sv',
     913              'tagalog', 'tl',
     914              'tajik', 'tg',
     915              'tamil', 'ta',
     916              'tatar', 'tt',
     917              'telugu', 'te',
     918              'thai', 'th',
     919              'tibetan', 'bo',
     920              'tigrinya', 'ti',
     921              'tonga', 'to',
     922              'tsonga', 'ts',
     923              'turkish', 'tr',
     924              'turkmen', 'tk',
     925              'twi', 'tw',
     926              'uighur', 'ug',
     927              'ukrainian', 'uk',
     928              'urdu', 'ur',
     929              'uzbek', 'uz',
     930              'vietnamese', 'vi',
     931              'volapÃŒk', 'vo',
     932              'welsh', 'cy',
     933              'wolof', 'wo',
     934              'xhosa', 'xh',
     935              'yiddish', 'ji',
     936              'yoruba', 'yo',
     937              'zulu', 'zu'
     938              );
     939
     940    return (\%languagecodes);
     941}
Note: See TracChangeset for help on using the changeset viewer.