\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#399: Dynamic Locale Changing for msgcat}
\date{March 27, 2012}
\author{Harald Oehlmann}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#399}&\textbf{Dynamic Locale Changing for msgcat}\\\hline
Author&

Harald Oehlmann \tipmail{harald.oehlmann}{elmicron.de}
\\
Created&Tuesday, \(\text{27}^{\text{th}}\) March 2012\\
Type&Project\\
Tcl Version&\(8.6\)\\
State&Accepted\\
Vote&Done\\
Version&\tipversion$Revision: 1.18 $\\
Keywords&Tcl, localization, msgcat\\
Obsoleted By&412\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP adds dynamic locale switching capabilities to the \textbf{msgcat} package.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

Within a multi-language application like a web-server, one may change the locale quite frequently, for example if users with different locales are requesting pages. Unfortunately, this does not fit well with the model adopted by the \textbf{msgcat} package, which assumes that all code follows this sequence:
\begin{enumerate}
\item{}
 Set locale list: \textbf{mclocale} \textit{locale}
\setcounter{enumi}{1}
\item{}
 Load language files with other package load: \textbf{mcload} \textit{msg-folder}
\setcounter{enumi}{2}
\item{}
 Translate strings: \textbf{mc} \textit{key args...}
\end{enumerate}

Note that if the locale should be changed after other packages are loaded, one must restart at step 2. This requires reloading all packages which is mostly not practical. The key issue is that \textbf{mcload} only loads language files included in the current locale (\textbf{mcpreferences}) and does not load any others.

The aim of this TIP is to extend \textbf{mcload} to load additional language files. Then \textbf{mclocale} may be called to change the locale on runtime without the need to re-execute \textbf{mcload} (which would normally imply to reinitialise or reload the package).

\section{Specification}

This TIP proposes to add a new command:

\begin{quote}
\textbf{msgcat::mcconfig -pattern} ?\textit{patternlist}?
\end{quote}

This command may get or set package options. There is currently one option ``\textbf{-pattern}''.

Options may be set using

\begin{quote}
\textbf{msgcat::mcconfig} \textit{option value} ?\textit{option}? ?\textit{value}?
\end{quote}

Current option values may be read using:

\begin{quote}
\textbf{msgcat::mcconfig} \textit{option}
\end{quote}

\subsection{Option -pattern}

The option \textbf{-pattern} consists of a list of language file name patterns like \textbf{fr*}, \textbf{*}, or \textbf{fr\_ch}.

Any \textbf{mcload} command executed after this setting will consider this list \textit{in addition} to the current locale list. Files are searched using a \textbf{glob} command per element on the specified pattern plus the string ``.msg''. If ``fr*'' is specified within the pattern list, the file search pattern is ``fr*.msg''.

The default option value is the empty list \{\}. In consequence, only files covered by the current locale list are sourced.

\section{Example Usage}

Imagine an application which supports the current user language and French, German and English. An external package \textbf{tp} is used. The package uses \textbf{msgcat} and performes within the \textbf{package require tp} call:
\begingroup\small\begin{verbatim}
package require msgcat
msgcat::mcload [file join [file dirname [info script]] msgs]
\end{verbatim}
\endgroup

An implementation of the application with the current msgcat 1.4.4 would require the following initialisation sequence:
\begingroup\small\begin{verbatim}
package require msgcat
package require np
\end{verbatim}
\endgroup

and the following code to change the locale to French:
\begingroup\small\begin{verbatim}
package forget np
msgcat::mclocale fr
package require np
\end{verbatim}
\endgroup

Using the extension of this tip, the required code for initialisation is:
\begingroup\small\begin{verbatim}
package require msgcat
msgcat::mcconfig -pattern {fr* de* en*}
package require np
\end{verbatim}
\endgroup

and to change to french locale:
\begingroup\small\begin{verbatim}
msgcat::mclocale fr
\end{verbatim}
\endgroup

Within this modification, locale change is a cheap operation. Before, it was computational expensive (if possible, as many packages are not reloadable or a reload may disturb current processing, e.g., by forcing the closing of sockets, etc.).

\section{Reference Implementation}

See Tcl Feature Request 3511941. [\url{http://sourceforge.net/support/tracker.php/?aid=3511941}]

\section{Compatibility}

No incompatibilities are introduced.

\section{Issues}

Packages might not be aware of a locale change and may buffer translations outside of \textbf{msgcat}. Packages should not buffer msgcat messages if they are used in a dynamic locale application (like tklib tooltip does for example).

\section{Alternatives}

This implementation requires the setting of the pattern before any package with msgcat is loaded. To avoid this, msgcat must store all paths passed by any \textbf{mcload} call. When a locale change happens, any currently missing files are loaded. This requires much more housekeeping and may lead to side effects, especially if packages are not aware of the fact that their package files are loaded outside of the \textbf{mcload} command.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
