summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-07-31 18:27:06 +0000
committerKarl Berry <karl@freefriends.org>2011-07-31 18:27:06 +0000
commitdac945b204407dae96f70ec228206516093156d7 (patch)
tree02ca182689947e45dec95e17ba08b503c959bd17 /Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
parentc1840548792cfbc7c9f746da1d53d89b94406e72 (diff)
l3kernel (5jun11)
git-svn-id: svn://tug.org/texlive/trunk@23282 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3msg.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3msg.dtx1609
1 files changed, 1609 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
new file mode 100644
index 00000000000..eceadf3c1a8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
@@ -0,0 +1,1609 @@
+% \iffalse meta-comment
+%
+%% File: l3msg.dtx Copyright (C) 2009-2011 The LaTeX3 Project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This file is part of the "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3msg.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental messages}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3msg} package\\ Messages^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Messages need to be passed to the user by modules, either when errors
+% occur or to indicate how the code is proceeding. The \pkg{l3msg}
+% module provides a consistent method for doing this (as opposed to
+% writing directly to the terminal or log).
+%
+% The system used by \pkg{l3msg} to create messages divides the process
+% into two distinct parts. Named messages are created in the first part
+% of the process; at this stage, no decision is made about the type
+% output that the message will produce. The second part of the process
+% is actually producing a message. At this stage a choice of message
+% \emph{class} has to be made, for example \texttt{error},
+% \texttt{warning} or \texttt{info}.
+%
+% By separating out the creation and use of messages, several benefits
+% are available. First, the messages can be altered later without
+% needing details of where they are used in the code. This makes it
+% possible to alter the language used, the detail level and so on.
+% Secondly, the output which results from a given message can be
+% altered. This can be done on a message class, module or message name
+% basis. In this way, message behaviour can be altered and messages can
+% be entirely suppressed.
+%
+% \section{Creating new messages}
+%
+% All messages have to be created before they can be used. All message
+% setting is local, with the general assumption that messages will
+% be managed as part of module set up outside of any \TeX{} grouping.
+%
+% The text of messages will automatically by wrapped to the length
+% available in the console. As a result, formatting is only needed
+% where it will help to show meaning. In particular, |\\| may be
+% used to force a new line and \verb*|\ | forces an explicit space.
+%
+% \begin{function}{\msg_new:nnnn, \msg_new:nnn}
+% \begin{syntax}
+% \cs{msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Creates a \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line. An error will be raised if the \meta{message} already exists.
+% \end{function}
+%
+% \begin{function}{\msg_set:nnnn, \msg_set:nnn}
+% \begin{syntax}
+% \cs{msg_set:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Sets up the text for a \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line.
+% \end{function}
+%
+% \section{Contextual information for messages}
+%
+% \begin{function}[EXP]{\msg_line_context:}
+% \begin{syntax}
+% \cs{msg_line_context:}
+% \end{syntax}
+% Prints the current line number when a message is given, and
+% thus suitable for giving context to messages. The number itself
+% is proceeded by the text |on line|.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_line_number:}
+% \begin{syntax}
+% \cs{msg_line_number:}
+% \end{syntax}
+% Prints the current line number when a message is given.
+% \end{function}
+%
+% \begin{variable}{\c_msg_return_text_tl}
+% Standard text to indicate that the user should try pressing
+% \meta{return} to continue. The standard definition reads:
+% \begin{verbatim}
+% Try typing <return> to proceed.
+%
+% If that doesn't work, type X <return> to quit.
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{\c_msg_trouble_text_tl}
+% Standard text to indicate that the more errors are likely and
+% that aborting the run is advised. The standard definition reads:
+% \begin{verbatim}
+% More errors will almost certainly follow:
+% the LaTeX run should be aborted.
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{function}[EXP]{\msg_fatal_text:n}
+% \begin{syntax}
+% \cs{msg_fatal_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% Fatal <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_critical_text:n}
+% \begin{syntax}
+% \cs{msg_critical_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% Critical <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_error_text:n}
+% \begin{syntax}
+% \cs{msg_error_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_warning_text:n}
+% \begin{syntax}
+% \cs{msg_warning_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> warning
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_info_text:n}
+% \begin{syntax}
+% \cs{msg_info_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> info
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \section{Issuing messages}
+%
+% Messages behave differently depending on the message class. A number
+% of standard message classes are supplied, but more can be
+% created.
+%
+% When issuing messages, any arguments passed should use
+% \cs{tl_to_str:n} or \cs{token_to_str:N} to prevent unwanted expansion
+% of the material.
+%
+% \begin{function}{\msg_class_set:nn}
+% \begin{syntax}
+% \cs{msg_class_set:nn} \Arg{class} \Arg{code}
+% \end{syntax}
+% Sets a \meta{class} to output a message, using \meta{code}
+% to process the message text. The \meta{class} should be a text
+% value, while the \meta{code} may be any arbitrary material.
+% The \meta{code} will receive $6$ arguments: the module
+% name (|#1|), the message name (|#2|) and the four arguments
+% taken by the message text (|#3| to |#6|).
+% \end{function}
+%
+% The kernel defines several common message classes. The following
+% describes the standard behaviour of each class if no redirection of
+% the class or message is active. In all cases, the message may be
+% issued supplying $0$ to $4$ arguments. The code will
+% ensure that there an no errors if the number of arguments supplied
+% here does not match the number in the definition of the message
+% (although of course the sense of the message may be impaired).
+%
+% \begin{function}
+% {
+% \msg_fatal:nnxxxx ,
+% \msg_fatal:nnxxx ,
+% \msg_fatal:nnxx ,
+% \msg_fatal:nnx ,
+% \msg_fatal:nn
+% }
+% \begin{syntax}
+% \cs{msg_fatal:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing a
+% fatal error the \TeX{} run will halt.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_critical:nnxxxx ,
+% \msg_critical:nnxxx ,
+% \msg_critical:nnxx ,
+% \msg_critical:nnx ,
+% \msg_critical:nn
+% }
+% \begin{syntax}
+% \cs{msg_critical:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing the
+% message reading the current input file will stop. This may halt
+% the \TeX{} run (if the current file is the main file) or
+% may abort reading a sub-file.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_error:nnxxxx ,
+% \msg_error:nnxxx ,
+% \msg_error:nnxx ,
+% \msg_error:nnx ,
+% \msg_error:nn
+% }
+% \begin{syntax}
+% \cs{msg_error:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The error will
+% stop processing and issue the text at the terminal. After user input,
+% the run will continue.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_warning:nnxxxx ,
+% \msg_warning:nnxxx ,
+% \msg_warning:nnxx ,
+% \msg_warning:nnx ,
+% \msg_warning:nn
+% }
+% \begin{syntax}
+% \cs{msg_warning:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} warning \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The warning text
+% will be added to the log file, but the \TeX{} run will not be
+% interrupted.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_info:nnxxxx ,
+% \msg_info:nnxxx ,
+% \msg_info:nnxx ,
+% \msg_info:nnx ,
+% \msg_info:nn
+% }
+% \begin{syntax}
+% \cs{msg_info:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_log:nnxxxx ,
+% \msg_log:nnxxx ,
+% \msg_log:nnxx ,
+% \msg_log:nnx ,
+% \msg_log:nn
+% }
+% \begin{syntax}
+% \cs{msg_log:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file: the output
+% is briefer than \cs{msg_info:nnxxxx}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_none:nnxxxx ,
+% \msg_none:nnxxx ,
+% \msg_none:nnxx ,
+% \msg_none:nnx ,
+% \msg_none:nn
+% }
+% \begin{syntax}
+% \cs{msg_none:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Does nothing: used as a message class to prevent any output at
+% all (see the discussion of message redirection).
+% \end{function}
+%
+% \section{Redirecting messages}
+%
+% \begin{function}{\msg_redirect_class:nn}
+% \begin{syntax}
+% \cs{msg_redirect_class:nn} \Arg{class one} \Arg{class two}
+% \end{syntax}
+% Changes the behaviour of messages of \meta{class one} so that they
+% are processed using the code for those of \meta{class two}. Multiple
+% redirections are possible. Redirection to a missing class or
+% infinite loops will raise errors when the messages are used,
+% rather than at the point of redirection.
+% \end{function}
+%
+% \begin{function}{\msg_redirect_module:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_module:nnn} \Arg{module} \Arg{class one}
+% ~~\Arg{class two}
+% \end{syntax}
+% Redirects message of \meta{class one} for \meta{module} to act as
+% though they were from \meta{class two}. Messages of \meta{class one}
+% from sources other than \meta{module} are not affected by this
+% redirection. This function can be used to make some messages
+% \enquote{silent} by default. For example, all of the
+% \texttt{trace} messages of \meta{module} could be turned off with:
+% \begin{verbatim}
+% \msg_redirect_module:nnn { module } { trace } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}{\msg_redirect_name:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_name:nn} \Arg{module} \Arg{message} \Arg{class}
+% \end{syntax}
+% Redirects a specific \meta{message} from a specific \meta{module}
+% to act as a member of \meta{class} of messages. This function can
+% be used to make a selected message \enquote{silent} without
+% changing global parameters:
+% \begin{verbatim}
+% \msg_redirect_name:nnn { module } { annoying-message } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \section{Low-level message functions}
+%
+% The lower-level message functions should usually be accessed from the
+% higher-level system. However, there are occasions where direct
+% access to these functions is desirable.
+%
+% \begin{function}[EXP]{\msg_newline:, \msg_two_newlines:}
+% \begin{syntax}
+% \cs{msg_newline:}
+% \end{syntax}
+% Forces a new line in a message. This is a low-level function, which
+% will not include any additional printing information in the message:
+% contrast with |\\| in messages. The |two| version adds two lines.
+% \end{function}
+%
+% \begin{function}{\msg_interrupt:xxx}
+% \begin{syntax}
+% \cs{msg_interrupt:xxx} \Arg{first line} \Arg{text} \Arg{extra text}
+% \end{syntax}
+% Interrupts the \TeX{} run, issuing a formatted message comprising
+% \meta{first line} and \meta{text} laid out in the format
+% \begin{verbatim}
+% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+% !
+% ! <first line>
+% !
+% ! <text>
+% !...............................................
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length. The user may then request more information, at which
+% stage the \meta{extra text} will be shown in the terminal in the
+% format
+% \begin{verbatim}
+% |'''''''''''''''''''''''''''''''''''''''''''''''
+% | <extra text>
+% |...............................................
+% \end{verbatim}
+% where the \meta{extra text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \begin{function}{\msg_log:x}
+% \begin{syntax}
+% \cs{msg_log:x} \Arg{text}
+% \end{syntax}
+% Writes to the log file with the \meta{text} laid out in the format
+% \begin{verbatim}
+% .................................................
+% . <text>
+% .................................................
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \begin{function}{\msg_term:x}
+% \begin{syntax}
+% \cs{msg_term:x} \Arg{text}
+% \end{syntax}
+% Writes to the terminal and log file with the \meta{text} laid out in the
+% format
+% \begin{verbatim}
+% *************************************************
+% * <text>
+% *************************************************
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \section{Kernel-specific functions}
+%
+% Messages from \LaTeX3 itself are handled by the general message system,
+% but have their own functions. This allows some text to be pre-defined,
+% and also ensures that serious errors can be handled properly.
+%
+% \begin{function}{\msg_kernel_new:nnnn, \msg_kernel_new:nnn}
+% \begin{syntax}
+% \cs{msg_kernel_new:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Creates a kernel \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line. An error will be raised if the \meta{message} already exists.
+% \end{function}
+%
+% \begin{function}{\msg_kernel_set:nnnn, \msg_kernel_set:nnn}
+% \begin{syntax}
+% \cs{msg_kernel_set:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Sets up the text for a kernel \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_fatal:nnxxxx ,
+% \msg_kernel_fatal:nnxxx ,
+% \msg_kernel_fatal:nnxx ,
+% \msg_kernel_fatal:nnx ,
+% \msg_kernel_fatal:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_fatal:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one}
+% to \meta{arg four} to the text-creating functions. After issuing a
+% fatal error the \TeX{} run will halt. Cannot be redirected.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_error:nnxxxx ,
+% \msg_kernel_error:nnxxx ,
+% \msg_kernel_error:nnxx ,
+% \msg_kernel_error:nnx ,
+% \msg_kernel_error:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_error:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one}
+% to
+% \meta{arg four} to the text-creating functions. The error will
+% stop processing and issue the text at the terminal. After user input,
+% the run will continue. Cannot be redirected.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_warning:nnxxxx ,
+% \msg_kernel_warning:nnxxx ,
+% \msg_kernel_warning:nnxx ,
+% \msg_kernel_warning:nnx ,
+% \msg_kernel_warning:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_warning:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} warning \meta{message}, passing
+% \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The warning text
+% will be added to the log file, but the \TeX{} run will not be
+% interrupted.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_info:nnxxxx ,
+% \msg_kernel_info:nnxxx ,
+% \msg_kernel_info:nnxx ,
+% \msg_kernel_info:nnx ,
+% \msg_kernel_info:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_info:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3msg} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{variable}{\l_msg_tmp_tl}
+% A general scratch for the module.
+% \begin{macrocode}
+\tl_new:N \l_msg_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+%\section{Creating messages}
+%
+% Messages are created and used separately, so there two parts to
+% the code here. First, a mechanism for creating message text.
+% This is pretty simple, as there is not actually a lot to do.
+%
+%\begin{variable}{\c_msg_text_prefix_tl, \c_msg_more_text_prefix_tl}
+% Locations for the text of messages.
+% \begin{macrocode}
+\tl_const:Nn \c_msg_text_prefix_tl { msg~text~>~ }
+\tl_const:Nn \c_msg_more_text_prefix_tl { msg~extra~text~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_new:nnnn, \msg_new:nnn}
+% \begin{macro}{\msg_set:nnnn, \msg_set:nnn}
+% Setting a message simply means saving the appropriate text
+% into two functions. A sanity check first.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_new:nnnn #1#2
+ {
+ \cs_if_exist:cT { \c_msg_text_prefix_tl #1 / #2 }
+ {
+ \msg_kernel_error:nn { msg } { message-already-defined }
+ {#1} {#2}
+ }
+ \msg_set:nnnn {#1} {#2}
+ }
+\cs_new_protected:Npn \msg_new:nnn #1#2#3
+ { \msg_new:nnnn {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \msg_set:nnnn #1#2#3#4
+ {
+ \cs_set:cpn { \c_msg_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#3}
+ \cs_set:cpn { \c_msg_more_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#4}
+ }
+\cs_new_protected:Npn \msg_set:nnn #1#2#3
+ { \msg_set:nnnn {#1} {#2} {#3} { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages: support functions and text}
+%
+% \begin{variable}
+% {
+% \c_msg_coding_error_text_tl ,
+% \c_msg_continue_text_tl ,
+% \c_msg_critical_text_tl ,
+% \c_msg_fatal_text_tl ,
+% \c_msg_help_text_tl ,
+% \c_msg_no_info_text_tl ,
+% \c_msg_on_line_tl ,
+% \c_msg_return_text_tl ,
+% \c_msg_trouble_text_tl
+% }
+% Simple pieces of text for messages.
+% \begin{macrocode}
+\tl_const:Nn \c_msg_coding_error_text_tl
+ {
+ This~is~a~coding~error.
+ \\ \\
+ }
+\tl_const:Nn \c_msg_continue_text_tl
+ { Type~<return>~to~continue }
+\tl_const:Nn \c_msg_critical_text_tl
+ { Reading~the~current~file~will~stop }
+\tl_const:Nn \c_msg_fatal_text_tl
+ { This~is~a~fatal~error:~LaTeX~will~abort }
+\tl_const:Nn \c_msg_help_text_tl
+ { For~immediate~help~type~H~<return> }
+\tl_const:Nn \c_msg_no_info_text_tl
+ {
+ LaTeX~does~not~know~anything~more~about~this~error,~sorry.
+ \c_msg_return_text_tl
+ }
+\tl_const:Nn \c_msg_on_line_text_tl { on~line }
+\tl_const:Nn \c_msg_return_text_tl
+ {
+ \\ \\
+ Try~typing~<return>~to~proceed.
+ \\
+ If~that~doesn't~work,~type~X~<return>~to~quit.
+ }
+\tl_const:Nn \c_msg_trouble_text_tl
+ {
+ \\ \\
+ More~errors~will~almost~certainly~follow: \\
+ the~LaTeX~run~should~be~aborted.
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_newline:, \msg_two_newlines:}
+% New lines are printed in the same way as for low-level file writing.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_newline: { ^^J }
+\cs_new_nopar:Npn \msg_two_newlines: { ^^J ^^J }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_line_number:}
+% \begin{macro}{\msg_line_context:}
+% For writing the line number nicely.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D }
+\cs_set_nopar:Npn \msg_line_context:
+ {
+ \c_msg_on_line_text_tl
+ \c_space_tl
+ \msg_line_number:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing messages: low level mechanism}
+%
+% \begin{variable}{\c_msg_hide_tl}
+% \begin{variable}[aux]{\c_msg_hide_tl<dots>}
+% An empty variable with a number of (category code 11) periods at the
+% end of its name. This is used to push the \TeX{} part of an error
+% message \enquote{off the screen}. Using two variables here means that
+% later life is a little easier.
+% \begin{macrocode}
+\char_set_catcode_letter:N \.
+\tl_new:N
+ \c_msg_hide_tl..........................................................
+\tl_const:Nn \c_msg_hide_tl
+ { \c_msg_hide_tl.......................................................... }
+\char_set_catcode_other:N \.
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\msg_interrupt:xxx}
+% \begin{macro}[aux]{\msg_interrupt_no_details:xx}
+% \begin{macro}[aux]{\msg_interrupt_details:xxx}
+% \begin{macro}[aux]{\msg_interrupt_text:n}
+% \begin{macro}[aux]{\msg_interrupt_more_text:n}
+% \begin{macro}[aux]{\msg_interrupt_aux:}
+% The low-level interruption macro is rather opaque, unfortunately. The
+% idea here is to create a a message which hides all of \TeX{}'s own
+% information by filling the output up with dots. To achieve this,
+% dots have to be letters. The odd
+% \cs{c_msg_hide_tl<dots>} actually does the hiding: it is the
+% large run of dots in the name that is important here. The meaning
+% of |\\| is altered so that the explanation text is a simple run
+% whilst the initial error has line-continuation shown.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_interrupt:xxx #1#2#3
+ {
+ \group_begin:
+ \tl_if_empty:nTF {#3}
+ { \msg_interrupt_no_details:xx {#1} {#2} }
+ { \msg_interrupt_details:xxx {#1} {#2} {#3} }
+ \msg_interrupt_aux:
+ \group_end:
+ }
+% \end{macrocode}
+% \begin{macrocode}
+% Depending on the availability of more information there is a choice of
+% how to set up the further help. The extra help text has to be set
+% before the message itself can be issued. Everything is done using
+% \texttt{x}-type expansion as the new line markers are different for
+% the two type of text and need to be correctly set up.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_interrupt_no_details:xx #1#2
+ {
+ \iow_wrap:xnnnN
+ { \\ \c_msg_no_info_text_tl }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_continue_text_tl }
+ { ! ~ } { 2 } {} \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_details:xxx #1#2#3
+ {
+ \iow_wrap:xnnnN
+ { \\ #3 }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_help_text_tl }
+ { ! ~ } { 2 } { } \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_text:n #1
+ { \tl_set:Nn \l_msg_text_tl {#1} }
+\cs_new_protected:Npn \msg_interrupt_more_text:n #1
+ {
+%<*initex>
+ \tl_set:Nx \l_msg_tmp_tl
+%</initex>
+%<*package>
+ \protected@edef \l_msg_tmp_tl
+%</package>
+ {
+ |'''''''''''''''''''''''''''''''''''''''''''''''
+ #1
+ \msg_newline:
+ |...............................................
+ }
+ \tex_errhelp:D \exp_after:wN { \l_msg_tmp_tl }
+ }
+% \end{macrocode}
+% The business end of the process starts by producing some visual
+% separation of the message from the main part of the log. It then
+% adds the hiding text to the message to print. The error message needs
+% to be printed with everything made \enquote{invisible}: this is where
+% the strange business with |&| comes in: this is made into another
+% |!|. There is also a closing brace that will show up in the output,
+% which is turned into a blank space.
+% \begin{macrocode}
+\group_begin: % {
+ \char_set_lccode:w `\} = `\ \scan_stop:
+ \char_set_lccode:w `\& = `\! \scan_stop:
+ \char_set_catcode_active:N \&
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \msg_interrupt_aux:
+ {
+ \iow_term:x
+ {
+ \iow_newline:
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ \iow_newline:
+ !
+ }
+ \tl_put_right:No \l_msg_text_tl { \c_msg_hide_tl }
+ \cs_set_protected_nopar:Npx &
+ { \tex_errmessage:D { \exp_not:o { \l_msg_text_tl } } }
+ &
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_log:x}
+% \begin{macro}{\msg_term:x}
+% Printing to the log or terminal without a stop is rather easier.
+% A bit of simple visual work sets things off nicely.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_log:x #1
+ {
+ \iow_log:x { ................................................. }
+ \iow_wrap:xnnnN { . ~ #1} { . ~ } { 2 } { }
+ \iow_log:x
+ \iow_log:x { ................................................. }
+ }
+\cs_new_protected:Npn \msg_term:x #1
+ {
+ \iow_term:x { ************************************************* }
+ \iow_wrap:xnnnN { * ~ #1} { * ~ } { 2 } { }
+ \iow_term:x
+ \iow_term:x { ************************************************* }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \subsection{Displaying messages}
+%
+% \LaTeX{} is handling error messages and so the \TeX{} ones are disabled.
+% \begin{macrocode}
+\int_set:Nn \tex_errorcontextlines:D { -1 }
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \msg_fatal_text:n ,
+% \msg_critical_text:n ,
+% \msg_error_text:n ,
+% \msg_warning_text:n ,
+% \msg_info_text:n
+% }
+% A function for issuing messages: both the text and order could
+% in principal vary.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_fatal_text:n #1 { Fatal~#1~error }
+\cs_new_nopar:Npn \msg_critical_text:n #1 { Critical~#1~error }
+\cs_new_nopar:Npn \msg_error_text:n #1 { #1~error }
+\cs_new_nopar:Npn \msg_warning_text:n #1 { #1~warning }
+\cs_new_nopar:Npn \msg_info_text:n #1 { #1~info }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_see_documentation_text:n}
+% Contextual footer information.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_see_documentation_text:n #1
+ { \\ \\ See~the~#1~documentation~for~further~information. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_msg_redirect_classes_prop, \l_msg_redirect_names_prop}
+% For filtering messages, a list of all messages and of those which have
+% to be modified is required.
+% \begin{macrocode}
+\prop_new:N \l_msg_redirect_classes_prop
+\prop_new:N \l_msg_redirect_names_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_class_set:nn}
+% Setting up a message class does two tasks. Any existing redirection
+% is cleared, and the various message functions are created
+% to simply use the code stored for the message.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_class_set:nn #1#2
+ {
+ \prop_clear_new:c { l_msg_redirect_ #1 _prop }
+ \cs_set_protected:cpn { msg_ #1 :nnxxxx } ##1##2##3##4##5##6
+ { \msg_use:nnnnxxxx {#1} {#2} {##1} {##2} {##3} {##4} {##5} {##6} }
+ \cs_set_protected:cpx { msg_ #1 :nnxxx } ##1##2##3##4##5
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} {##5} { } }
+ \cs_set_protected:cpx { msg_ #1 :nnxx } ##1##2##3##4
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nnx } ##1##2##3
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} { } { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nn } ##1##2
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} { } { } { } { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\msg_if_more_text:N, \msg_if_more_text:c}
+% \begin{macro}[aux]{\msg_no_more_text:xxxx}
+% A test to see if any more text is available, using a
+% permanently-empty text function.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \msg_if_more_text:N #1 { p , T , F , TF }
+ {
+ \cs_if_eq:NNTF #1 \msg_no_more_text:xxxx
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\cs_new:Npn \msg_no_more_text:xxxx #1#2#3#4 { }
+\cs_generate_variant:Nn \msg_if_more_text_p:N { c }
+\cs_generate_variant:Nn \msg_if_more_text:NT { c }
+\cs_generate_variant:Nn \msg_if_more_text:NF { c }
+\cs_generate_variant:Nn \msg_if_more_text:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}
+% {
+% \msg_fatal:nnxxxx ,
+% \msg_fatal:nnxxx ,
+% \msg_fatal:nnxx ,
+% \msg_fatal:nnx ,
+% \msg_fatal:nn
+% }
+% For fatal errors, after the error message \TeX{} bails out.
+% \begin{macrocode}
+\msg_class_set:nn { fatal }
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_critical:nnxxxx ,
+% \msg_critical:nnxxx ,
+% \msg_critical:nnxx ,
+% \msg_critical:nnx ,
+% \msg_critical:nn
+% }
+% Not quite so bad: just end the current file.
+% \begin{macrocode}
+\msg_class_set:nn { critical }
+ {
+ \msg_interrupt:xxx
+ { \msg_critical_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_critical_text_tl }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_error:nnxxxx ,
+% \msg_error:nnxxx ,
+% \msg_error:nnxx ,
+% \msg_error:nnx ,
+% \msg_error:nn
+% }
+% For an error, the interrupt routine is called, then any recovery code
+% is tried.
+% \begin{macrocode}
+\msg_class_set:nn { error }
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \use:c { \c_msg_more_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_warning:nnxxxx ,
+% \msg_warning:nnxxx ,
+% \msg_warning:nnxx ,
+% \msg_warning:nnx ,
+% \msg_warning:nn
+% }
+% Warnings are printed to the terminal.
+% \begin{macrocode}
+\msg_class_set:nn { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_info:nnxxxx ,
+% \msg_info:nnxxx ,
+% \msg_info:nnxx ,
+% \msg_info:nnx ,
+% \msg_info:nn
+% }
+% Information only goes into the log.
+% \begin{macrocode}
+\msg_class_set:nn { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_log:nnxxxx ,
+% \msg_log:nnxxx ,
+% \msg_log:nnxx ,
+% \msg_log:nnx ,
+% \msg_log:nn
+% }
+% \enquote{Log} data is very similar to information, but with no extras
+% added.
+% \begin{macrocode}
+\msg_class_set:nn { log }
+ {
+ \msg_log:x
+ { \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_none:nnxxxx ,
+% \msg_none:nnxxx ,
+% \msg_none:nnxx ,
+% \msg_none:nnx ,
+% \msg_none:nn
+% }
+% The \texttt{none} message type is needed so that input can be gobbled.
+% \begin{macrocode}
+\msg_class_set:nn { none } { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \l_msg_redirect_classes_seq ,
+% \l_msg_class_tl ,
+% \l_msg_current_class_tl ,
+% \l_msg_current_module_tl
+% }
+% Support variables needed for the redirection system.
+% \begin{macrocode}
+\seq_new:N \l_msg_redirect_classes_seq
+\tl_new:N \l_msg_class_tl
+\tl_new:N \l_msg_current_class_tl
+\tl_new:N \l_msg_current_module_tl
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{macro}[int]{\msg_use:nnnnxxxx}
+% \begin{macro}[aux]{\msg_use_aux:nnn}
+% \begin{macro}[aux]{\msg_use_aux:nn}
+% \begin{macro}[aux]{\msg_use_loop_check:nn}
+% \begin{macro}[aux]{\msg_use_code:}
+% \begin{macro}[aux]{\msg_use_loop:n, \msg_use_loop:o}
+% The main message-using macro creates two auxiliary functions: one
+% containing the code for the message, and the second a loop function.
+% There is then a hand-off to the system for checking if redirection is
+% needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_use:nnnnxxxx #1#2#3#4#5#6#7#8
+ {
+ \cs_set_protected_nopar:Npx \msg_use_code:
+ {
+ \seq_clear:N \exp_not:N \l_msg_redirect_classes_seq
+ \exp_not:n {#2}
+ }
+ \cs_set_protected:Npx \msg_use_loop:n ##1
+ {
+ \seq_if_in:NnTF \exp_not:n \l_msg_redirect_classes_seq {#1}
+ { \msg_kernel_error:nn { msg } { message-loop } {#1} }
+ {
+ \seq_put_right:Nn \exp_not:N \l_msg_redirect_classes_seq {#1}
+ \exp_not:N \cs_if_exist:cTF { msg_ ##1 :nnxxxx }
+ {
+ \exp_not:N \use:c { msg_ ##1 :nnxxxx }
+ \exp_not:n { {#3} {#4} {#5} {#6} {#7} {#8} }
+ }
+ {
+ \msg_kernel_error:nnx { msg } { message-class-unknown } {##1}
+ }
+ }
+ }
+ \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 }
+ { \msg_use_aux:nnn {#1} {#3} {#4} }
+ { \msg_kernel_error:nnxx { msg } { message-unknown } {#3} {#4} }
+ }
+% \end{macrocode}
+% The first auxiliary macro looks for a match by name: the most
+% restrictive check.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_use_aux:nnn #1#2#3
+ {
+ \tl_set:Nn \l_msg_current_class_tl {#1}
+ \tl_set:Nn \l_msg_current_module_tl {#2}
+ \prop_if_in:NnTF \l_msg_redirect_names_prop { // #2 / #3 / }
+ { \msg_use_loop_check:nn { names } { // #2 / #3 / } }
+ { \msg_use_aux:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% The second function checks for general matches by module or for
+% all modules.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_use_aux:nn #1#2
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {#2}
+ { \msg_use_loop_check:nn {#1} {#2} }
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } { * }
+ { \msg_use_loop_check:nn {#1} { * } }
+ { \msg_use_code: }
+ }
+ }
+% \end{macrocode}
+% When checking whether to loop, the same code is needed in a few
+% places.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_use_loop_check:nn #1#2
+ {
+ \prop_get:cnN { l_msg_redirect_ #1 _prop } {#2} \l_msg_class_tl
+ \tl_if_eq:NNTF \l_msg_current_class_tl \l_msg_class_tl
+ {
+ { \msg_use_code: }
+ { \msg_use_loop:o \l_msg_class_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \msg_use_code: { }
+\cs_new_protected:Npn \msg_use_loop:n #1 { }
+\cs_generate_variant:Nn \msg_use_loop:n { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_class:nn}
+% Converts class one into class two.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_class:nn #1#2
+ { \prop_put:cnn { l_msg_redirect_ #1 _prop } { * } {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_module:nnn}
+% For when all messages of a class should be altered for a given module.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_module:nnn #1#2#3
+ { \prop_put:cnn { l_msg_redirect_ #2 _prop } {#1} {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_name:nnn}
+% Named message will always use the given class.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_name:nnn #1#2#3
+ { \prop_put:Nnn \l_msg_redirect_names_prop { // #1 / #2 / } {#3} }
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Kernel-specific functions}
+%
+% \begin{macro}{\msg_kernel_new:nnnn}
+% \begin{macro}{\msg_kernel_new:nnn}
+% \begin{macro}{\msg_kernel_set:nnnn}
+% \begin{macro}{\msg_kernel_set:nnn}
+% The kernel needs some messages of its own. These are created using
+% pre-built functions. Two functions are provided: one more general
+% and one which only has the short text part.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnnn #1#2
+ { \msg_new:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnn #1#2
+ { \msg_new:nnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnnn #1#2
+ { \msg_set:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnn #1#2
+ { \msg_set:nnn { LaTeX } { #1 / #2 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_fatal:nnxxxx}
+% \begin{macro}{\msg_kernel_fatal:nnxxx}
+% \begin{macro}{\msg_kernel_fatal:nnxx}
+% \begin{macro}{\msg_kernel_fatal:nnx}
+% \begin{macro}{\msg_kernel_fatal:nn}
+% Fatal kernel errors cannot be re-defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n { LaTeX } : ~ "#1 / #2" }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxx #1#2#3#4#5
+ {\msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxx #1#2#3#4
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnx #1#2#3
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nn #1#2
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_error:nnxxxx}
+% \begin{macro}{\msg_kernel_error:nnxxx}
+% \begin{macro}{\msg_kernel_error:nnxx}
+% \begin{macro}{\msg_kernel_error:nnx}
+% \begin{macro}{\msg_kernel_error:nn}
+% Neither can kernel errors.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_kernel_error:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ {
+ \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { }
+ }
+ }
+\cs_new_protected:Npn \msg_kernel_error:nnxxx #1#2#3#4#5
+ {\msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_set_protected:Npn \msg_kernel_error:nnxx #1#2#3#4
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nnx #1#2#3
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nn #1#2
+ { \msg_kernel_error:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_warning:nnxxxx}
+% \begin{macro}{\msg_kernel_warning:nnxxx}
+% \begin{macro}{\msg_kernel_warning:nnxx}
+% \begin{macro}{\msg_kernel_warning:nnx}
+% \begin{macro}{\msg_kernel_warning:nn}
+% \begin{macro}{\msg_kernel_info:nnxxxx}
+% \begin{macro}{\msg_kernel_info:nnxxx}
+% \begin{macro}{\msg_kernel_info:nnxx}
+% \begin{macro}{\msg_kernel_info:nnx}
+% \begin{macro}{\msg_kernel_info:nn}
+% Kernel messages which can be redirected.
+% \begin{macrocode}
+\prop_new:N \l_msg_redirect_kernel_warning_prop
+\cs_new_protected:Npn \msg_kernel_warning:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_warning:nnxxx #1#2#3#4#5
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnxx #1#2#3#4
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnx #1#2#3
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nn #1#2
+ { \msg_kernel_warning:nnxxxx {#1} {#2} { } { } { } { } }
+\prop_new:N \l_msg_redirect_kernel_info_prop
+\cs_new_protected:Npn \msg_kernel_info:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_info:nnxxx #1#2#3#4#5
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_info:nnxx #1#2#3#4
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nnx #1#2#3
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nn #1#2
+ { \msg_kernel_info:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Error messages needed to actually implement the message system
+% itself.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { msg } { message-already-defined }
+ { Message~'#2'~for~module~'#1'~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~define~a~new~message~called~'#2'
+ by~the~module~'#1'~module:\\
+ this~message~already~exists.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-unknown }
+ { Unknown~message~'#2'~for~module~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~display~a~message~called~'#2'\\
+ by~the~module~'#1'~module:~this~message~does~not~exist.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-class-unknown }
+ { Unknown~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
+ this~was~never~defined.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { redirect-loop }
+ { Message~redirection~loop~for~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~in~an~infinite~loop.\\
+ The~original~message~here~has~been~lost.
+ \c_msg_return_text_tl
+ }
+% \end{macrocode}
+%
+% Messages for earlier kernel modules.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { kernel } { bad-number-of-arguments }
+ { Function~'#1'~cannot~be~defined~with~#2~arguments. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~a~function~'#1'~with~
+ #2~arguments. \\
+ TeX~allows~between~0~and~9~arguments~for~a~single~function.
+ }
+\msg_kernel_new:nnnn { kernel } { command-already-defined }
+ { Control~sequence~#1~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~new~control~sequence~'#1'~
+ but~this~name~has~already~been~used~elsewhere. \\ \\
+ The~current~meaning~is:\\
+ \ \ #2
+ }
+\msg_kernel_new:nnnn { kernel } { command-not-defined }
+ { Control~sequence~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~use~a~command~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { kernel } { variable-not-defined }
+ { Variable~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { seq } { empty-sequence }
+ { Empty~sequence~#1. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~recover~an~entry~from~a~sequence~that~
+ has~no~content:~that~cannot~happen!
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\msg_kernel_bug:x}
+% \begin{variable}{\c_msg_kernel_bug_text_tl, \c_msg_kernel_bug_more_text_tl}
+% The \LaTeX{} coding bug error gets re-visited here.
+% \begin{macrocode}
+\cs_set_protected:Npn \msg_kernel_bug:x #1
+ {
+ \msg_interrupt:xxx { \c_msg_kernel_bug_text_tl }
+ {
+ #1
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_kernel_bug_more_text_tl }
+ }
+\tl_const:Nn \c_msg_kernel_bug_text_tl
+ { This~is~a~LaTeX~bug:~check~coding! }
+\tl_const:Nn \c_msg_kernel_bug_more_text_tl
+ {
+ There~is~a~coding~bug~somewhere~around~here. \\
+ This~probably~needs~examining~by~an~expert.
+ \c_msg_return_text_tl
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\msg_class_new:nn}
+% This is only ever used in a |set| fashion.
+% \begin{macrocode}
+\cs_new_eq:NN \msg_class_new:nn \msg_class_set:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_trace:nnxxxx, \msg_trace:nnxxx, \msg_trace:nnxx,
+% \msg_trace:nnx, \msg_trace:nn
+% }
+% The performance here is never going to be good enough for tracing
+% code, so let's be realistic.
+% \begin{macrocode}
+\cs_new_eq:NN \msg_trace:nnxxxx \msg_log:nnxxxx
+\cs_new_eq:NN \msg_trace:nnxxx \msg_log:nnxxx
+\cs_new_eq:NN \msg_trace:nnxx \msg_log:nnxx
+\cs_new_eq:NN \msg_trace:nnx \msg_log:nnx
+\cs_new_eq:NN \msg_trace:nn \msg_log:nn
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\msg_generic_new:nnn}
+% \begin{macro}{\msg_generic_new:nn}
+% \begin{macro}{\msg_generic_set:nnn}
+% \begin{macro}{\msg_generic_set:nn}
+% \begin{macro}{\msg_direct_interrupt:xxxxx}
+% \begin{macro}{\msg_direct_log:xx}
+% \begin{macro}{\msg_direct_term:xx}
+% These were all too low-level.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_generic_new:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_new:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_interrupt:xxxxx #1#2#3#4#5 { \deprecated }
+\cs_new_protected:Npn \msg_direct_log:xx #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_term:xx #1#2 { \deprecated }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex