MSGCAT, i18n (internationalisation), multi langues SCRIPTS
#1
Je vous quote un début conversation IRC.
Pour rendre les scripts multi-langue et les méthodes.

Je ferais un feed back de l'avancer de mes recherches.

Lien wiki : msgcat - catalogue de messages | Rendre multi-langue/internationalisation i18n


McDeffice> Je suis occupé a regarder pour le package MSGCAT (j'ai mis a jour le wiki l'autre jour). Je regarde le methode dans les cripts de notre ami MenzAgitat car en general c'est une reference.
McDeffice> J'ai toutes un tas de questions qui me viennent.
McDeffice> Au debut, j'aimais bien l'idée de MenzAgitat de mettre un code mXXX (genre m0,m1) dans le TCL. je me suis dis bonne idées, car si on met par exemple du text anglais pour changer apres sa peut etre embetant.
McDeffice> Mais je me rend compte que lors qu'on veux faire ca avec un code de 3k de lignes de codes, et donc pas mal de choses a traduire dans differentes langues. ont ce rend comptes que les .msg de  msgcat sont vite fastidieux. jai mis un jour complet a remplacer le texte du code en code mXXX maintenant traduire en 12 langues ca va me prendre une plombe
McDeffice> 12 langues, car je reprend les langues proposer dans anope (nickserv set language)
McDeffice> C'est la que j'ai fais quelques recherches qui mont orienté vers gettext
McDeffice> car apres, certaines plateforme/logiciel permet de auto traduire en partie un fichier .pot/.po
McDeffice> et que apres msgfmt (de gettext) permet de convertir simplement en tcl ; fichier .msg (msgcat) ses catalogues
McDeffice> Le probleme reside que ses plateforme/logiciel considere qu'on parte toujours de la langue anglaise, et non pas de reference telle que mXXX
McDeffice> J'ai poser la choses un peu plus loin. Car tout comme MenzAgitat, j'ai ajouter un commentaire dans mon code source tcl avant chaque msgcat :
McDeffice> # Message : "VERIFICATION FOR INACTIF ACCOUNTS... :"
McDeffice> ::DSh::FCT:IRC:SendTo:PRIVMSG $ToChannel [_ m001]
McDeffice> Et en utilisant 'xgettext -k_ mon.tcl --language=Tcl --add-comments="Message :" --output messages.pot' j'exporte depuis le code source mon.tcl les mXXX ainsi que les commentaire dans un catalogues messages.pot
McDeffice> C'est genial, sa permet d'avoir les commentaires pour chaque ref dans poedit(par example) mais "m001" est considerer comme langue anglaise. donc ca bloque pour les traductions
McDeffice> C'est la ou je me suis dit, il y a peut -etre moyen de dertourner ca. Il sufis peut etre d'utiliser les commentaires comme langue traduite a chaque reference et ensuite traduire depuis le catalogue anglais traduite vers d'autres langues, en ce basant sur la traduction et non sur la langue sources ...
McDeffice> J'ai également fais un petit script pour essayer ca, et cela m'avance pas plus :D
McDeffice> Depuis la version 1.8.10 de POEdit, il est possible de changer la langue source par default avec un tag en tete : "X-Source-Language: tcl", evidement ca change rien au faite que "m1" ne ce traduit pas en faite.
McDeffice> Donc, au final; je pense qu'il est finalement mieux d'utilise l'anglais ou francais plutot que des REF dans le code source. Apres je n'ai pas encore tout explorer ..
McDeffice> Si jamais quelqu'un utilise gettext (peut importe le language) et maitrise un peu, ca serais gentil de m'aidé :D J'aimerais arrivé a quelques choses de concluant et le propose sur le wiki avec eventuellement mes scripts pour faire un toolkit plus complet que ce que propose le package msgcat
CrazyCat> McDeffice> j'ai pas tout lu, mais moi j'aime bien ma méthode qui est à https://gitlab.com/tcl-scripts/tcl-utili...utools.tcl
CrazyCat> (à partir de la ligne 105)
CrazyCat> (j'aime pas les m0, m1, mxxx. Je préfère avoir du vrai texte dans mes scripts)
CrazyCat> Sinon, gettext je l'ai utilisé en php et en C, je regarderai en tcl si ça s'applique
  Reply
#2
Après quelques recherches, le gettext en tcl n'est plus ou moins qu'un alias:
tcl
package require msgcat
proc _ {s} {return [::msgcat::mc $s]}
 
puts [_ "abc"]


cf https://www.gnu.org/software/gettext/man...e/Tcl.html

Et plus d'explications à http://wfr.tcl-lang.org/1173
irc.zeolia.net - Offrez-moi un café
Merci de ne pas demander d'aide en MP
  Reply
#3
(10/12/2020, 19:20)CrazyCat Wrote: Après quelques recherches, le gettext en tcl n'est plus ou moins qu'un alias:
tcl
package require msgcat
proc _ {s} {return [::msgcat::mc $s]}
 
puts [_ "abc"]


cf https://www.gnu.org/software/gettext/man...e/Tcl.html

Et plus d'explications à http://wfr.tcl-lang.org/1173

Ceci est l'équivalent dans d'autres langues oui.
Ca permet simplement de raccourcis un nom de fonction pour faire appelle au catalogue et facilité l'extraction des codes sources.
Ce n'ait qu'un alias. [_ "abc"] au lieu de [::msgcat::mc $s]

De la meme manière que en PHP on va creer l'alias _() : _("Have a nice day"); au lieu de gettext("Have a nice day");

C'est surtout pour avoir une clarté accru dans les codes ..

Ce n'est une méthode pour appeler la fonction ::msgcat::mc, ca ne remplace par le gettext en TCL.


-----


MenzAgitat m'informe que l'utilisation des "mXXX" au lieu de texte directement dans le code permet d'éviter des "doublons".

Je pense en effet que utilise des références pourrais avoir plusieurs intérêt:
Les messages qui se rapproche pourrais etre rassembler en une seul référence exemple :
# Message : "Aide pour EGG"
puts [_ m001]
# Message : "Aide pour IRC"
puts [_ m002]

on peu rassembler en :
# Message : "Aide pour %"
puts [_ mXXX EGG]
puts [_ mXXX IRC]
  Reply
#4
Topo actuel

J'essaye la méthode de MenzAgitat c'est-à-dire dans mon code source j'utilise des références et au dessus je commentes exemple:
Code:
# Message : "HELP"
putquick "PRIVMSG $chan : [::msgcat::mc m000]"
# Message : "Aide pour %"
putquick "PRIVMSG $chan : [::msgcat::mc m001 EGG]"

J'ai créer une fonction 'alias' comme cité par CrazyCat

Code:
package require msgcat
proc _ {s} {return [::msgcat::mc $s]}

puts [_ "abc"]

Cela permet de remplacer ::msgcat::mc par _
Code:
# Message : "HELP"
putquick "PRIVMSG $chan : [_ m000]"

Pour exporter tout les références vers un fichier j'utilise "xgettext" venant des toolkit de gettext (windows/linux)
CECI SORT DE L'UTILISATION HABITUEL DU PACKAGE MSGCAT

Code:
#!/bin/sh
xgettext -k_ MonCode.tcl \
--language=Tcl \
--add-comments="Message :" \
--output messages.pot
echo "extract from 'MonCode.tcl' to 'messages.pot'"
L'argument "-k_" permet de définir la fonction utiliser pour afficher les message dans mon cas _ pour [_ mXXX]
L'argument "--language=Tcl" permet de définir la langue source du code, en gros il exportera ce qui est entre la fonction [_ ] dans mon cas
L'argument --add-comments="Message :" permet d'introduire les commentaire mis haut dessus des textes;  
L'argument "--output" permet de définir le fichier de sortie ici messages.pot, notez que je met l'extension ".pot" car si j'ai bien compris ca définis le fichier comme une Template PO. et donc un modèle type. Vous pouvez mettre ".po" qui est considérai comme une traduction dans une langue.

Maintenant avec le fichier messages.pot, si j'ouvre j'ai quelque chose comme ceci :
Code:
#. Message : "HELP"
#: MonCode.tcl:10
msgid   "m000"
msgstr  ""

#. Message : "Aide pour ${WHAT}"
#: MonCode.tcl:12
msgid   "m001"
msgstr  ""
....
...

Nous avons bien toutes nos références exporter avec nos commentaires (texte) + la lignes qui a été exporter.

Mon problème réside maintenant. Car je n'ai pas trouver de bonne méthode encore pour traduire ensuite dans d'autres langues "facilement".
Bien que nous pouvons utiliser un éditeur comme POEdit
Dans ce cas, quand nous chargeons le fichier messages.pot, nous avons que les références et les champs de traduction ne sont pas prédéfinis avec les commentaires. dans les notes pour traducteur nous avons nos commentaires depuis le code source
[Image: https://snipboard.io/3h9aoj.jpg]

j'ai essayer pas mal de chose et je calle pour la bonne méthode une fois ici.

Je me suis dis qu'il serais que les commentaires que nous avons mis deviens en faite le texte traduit et exporter en fichier ".po" et la peut etre apres pouvoir traduire depuis ce po vers d'autres langages

J'ai créer un petit code pour faire ca :
Code:
#!/usr/bin/tclsh
if { $argv == "" || [lindex $argv 1] == "" } {
puts "Use: $argv0 <input file> <export file> \[CTAG\] \[CTAG_END\]"
puts "Exemple: $argv0 messages.pot en_us.po \"#. Message : \\\"\" \\\""
exit
}

set FILE_INPUT [lindex $argv 0]
set FILE_OUTPUT [lindex $argv 1]
set CTAG [lindex $argv 2]
set CTAG_END [lindex $argv 3]
if { $CTAG == "" } {
set CTAG {#. }
}
if { ![file isfile $FILE_INPUT] } { puts "ERROR: <input file> ($FILE_INPUT) not good"; exit }
if { [file isfile $FILE_OUTPUT] } { puts "ERROR: <output file> ($FILE_OUTPUT) already exist"; exit }

puts "CTAG> '$CTAG'"
puts "CTAG_END> '$CTAG_END'"

set FILE_INPUT_PIPE [open $FILE_INPUT r]
set FILE_INPUT_DATA [read $FILE_INPUT_PIPE]
close $FILE_INPUT_PIPE

set FILE_OUTPUT_PIPE [open $FILE_OUTPUT a+]

foreach INPUT_LINE [split $FILE_INPUT_DATA "\n"] {
set RE "^${CTAG}(.*)${CTAG_END}\$"
regexp -nocase $RE $INPUT_LINE - LAST_COMMENT;
if { [regexp -nocase {^msgstr  ""} $INPUT_LINE] } {
set LAST_COMMENT [string map { {\"} ""} $LAST_COMMENT]
set RE_ONE {\((\$[^.'\"\s<>]+)\)}
if { [regsub -nocase -all $RE_ONE $LAST_COMMENT "(%s)" LAST_COMMENT] } {
puts "MODIFIED LINE '$LAST_COMMENT' BY REGEXP '$RE_ONE' to \"%s\""
}
set RE_TWO {(\${[^\}]+})|(\$[^.'\"\s<>]+)}
if { [regsub -nocase -all $RE_TWO $LAST_COMMENT "%s" LAST_COMMENT] } {
puts "MODIFIED LINE '$LAST_COMMENT' BY REGEXP '$RE_ONE' to \"%s\""
}

set INPUT_LINE "msgstr  \"$LAST_COMMENT\""
}
puts $FILE_OUTPUT_PIPE $INPUT_LINE
}
close $FILE_OUTPUT_PIPE
proc linecount {file} {
set i 0
set fid [open $file r]
while {[gets $fid line] > -1} {incr i}
close $fid
return $i
}
puts "INPUT FILE> $FILE_INPUT [file size $FILE_INPUT] bytes / [linecount $FILE_INPUT] lines"
puts "OUTPUT FILE> $FILE_OUTPUT [file size $FILE_OUTPUT] bytes / [linecount $FILE_OUTPUT] lines"

Il permet de mettre les commentaire dans 'msgstr'  du fichier et crée une copie .po
petit plus de mon script , si dans votre commentaire vous avez laisser les variables -qui sont utilise pour savoir ce qu'on affiche comme valeur- il seront transformer en "%s"

exemple:
Code:
locales/Outils> ./AddComment2msgstr.tcl ../PO/messages.pot ../PO/en_us.po "#. Message : \"" \"                                                                                                                            CTAG> '#. Message : "'
CTAG_END> '"'
MODIFIED LINE 'REQUEST CHANNEL ID '%s' invalide.' BY REGEXP '\((\$[^.'\"\s<>]+)\)' to "%s"
INPUT FILE> ../PO/messages.pot 26398 bytes / 1048 lines
OUTPUT FILE> ../PO/en_us.po 33493 bytes / 1049 lines
locales/Outils>

a présent de mon fichier .pot , j'ai un fichier "en_us.po"
Code:
#. Message : "HELP"
#: MonCode.tcl:10
msgid   "m000"
msgstr  "HELP"

#. Message : "Aide pour ${WHAT}"
#: MonCode.tcl:12
msgid   "m001"
msgstr  "Aide pour %s"
....
...

Dans POEdit:
[Image: https://snipboard.io/9pHJaR.jpg]

Mon but serais évidement de traduire dans plusieurs langue, et de manière automatique si possible ..

EN SUSPEND ... espérant trouver quelques choses concluants

Imaginons que nous avons que nous avons nos .po traduits.
Il nous faut encore a les re-rendre compatibles avec le package msgcat qui lis des fichier ".msg"
pour convertir j'utilise "msgfmt" qui fait partie du toolkit gettext
Code:
locales/PO > ls                                                                                                                                                                                                            
en_us.po  messages.pot
locales/PO > msgfmt --tcl en_us.po -l en_us -d .                                                                                                                                                                           locales/PO > ls                                                                                                                                                                                                            
en_us.msg  en_us.po  messages.pot
locales/PO> cat en_us.msg                                                                                                                                                                                                
set ::msgcat::header "..........\n"
::msgcat::mcset en_us "m000" "Help"
::msgcat::mcset en_us "m001" "help of %s"


Voila ...
Petit plus, j'ai modifier la fonction
"proc _ {s} {return [::msgcat::mc $s]}"

par
Code:
proc _ { code { liststr "" } { IRC_USERNAME "" } } {
variable PATH
if { ${IRC_USERNAME} != "" } {
# GET USER LANG
set LOCAL_LANG [string tolower [FCT:IRC:User:Get:Lang ${IRC_USERNAME}]]
} else {
set LOCAL_LANG "en_us"
}

# Get user lang
::msgcat::mclocale ${LOCAL_LANG}

# Get TEXT in user lang
set TEXT_TRANSLATE [::msgcat::mc $code]

# reset to default lang
::msgcat::mclocale "en_us"

return $TEXT_TRANSLATE;
}
Il permet a présent de traduire dans la langue utilisateur le texta et de remettre dans la langue en_us par default. Car msgcat charge de manière global;

La fonction "FCT:IRC:User:Get:Lang" récupérer la langue définis par l'utilisateur (par exemple fr_fr)

Code:
# Message : "HELP"
putquick "PRIVMSG $chan : [::msgcat::mc m000]"
# Message : "Aide pour %s"
putquick "PRIVMSG $chan : [::msgcat::mc m001 EGG]"
deviens

Code:
# Message : "HELP"
putquick "PRIVMSG $chan : [::msgcat::mc m000 "" $nick]"
# Message : "Aide pour %s"
putquick "PRIVMSG $chan : [::msgcat::mc m001 "EGG" $nick]"
# Message : "coucou $nick Aide pour $what"
putquick "PRIVMSG $chan : [::msgcat::mc m001 "$nick EGG" $nick]"

Voila pour l'instant... en espérant que ca aide
  Reply
#5
Je n'ai pas tout lu, mais je pense que tu n'as pas bien compris le principe de gettext et des fichiers .po, je vais tâcher de résumer :
- tu crées un script (tcl, php, c++) dans une langue donnée et définie où chaque chaîne est encapsulée dans une commande de traduction (t(), _, gettext(), ...)
- tu génères un fichier initial à partir d'un outil (comme xgettext, d'autres existent) qui te crée le catalogue de la langue d'origine
- tu utilises poedit (ou un autre) pour créer les différentes traductions
- lorsque tu veux utiliser ton script dans une autre langue que celle d'origine, ta fonction t() va afficher soit le texte traduit soit, si la traduction n'est pas trouvée, le texte d'origine

Si tu utilises dans msgcat des "variables" de type m00, mXX, ta langue initiale est le ma_MA (MenzAgitatien) et chaque fichier de traduction contiendra comme entrée à traduire un code abscont. Et si tu oublies une traduction, tu prendras un "m737" au lieu de "I'm an error message".

Je comprends bien l'idée du "je suis sûr d'avoir tout traduit parce que mes ID se suivent", mais gettext/poedit est fait pour que tu puisses supprimer/modifier des textes simplement. Si tu avais remplacé m911 par "Call the firemen" et que tu te rends compte que c'est en fait "Call the police", rien ne te dit que tu auras corrigé la traduction vu que m911 reste comme elle était. Alors que si tu as initialement la chaine "Call the firemen" à traduire, poedit te diras qu'une des traductions manque et qu'une est à supprimer.
irc.zeolia.net - Offrez-moi un café
Merci de ne pas demander d'aide en MP
  Reply
#6
Merci.
Si j'avais bien compris le principe. Au moins ca fais un joli résumer tres claire.
La seul chose, c'est que je m'obstine a vouloir mettre une langue initiale 'ma_MA' (MenzAgitatien) comme tu dit.
Je pense que tu me la dit deux fois qu'il vaut mieux utiliser une langue initial existante (réelle) et de plus l'anglais comme prévu par ses outils.

"je suis sûr d'avoir tout traduit parce que mes ID se suivent" <= heu non pas tout par contre. Car xgettext exporte de toute façon chaque chaine à traduire. C'est d'ailleurs l'intérêt d'exporter avec xgettext quoi qu'il en soi.

Apres la où je ne comprend peut-être pas bien, si dans ton code tu as "Call the firemen" , dans tes catalogues (dans toutes les langues) tu as comme langue source "Call the firemen" , si tu change "Call the firemen" par "Call the police" tu dois rechanger tout tes catalogues?

Or si tu as "m911"; il suffirai de changer simplement ton catalogue en_us.po en changeant "juste" cette valeur m911 en "Call the firemen" sans que sa impacte tout tes catalogues.

Je comprend que si la chaine est manquante dans un des mes catalogues le message sera "m911" qui est beaucoup moins sexy et explicite que "Call the firemen" en anglais.

Je pense suivre tes conseils tout de meme; vu que c'est "comme ca" alors c'est "comme ca". Bien qu'une petite amélioration a été apporter a gettext, car maintenant on peu définir une autre langue que anglais comme langue de source.

Voir aussi :
https://stackoverflow.com/questions/2164...glish-text
https://www.hadrons.org/~guillem/docs/ge...tr-id.html
http://docs.translatehouse.org/projects/...oswap.html
  Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Recherche] Scripts de statistiques Marc 22 9,745 08/02/2010, 07:49
Last Post: Marc

Forum Jump:


Users browsing this thread: 1 Guest(s)