package require Tcl 8.2
package provide msgcat 1.3
namespace eval msgcat {
namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \
mcunknown
variable Locale ""
variable Loclist {}
array set Msgs {}
array set WinRegToISO639 {
01 ar 0401 ar_SA 0801 ar_IQ 0c01 ar_EG 1001 ar_LY 1401 ar_DZ
1801 ar_MA 1c01 ar_TN 2001 ar_OM 2401 ar_YE 2801 ar_SY
2c01 ar_JO 3001 ar_LB 3401 ar_KW 3801 ar_AE 3c01 ar_BH
4001 ar_QA
02 bg 0402 bg_BG
03 ca 0403 ca_ES
04 zh 0404 zh_TW 0804 zh_CN 0c04 zh_HK 1004 zh_SG 1404 zh_MO
05 cs 0405 cs_CZ
06 da 0406 da_DK
07 de 0407 de_DE 0807 de_CH 0c07 de_AT 1007 de_LU 1407 de_LI
08 el 0408 el_GR
09 en 0409 en_US 0809 en_GB 0c09 en_AU 1009 en_CA 1409 en_NZ
1809 en_IE 1c09 en_ZA 2009 en_JM 2409 en_GD 2809 en_BZ
2c09 en_TT 3009 en_ZW 3409 en_PH
0a es 040a es_ES 080a es_MX 0c0a es_ES@modern 100a es_GT 140a es_CR
180a es_PA 1c0a es_DO 200a es_VE 240a es_CO 280a es_PE
2c0a es_AR 300a es_EC 340a es_CL 380a es_UY 3c0a es_PY
400a es_BO 440a es_SV 480a es_HN 4c0a es_NI 500a es_PR
0b fi 040b fi_FI
0c fr 040c fr_FR 080c fr_BE 0c0c fr_CA 100c fr_CH 140c fr_LU
180c fr_MC
0d he 040d he_IL
0e hu 040e hu_HU
0f is 040f is_IS
10 it 0410 it_IT 0810 it_CH
11 ja 0411 ja_JP
12 ko 0412 ko_KR
13 nl 0413 nl_NL 0813 nl_BE
14 no 0414 no_NO 0814 nn_NO
15 pl 0415 pl_PL
16 pt 0416 pt_BR 0816 pt_PT
17 rm 0417 rm_CH
18 ro 0418 ro_RO
19 ru
1a hr 041a hr_HR 081a sr_YU 0c1a sr_YU@cyrillic
1b sk 041b sk_SK
1c sq 041c sq_AL
1d sv 041d sv_SE 081d sv_FI
1e th 041e th_TH
1f tr 041f tr_TR
20 ur 0420 ur_PK 0820 ur_IN
21 id 0421 id_ID
22 uk 0422 uk_UA
23 be 0423 be_BY
24 sl 0424 sl_SI
25 et 0425 et_EE
26 lv 0426 lv_LV
27 lt 0427 lt_LT
28 tg 0428 tg_TJ
29 fa 0429 fa_IR
2a vi 042a vi_VN
2b hy 042b hy_AM
2c az 042c az_AZ@latin 082c az_AZ@cyrillic
2d eu
2e wen 042e wen_DE
2f mk 042f mk_MK
30 bnt 0430 bnt_TZ
31 ts 0431 ts_ZA
33 ven 0433 ven_ZA
34 xh 0434 xh_ZA
35 zu 0435 zu_ZA
36 af 0436 af_ZA
37 ka 0437 ka_GE
38 fo 0438 fo_FO
39 hi 0439 hi_IN
3a mt 043a mt_MT
3b se 043b se_NO
043c gd_UK 083c ga_IE
3d yi 043d yi_IL
3e ms 043e ms_MY 083e ms_BN
3f kk 043f kk_KZ
40 ky 0440 ky_KG
41 sw 0441 sw_KE
42 tk 0442 tk_TM
43 uz 0443 uz_UZ@latin 0843 uz_UZ@cyrillic
44 tt 0444 tt_RU
45 bn 0445 bn_IN
46 pa 0446 pa_IN
47 gu 0447 gu_IN
48 or 0448 or_IN
49 ta
4a te 044a te_IN
4b kn 044b kn_IN
4c ml 044c ml_IN
4d as 044d as_IN
4e mr 044e mr_IN
4f sa 044f sa_IN
50 mn
51 bo 0451 bo_CN
52 cy 0452 cy_GB
53 km 0453 km_KH
54 lo 0454 lo_LA
55 my 0455 my_MM
56 gl 0456 gl_ES
57 kok 0457 kok_IN
58 mni 0458 mni_IN
59 sd
5a syr 045a syr_TR
5b si 045b si_LK
5c chr 045c chr_US
5d iu 045d iu_CA
5e am 045e am_ET
5f ber 045f ber_MA
60 ks 0460 ks_PK 0860 ks_IN
61 ne 0461 ne_NP 0861 ne_IN
62 fy 0462 fy_NL
63 ps
64 tl 0464 tl_PH
65 div 0465 div_MV
66 bin 0466 bin_NG
67 ful 0467 ful_NG
68 ha 0468 ha_NG
69 nic 0469 nic_NG
6a yo 046a yo_NG
70 ibo 0470 ibo_NG
71 kau 0471 kau_NG
72 om 0472 om_ET
73 ti 0473 ti_ET
74 gn 0474 gn_PY
75 cpe 0475 cpe_US
76 la 0476 la_VA
77 so 0477 so_SO
78 sit 0478 sit_CN
79 pap 0479 pap_AN
}
}
proc msgcat::mc {src args} {
variable Msgs
variable Loclist
variable Locale
set ns [uplevel 1 [list ::namespace current]]
while {$ns != ""} {
foreach loc $Loclist {
if {[info exists Msgs($loc,$ns,$src)]} {
if {[llength $args] == 0} {
return $Msgs($loc,$ns,$src)
} else {
return [uplevel 1 \
[linsert $args 0 ::format $Msgs($loc,$ns,$src)]]
}
}
}
set ns [namespace parent $ns]
}
return [uplevel 1 \
[linsert $args 0 [::namespace origin mcunknown] $Locale $src]]
}
proc msgcat::mclocale {args} {
variable Loclist
variable Locale
set len [llength $args]
if {$len > 1} {
error {wrong }
if {$len == 1} {
set Locale [string tolower [lindex $args 0]]
set Loclist {}
set word ""
foreach part [split $Locale _] {
set word [string trimleft "${word}_${part}" _]
set Loclist [linsert $Loclist 0 $word]
}
}
return $Locale
}
proc msgcat::mcpreferences {} {
variable Loclist
return $Loclist
}
proc msgcat::mcload {langdir} {
set x 0
foreach p [mcpreferences] {
set langfile [file join $langdir $p.msg]
if {[file exists $langfile]} {
incr x
set fid [open $langfile "r"]
fconfigure $fid -encoding utf-8
uplevel 1 [read $fid]
close $fid
}
}
return $x
}
proc msgcat::mcset {locale src {dest ""}} {
variable Msgs
if {[string equal $dest ""]} {
set dest $src
}
set ns [uplevel 1 [list ::namespace current]]
set Msgs([string tolower $locale],$ns,$src) $dest
return $dest
}
proc msgcat::mcmset {locale pairs } {
variable Msgs
set length [llength $pairs]
if {$length % 2} {
error {bad translation list: should be "mcmset locale {src dest ...}"}
}
set locale [string tolower $locale]
set ns [uplevel 1 [list ::namespace current]]
foreach {src dest} $pairs {
set Msgs($locale,$ns,$src) $dest
}
return $length
}
proc msgcat::mcunknown {locale src args} {
if {[llength $args]} {
return [uplevel 1 [linsert $args 0 ::format $src]]
} else {
return $src
}
}
proc msgcat::mcmax {args} {
set max 0
foreach string $args {
set translated [uplevel 1 [list [namespace origin mc] $string]]
set len [string length $translated]
if {$len>$max} {
set max $len
}
}
return $max
}
proc msgcat::ConvertLocale {value} {
regexp {^([^_.@]*)(_([^.@]*))?([.]([^@]*))?(@(.*))?$} $value \
-> language _ territory _ codeset _ modifier
set ret $language
if {[string length $territory]} {
append ret _$territory
}
if {[string length $modifier]} {
append ret _$modifier
}
return $ret
}
proc msgcat::Init {} {
foreach varName {LC_ALL LC_MESSAGES LANG} {
if {[info exists ::env($varName)]
&& ![string equal "" $::env($varName)]} {
mclocale [ConvertLocale $::env($varName)]
return
}
}
set key {HKEY_CURRENT_USER\Control Panel\International}
if {[catch {package require registry}] \
|| [catch {registry get $key "locale"} locale]} {
mclocale C
return
}
variable WinRegToISO639
set locale [string tolower $locale]
while {[string length $locale]} {
if {![catch {mclocale [ConvertLocale $WinRegToISO639($locale)]}]} {
return
}
set locale [string range $locale 1 end]
}
mclocale C
}
msgcat::Init