<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% \iffalse meta-comments
% msg.dtx original file name. This is a 8bits file.      
%
% Copyright (C) 2004 LPPL - Bernard Gaulle.
%
% This file may be distributed and/or modified under the conditions of
% the LaTeX Project Public License as of http://www.latex-project.org/lppl.txt
%
% This file has the LPPL maintenance status "maintained".
% The current maintainer is Bernard.Gaulle at idris.fr
% \fi 
% \CheckSum{1333}
% \iffalse
%    \begin{macrocode}
%&lt;*README&gt;
%% To unpack this package: latex msg.ins
%% To prepare for TeX Live: make TL
%%
%%                   HERE IS THE MSG PACKAGE FOR LaTeX
%%
%%  A LaTeX package to localize any package or document class.
%% 
%%  A LaTeX package able to issue messages in the language provided as option
%%  of \documentclass or in use in the document (\languagename). All messages
%%  are identified with a unique "id" and stored in a MessagesFile whose name
%%  is related to the package and optionnaly to the language.
%% 
%%  MessagesFile, name: [&lt;language&gt;]_&lt;package&gt;-msg.tex
%%            contents: \msg{&lt;id&gt;}{&lt;message&gt;}    % defines the message "id".
%%                      \msg*{&lt;id&gt;}{&lt;message&gt;}   % star form for msg emphasis.
%%                      \msg{*}{&lt;error message&gt;} % bad "id" default message.
%%    Messages can have 3 more parts defined asis:
%%                      \msg{&lt;id&gt;}{&lt;msg&gt;}[     % defines the msg first part.
%%                      \msgparti{&lt;msg_part&gt;}  % defines the msg second part.
%%                     \msgpartii{&lt;msg_part&gt;}  % defines the msg third part.
%%                    \msgpartiii{&lt;msg_part&gt;}] % defines the msg fourth part.
%%    Any message part can include a |#1| parameter provided from any
%%    of the macros below.
%%    Error messages have just a help more part as follows:
%%                      \msg{&lt;id&gt;}{&lt;msg&gt;}[     % defines the msg first part.
%%                        \help{&lt;help_part&gt;}]  % defines the help part.
%%    All messages should be fully expandable.
%%    Custolization:
%%                      \msgheader{&lt;head part of messages&gt;}
%%                      \msgtrailer{&lt;final part of messages&gt;}
%%                      \msgencoding{&lt;encoding of messages&gt;}% as for inputenc.
%%    Check "msg-msg.tex" file for msg's own messages file.
%% 
%%  Document usage:  \documentclass[any_option]{any_class}
%%           call:      \usepackage[options,language]{msg}
%% 
%%    to issue the message "id":    \issuemsg{&lt;id&gt;}(&lt;package&gt;)[#1]
%%       One can use any message macro (defaultly \typeout) with:
%%                   \issuemsg[msg_macro]{&lt;id&gt;}(&lt;package&gt;)[#1]
%%       Multi-parts message can't be issued through \issuemsg.
%%       One can specify the macro name to issue message as an option
%%          of \usepackage: \message, \wlog, \typeout, \kbtypyeout or 
%%          \ClassWarning, \ClassError, \PackageWarning, \PackageError, ...
%% 
%%    to retrieve the message "id" in \themsg (without typesetting):
%%                               \retrievemsg{&lt;id&gt;}(&lt;package&gt;)[#1]
%%       Multi-parts message will have defined also \themsgi, 
%%                                                  \themsgii and \themsgiii.
%%    to get the message "id":        \getmsg{&lt;id&gt;}(&lt;package&gt;)[#1]
%%  
%%    Usually, the requested message "id" is retrieved from 
%%           [&lt;language&gt;]_&lt;package&gt;-msg.tex but if there is no active language 
%%             or if file don't exist then message is searched in the 
%%            &lt;package&gt;-msg.tex file. 
%%
%%    For testing a messages file, you can code:
%%                   \issueallmsg[msg_macro](&lt;package&gt;)
%%            and all messages from the file will be retrieved and issued.
%%
%%    For tracing all accessed files you should load the "msg" package with
%%            the option: tracefiles.
%%
%%    In case of trouble you can ask the "msg" package not to load
%%            any message file, just load the "msg" package with the
%%            option: noop, and then you just obtain a message containing
%%            the "msgid".
%%
%% Please look at the documentations for more details.
%%
%&lt;/README&gt;
%    \end{macrocode}
% \fi
% \catcode`\&lt;=\active\def&lt;{$\langle$}
% \catcode`\&gt;=\active\def&gt;{$\rangle$}
% \def\msgname{``\textsf{msg}''}
% \title{\vspace*{-1cm}The \LaTeXe\ \msgname\  package\\
%        for package localization\thanks{This file has version
% \fileversion\ last revised \filedate}\\[0.25\baselineskip]
% \ifguide\textit{Package writer's guide}
% \else\textit{Comprehensive documentation}
% \fi}
% \author{Bernard \textsc{Gaulle}}
% \date{As of \filedate
%       \vfill{\small\tableofcontents}}
% \maketitle
%
% \section{Introduction}
%
% Since a \LaTeX\ package issues various messages, mostly in English (but,
% unfortunately, often in an English-like language), it is usefull 
% to provide a feature to localize any \LaTeXe\ package or document class. 
% The \msgname\  package is designed for that.
% Messages are in dedicated files and retrieved when needed.\\
% 
% Packages writers (as well as document class writers) just have to create
% their native messages file and ask for any message when needed.
%
% \ifguide\else
% \section{The documentation driver}
%
% This code will generate the documentation. Since it is the first piece of
% code in the file, the documentation can be obtained by simply processing
% this file with \LaTeXe.
%
% We just load the \msgname\  package for self testing purposes (which needs
% we keep track of the |doc|'s |\MakePercent| macros later used).
% \fi
%    \begin{macrocode}
%&lt;*driver&gt;
\documentclass[10pt]{ltxdoc}
  \makeatletter
  \let\msg@MPC\MakePercentComment
  \let\msg@MPI\MakePercentIgnore
  \makeatother
  \usepackage[T1]{fontenc}
  \usepackage{lmodern}% You can remove it if you don't have that font.
  \usepackage{makeidx}
  \usepackage[tracefiles]{msg}
% \usepackage{msg}% should also be tested without "tracefiles"
  \begin{document} 
  \let\hard\relax\let\endhard\relax\let\ifguide\iffalse
  \DocInput{msg.dtx} 
  \end{document}
%&lt;/driver&gt;
%    \end{macrocode}
% 
% \ifguide\else
% A package writer's guide can also be typeset using the file
% |msgguide.tex|.
% \fi
%
% \ifguide\else
% \section{Initialization}
%
% Check if the msg package is already loaded and if yes end input.
% Set the ``catcode'' for |@| if not already done.
% Assume defaultly that the output macro (|\issuemsgio|) 
% will be |\typeout| if not already initiated. Force the \texttt{inputenc}
% package to be loaded, if not already done and even from a Babel option
% since it could issue messages via our \msgname\ package.
% Check also if the english ``msg'' file \texttt{msg-msg.tex} is not installed
% to detect the original bug of TeXLive 2005 and then stop typesetting.
% \fi
%
%    \begin{macrocode}
%&lt;*code&gt;
\iffalse checksum part
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%      checksum        = "32817 1583 6882 65979"
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\fi
\def\fileversion{V0.50}\def\filedate{2006/11/09}%
\ifx\issuemsg\undefined\else\expandafter\endinput\fi%
\ifnum\catcode`\@=11\else\expandafter\catcode`\@=11\fi%
\ifx\kbencoding\undefined% If we don't have any keyboard reencoding 
  \ifx\LdfInit\@undefined% we need at least inputenc package.
       \RequirePackage{inputenc}% Usually, load that package.
  \else% But with Babel, dont use \usepackage or such,
       \let\@msg@tempa\@currname% Save current package name.
       \xdef\@currname{inputenc}% set package req.
       \@@input inputenc.sty% and input it now.
       \makeatletter%
       \let\@currname\@msg@tempa% Reset original package name.
  \fi%
  \let\@previeg\empty% We have no encoding at this time.
\fi%
\IfFileExists{msg-msg.tex}{}{%
              \message{msg: ERROR, file msg-msg.tex is missing}\stop%
                            }%
%    \end{macrocode}
% \begin{macro}{\issuemsgio}
%    \begin{macrocode}
\ifx\issuemsgio\undefined\let\issuemsgio\typeout\fi%
%    \end{macrocode}\label{msgio}
% \end{macro}
%
% \ifguide\else
% Verify that |\languagename| which is 
% set by \texttt{babel} or \texttt{mlp} or \texttt{frenchpro} 
% or \texttt{frenchle} or \ldots 
% is not a virtual language such as
% |dummy| or |nohyphenation| and then keep it as 
% the \msgname\  package's language name.
% \fi
%
%    \begin{macrocode}
\def\@msg@tempa{dummy}%
\def\@msg@tempb{nohyphenation}%
\def\@msg@tempc{english}% Default language for msg package.
\ifx\languagename\@msg@tempa\else%
 \ifx\languagename\@msg@tempb\else%
  \ifx\languagename\@msg@tempc\let\msg@languagename\undefined\else
   \ifx\languagename\undefined\let\msg@languagename\undefined%
    \else\edef\msg@languagename{\languagename}% Set it for now.
   \fi%
  \fi%
 \fi%
\fi%
%    \end{macrocode}
% \ifguide\else
% \begin{macro}{\packagewarningheader}|#1|
% This code is designed to localize text of macro |\PackageWarning| which
% we, now, redefine.
%
%    \begin{macrocode}
\def\packagewarningheader#1{Package #1 Warning: }%
%
\renewcommand{\PackageWarning}[2]{\GenericWarning{(#1)%
                                  \@spaces\@spaces\@spaces\@spaces}%
                                  {\packagewarningheader{#1}#2}%
                                 }
%    \end{macrocode}
% \end{macro}\label{pw}
% 
% Few other internal \LaTeX\ macros might be localized here... but preferably
% within the kernel.
% \fi
%
%    \begin{macrocode}
\edef\@msg@code@ast{\the\catcode`\*}% Save the current catcode of ``*''.
%    \end{macrocode}
%
% \section{Macros to be used in a \LaTeX\ package}
%
% Basically, three macro commands can be coded for package localization:\\
% |\issuemsg|, |\getmsg| and |\retrievemsg|.
% Another macro, |\issuemsgx| is given for specific cases, we will see
% that later, page \pageref{encodings}.
%
% \subsection*{Output a message}
% 
% Here is the main macro which will issue a message ``id'' via the
% command |\issuemsgio| defaultly set to |\typeout| 
% \ifguide.\else(cf page~\pageref{msgio}).\fi
% \begin{macro}{\issuemsg}|[#1]#2(#3)[#4]|
% \begin{macro}{\issuemsgx}|[#1]#2(#3)[#4]|
%    \begin{macrocode}
\def\issuemsg{\@ifnextchar[{\i@suemsg}{\i@suemsg[\issuemsgio]}%]
             }%
\def\issuemsgx{\@ifnextchar[{\i@suemsgx}{\i@suemsgx[\issuemsgio]}%]
             }%
%    \end{macrocode}
% \end{macro}
% \end{macro}
% One can provide another command to issue the message
% by the way of the first optional argument. The second argument is the 
% message ``id''; the third is the name of the package (or document 
% class\footnote{Each time we are talking about a \LaTeX\ package, please
% consider it applies also to any \LaTeX\ document class.})
% which provides that message through a
% message file whose name is |[language_]package-msg.tex|. Lastly an optional
% parameter can be set to ``|#1|\footnote{You can put here
% any replacement text instead of this \texttt{\#1} parameter. Be careful,
% this parameter or replacement text will be, usually, expanded; so
% protect any string which should not with a \texttt{\textbackslash string}
% prefix.}'' to forward an argument
% directly inside the message content. I thought the syntax would be too
% much complicated to offer much more parameters through that mean.
% We will see later that the message can also be split in four parts,
% allowing anyone to display the message differently but not as
% |\issuemsg| does.
%
% \begin{center}
% \fbox{{\texttt{\textbackslash issuemsg[&lt;\emph{message\_macro}&gt;]\{&lt;\emph{id}&gt;\}(&lt;\emph{package}&gt;)[\#1]}}}
% \end{center}
%
% The message macro could be the usual |\typeout| or any other output macro
% with one argument such as |\message| or |\wlog|.
% You can also code a macro with two arguments, such as |\ClassWarning|, 
% |\ClassWarningNoLine|, |\PackageWarning|,  |\PackageWarningNoLine|, 
% |\ClassInfo| or |\PackageInfo| which have just a name as first argument, 
% like this:
%
% \begin{center}
% \fbox{{\texttt{\textbackslash issuemsg[&lt;\emph{message\_macro\{arg1\}}&gt;]\{&lt;\emph{id}&gt;\}(&lt;\emph{package}&gt;)[\#1]}}}
% \end{center}
% That way the first argument is not localized (usually this is a class or
% package name) and the second argument is provided by the message file 
% entry and so localized.
%
% You can also use special error macros with 3 arguments as explained below.
%
% \subsection*{Willing to issue a 
%             {\mdseries\texttt{\textbackslash PackageError}}?}
% \label{willingPE}
%
% The \msgname\  package is designed for basic macro messages which have
% just only one text argument to localize. 
% The |\PackageError| is one exception; it has
% 3 arguments: the first one (name of package in error: 
% |&lt;|\texttt{\emph{package1}}|&gt;|) which is given as the following:
%
% \begin{center}
% \fbox{{\texttt{\textbackslash issuemsg[\textbackslash PackageError\{&lt;\emph{package1}&gt;\}]\{&lt;\emph{id}&gt;\}(&lt;\emph{package2}&gt;)[\#1]}}}
% \end{center}
% 
% \noindent the other two arguments will be retrieved from the message file
% of \texttt{&lt;\emph{package2}&gt;} and localized.
%
% The same coding can be used for |\ClassError|:
%
% \begin{center}
% \fbox{{\texttt{\textbackslash issuemsg[\textbackslash ClassError\{&lt;\emph{class1}&gt;\}]\{&lt;\emph{id}&gt;\}(&lt;\emph{class2}&gt;)[\#1]}}}
% \end{center}
% 
% \subsection*{Examples \&amp; tests\\
% (using the message files listed page \pageref{msgfiles})}
% |\issuemsg1(msg)| will give at the console: \\ 
% \centerline{\tt\getmsg1(msg)} but
% |\issuemsg01(msg)| will give: \retrievemsg01(msg){\tt\themsg}.
%
% While defining |\def\test#1{`\issuemsg4(msg)[#1]'}| the following call 
% |\emph{\test{SPECIAL}}| will print: \def\test#1{`\getmsg4(msg)[#1]'}\\
% \centerline{\emph{\test{SPECIAL}}}  showing that the argument
% was inserted inside the message at the exact area, replacing |#1|.
%
% In a French document, the same codes will issue:\\
% \bgroup\makeatletter\@msgINfrench\def\msg@languagename{french}
% \centerline{\tt\getmsg1(msg)}
% \centerline{\retrievemsg01(msg){\tt\themsg}}
% \centerline{\emph{\test{SPECIAL}}}
% \egroup
%
%    \begin{macrocode}
\let\@msgalspace\space%
\def\@msgalign#1{\ifx\empty#1\else\expandafter\@msgalign@%
                                  \expandafter#1\fi}%
\def\@msgalign@#1{\ifx\void#1\else\expandafter\@msgalign@@%
                                  \expandafter#1\fi}%
\def\@msgalign@@#1{\ifx\protect#1\expandafter\@msgalign@@@%
                   \else\expandafter\@msgalign@@@@%
                   \fi}%
\def\@msgalign@@@{\@msgalign}%
\def\@msgalign@@@@{\@msgalspace\@msgalign}%
\let\msg@cmd\relax%
\def\i@suemsg{\let\msg@cmd\issuemsg\i@suemsgx}%
\def\i@suemsgx[#1]#2(#3){\@ifnextchar[{\i@@uemsg[#1]#2(#3)}%]
                                     {\i@@uemsg[#1]#2(#3)[]}%
                       }%
\let\if@msg@pkg@error\iffalse% Defaultly, not an error macro message.
\def\i@@uemsg[#1]#2(#3)[#4]{%
                    \def\@argmsg{#4}%
                    \def\@msg@iocmd{#1}%
                    \def\@msg@txt{%
                                  \themsg\themsgi\themsgii\themsgiii%
                                 }%
      \let\@msg@MBori\MessageBreak%
      \ifx\MessageBreak\relax%
          \def\MessageBreak{^^J\expandafter\@msgalign\msg@header\void}%
      \fi%
%    \end{macrocode}
%
% \ifguide\else
% Here, we check for error macros and, if any, set the flag for
% further processing.
% \fi
%
%    \begin{macrocode}
                    \let\@msg@txt@\empty%
                    \def\@msg@tempb##1##2/{\let\@msg@tempb=##1}%
                    \def\@msg@tempa{\let\if@msg@pkg@error\iftrue}%
                    \@msg@tempb#1/% \PackageError is a special case with
                    \ifx\@msg@tempb\PackageError% package name and msg+help.
                          \@msg@tempa% Keep it in mind for \@msgparts.
                    \fi%
%    \end{macrocode}
%
% \ifguide\else
% Now we test if the output macro name provided is well defined ; if not 
% we retrieve our own message \#1 in place of requested one, otherwise
% we call the |\retrievemsg| macro and output the message text parts.
% \fi
%
%    \begin{macrocode}
                    \ifx\@msg@tempb\ClassError% The same for \ClassError.
                          \@msg@tempa% 
                    \fi%
                    \ifx\undefined#1\retrievemsg2(msg)%
                          \PackageWarning{msg}\@msg@txt%
                    \else\retrievemsg#2(#3)[#4]%
                        \ifx\kbencoding\undefined% Expand text now if
                          \edef\@msg@txt{\@msg@txt}% output encoding is
                          \edef\@msg@txt@{\@msg@txt@}% not available.
                        \fi%
                        \@relaxORgobble\@msg@iocmd{\@msg@txt}{\@msg@txt@}%
%%%             \csname @originalkbe\endcsname% Get back encoding if necessary.
                    \fi%
              \let\MessageBreak\@msg@MBori%
              }%
%    \end{macrocode}
%
% \subsection*{Get a message for typesetting}
%
% Sometimes we only want to get the message and typeset it. The syntax is
% the same as |\issuemsg| except there is no first optional argument for
% providing the macro name to issue the message since it is not issued at all.
%
% \begin{center}
% \fbox{{\texttt{\textbackslash getmsg\{&lt;\emph{id}&gt;\}(&lt;\emph{package}&gt;)[\#1]}}}
% \end{center}
% \subsection*{Examples \&amp; tests}
% |`\textsl{\getmsg1(msg)}'| will insert at this point 
% for typesetting the message: `\textsl{\getmsg1(msg)}'; 
% nothing is issued at the console nor in the
% log, except if the |&lt;|\emph{id}|&gt;| is not found in the message file.
%
% In a French document, the same code will issue:
%
% \bgroup\makeatletter\def\msg@languagename{french}
% \centerline{`\textsl{\getmsg1(msg)}'}
% \egroup
%
% \ifguide\else
% Here is the very simple code for |\getmsg|; just a |\retrievemsg| and
% the expansion of the message when correctly retrieved.
% \fi
%
% \begin{macro}{\getmsg}|#1(#2)[#3]|
%    \begin{macrocode}
      \def\getmsg#1(#2){\@ifnextchar[{\g@tmsg#1(#2)}{\g@tmsg#1(#2)[]}%]
                       }%
      \def\g@tmsg#1(#2)[#3]{\retrievemsg{#1}(#2)[#3]\@relaxORgobble%
                            \themsg}%
%    \end{macrocode}
% \end{macro}
%
% \subsection*{The message file input routine}\label{readingprocess}
%
% To avoid having superfluous file names listed in the \texttt{log}
% each time we request a message from a file, defaultly we read the
% file with the \TeX\ |\read| command\ifguide.\else, as the following.
% This code will not be used when the option |tracefiles| is given (in
% which case we will input the message file with an usual |\input| macro). 
% \fi
% \label{readcode}
% 
%    \begin{macrocode}
 \newif\if@msg@more%
 \def\@msglineparse#1#2\void{\def\@msg@tempa{\msg}%
                             \def\@msg@tempb{#1}%
                             \ifx\@msg@tempa\@msg@tempb%
                                   \@msg@tempf% Execute the previous line.
                                   \def\@msg@tempf{}% Start a new one.
                                   \if@msg@more% Continue line feed.
                                    \def\@msg@tempf{\protect#1#2}%
                                   \fi%
                             \else%
                                  \let\msgheaderOLD\msgheader%
                                  \let\msgtrailerOLD\msgtrailer%
                                  \let\msgencodingOLD\msgencoding%
                                  \let\spaceOLD\space%
                       \let\UTFviii@two@octetsOLD\UTFviii@two@octets%
                       \let\UTFviii@two@octetsOLD\UTFviii@two@octets%
                       \let\UTFviii@four@octetsOLD\UTFviii@four@octets%
                       \let\UTFviii@two@octets\string% If utf8 was loaded then
                       \let\UTFviii@three@octets\string% nullify it until 
                       \let\UTFviii@four@octets\string% necessary.
                                  \def\msgheader{\protect\msgheader}%
                                  \def\msgtrailer{\protect\msgtrailer}%
                                  \def\msgencoding{\protect\msgencoding}%
                                  \def\space{\noexpand\space}%
                             \def\help{\protect\helpi}%
                             \protected@edef\@msg@tempf{\@msg@tempf\@msgline}%
                       \let\UTFviii@two@octets\UTFviii@two@octetsOLD%
                       \let\UTFviii@two@octets\UTFviii@two@octetsOLD%
                       \let\UTFviii@four@octets\UTFviii@four@octetsOLD%
                                  \let\space\spaceOLD%
                                  \let\msgheader\msgheaderOLD%
                                  \let\msgtrailer\msgtrailerOLD%
                                  \let\msgencoding\msgencodingOLD%
                                  \let\spaceOLD\undefined%
                                  \let\msgheaderOLD\undefined%
                                  \let\msgtrailerOLD\undefined%
                                  \let\msgencodingOLD\undefined%
                             \fi%
                            }%
%    \end{macrocode}
%
% NOTICE: all messages read until the requested one (included) are expanded
% (before parsing) in the following macro. Thus, each (|\msg|) macro call
% should contain significant value or |\protect| a macro. The same reason
% applies to |\msgheader| and |\msgtrailer| we will discuss later (cf 
% p~\pageref{msgtrailerdef}).
%
%    \begin{macrocode}
 \let\endinputORI\endinput% Save \endinput for any use in an alone \msgencoding
 \newread\@inputmsg% We'll need it at least for the banner message.
 \def\@@input@msg@filename{% Doing nearly like \@@input\msg@filename
                           \openin\@inputmsg=\msg@filename\@msg@moretrue%
                           \let\msgparti\relax%
                           \let\msgpartii\relax%
                           \let\msgpartiii\relax%
                           \def\@msg@tempf{}%
                           \let\endinputORI\endinput%
                           \let\endinput\undefined% To avoid redef info msg.
                           \DeclareRobustCommand*{\endinput}{\@msg@morefalse%
                                                 }% 
                           \let\reserved@a\@gobble% Clean remaining code.
                           \loop\catcode`\#=\active%
                              \endlinechar=-1%
                              \read\@inputmsg to \@msgline%
                              \endlinechar`\^^M% 
                              \catcode`\#=6%
                              \ifx\@msgline\empty\else%
                                \expandafter\@msglineparse\@msgline\void%
                              \fi%
                              \ifeof\@inputmsg\@msg@morefalse\fi% 
                           \if@msg@more\repeat%
                           \closein\@inputmsg\@msg@tempf% 
                           \catcode`\#=6%
                           \let\endinput\endinputORI%
                          }%
\def\@msginput@usual{\let\endinputORI\endinput\@@input\msg@filename}% 
%    \end{macrocode}
%
%
% \subsection*{Just retrieve \texttt{\textbackslash themsg}}
%
% 
% One can also want to retrieve the message from the file and save 
% it in a macro for later use. 
% In fact, if this is a one-part message it will be saved 
% in |\themsg|, otherwise this will be the first part message and other parts 
% will be saved in |\themsgi|, |\themsgii| and |\themsgiii|.
% \ifguide\else
% This will be achieved via the |\retrievemsg| macro defined as the
% following:
% \fi
%
% \begin{macro}{\retrievemsg}|#1(#2)[#3]|
%    \begin{macrocode}
 \def\retrievemsg#1(#2){\catcode`\*=\@msg@code@ast%
                        \@ifnextchar[{\r@trievemsg#1(#2)}%]
                                     {\r@trievemsg#1(#2)[]}%
                       }%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
 \let\msg@empty\empty%
 \let\if@msgnext\iffalse% Set no request for all messages.
%    \end{macrocode}
% \begin{macro}{\themsg}
% \begin{macro}{\themsgi}
% \begin{macro}{\themsgii}
% \begin{macro}{\themsgiii}
% \begin{macro}{\msgid}\end{macro}
%    \begin{macrocode}
 \def\r@trievemsg#1(#2)[#3]{\def\@argmsg{#3}%
              \let\msg@header\empty\let\msg@trailer\empty%
              \xdef\msgid{#1}%
              \def\@msg@pkg{#2}% Prevent from empty file:
              \let\themsg\msg@empty%
              \if@msgnext\let\help\helpi\fi%
              \let\themsgi\empty%
              \let\themsgii\empty%
              \let\themsgiii\empty%
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%    \begin{macrocode}
              \let\@relaxORgobble\relax%
              \edef\@msg@tempd{\@msg@pkg-msg.tex}%
              \ifx\msg@languagename\undefined%
                 \ifx\languagename\undefined\else% Get current language.
                       \let\msg@input@lang\languagename%
                 \fi% If no current language, use msg's language.
              \else\let\msg@input@lang\msg@languagename%
              \fi%
              \csname msg@MPC\endcsname% req. when ltxdoc
              \ifx\msg@input@lang\undefined%
                  \let\msg@filename\@msg@tempd%
              \else%
                  \edef\@msg@tempc{\msg@input@lang\string_\@msg@tempd}%
                  \IfFileExists\@msg@tempc{\let\msg@filename\@msg@tempc}%
                                      {\let\msg@filename\@msg@tempd}%
              \fi%
              \edef\msg@inputlineno{the\inputlineno}%
              \makeatletter%
              \let\@msg@gobble@space\relax% Case \msgheader in 1st line.
              \let\reserved@a\@gobble% Avoid runaway.
              \bgroup\@@input@msg@filename\relax\egroup% 
              \let\msg@cmd\relax%
              \csname msg@MPI\endcsname% req. when ltxdoc
              \ifx\themsg\empty% Unusual end of file reached.
                   \def\@msg@tempa{\let\msg@empty\relax% to avoid loop.
                               \r@trievemsg6(msg)[]%
                               }%
                   \expandafter\@msg@tempa%
              \fi%
              \ifx\themsg\msg@empty%
                   \PackageError{msg}%
                       {\string\msg{*} not found in \msg@filename}%
                       {please reinstall the msg package}%
              \fi%                                
              \let\if@msg@pkg@error\iffalse% Reset for next msg request.
              \catcode`\*=\@msg@code@ast% Reset catcode too.
                           }%
%    \end{macrocode}
%
% The |\retrievemsg| command is the heart of all macros to obtain the
% wanted message. It will input the message file, depending on the
% language to use, searching for the message ``id''. If this is a valid
% language (i.e. defined in the \texttt{language.dat} 
% file in use) and the corresponding
% language file exists it is inputed otherwise it is the package default
% message file which is inputed (which should be usually in English).
% In case the message ``id'' is still not found in that file and no
% ``|*|'' message ``id'' exists we will try to access message number 6
% of the \msgname\  package. And again, if still not found we terminate
% the process with a final package error; this is the only English message
% hard coded in the \msgname\ package. Localization might occur but
% should be also hard coded; not really usefull since it is not
% addressed to the end user but to a package or class writer. 
%
% \begin{center}
% \fbox{{\texttt{\textbackslash retrievemsg\{&lt;\emph{id}&gt;\}(&lt;\emph{package}&gt;)[\#1]}}}
% \end{center}
% \subsection*{Examples \&amp; tests}
%  \retrievemsg1(msg)
% |\retrievemsg1(msg)| will set |\themsg| with the value of
% the corresponding message ; nothing is issued at the console 
% nor in the log, except if the |&lt;|\emph{id}|&gt;| is not found in 
% the message file. 
%
% \noindent|\show\themsg| will explain:
%
% \noindent|&gt; \themsg=macro:|
%
% \noindent|-&gt;|\texttt{\themsg}
% 
% \noindent In a French document, the same code will issue:
%
% \bgroup\makeatletter\def\msg@languagename{french}
%  \retrievemsg1(msg)
% \noindent|&gt; \themsg=macro:|
%
% \noindent|-&gt;|\texttt{\themsg}
% \egroup
%
% In case the message file is empty or do not contain neither the message 
% ``id'' nor any |\msg{*}| macro then we will obtain:
% \bgroup\makeatletter
% \catcode`*=\active\let*\relax%^^A for expansion when \read case.
% \let\@msg@code@ast=\active%^^A to simulate a missing \msg{*}.
% \retrievemsg999(msg)
%
% \noindent|&gt; \themsg=macro:|
%
% \noindent|-&gt;|\texttt{\themsg}
% \egroup
%
% It may also arrive that we don't find that former message (|#6|) at all
% then we will issue the usual \LaTeX\ |\PackageError| macro.
%
% \section{The message files}
%
% The default (English) message files should have the name 
% \texttt{\emph{package}-msg.tex} and localized ones should be
% \texttt{\emph{language}\_\emph{package}-msg.tex}.
% I would have prefered the file names begin with a dot which is
% a hidden file in unix and thus avoid visual pollution inside packages
% directories but, unfortunately, writing them with |doctrip| is
% generally forbiden due to `|openout_any = p|' in |texmf.cnf| 
% configuration file.
%
% These files contain only the messages which could be requested
% by the associated \texttt{\emph{package}}. It is important to say now
% that when a message is split on multiple lines, each line must end
% with "\verb*X %X" to avoid to loose the ending space when any is
% required; this is due to the special |\read|ing process shown
% \ifguide.\else
% page \pageref{readingprocess}. 
%
% \subsection*{About the \TeX\ Directory Structure}
%
% Notice that a specfic area where to place these files could be
% defined in the TDS.
%
% \bigskip\noindent
% WARNING regarding the TDS: currently file names in the TDS should not
% exceed 8 characters to be 8.3 file system compliant. 
% Thus file names used by the \msgname\  package have
% a great chance to be not TDS compliant. The files would not be used
% also on ISO-9660 CD-ROMs. But, as said Karl Berry: "I rather
% doubt TeX Live itself would be usable on an 8.3 filesystem these days".
% \bigskip
% \fi
%
% \subsection*{Message files contents}
%
% A typical file content is the following |msg-msg.tex| file, used by
% the \msgname\ package itself:
%
%&lt;/code&gt;\hard
%    \begin{macrocode}
%&lt;*english&gt;
% File: msg-msg.tex
% Here are the English messages for the \msgname\  package.
%
% The following line is just for testing purpose:
\msgencoding{}\msgheader{}\msgtrailer{}
\msg{1}{\filedate\space \fileversion\space package to issue localized %
        messages, now loaded.}{}
\msg{2}{invalid optional parameter provided:}{}
\msg{3}{invalid language requested: ``\CurrentOption''}{}
\msg{4}{This is to test the #1 feature}{}
\msg{5}{``msg'' package line number }{\msgparti{issues %
        \#\msgid\ #1 message}}
\msg{6}{msg package: UNUSUAL end of file reached when %
        \MessageBreak %
        loading \msg@filename\space file!}{}
\msg{7}{\string\msg\space syntax error}{\help{last % special test case
        argument is missing.}}
\msgheader{MESSAGE\space\msgid:\space``}\msgtrailer{''}
\msg{8}{here is a customized message}{}%
\msg{9}{here is a customized message %
        \MessageBreak which continuation is aligned}{}
\msgheader{Message\space\msgid\space(msg):\space}\msgtrailer{}
\msg*{10}{****** I emphasize: this is a WARNING! ****** %
          \MessageBreak ****** Be careful.^^J}{}
\msgheader{}\msgtrailer{}
\msg{11}{The msg package is in use with ``tracefiles'' option.}{}
\msg{12}{A risk of infinite loop arose; %
         \MessageBreak %
         please check the message file: \msg@filename}%
         {\help{Look at rules to apply in messages files.}}
\msg{*}{erroneous message id ``\msgid''}{}
%&lt;/english&gt;
%    \end{macrocode}\endhard
%
% If necessary, one can link |english_msg-msg| to that file, but since English
% is always the default language for \LaTeX\ this is useless.
%
% The same messages, localized for French, are located in 
% \label{msgfiles}
% the following messages file (|french_msg-msg.tex|):
%\hard
%    \begin{macrocode}
%&lt;*french&gt;
% Fichier french_msg-msg.tex
% Ici on trouve les messages en francais pour l'extension \msgname\ .
%
\msgencoding{latin1}\msgheader{}\msgtrailer{}
\msg{1}{\filedate\space chargement de l'extension de %
        localisation (\fileversion).}{}
\msg{2}{le param�tre optionnel est invalide}{}
\msg{3}{le langage demand� (\CurrentOption) n'existe pas}{}
\msg{4}{Ceci est pour tester le dispositif #1}{}
\msg{5}{ligne }{\msgparti{de l'extension ``msg'' g�n�re le %
                message de #1 \#\msgid}}
\msg{6}{extension msg \string: fin ANORMALE de fichier rencontr�e %
        \MessageBreak %
        en chargeant le fichier \msg@filename\space\string!}{}
\msg{7}{erreur de syntaxe � l'appel de \string\msg}% cas special de test
       {\help{il manque le dernier argument.}}
\msgheader{MESSAGE\space\msgid\space\string:\space %
           \string&lt;\string&lt;\space}
\msgtrailer{\space\string&gt;\string&gt;}
\msg{8}{ceci est un message personnalis�}{}
\msg{9}{ceci est un message personnalis� %
        \MessageBreak et align�}{}
\msgheader{Message\space\msgid\space(msg)\space\string: %
           \space}\msgtrailer{}
\msg*{10}{****** Je mets en valeur \string: %
          ceci est un AVERTISSEMENT ! ****** %
          \MessageBreak ****** Soyez prudent.^^J}{}
\msgheader{}\msgtrailer{}
\msg{11}{L'extension msg est en service avec l'option %
         \string&lt;\string&lt; tracefiles \string&gt;\string&gt;.}{}
\msg{12}{Un risque de boucle infinie a �t� rencontr� \string; %
         \MessageBreak %
         v�rifier le fichier des message \string: \msg@filename}%
         {\help{Voir les r�gles � appliquer dans les fichiers de messages.}}
\msg{*}{le message id ``\msgid'' n'est pas r�pertori�}{}
%&lt;/french&gt;
%    \end{macrocode}\endhard
%
%&lt;*code&gt;
% \bigskip
%
% Notice that you can have messages which call any internal macro name
% since the |\catcode| for |@| is assigned to letter when the message
% file is read in.
%
% \ifguide\else
% As you see, these files mostly contain |\msg| calls with three
% arguments, so it's time now to look at this code.
%
% Notice that we don't use the real filenames in the above 
% |&lt;*...&gt;| tags since they contain an underscore character which
% is not protected at this level when using  the \textsl{ltxdoc} 
% document class.
% \fi
%
% \section{The macros to use in message files}
%
% The simpliest way to code a message is: 
% \begin{center}
% \fbox{\texttt{\textbackslash msg\{&lt;\emph{id}&gt;\}\{&lt;\emph{message}&gt;\}\{\}}}
%
% \end{center}
%
% The last message in the file should have \texttt{&lt;\emph{id}&gt;} equal 
% to \texttt* to say that, when reached, no valid \texttt{&lt;\emph{id}&gt;}  
% was found in the file and
% the \msgname\  package should issue (or get or retrieve) that
% error \texttt{\emph{message}}, which could be
% e.g. |\msg{*}{erroneous message id ``\msgid''}|.
%
%    \begin{macrocode}
\catcode`\#=\active\def\set@argmsg{\def#1{\@argmsg}}%
\catcode`\#=6%
%    \end{macrocode}
% \begin{macro}{\msg}|#1#2#3|
%    \begin{macrocode}
\def\msg{\let\@msg@gobble@space\@gobble% Should apply after firs call.
         \@ifstar{\def\@msgskip{^^J}\@msg}{\def\@msgskip{}\@msg}}%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\long\def\@msg#1{\def\@msg@tempc{#1}\catcode`\#=\active%
                 \def\@msg@tempd##1##2\void{\def\@msg@tempd{##2}%
                                            \let\@msg@tempe\empty%
                                            \ifx\@msg@tempd\empty%
                                             \def\@msg@tempe{##1}%
                                            \fi}%
                 \@msg@tempd#1\void\relax% \@msg@tempe is the first #1 token.
                 \let\themsgi\empty% We need to clean any
                 \let\themsgii\empty% previous read
                 \let\themsgiii\empty% message parts.
                 \set@argmsg\@msg@%
                }%
\def\@gobble@help#1#2{\@msgparts}% Case 2 lines \msg with \read 
\long\def\@msg@#1{\def\@msg@tempd{% but not \input.
                           \ifx\@msginput@usual\@@input@msg@filename%
                               \def\space{\noexpand\space}%
                               \protected@edef\msg@header{\msg@header}%
                               \protected@edef\msg@trailer{\msg@trailer}%
                            \else%
                               \edef\msg@header{\msg@header}%
                               \edef\msg@trailer{\msg@trailer}%
                            \fi%
                            \edef\space{ }% 
                            \protected@xdef\themsg{%
                                       \@msgskip\msg@header#1\msg@trailer}%
                            \def\space{ }% 
                                  }%
            \catcode`\#=6\let\@msg@tempb\relax%
            \def\@msg@tempb{\@ne\tw@\thr@@\sixt@@n\@cclv}%
            \ifx\msgid\@msg@tempb% Check for any next message request.
                 \global\let\msgid\@msg@tempc%
            \else%
                 \ifx\msgid\@msg@tempc% Check for the previous id.
                      \if@msgnext\def\msgid{\@ne\tw@\thr@@\sixt@@n\@cclv}%
                      \fi%
                 \fi%
            \fi%
            \ifx\msgid\@msg@tempc% Check for the "id".
                  \let\@msgparts@ORnot\@msgparts@%
                  \def\@msg@tempb{\endinput}%
                  \if@msg@pkg@error%
%    \end{macrocode}
% \begin{macro}{\help}|#1|
%    \begin{macrocode}
                     \let\help\@firstofone%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
                     \def\@msgparts@ORnot{\endinput\def\@msg@txt@}%
                  \fi%
                  \def\@msg@tempf{}%
                  \expandafter\@msg@tempd%
            \else\expandafter%
                  \ifx\@msg@tempe*\let\@msgparts@ORnot\@msgparts@%
                      \def\@msg@tempb{\endinput\@msg@tempd%
                      \PackageWarningNoLine{msg}{\themsg% 
                                           \themsgi\themsgii\themsgiii}%
                      \global\let\@relaxORgobble\@gobble}%
                  \else\let\@msgparts@ORnot\@gobble%
                  \fi%
            \fi%
            \catcode`\#=\active
            \@ifnextchar\protect{\expandafter\@gobble@help}{\@msgparts}%
                 }%
%    \end{macrocode}
%
% When the |\msg{*}| is reached the \msgname\  package will issue a
% |\PackageWarning| with that message, but no line number is sent
% because the message file is still not closed and the current line
% number is that from the message file. The message is also forwarded
% to the \TeX\ mouth even when an |\issuemsg| was requested.
%
% \subsection*{To build a \texttt{\textbackslash PackageError} 
%              or \texttt{\textbackslash ClassError} message}
% \label{buildPE}
%
% A |\PackageError| has a message part and a help part; these are
% given as the following:
%
% \begin{minipage}[t]{0.9\textwidth}
% \hrule\medskip
% \begin{center}
% \begin{tabbing}
% |\msg{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part}|&gt;}|\=\kill^^A]
% |\msg{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part}|&gt;}|
% \&gt; |{\help{&lt;|\emph{help-part}|&gt;}}|
% \end{tabbing}
% \end{center}
% \medskip
% \hrule\medskip
% \end{minipage}
%
% \noindent in that special case you can't build a multi-parts message as
% explained in the following section.
%
% \subsection*{To build a multi-parts message}
%
% When given, the optional argument provides 3 additional message parts.
% Here is the syntax :
%
% \begin{minipage}[t]{0.9\textwidth}
% \hrule\medskip
% \begin{center}
% \begin{tabbing}
% |\msg{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part1}|&gt;}{|\=\kill^^A]
% |\msg{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part1}|&gt;}{|
% \&gt; |\msgparti{&lt;|\emph{message-part2}|&gt;}|\\
% \&gt; |\msgpartii{&lt;|\emph{message-part3}|&gt;}|\\
% \&gt; |\msgpartiii{&lt;|\emph{message-part4}|&gt;}}|
% \end{tabbing}
% \end{center}
% (Any |\msgparti*| can be omitted)
% \medskip
% \hrule\medskip
% \end{minipage}
%
% When retrieved, |\themsg| will contain \emph{message-part1},
% |\themsgi| the \emph{message-part2},
% |\themsgii| the \emph{message-part3} and
% |\themsgiii| the \emph{message-part4}.
% One can build the wanted message with the mix of these four parts and other
% materials. When requested via |\getmsg| or |\issuemsg| the four
% parts are sticked in the usual order.
%
% \ifguide\else
% These macros are defined when the last |\msg| argument is read in.
% \fi
%
%    \begin{macrocode}
\long\def\@msgparts#1{\def\@msg@tempc{\catcode`\#=6% 
                                      \def\@msg@tempb{\issuemsg[%
                                           \PackageError{\@msg@pkg}]{7}(msg)%
                                            \endinput}%
                                      \expandafter\@msg@tempb%
                                      }%
         \ifx\msg#1% When #1 is \msg it's sure the previous \msg
             \@msg@tempc% didn't provided the correct arguments.
         \else%
          \ifx\msgheader#1\@msg@tempc% ditto for \msgheader
          \else%
           \ifx\msgtrailer#1\@msg@tempc% ditto for \msgtrailer
           \else%
            \ifx\msgencoding#1\@msg@tempc% ditto for \msgencoding
            \else%
            \@msgparts@ORnot{#1}%
            \fi%
           \fi%
          \fi%
         \fi%
         \@ifnextchar\space{\@gobble}{}% Gobble any superfluous blank.
                     }%
%    \end{macrocode}
% \begin{macro}{\msgparti}|#1|
% \begin{macro}{\msgpartii}|#1|
% \begin{macro}{\msgpartiii}|#1|
%    \begin{macrocode}
%
\long\def\@msgparts@#1{\long\def\msgparti##1{\xdef\themsgi{##1}}%
                       \long\def\help##1{\xdef\themsgi{\space help=##1}}%
                       \long\def\helpi##1{\xdef\themsgi{\space help=##1}}%
                       \long\def\msgpartii##1{\xdef\themsgii{##1}}%
                       \long\def\msgpartiii##1{\xdef\themsgiii{##1}}%
                       #1\catcode`\#=6\expandafter\@msg@tempb%
                      }%
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \section*{Input encoding discussion}\label{encodings}
%
% It is assumed that, defaultly, |\issuemsg| will finally provide a message
% to the console (without any encoding). 
% The macro |\getmsg| is designed for typesetting (usually with an
% input encoding). Since
% |\retrievemsg|'s target is unknown, display or typesetting, we let
% the package or class maker to decide which input encoding has to be
% set up.
%
% If you want to issue a message but not to the console, you should
% probably use the macro |\issuemsgx| in place of |\issuemsg|.
%
% \subsection*{For messages issued to the console}
%
% If your messages can be coded in 7bits, no problem except that you 
% probably need to avoid macros like |\aa|, |\oe|, |\ae|, etc. which
% can't output as expected on the console or log file.
% If your messages use 8bits characters, these 8bits characters will
% be output asis (until the \LaTeX\ team introduces a real output
% encoding for the console\footnote{The \msgname\ package is already designed
% for any output encoding; this is the \texttt{\textbackslash kbencoding}
% macro call which can do that (as currently done by my experimental
% \texttt{keyboard} package).}).
%
% \subsection*{For messages to be typeset}
%
% If any of your messages use at least one 8bits character, you need to 
% specify which input encoding you are using:
% \begin{center}
% \fbox{\texttt{\textbackslash msgencoding\{&lt;\emph{input encoding}&gt;\}}}
%
% \end{center}
% you just have to give the name of the input encoding, exactly like
% with |\inputencoding| for the \texttt{inputenc} package.
% This is usually the first command in the messages file.
%
% \begin{macro}{\msgencoding}|#1|
%    \begin{macrocode}
\let\@msgencoding\@gobble% Nearly null macro until \AtBeginDocument,
\def\msgencoding#1{\ifx\empty#1\else% just disactive 8bits chars.
                    \let\iterateORI\iterate% 
                    \def\@msg@encoding{#1}%
                    \ifx\msg@cmd\issuemsg% If there is not output encoding:
                      \ifx\kbencoding\undefined%\inputencoding{ascii}%
                      \def\@msgenc@loop##1##2{\@tempcnta`##1\relax%
                                              \loop\catcode\@tempcnta=11%
                                               \ifnum\@tempcnta&lt;`##2\relax%
                                               \advance\@tempcnta\@ne%
                                              \repeat}%
                      \@msgenc@loop\^^A\^^H%
                      \@msgenc@loop\^^K\^^K%
                      \@msgenc@loop\^^N\^^_%
                      \@msgenc@loop\^^?\^^ff% 128-255
%%%                     \global\let\@originalkbe\relax%
                      \else%
%%%                     \xdef\@originalkbe{\noexpand\kbencoding{\@kbencoding}}%
                        \let\languagename\msg@languagename%
                        \let\msgidORI\msgid% Save current msgid because
                        \kbencoding{#1}%  it may issue any message.
                        \let\msgid\msgidORI% Now reset it.
                        \@msg@moretrue% Continue file reading. 
                      \fi%
                    \else\let\@latex@infoORI\@latex@info%
                         \let\@latex@info\@gobble%
                         \let\endinputBACK\endinput%
                         \let\endinput\endinputORI%
                         \let\msgidORI\msgid% Save current msgid because
                         \@msgencoding{#1}% it may issue any message.
                         \let\msgid\msgidORI% Now reset it.
                         \let\endinput\endinputBACK%
                         \let\@latex@info\@latex@infoORI%
                    \fi\makeatletter%
                    \let\iterate\iterateORI%
                   \fi%
                  }%
\let\@msg@encoding\empty% Unknown current encoding.
\ifx\kbencoding\undefined%
    \AtBeginDocument{\let\@msgencoding\inputencoding}%
    \let\inputencodingORI\inputencoding% Save \inputencoding code
    \def\inputencoding#1{\def\@ieg{#1}\let\exec@ieg\relax% Avoid
                         \ifx\@ieg\@previeg\else% to load twice
                              \def\@previeg{#1}% the same encoding file.
                              \def\exec@ieg{\inputencodingORI\@ieg}%
                         \fi%
                         \exec@ieg%
                        }%
\else%
    \AtBeginDocument{\let\@msgencoding\kbencoding}%
\fi%
%    \end{macrocode}
% \subsection*{Disadvantage using \texttt{\textbackslash msgencoding}}
%
% As the \texttt{inputenc} package is automatically loaded when
% |\msgencoding| is executed, there is a risk you try loading again
% \texttt{inputenc} in the preamble via |\usepackage|. This is the case
% if any message was already issued by the \msgname\ package and then
% an option clash will occur and force you to put the encoding option
% as a global option in |\documentclass|.
%
% Since \msgname\ is calling |inputenc| there will be real difficulties
% to localize the |inputenc| package itself.
% \end{macro}
%
% \section*{The messages file rules}
%
% Due to the \ifguide |reading| process \else
% previous |\read| (page \pageref{readcode}) code \fi 
% you should apply the following rules in
% a message file:
% \begin{description}
% \item [Rule 1:] A line can be a comment (begining with \%).
% \item [Rule 2:] A line can begin with |\msg|,|\msgheader|,|\msgtrailer|
%                 or |\msgencoding|.
% \item [Rule 3:] A |\msg| line can be continued on the next line(s), assuming
%         each one ends with \verb*X %X.
% \item [Rule 4:] The following macros: |\msgheader|, |\msgtrailer|,
%                 or  |\msgencoding| are always executed.
% \item [Rule 5:] Spacing inside |\msgheader| and |\msgtrailer| should be
%       made only by the use of the macro |\space|.
% \item [Rule 6:] Any of these three macros should be expandable at any time.
% \item [Rule 7:] No other macro command can begin a line. 
% \item [Rule 8:] All 8bits characters used should in the range specified
%                 by the  macro command |\msgencoding|.
% \end{description}
% That's all!
%
% \subsection*{To build messages with header and/or trailer}
%
% \begin{macro}{\msgheader}|#1|\label{msgtrailerdef}
% \begin{macro}{\msgtrailer}|#1|\end{macro}\end{macro}
%    \begin{macrocode}
\def\msgheader#1{\let\reserved@a\relax%
                 \def\msg@header{#1}\protect\@msgHTsptoken}%
\def\msgtrailer#1{\let\reserved@a\relax%
                  \def\msg@trailer{#1}\protect\@msgHTsptoken}%
\def\@msgHTsptoken{\@ifnextchar\@sptoken{\@msg@gobble@space%
                                         \let\@msg@gobble@space\@gobble}%
                                        {\let\@msg@gobble@space\@gobble}%
                  }%
%    \end{macrocode}
%
% Before any |\msg| call you can specify which header and/or trailer you
% want in the following message or messages. You just have to specify them:
%
% \begin{minipage}[t]{0.4\textwidth}
% \hrule\medskip
% \begin{center}
% |\msgheader{&lt;|\emph{my\_header}|&gt;}|\\
% |\msgtrailer{&lt;|\emph{my\_trailer}|&gt;}|
% \end{center}
% \hrule\medskip
% \end{minipage}
%
% When a message needs to be continued on the next line you just
% have to insert |\MessageBreak| where you want the new line will
% start and then the \msgname\ package will try to align the following
% text by adding the same number of |\space|s as tokens in  the
% expanded |\msgheader|. That feature only applies with |\issuemsg| and
% only to the |&lt;|\emph{message-part1}|&gt;| (the three other message parts
% can not have any header or trailer).
% 
% \subsection*{To emphasize a message}
%
% When you want to emphasize a message you just have to code the star form of
% the |\msg| macro:
%
% \begin{minipage}[t]{0.9\textwidth}
% \hrule\medskip
% \begin{center}
% \begin{tabbing}
% |\msg*{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part1}|&gt;}|\=\kill^^A]
% |\msg*{&lt;|\emph{id}|&gt;}{&lt;|\emph{message-part1}|&gt;}|
% \&gt; |{&lt;|\emph{part2}|}&gt;}|
% \end{tabbing}
% \end{center}
% \hrule\medskip
% \end{minipage}
%
% and then the message will be issued after a line skip on the console and log.
% If your message ends with |^^J| another line will be skiped after.
% Obviously this feature only works with |\issuemsg| but not with
% |\getmsg| or |\retrievemsg|.
%
% \subsection*{Examples \&amp; tests}
%
% We use message \# 5 of |msg-msg.tex| file as following:
%
% \noindent
%  \def\foo#1{\retrievemsg5(msg)[#1]\themsg\the\inputlineno\ \themsgi}
% |\def\foo#1{\retrievemsg5(msg)[#1]\themsg\the\inputlineno\ \themsgi}|
%
% \medskip\noindent
% then |\emph{The \foo{test}}| will generate: 
%
% \centerline{The \emph{\foo{test}}}
%
% \noindent
% In a French document, the code |\emph{La \foo{test}}| will issue:
%
% \bgroup\makeatletter\def\msg@languagename{french}
% \centerline{\emph{La \foo{test}}}
% \egroup
%
% \medskip
% We will now use the message \# 8  of |msg-msg.tex| file in order
% to show the customization set in that file.
%
% \medskip\noindent
% |\getmsg8(msg)| will generate:\\
% \getmsg8(msg)
%
% The following |\texttt{\getmsg9(msg)}| using 
% |\MessageBreak| will give at the console:\\%
% {\catcode`^^J=\active\let^^J\\%^^A We try to simulate the output console.
%  \def\@msgalspace{\hbox{\space}}%^^A In order to simule \obeyspaces
%  \def\space{\@sptoken}%^^A  we used \space in \msgheader argument.
%  \def\MessageBreak{^^J\expandafter\@msgalign\msg@header\void%
%                    \hbox{\space}}%^^A Please explain this tt behaviour...
%  \texttt{\getmsg9(msg)}\\%
% }
% (same message issued to the console\issuemsg9(msg)).%^^A Issue it really.
% 
% \noindent
% And in a French document, the same calls will issue:\\
%  \bgroup\makeatletter\def\msg@languagename{french}%
%  \getmsg8(msg)\\%
%  \catcode`&lt;=12\catcode`&gt;=12\relax%^^A To remove ltxdoc active chars.
%  \catcode`^^J=\active\let^^J\\%^^A We try to simulate the output console.
%  \def\@msgalspace{\hbox{\space}}%^^A In order to simule \obeyspaces
%  \def\space{\@sptoken}%^^A We try to simulate the output console.
%  \def\MessageBreak{^^J\expandafter\@msgalign\msg@header\void%
%                    \hbox{\space}}%^^A Please explain this tt behaviour...
%  \texttt{\getmsg9(msg)}
% 
% \egroup
%
% Below is a test of an emphasized message (|\texttt{\getmsg{10}(msg)}|):
%
% {\catcode`^^J=\active\let^^J\\%^^A We try to simulate the output console.
%  \def\msg{\@ifstar{\def\@msgskip{\\}\@msg}{\def\@msgskip{}\@msg}}%
%  \def\@msgalspace{\hbox{\space}}%^^A In order to simule \obeyspaces
%  \def\space{\@sptoken}%^^A  we used \space in \msgheader argument.
%  \def\MessageBreak{^^J\expandafter\@msgalign\msg@header\void%
%                    \hbox{\space}}%^^A Please explain this tt behaviour...
% \noindent\texttt{\getmsg{10}(msg)}%
% }
% (same message issued to the console\issuemsg{10}(msg)).
% 
% \section{Testing a message file}
%
%
% When you are building a messages file few typing errors can occur; so
% there is a need to test that file. You can do this by using the
% following macro call: 
%
% \begin{center}
% \fbox{{\texttt{\textbackslash issueallmsg[&lt;\emph{message\_macro}&gt;](&lt;\emph{package}&gt;)}}}
% \end{center}
%
% All messages will be retrieved and issued as requested (with the message
% macro) but not, perhaps, with the exact macro call which will be used in the
% \LaTeXe\ package or document class. Specially, the |\help| macro call
% does nothing and |\msgpart|s are listed in the order found in the file.
% You should also notice that all macros used inside the
% messages should be expandable. This macro is allways executed with
% the \texttt{tracefiles}\footnote{I never found the right code 
% to avoid a loop with
% \texttt{tracefiles} option...} option.
%
% Here is an example using the \msgname\ file
% (|\issueallmsg[\wlog](msg)|)%
% \wlog{^^J **************** Testing the file *************}%
% \issueallmsg[\wlog](msg)  
% \wlog{^^J **************** The End  of test *************}%
% please check the log file to find the output.
%
% \begin{macro}{\issueallmsg}|[#1](#2)|\label{issueallmsg}
%    \begin{macrocode}
  \def\issueallmsg{\bgroup\let\@@input@msg@filename\@msginput@usual%
                   \let\msg@cmd\issuemsg%
                   \@ifnextchar[{\i@sueallmsg}{\i@sueallmsg[\issuemsgio]}%]
                  }%
  \def\i@sueallmsg[#1]{\let\@msg@iocmdn#1\i@@ueallmsg}%
  \def\i@@ueallmsg(#1){\def\next{\i@@@eallmsg(#1)}%
                       \long\def\help##1{\xdef\themsgi{\space help=##1}}%
                       \let\if@msgnext\iftrue% begin/continue loop.
              \def\msgid{\@ne\tw@\thr@@\sixt@@n\@cclv}% Set next one wanted.
              \let\prev@msgid\msgid% Save previous id.
                       \i@@@eallmsg(#1)% Go for looping.
                       \let\if@msgnext\iffalse%
                      }%
  \def\i@@@eallmsg(#1){\def\@tempa{\i@@uemsg[\@msg@iocmdn]}%
                       \let\themsg\empty%
                       \expandafter\@tempa\expandafter{\msgid}(#1)[]% Get it.
                       \def\@tempa{\let\if@msgnext\iffalse}%
                       \ifx\prev@msgid\msgid%
                           \@tempa%
                           \let\@@input@msg@filename\@msginput@usual%
                           \issuemsg[\PackageError{msg}]{12}(msg)%
                           \expandafter\stop%
                       \fi%
                       \let\prev@msgid\msgid% Save previous id.
                       \def\@tempa{*}% Check if last one.
                       \ifx\msgid\@tempa%
                            \let\next\egroup% This is the end.
                       \fi%
                       \let\msg@cmd\issuemsg%
                       \next%
                      }%
%    \end{macrocode}
% \end{macro}
% \section{Output options}
%
% \begin{center}
% \fbox{\texttt{\textbackslash usepackage[&lt;\emph{output-options}&gt;]\{msg\}}}%
% \end{center}
%
% The output options provide to the \msgname\  package with a running
% macro name to issue any message, in replacement of the default
% |\issuemsgio| macro initialized at the begining (cf page~\pageref{msgio}).
% Currently the following macro names are defined as options:
% 
% \begin{center}
% \def|{$\mid$}
% \fbox{\texttt{\textbackslash usepackage[message|wlog|typeout|kbtypeout]\{msg\}}}%
% \end{center}
%
%    \begin{macrocode}
\ifx\intern@lc@llfrom\undefined% Options aren't declared for internal/kernel calls
  \DeclareOption{message}{\let\issuemsgio\message}% TeX cs.
  \DeclareOption{wlog}{\let\issuemsgio\wlog}% Plain TeX cs.
  \DeclareOption{typeout}{\let\issuemsgio\typeout}% LaTeX cs.
  \DeclareOption{kbtypeout}{\let\issuemsgio\kbtypeout}% Keyboard cs.
\fi%
%    \end{macrocode}
%
% These options are related to basic messages macros but this
% is not an exhaustive list of macros which can be called by
% |\issuemsg|. Specially, |\PackageError| can also be used,
% as already discussed p.~\pageref{willingPE} and p.~\pageref{buildPE}.
% The last one macro name is coming from a package of mine 
% (\textsf{keyboard}) doing input encoding and output decoding.
%
% \section{A tracing option}
%
% \begin{center}
% \fbox{\texttt{\textbackslash usepackage[&lt;\emph{tracefiles}&gt;]\{msg\}}}%
% \end{center}
%
% The \texttt{tracefiles} option changes the processing for reading
% messages files. Defaultly these files are not read with the usual
% |\input| macro and so the files are not listed in the \texttt{log}
% file. When giving the \texttt{tracefiles} option messages files
% are read with a |\input| macro like and then the full path names 
% are listed.
%
%    \begin{macrocode}
\ifx\intern@lc@llfrom\undefined% Options aren't declared for internal/kernel calls
  \DeclareOption{tracefiles}{\let\@@input@msg@filename\@msginput@usual}%
\fi%
%    \end{macrocode}
%
% \section{A special option}
%
% \begin{center}
% \fbox{\texttt{\textbackslash usepackage[&lt;\emph{noop}&gt;]\{msg\}}}%
% \end{center}
%
% The \texttt{noop} option changes the processing: don't read the
% messages files and just provides the "msgid" as text message with
% the following header: |0&lt;msg noop&gt;|. 
%
%    \begin{macrocode}
\ifx\intern@lc@llfrom\undefined% Options aren't declared for internal/kernel calls
  \DeclareOption{noop}{\def\@@input@msg@filename{\xdef\themsg{0}%
            \xdef\themsgi{\string&lt;msg noop\string&gt;\space\msgid}%
                                                }%
                      }%
\fi%
%    \end{macrocode}
%
% \section{Language options}
%
% \begin{center}
% \fbox{\texttt{\textbackslash usepackage[&lt;\emph{output-options}&gt;,&lt;\emph{language-name}&gt;]\{msg\}}}%
% \end{center}
%
% Defaultly messages are issued from the message file dedicated to the
% document running language. One can force the \msgname\  package to use
% a specific language (assuming it was defined in the \texttt{language.dat}
% file in use), just give it as the last option.
%
% \begin{macro}{\nativelanguage}|#1|\end{macro}
%    \begin{macrocode}
\edef\nativelanguage{french}% This is my native language.
%    \end{macrocode}
% This optional macro is usefull to understand and/or translate
% correctly the message files. Each package writer can define it
% as i currently do for the \msgname\  package here. To obtain messages
% in writer's native language, just call the \msgname\  package with
% the option `|native|':
%
% \begin{center}
% \fbox{\texttt{\textbackslash usepackage[&lt;\emph{output-options}&gt;,native]\{msg\}}}%
% \end{center}
%
% \ifguide\else
% The previous line of code declares |french| as an option for the \msgname\  
% package itself. Going this way we redefine |\packagewarning| we set at
% the begining page~\pageref{pw} and translate |\on@line| in French.
% I don't suggest to do the same for all other languages... this is just
% a native language privilege.
% \fi
%
%    \begin{macrocode}
\let\on@lineORI\on@line%
\let\pwhORI\packagewarningheader%
\ifx\intern@lc@llfrom\undefined% Options aren't declared for internal/kernel calls
  \DeclareOption{french}{% Mostly a testing option 
                         % or have msg's messages in French.
                         \@msgINfrench}%
\fi%
\def\@msgINfrench{%
     \def\on@line{ (voir le source, ligne \the\inputlineno)}%
     \def\packagewarningheader##1{Extension ##1 : ATTENTION, }%
     \def\msg@languagename{french}}%
%    \end{macrocode}
%
% \ifguide\else
% It may occur that the |\languagename| is already set (e.g. in the 
% \LaTeX\ format), so we test it; if French is set the \msgname\  package will
% then speak that language.
%
%    \begin{macrocode}
\edef\@msg@tempa{french}\ifx\languagename\@msg@tempa\@msgINfrench\fi%
%    \end{macrocode}
% Here is the code to process the last option:
% \fi
%    \begin{macrocode}
% Last option will be the msg's language if defined (within the
% \texttt{language.dat} file in use).
\ifx\intern@lc@llfrom\undefined% Options aren't declared for internal/kernel calls
  \DeclareOption*{% Once a language is provided we should 
     \let\on@line\on@lineORI% reset to default.
     \let\packagewarningheader\pwhORI%
     \def\@msg@tempa{native}%
     \ifx\@msg@tempa\CurrentOption%
      \let\msg@languagename\nativelanguage%
     \else%
     \expandafter%
     \ifx\csname l@\CurrentOption\endcsname\relax%
          \def\@msg@tempa{\retrievemsg3(msg)\PackageWarningNoLine{msg}%
                     {\themsg\themsgi\themsgii\themsgiii}}%
     \else\def\@msg@tempa{\edef\msg@languagename{\CurrentOption}}%
     \fi\@msg@tempa%
   \fi%
               }%
\fi%
%
%    \end{macrocode}
% The last option, if undeclared as an option, is assumed to be 
% a language name. If that  language is unknown (i.e. undefined 
% in the \texttt{language.dat} file in use) we issue a warning 
% with message number 3, 
% otherwise that language name will be now the prefix for all
% the message files names searchs. It overides any previously set
% (in format, package, ...) language name for use by the \msgname\  package.
%
% Notice that, when set (and forced) as option, the \msgname\  language 
% name can't be changed any way inside the document (no language 
% change can modify that).
%
% \ifguide\else
% \section{Finally}
%
% It's time now to process the options, get the \msgname\  package's banner
% and issue it as well in the log file.
%
% That's all for the code.
% \fi
%
%    \begin{macrocode}
\ifx\intern@lc@llfrom\undefined% No process of options for internal/kernel calls
  \ProcessOptions% Process options
\fi% 
% Retrieve msg: \filedate\ msg package (\fileversion) loaded.
\bgroup% Protect from any setting.
\retrievemsg1(msg)% 
\csname msg@MPC\endcsname% required when ltxdoc
\ProvidesPackage{msg}[\themsg]% Issue that message in log file with 
\def\@msg@tempa{\retrievemsg{11}(msg)\wlog{\themsg}}% options messages.
\ifx\@@input@msg@filename\@msginput@usual\expandafter\@msg@tempa\fi%
\egroup%
%&lt;/code&gt;
%    \end{macrocode}
% \section{Migration scheme}
% 
% If you want to migrate a document class ou package issuing messages
% in order it could be localized for any language, you just have
% to follow the following steps:
%
% \begin{enumerate}
% \item Chose the native language and create the related messages file.
% \item Chose the input encoding and define it in the messages file
%       with the macro |\msgencoding|.
% \item Insert the final error message (|\msg(*){...}{}|).
% \item Isolate all messages in the code. 
% \item Attach to each message a unique \textsl{id}.
% \item Comment each message argument(s) and put these arguments
%       in the message file as: \\
% |\msg{|\textsl{id}|}{|\textsl{argument1}|}{&lt;|\textsl{argument2}|&gt;}|
% \item Replace the message macro call (|\typeout| or |\wlog| or ...)
%       by : \\
%       |\issuemsg[&lt;|\textsl{message macro}|&gt;]{|\textsl{id}|}(|\textsl{package}|)|
% \item Check the syntax carefully, specially, for error messages and 
%       when a parameter will be used. 
% \item Test each message independtly and tune it considering the 
%       display option, the header and trailer facilities, etc.
% \item Test the messages file with |\issueallmsg|.
% \item Consider other translations of your native messages file.
% \item Release the new code along with its messages files.
% \end{enumerate} 
%
% \section{Generated files}
%
% Currently the file |msg.ins| is the file to compile with (La)TeX
% to generate all the \msgname\  stuff. Here is |msg.ins| showing
% the |doctrip| generated files:
%
% \makeatletter%
% \def\verbatimfile#1{\begingroup\small\let\check@percent\relax\tt%
%                     \@verbatim\frenchspacing\@vobeyspaces%
%                     \@@input#1\endgroup}%
% \makeatother%
% \bigskip\hrule
% \verbatimfile{msg.ins}%
%
% \bigskip
% \hrule
%
% \section{Volunteers}
%
% Volunteers are welcome to translate the \msgname\ package message
% file (the English one or the native one in French) in their mother language.
% Lot of thanks to them! 
%
% \section{Thanks}
%
% The following people contributed to that project and we really appreciate
% their effort for testing, translating, documenting, etc.:
% Hans~F.~Nordhaug, Harald~Harders.
% \vfill
% Enjoy!
% \vfill
% \centerline{$*$--$*$}
% \vfill
% \newpage
% \iffalse
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&amp;
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \&lt;
%%   Equals        \=     Greater than  \&gt;     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~
%%   And any code from 128 to 255
%%  }
%%
% \fi
% \Finale%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
</pre></body></html>