msgcat magic

On the 22. Aug 2002 an interesting usage for the msgcat package has been discussed briefly in the Tcl chatroom.

Normally msgcat just translates messages, but you can use it to translate, for example, proc names and switch between locale-specific procs with this.

Example:

     package require msgcat
     msgcat::mcset en "l10nproc:foo" "foo_en"
     msgcat::mcset de "l10nproc:foo" "foo_de"

     proc foo_en {} {
        puts "some english text"
     }

     proc foo_de {} {
        puts "etwas deutscher text"
     }

     [msgcat::mc i10nproc:foo]

There is a risk however, if you pass your .msg files to unknowing translators who mess things up.


FB: while experimenting with msgcat today I thought it would be neat to have the script update the local language msg file with any missing mcset entries. This method would append undefined msgcat strings to the msg file as mc text strings are added to the TCL script. This might make for easier translations of a script.

As this is my first attempt, I submit to the community's great coding skills. Please be gentle.

Some trivial procedures were omitted for space, such as log, program_title, get_date, and get_time.

        ## Procedure:  mcunknown
        # output debug message about missing string in msgcat language file
        # store the src string in translations var to be added to msg file at program exit

        proc msgcat::mcunknown {locale src args} {
        global translations
        log "- add translation to [file join lang $locale].msg:\t$src translated-text"
        if {[lsearch $translations $src] < 0} {lappend translations $src}
        return $src
        }

        ## Procedure:  save_missing_translations
        # save to msgcat language file all missing translation strings
        # assumes msg file is stored in a lang subdir
        # note that TCL 8.3 does not have ::mcmset proc defined

        proc save_missing_translations {args} {
        global translations
        if {![info exists translations]} {
                log "- error: translations variable not defined"
                return
                }
        if {[llength $translations] < 1} {return}
        set locale [::msgcat::mclocale]
        set f [file join [file dirname [info script]] lang $locale.msg]

        # append to existing file or create new
        if {[catch {set fid [open $f a]} result]} {
                log "- error saving missing translations to $f"
                log " $result"
                return
                }

        puts $fid "# TRANSLATION FILE FOR [program_title]"
        puts $fid "# LANGUAGE: $locale"
        puts $fid "# written [get_date] at [get_time]\n"

        puts $fid "::msgcat::mcmset $locale {"

        # write out each new string to file so it can be translated later
        foreach str [lsort $translations] {
                puts $fid "[list $str] [list $str]"
                }
        puts $fid "}\n"
        close $fid
        log "+ saved missing translations to $f"
        }

        ## Procedure:  quit_program

        proc quit_program {args} {
        save_missing_translations
        exit
        }

        # call quit_program before the script exits
        wm protocol . WM_DELETE_WINDOW {quit_program}