# vim: set cindent expandtab ts=4 sw=4:
#
# Copyright (c) 1998-2005 Chi-Keung Ho. All rights reserved.
#
# This programe is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# Extmail - a high-performance webmail to maildir
# $Id$
package Ext::Lang;
use strict;
use Ext;
use Exporter;
use Ext::Utils qw(untaint);
use vars qw(@ISA @EXPORT $LANG);
@ISA = qw(Exporter);
@EXPORT = qw(initlang langlist guess_intl intl2euc curlang charset_detect);
use vars qw(%http2intl %intl2euc);
%http2intl = (
'en' => 'en_US',
'ja' => 'ja',
'ko' => 'ko',
'zh' => 'zh_CN',
'zh-sg' => 'zh_CN',
'zh-tw' => 'zh_TW',
'zh-hk' => 'zh_TW',
);
%intl2euc = (
'en_US' => 'iso-8859-1',
'ja' => 'euc-jp',
'ko' => 'euc-kr',
'zh' => 'GB2312',
'zh_CN' => 'GB2312',
'zh_TW' => 'BIG5',
);
# initlang($locale)
sub initlang {
my ($lang,$pkg) = @_;
$pkg = $pkg|| 'main'; # default to main::
if (!$lang) { $lang = guess_intl() }
$LANG = $lang; # ouch :-(
if (-r (my $file = $Ext::Cfg{SYS_LANGDIR}."/$lang")) {
eval {
loadlang($pkg, $file);
};
warn "Error on load $lang, $@" if($@);
} else {
# load default en_US locale
loadlang($pkg, $Ext::Cfg{SYS_LANGDIR}."/en_US");
}
}
sub loadlang {
my ($newpkg, $lang, @symlist)=@_;
require $lang;
# lang pack type for certain application
my $LangPackName = $Ext::Cfg{SYS_APP_TYPE};
if($lang=~m{/}) {
$lang =~s#.*/([^\/]+)$#$1#; # strip path info
}
my $langpkg = ($LangPackName || 'Ext::Lang') .'::'.$lang;
no strict 'refs';
@symlist=keys %{$langpkg.'::'} if ($#symlist<0);
foreach my $sym (@symlist) {
# alias symbo of sub routine into current package
*{$newpkg.'::'.$sym}=*{$langpkg.'::'.$sym};
}
}
sub guess_intl {
my @lang;
foreach ( split(/[,;\s]+/, lc($ENV{'HTTP_ACCEPT_LANGUAGE'})) ) {
push(@lang, $_) if (/^[a-z\-_]+$/);
push(@lang, $1) if (/^([a-z]+)\-[a-z]+$/ ); # eg: zh-tw -> zh
}
foreach my $lang (@lang) {
return $http2intl{$lang} if (defined($http2intl{$lang}));
}
return('en_US');
}
sub intl2euc {
my $lang = shift;
return unless $lang;
if ($intl2euc{$lang}) {
return $intl2euc{$lang};
}
}
sub langlist {
my $regexp = '^\s*\$lang_description\s*=\s*(\'|")([^\'"]+)(\'|")\s*';
my $lang_dir = $Ext::Cfg{SYS_LANGDIR};
my @pref_lang;
opendir(DIR, $lang_dir) or die "Can't opendir $lang_dir, $!\n";
my @locales = grep { !/^\./ } readdir DIR;
close DIR;
for my $f (@locales) {
open(FD, "< $lang_dir/$f"); # ignore error;
while(<FD>) {
push @pref_lang, {lang=>$f, desc=>$2}
and last if(/$regexp/);
}
close FD;
}
\@pref_lang;
}
# getlang - user land function, not available here, go to App level
sub curlang {
return $LANG || 'en_US';
}
# XXX FIXME the core charset detect function - experimantal
sub charset_detect {
my ($buf, $len) = @_;
my $char;
$buf = substr($buf, 0, $len) if ($len);
# stage 1, load module
eval {
# this module seems to be more acuccury than Encode::Detect
require Encode::PPDetector;
if ($@) {
require Encode::Detect::Detector;
$char = Encode::Detect::Detector::detect($buf);
} else {
$char = Encode::PPDetector::detect($buf);
}
};
# stage 2, return default unless detect success
return 'iso-8859-1' unless ($char);
# lower case it
$char = lc $char;
# stage 3, fix charset name
if ($char =~ /^shift[-\_]*jis$/) {
$char = 'shift-jis';
} elsif ($char eq 'gb18030') {
$char = 'cp936';
} elsif ($char =~ /^utf-*8$/) {
$char = 'utf-8';
}
return $char;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1