Purpose: information relating to the message catalog interface. ---- Documentation can be found at http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/msgcat.htm ---- The msgcat package (standard with Tcl since 8.1) addresses the problem of hard coded application text. Instead of ====== label .x -text Files ====== if you write ====== label .x -text [mc Files] ====== then you can create catalog entries for various languages for the term "Files". Also, ''mc'' will apply formatting to the string, so ====== puts [mc "Directory contains %d files" $nfiles] ====== will allow a translator to work with the string "Directory contains %d files". The above example assumes you have once invoked ====== package require msgcat ;# and done namespace import msgcat::* ;# (or msgcat::mc). ====== Provided you have .msg files containing ====== ::msgcat::mcset de Files Dateien ::msgcat::mcset fr Files Fichiers ====== (notice that the rootname part has the naming convention that it shall be the contained language - for e.g. locale "en_us_funky", ''msgcat'' searches the contents of first ''en_us_funky.msg'', then ''en_us.msg'', then ''en.msg'') then either automagically (when env(LANG) is accordingly set) or by ====== ::msgcat::mclocale fr ====== .x will have the text "Fichiers". If you want to package your messages into the application file, you can as well do this with ''mcset''. See [Multilingual menu] and [A little stopwatch] for examples. <> Note that msgcat 1.3 (comes with Tcl 8.4) also initializes the locale from ''::env(LC_ALL)'' or ''::env(LC_MESSAGES)''. [LES]: I don't have ''::env(LC_ALL)'' and ''::env(LC_MESSAGES)'' on [Slackware] 11. ---- [Arjen Markus] This came up in the newsgroup: The utility [frink] is able to adjust the source code so that the new code uses the msgcat package. ---- The 8.3.4 release of the [PPC] binary is broken in that it lacks msgcat and [bgerror] implementations. [Melissa Schrumpf] explains the situation with her customary clarity ... bgerror and msgcat are contained in tcl/library/msgcat/msgcat.tcl. Do this: Copy "Simply Tk (PPC)" to "Simply Tk (PPC).edit" Run ResEdit (or Resourcer, or whathaveyou). Open a "Simply Tk (PPC).edit" in ResEdit. Open the "TEXT" resources. Open resource ID "package require msgcat" This will be right at the top. Next, open tcl/library/msgcat/msgcat.tcl in a text editor. Copy from the beginning of the line: package provide msgcat 1.1.1 through to the end of the file. Return to ResEdit. Delete the line "package require msgcat" and, in its place, paste the code you copied from msgcat.tcl. Close all resources and save. You now have a fixed stand-alone Tk shell. ---- [Anton Kovalenko] has written, "Also, there is a small but useful script, which converts non-ascii characters from current system encoding to \uXXXX sequences. I think it would be useful to anyone who works often with tcl message catalogs. http://kovalenko.webzone.ru/unicodize.tcl (A/AK: chat.ru is down, so my page migrated) " LES: "Forbidden. You don't have permission to access /unicodize.tcl on this server." ---- A/AK: there are some things about [msgcat and shortcut keys], that are important for GUI application writers. [EKB] And this seems to have been continued into [ampersand magic]. ---- [KHM] Any Idea where to download this tool? [LV] KHM - msgcat is a part of Tcl itself. Or are you talking about some other tool? ----- GNU gettext has support (since V 0.13 [http://groups.yahoo.com/group/tcl_announce/message/1750]) for Tcl msgcat and conversion tools from and to PO format. http://ftp.gnu.org/gnu/gettext/ ----- Simple Tk example of switching languages, complements of [dgp]: ====== package require Tk bgerror 123 msgcat::mclocale "fr" msgcat::mcload [file join $::tk_library msgs] bgerror 123 msgcat::mclocale "en_gb" msgcat::mcload [file join $::tk_library msgs] bgerror 123 ====== ---- Now, how can I determine what languages are available for mclocale? ---- ''[escargo] 8 Dec 2003'' - What if you want to do some form of parameter substitution in the strings that you might use with '''msgcat'''? In some systems I have developed, messages were somewhat macro-like; you might pass a number or a name (of a file, for example) that should be part of the message. Is there anything in the '''msgcat''' that does the substitution internally, or do I have to add my own layer on top of it? [RS]: Easy, for instance with [format]: ====== msgcat::mcset fr "Directory contains %d files" "Il y a %d fichiers" ... puts [format [mc "Directory contains %d files"] $nfiles] ====== '''[DGP]''' Even easier. There's a [format] already built-in to [mc]: ====== puts [mc "Directory contains %d files" $nfiles] ====== [EKB] I moved this example up to the top of the page and combined it with the intro text so it's easier to find. [AM] Also very useful: the %1$s type format codes - with this you can interchange variables if needed. ====== % mc "this is a %s test for %s" first anything this is a first test for anything % mc {this is a %2$s test for %1$s} first anything this is a anything test for first ====== Note the {} around the text to prevent the $ to be interpreted and looking for the variable $s. ---- [RS] 2007-01-08: Here's a simple self-contained example for testing: ====== #!/usr/bin/env tclsh package require msgcat msgcat::mcset de yes Ja msgcat::mcset de no Nein msgcat::mcset fr yes Oui msgcat::mcset fr no Non proc localbool value { if {$value} {msgcat::mc yes} else {msgcat::mc no} } puts [localbool 0]/[localbool 1] That's all. Save that to a file, and run it with different LANG settings: $ /Tcl/msgcat.tcl Nein/Ja $ LANG=fr /Tcl/msgcat.tcl Non/Oui $ LANG=en /Tcl/msgcat.tcl no/yes ====== ---- [HaO] 2010-04-07: '''Switching locale at runtime''' `msgcat::mcload` only loads the message files required by the current locale. Given a locale `de_CH` (swiss german), the following files will be loaded: `de_ch.msg`, `de.msg` and `ROOT.msg`. ***Example*** An application is localised in german, french and, as default, english. ****msg file setup**** Each namespace has a folder containing the following files: * `de.msg` : german translation * `fr.msg` : french translation * `ROOT.msg` : english translation as default ****load message catalogues**** Within each namespace, the following commands must be executed: ====== msgcat::mclocale de msgcat::mcload msgcat::mclocale fr msgcat::mcload ====== ****switch locale**** ====== # switch to french msgcat::mclocale fr msgcat::mc