summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3messages.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3messages.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3messages.dtx972
1 files changed, 972 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3messages.dtx b/Master/texmf-dist/source/latex/expl3/l3messages.dtx
new file mode 100644
index 00000000000..5aea5a26d35
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3messages.dtx
@@ -0,0 +1,972 @@
+% \iffalse
+%% File: l3messages.dtx Copyright (C) 1990-2006 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/cgi-bin/cvsweb.cgi/
+%%
+%% 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\RequirePackage{l3names}
+%<package>\RequirePackage{l3basics}
+%<package>\RequirePackage{l3tlp}
+%<package>\RequirePackage{l3expan}
+%<package>\RequirePackage{l3num}
+%<package>\RequirePackage{l3io}
+%<package>\RequirePackage{l3int}
+%<package>\RequirePackage{l3toks}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+ \def\fileversion{#2}%
+ \def\filedate{#3/#4/#5}%
+ \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%</dtx>
+%\fi
+\GetIdInfo$Id: l3messages.dtx 573 2006-08-21 20:59:37Z morten $
+ {L3 Experimental LaTeX Messages module}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3messages.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \section{Communicating with the user}
+%
+% Sometimes it is necesary to pass information back to the user
+% about what is going on. The information can be just that,
+% information, or it can be a warning that something might not
+% happen to his expectation. It could also be that something has
+% gone awry and that processing can't reliably continue without
+% some help from the user. In such a case an error is signalled.
+% When things are really bad, processing may have to stop as there
+% is no way to enter additional commands that put things right
+% again. In such a case we have a fatal error and the \LaTeX\ run
+% will be aborted.
+%
+% \subsection{Displaying the information}
+%
+% First of all we need a couple of fairly low level functions that
+% deal with the job of passing the information to the user.
+%
+% Real information is usually only written to the log file, while
+% warnings are displayed on the screen as well.
+% \begin{function}{%
+% \err_info:nn |
+% \err_warn:nn
+% }
+% \begin{syntax}
+% "\err_info:nn" "{" <message> "}" "{"<continuation>"}"
+% \end{syntax}
+% The <message> will be written to the log file. When it contains
+% the command "\err_newline:" a line break will occur and the new
+% line will start with the <continuation>. The function
+% "\err_warn:nn" writes the message to the terminal as well.
+% \end{function}
+% When an erroneous situation is encountered, a message is
+% displayed and the user is given the opportunity to enter some
+% additional code in an attempt to put things right. He may first
+% ask for some help, in which case some extra text will be
+% displayed to him.
+% \begin{function}{\err_interrupt:NNw}
+% \begin{syntax}
+% "\err_interrupt:NNw" <err id> <label> <more args>
+% \end{syntax}
+% This function signals a user error by searching the error file
+% denoted by <err id> for an error message associated with <label>,
+% i.e., specified by a corresponding "\err_interrupt_new:NNNnnn"
+% command. Depending on the number of arguments specified as
+% <argno> when the error message was defined, further arguments are
+% read. Then the error message is displayed as explained in
+% "\err_interrupt_new:NNNnnn".
+% \end{function}
+%
+% Finally, when something really serious occurs, \LaTeX\ will tell
+% the user about it and abort the run.
+% \begin{function}{\err_fatal:nn}
+% \begin{syntax}
+% "\err_fatal:nn" "{" <message> "}" "{"<continuation>"}"
+% \end{syntax}
+% Just displays the <message> and then aborts the \LaTeX\ run.
+% \end{function}
+%
+% \begin{function}{\err_newline:}
+% \begin{syntax}
+% "\err_newline:"
+% \end{syntax}
+% Is used to break an informational, warning or error message up
+% into multiple lines. May be defined in such a way that the new
+% line starts with a standard <continuation>.
+% \end{function}
+%
+% \subsection{Storing the information}
+%
+% The informational and warning messages are usually short and can
+% be stored as part of a macro; but error messages need to be more
+% verbose. Therefor error messages are stored in external files
+% which are read and searched for the correct error message at the
+% time of the error. In this way it is possible to write extensive
+% help texts without cluttering \TeX{}'s main memory.
+%
+% \subsubsection{Dealing with the error file}
+%
+% \begin{function}{\err_file_new:Nn}
+% \begin{syntax}
+% "\err_file_new:Nn" <err id> "{"<err file name>"}"
+% \end{syntax}
+% Opens a new error file to write errors to. <err id> is a unique
+% identifier for the external <err file name>. By convention <err
+% id> is declared as a constant (i.e., starts with "\c_") und ends
+% with "_tlp". If this command is issued while some other error
+% file is open we get an internal error message.
+% \end{function}
+%
+% \begin{function}{\err_file_close:N}
+% \begin{syntax}
+% "\err_file_close:N" <err id>
+% \end{syntax}
+% Closes the currently open error file and checks that it matches
+% <err id>, i.e., that everything is alright in the code.
+% \end{function}
+%
+% \subsubsection{Declaring an error message in the error file}
+% \begin{function}{\err_interrupt_new:NNNnnn}
+% \begin{syntax}
+% "\err_interrupt_new:NNNnnn" <err id> <label> <argno>
+% "{" <short msg> "}"
+% "{" <long msg> "}"
+% "{" <recovery code> "}"
+% \end{syntax}
+% This function declares an new error message which can be
+% addressed via "\err_interrupt:NNw". The pair (<err id>, <label>)
+% has to be unique where <label> can be some otherwise arbitrary
+% token (usually the function name in which the error routine is
+% called. Actually, the pair (<err id>, expansion of <label>) has
+% to be unique since for reasons of speed, tests are carried out
+% using "\if_meaning:NN".
+%
+% <argno> specifies the number of extra arguments that will be
+% supplied to the error routine when "\err_interrupt:NNw" is
+% called. These arguments can be used within <short msg>, <long
+% msg>, and/or <recovery code> to provide further information to
+% the user. They are denoted with "#1", "#2", etc.\ within these
+% arguments.
+%
+% The <short msg> is displayed directly on the terminal if the
+% error occurs, <long msg> is displayed when the user types "h" in
+% response to the error prompt of \TeX{}, and <recovery code> is
+% executed afterwards. This means that <recovery code> is inserted
+% after any deletions or insertions given by the user. All three
+% arguments are expanded while they are written to the error file,
+% therefore one has to prevent expansion of tokens with
+% "\token_to_string:N" that should be expanded when the error is
+% triggered.
+% \end{function}
+%
+% \subsection{Internal functions}
+%
+% \begin{function}{\err_display_aux:w}
+% This function is constructed on the fly while reading the error file.
+% It grabs following arguments from the code (if any) and then displays
+% the error message and inserts the <recovery code>.
+% \end{function}
+%
+% \begin{function}{\err_interrupt_new_aux:w}
+% Helper function used to write the error message info onto the error
+% file.
+% \end{function}
+%
+% \begin{function}{\err_msgline_aux:NNnnn}
+% \begin{syntax}
+% "\err_msgline_aux:NNnnn" <argno> <label> "{"<short>"}"
+% "{"<long msg>"}{"<recovery code>"}"
+% \end{syntax}
+% Function written in front of every error message on the error file. It
+% will be executed when the error file is read back in comparing <label>
+% to "\l_err_label_token". If they are the same, "\err_display_aux:w"
+% will be defined and the reading process will stop.
+% \end{function}
+%
+% \begin{function}{\err_message:x}
+% \begin{syntax}
+% "\err_message:x" "{"<error message>"}"
+% \end{syntax}
+% Function that directly triggers \TeX{}'s error handler. It should
+% not be used directly.
+% \begin{texnote}
+% This is the \LaTeX3 name for the \tn{errormessage} primitive.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Kernel specific functions}
+%
+% For a number of the functions described above specific variants
+% are provided that are used in the kernel of \LaTeX3.
+%
+% \begin{function}{%
+% \err_kernel_info:n |
+% \err_kernel_warn:n |
+% \err_kernel_fatal:n
+% }
+% \begin{syntax}
+% "\err_kernel_info:n" "{"<message>"}"
+% \end{syntax}
+% \end{function}
+% \begin{function}{%
+% \err_kernel_interrupt:Nw |
+% \err_kernel_interrupt_new:NNnnn |
+% }
+% Abbrivations for writing and accessing kernel error messages that
+% go to the error file "\c_kernel_err_tlp".
+% \end{function}
+%
+% \begin{function}{\err_latex_bug:x}
+% \begin{syntax}
+% "\err_latex_bug:x" "{"<error message>"}"
+% \end{syntax}
+% Creates an internal error message. This is intended to be used in
+% places that should not be reached in normal operation. Something is
+% wrong with the code.
+% \end{function}
+%
+% \subsection{Variables and constants}
+%
+% \begin{variable}{\iow_newline}
+% Identifier denoting the character that triggers a line break in
+% the output.
+% \end{variable}
+%
+% \begin{variable}{\c_iow_err_stream}
+% Output stream used to access the error files during their
+% generation.
+% \end{variable}
+%
+% \begin{variable}{\c_kernel_err_tlp}
+% Identifier denoting the kernel error file. (Its contents is the
+% name of the external file.)
+% \end{variable}
+%
+% \begin{variable}{\g_err_curr_fname}
+% Global variable containing the name of the currently open error
+% file. Empty when no such file is open for writing.
+% \end{variable}
+%
+% \begin{variable}{\tex_errorcontextlines:D}
+% Variable determining the amount of macro expansion contents shown
+% to the user when an error is triggered. \LaTeX3 sets this to -1
+% since to the average user this contents is of no interest.
+% \begin{texnote}
+% This is the \LaTeX3 name for the \TeX3 primitive
+% \tn{errorcontextlines}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\g_err_help_toks}
+% Token register that holds the message that will be shown if the
+% user types "h" in response to an error message that was produced
+% by "\err_message:x".
+% \begin{texnote}
+% This is the \LaTeX3 name for the \TeX\ primitive \tn{errhelp}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\l_err_label_token}
+% Variable holding the <label> to look up in an error file.
+% \end{variable}
+%
+% \StopEventually{}
+%
+% \subsection{The implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \subsubsection{Code to be moved to other modules}
+%
+% \begin{macro}{\g_file_curr_name_tlp}
+% This variable is used to store the name of the file currently
+% being processed. It should be part of the code that defines the
+% higher level I/O commands.
+% \begin{macrocode}
+\tlp_new:Nn \g_file_curr_name_tlp {no~file}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_message:x}
+% The \LaTeX3 name for a \TeX\ primitive. This should perhaps move
+% to \texttt{l3names.dtx}.
+% \begin{macrocode}
+\let_new:NN \err_message:x \tex_errmessage:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\text_put_sp:}
+% \begin{macro}{\text_put_four_sp:}
+% We need these functions for certain error and warning messages
+% right away. They put one and four spaces into the message stream.
+% \begin{macrocode}
+\def_new:Npn \text_put_sp: {~}
+\def_new:Npn \text_put_four_sp: {\text_put_sp: \text_put_sp:
+ \text_put_sp: \text_put_sp: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cmd_arg_list_build}
+% This macro takes a digit as its argument and creates a string of
+% |#| characters and argument numbers, such as |##1##2##3|. This
+% list can then later be used in defining a new macro.
+% To do this it locally uses a count register and a token
+% register.
+%
+% \begin{macrocode}
+\def:Npn\cmd_arg_list_build#1{
+% \end{macrocode}
+% First we need to make sure that the token register we will be
+% using for temporary storage is empty.
+% \begin{macrocode}
+ \toks_clear:N\l_tmpb_toks
+% \end{macrocode}
+% Then we can store the argument in a count register that will be
+% decremented untill it's value is zero. Beacuse of the use of the
+% result of this macro, the argument needs to be between 1 and 9;
+% this could be tested, but such a test is not (yet) added.
+% \begin{macrocode}
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_while:nNnT \l_tmpa_int > \c_zero {
+% \end{macrocode}
+% In the loop we first add the value of our counter to the contents
+% of the token register;
+% \begin{macrocode}
+ \toks_put_left:No \l_tmpb_toks {\the_internal:D\l_tmpa_int}
+% \end{macrocode}
+% and precede it with two hash marks.
+% \begin{macrocode}
+ \toks_put_left:Nn \l_tmpb_toks {##}
+% \end{macrocode}
+% Now the count register is decremented and another iteration will
+% follow so long as zero isn't reached.
+% \begin{macrocode}
+ \int_decr:N\l_tmpa_int
+ }
+% \end{macrocode}
+% Finally the contents of the token register needs to be copied as
+% the expansion of a local variable.
+% \begin{macrocode}
+ \def:Npx\l_cmd_arg_list{\the_internal:D\l_tmpb_toks}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cmd_declare:Nnn}
+% This macro is a first replacement for \LaTeXe's |\newcommand|. It
+% takes the name of a new macro as its first argument, the number
+% of arguments for the new macro is taken as the second argument.
+% \begin{macrocode}
+\def:Npn\cmd_declare:Nnn#1[#2]{
+ \cmd_arg_list_build{#2}
+ \exp_args:NNO\def:Npn#1\l_cmd_arg_list
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\io_show_file_lineno:}
+% A function to add the number of the line and the name of the file
+% to a message as an indication of where the message was triggered.
+% \begin{macrocode}
+\def_new:Npn \io_show_file_lineno:{
+ on~line~\the_internal:D\tex_inputlineno:D\text_put_sp:~of~
+ file~\g_file_curr_name_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Variables and constants}
+%
+% \begin{macro}{\g_err_help_toks}
+% A token register to store the help text for an error message in.
+% \begin{macrocode}
+\let:NwN \g_err_help_toks \tex_errhelp:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_err_label_token}
+% This will hold the current error label.
+% \begin{macrocode}
+\def_new:Npn \l_err_label_token {}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tex_errorcontextlines:D}
+% Since we are producing our own error and help messages we can
+% turn off the nasty stack information coming from \TeX{}'s
+% stomach.
+% \begin{macrocode}
+\int_set:Nn\tex_errorcontextlines:D\c_minus_one
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Displaying the information}
+%
+% Here we define the fairly low level commands needed to
+% communicate with the user.
+%
+% \begin{macro}{\err_info:nn}
+% \begin{macro}{\err_warn:nn}
+% Write a message to the log file ("\err_info:nn") or to both the
+% log file and the terminal ("\err_warn:nn").
+% \begin{macrocode}
+\def_new:Npn \err_info:nn #1#2{
+% \end{macrocode}
+% Make sure that the \emph{continuation} is part of "\err_newline:".
+% \begin{macrocode}
+ \def:Npn\err_newline:{\iow_newline#2}
+% \end{macrocode}
+% Then write the message.
+% \begin{macrocode}
+ \io_put_log:x {#1~\io_show_file_lineno:}}
+\def_new:Npn \err_warn:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1~\io_show_file_lineno:}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_info_noline:nn}
+% \begin{macro}{\err_warn_noline:nn}
+% These variants of the above two functions don't add the
+% linenumber to the message.
+% \begin{macrocode}
+\def_new:Npn \err_info_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_log:x {#1}}
+\def_new:Npn \err_warn_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_interrupt:NNw}
+% |\err_interrupt:NNw| is the function that is called when some error
+% occurs in the code. It takes at least two arguments, the
+% \m{errfile} which is a token list that holds the name of the file
+% where the error message should be fetched from, and the label to
+% identify the error message in the error file. However, it may
+% have additional arguments that are picked up by the error handler
+% extracted from the error file. This is specified in the third
+% argument to |\err_interrupt_new:NNNnnn|.
+% \begin{macrocode}
+\def_new:Npn \err_interrupt:NNw #1#2{\let:NwN \l_err_label_token #2
+ \group_begin:
+% \end{macrocode}
+% For some reason we get some |\par|s into the file if we use the
+% current definition of |\iow_long_unxepanded:N| to write the messages.
+% This is probably a consequence of using token registers to
+% prohibit the expansion of code.
+% \begin{macrocode}
+ \let:NwN \par\use_noop:
+% \end{macrocode}
+% We want to ensure that we are not in programmer's mode (no spaces)
+% but we want to switch on internal naming conventions.
+% \begin{macrocode}
+ \CodeStop
+ \NamesStart:
+% \end{macrocode}
+% We better clear all short references that are active, otherwise
+% we may get surprising results.
+% \begin{macrocode}
+ %\clearshortrefmaps
+ \tex_input:D #1~\err_display_aux:w}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_fatal:nn}
+% \begin{macro}{\err_fatal_noline:nn}
+% Write a message to the log file and to the terminal.
+% \begin{macrocode}
+\def_new:Npn \err_fatal:nn #1#2{
+% \end{macrocode}
+% Make sure that the \emph{continuation} is part of "\err_newline".
+% \begin{macrocode}
+ \def:Npn\err_newline:{\iow_newline#2}
+% \end{macrocode}
+% Then write the message.
+% \begin{macrocode}
+ \io_put_term:x {#1~\io_show_file_lineno:}
+% \end{macrocode}
+% Finally abort the \LaTeX{} run.
+% \begin{macrocode}
+ \tex_end:D
+ }
+% \end{macrocode}
+% A variant that doesn't include the line number where the error
+% occured.
+% \begin{macrocode}
+\def_new:Npn \err_fatal_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1}
+ \tex_end:D
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_newline:}
+% |\err_newline:| is used to introduce a new line in an error
+% message. I would like to use |\\| but this would mean
+% redefinition which should be avoided to make the error message
+% the last action before control is given to the user (otherwise
+% something like |\group_end:| would interfere with
+% insertions/deletions by the user). "\err_newline:" will be
+% redefined by the various functions displaying messages to include
+% the correct \emph{continuation}.
+% \begin{macrocode}
+\def_new:Npn \err_newline: {^^J}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Dealing with the error file}
+%
+% This section contains code that combines Michaels original thoughts
+% on the the subject with Denys' further ideas.
+%
+% \begin{macro}{\c_iow_err_stream}
+% Error messages are logged using the output stream
+% |\c_iow_err_stream|.
+% \begin{macrocode}
+\iow_new:N \c_iow_err_stream
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_err_curr_fname}
+% A nick name for the currently open error file. It is empty
+% if no error file is currently open.
+% \begin{macrocode}
+\tlp_new:Nn \g_err_curr_fname{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_file_new:Nn}
+% This function defines a new error file. The first argument is a
+% token list which should hold the name of the error file, the second
+% argument is the name of the error file. The token list should be
+% a constant defined by this function.
+% \begin{macrocode}
+\def_new:Npn \err_file_new:Nn #1#2{
+ \tlp_if_empty:NF\g_err_curr_fname
+ {\err_latex_bug:x{Unclosed~error~file~`\g_err_curr_fname'}}
+ \iow_open:Nn \c_iow_err_stream {#2}
+ \err_kernel_info:n{Errorfile~`#2'~opened~for~output}
+ \tlp_gset:Nn \g_err_curr_fname{#2}
+ \tlp_new:Nn #1{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_file_close:N}
+% This function closes the current error file.
+% \begin{macrocode}
+\def_new:Npn \err_file_close:N#1{
+% \end{macrocode}
+% Before we close the stream, we write out a final error handler
+% that catches mismatch within error message labels and their
+% calls. Actually this should be integrated into
+% |\err_file_new:Nn|, too.
+% \begin{macrocode}
+ \tlp_if_eq:NNF#1\g_err_curr_fname
+ {\err_latex_bug:x{You~closed~the~wrong~error~file~`#1'.~
+ Open~is~`\g_err_curr_fname'.}}
+ \iow_long_unexpanded:Nn \c_iow_err_stream {\err_latex_bug:x{Didn't~find~the~
+ correct~error~message~to~show.\iow_newline
+ Was~searching~for~a~function~
+ with~the~following~meaning:\iow_newline
+ \token_to_string:N\token_to_meaning:N
+ \token_to_string:N\l_err_label_token}
+% \end{macrocode}
+% The |\group_end:| here matches the one from |\err_interrupt:NNw| that
+% is used to hide changes to |\par| etc.
+% \begin{macrocode}
+ \group_end:}
+ \iow_close:N \c_iow_err_stream
+ \err_kernel_info:n{Errorfile~`\g_err_curr_fname'~closed}
+ \tlp_gset_eq:NN\g_err_curr_fname\c_empty_tlp
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Declaring an error message in the error file}
+%
+% \begin{macro}{\err_interrupt_new:NNNnnn}
+% This function declares a new error message.
+% |\err_interrupt_new:NNNnnn| \m{errfile} \m{errlabel} \m{argno}
+% \m{errmsg} \m{helpmsg} \m{code}. That error message is fetched
+% from the error file \m{errfile}. The label to search for is
+% \m{errlabel}, the error handler has \m{argno} number of arguments
+% (actually \m{argno} + 3 since the \m{errmsg}, \m{helpmsg} and
+% \m{code} are also arguments), and \m{errmsg} is the message to
+% display, \m{helpmsg} is the message that is displayed when the
+% user enters |h|, while \m{code} is extra code to perform when the
+% error occurs. \m{code} is perhaps not necessary, we will see.
+%
+% We have to check that the label associated with the error message
+% is unique. This means that its replacement text (labels are
+% simply arbitrary functions) is different from the replacement
+% text of any other label in the same error set.
+% \begin{macrocode}
+\def_new:Npn \err_interrupt_new:NNNnnn #1{
+% \end{macrocode}
+% Both \m{errmsg} and \m{code} might contain hashmarks denoting
+% arguments to the error handler.
+% \begin{macrocode}
+ \group_begin: \tex_catcode:D`\#\c_other_char_code
+% \end{macrocode}
+% We also have to check that output goes to the correct error file.
+% \begin{macrocode}
+ \if_meaning:NN#1\g_err_curr_fname
+ \else:
+ \err_latex_bug:x{Error~text~goes~to~wrong~err~file:~
+ `\g_err_curr_fname'~is~open~but~you~requested~
+ `#1'}
+ \fi:
+ \err_interrupt_new_aux:w}
+\def_long_new:Npn \err_interrupt_new_aux:w #1#2#3#4#5{
+ \iow_long_unexpanded:Nn \c_iow_err_stream
+ {\err_msgline_aux:NNnnn #1#2{#3}{#4}{#5}\use_noop:}
+ \group_end:}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_msgline_aux:NNnnn}
+% This function is executed when an error file is read back by
+% |\err_interrupt:NNw|. It compares its first argument against
+% |\l_err_label_token| using |\if_meaning:NN| and if this fails the
+% function does nothing; otherwise it defines |\err_display_aux:w| in
+% a way that it will pick up the arguments (if any) from the code and
+% generates a suitable error message.
+% \begin{macrocode}
+\def_new:Npn \err_msgline_aux:NNnnn #1#2#3#4#5{
+ \if_meaning:NN#1\l_err_label_token
+% \end{macrocode}
+% At the moment we simply use the old \LaTeX{} error code and
+% |\renewcommand| to generate the error handler. After displaying
+% the error message we insert error code this can be manipulated by
+% the user with the deletion/insertion facility of \TeX{}'s error
+% mechanism.
+%
+% The |\group_end:| at the very beginning matches the
+% |\group_begin:| when the file starts.
+% \begin{macrocode}
+ \cmd_declare:Nnn\err_display_aux:w [#2]{
+ \group_end:
+ \toks_gset:Nx\g_err_help_toks{#4}
+ \io_put_term:x{LaTeX~error~\io_show_file_lineno:.\iow_newline
+ \text_put_sp:\text_put_four_sp: \text_put_sp:
+ See~LaTeX~manual~for~explanation.\iow_newline
+ \text_put_sp:\text_put_four_sp: \text_put_sp:
+ Type~\text_put_sp: H~<return>~\text_put_sp: for~
+ immediate~help.}
+ \err_message:x{#3}
+ #5}
+ \tex_endinput:D
+ \fi:}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\err_display_aux:w}
+% We should make sure that this function is definable.
+% \begin{macrocode}
+\def_new:Npn \err_display_aux:w {}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Kernel specific functions}
+%
+% \begin{macro}{\err_kernel_interrupt:Nw}
+% |\err_kernel_interrupt:Nw | is just the abbreviation to read from
+% the standard system error file.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_interrupt:Nw {\err_interrupt:NNw \c_kernel_err_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_kernel_interrupt_new:NNnnn}
+% To ease the coding in case of system messages that should all go
+% to one and the same error file (if!) we also have the following
+% function.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_interrupt_new:NNnnn {
+ \err_interrupt_new:NNNnnn \c_kernel_err_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_kernel_info:n}
+% \begin{macro}{\err_kernel_warn:n}
+% \begin{macro}{\err_kernel_fatal:n}
+% \begin{macro}{\err_kernel_info_noline:n}
+% \begin{macro}{\err_kernel_warn_noline:n}
+% \begin{macro}{\err_kernel_fatal_noline:n}
+% These variants are specific for the \LaTeX\ kernel.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_info:n #1 {
+ \err_info:nn {LaTeX~Info:~#1}
+ {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_warn:n #1 {
+ \err_warn:nn {LaTeX~Warning:~#1}
+ {\text_put_sp:\text_put_sp:\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_fatal:n #1 {
+ \err_fatal:nn {LaTeX~Fatal:~#1}
+ {\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_info_noline:n #1 {
+ \err_info_noline:nn {LaTeX~Info:~#1}
+ {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_warn_noline:n #1 {
+ \err_warn_noline:nn {LaTeX~Warning:~#1}
+ {\text_put_sp:\text_put_sp:\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_fatal_noline:n #1 {
+ \err_fatal_noline:nn {LaTeX~Fatal:~#1}
+ {\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+%</initex|package>
+% \end{macrocode}
+% At a later stage variants may be provided for what in \LaTeXe{}
+% used to be called document classes and packages.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_kernel_err_tlp}
+% Most error messages will go to the system error file; it's name is
+% stored in |\c_kernel_err_tlp|.
+% \begin{macrocode}
+%<initex>\err_file_new:Nn \c_kernel_err_tlp {ltxkernel.err}
+%<package>\err_file_new:Nn \c_kernel_err_tlp {l3in2e.err}
+% \end{macrocode}
+% \end{macro}
+%
+% The code below is a temporary implementation of a few of
+% \LaTeX209 error messages with the new syntax. They are only
+% included in the package as the \LaTeX3 kernel will certainly have
+% it's own error message definitions that differ from \LaTeXe's way
+% of signalling errors. These primarily serve as an example on how
+% to use this concept of dealing with errors.
+%
+% First we declare a couple of helper macros that contain texts
+% that are used frequently throughout \LaTeX.
+% \begin{macrocode}
+%<*package>
+\def:Npn\err_help_ignored: {
+ Your~command~was~ignored.\iow_newline
+ Type \text_put_sp: I~<command>~<return>
+ \text_put_sp: to~replace~it~with~another~command,\iow_newline
+ or~\text_put_sp: <return> \text_put_sp: to~continue~without~it.}
+
+\def:Npn\err_help_textlost: {
+ You've~lost~some~text.\text_put_sp: \err_help_return_or_X:}
+
+\def:Npn\err_help_return_or_X: {
+ Try~typing\text_put_sp: <return>
+ \text_put_sp: to~proceed.\iow_newline
+ If~that~doesn't~work,~type
+ \text_put_sp: X~<return>\text_put_sp: to~quit.}
+
+\def:Npn\err_help_trouble: {
+ You're~ in~ trouble~ here.
+ \text_put_sp:\err_help_return_or_X:}
+% \end{macrocode}
+%
+% Below are the definitions of the complete messages
+% \begin{macrocode}
+
+\err_kernel_interrupt_new:NNnnn\cs_free_p:N{1}
+ {Command~name~`\tex_string:D#1'~already~used}
+ {You~tried~to~define~a~command~which~already~has~
+ a~meaning.\iow_newline
+ If~you~really~want~to~redefine~it~try~
+ \token_to_string:N\cmd_declare:Nnn\text_put_sp:
+ next~time.\iow_newline
+ For~this~run~I~will~ignore~your~definition.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\newline{0}
+ {There's~no~line~here~to~end}
+ {You~tried~to~end~a~line~at~a~place~where~I~thought~
+ we~were~already~between~paragraphs.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\newcnt{0}
+ {No~such~counter}
+ {The~counter~name~mentioned~in~the~operation~is~not~
+ known~to~me.\iow_newline
+ Check~the~spelling.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\nodocument{0}
+ {Missing~\token_to_string:N\begin{document}}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badmath{0}
+ {Bad~math~environment~delimiter}
+ {\err_help_ignored:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\toodeep{0}
+ {Too~deeply~nested}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badpoptabs{0}
+ {\token_to_string:N\pushtabs \text_put_sp:
+ and~\token_to_string:N\poptabs
+ \text_put_sp: don't~match}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badtab{0}
+ {Undefined~tab~position}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\preamerr{}
+ {\if_case:w #1~Illegal~character\or:
+ Missing~@-exp\or: Missing~p-arg\fi:\text_put_sp:
+ in~array~arg}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badlinearg{}
+ {Bad~\token_to_string:N\line
+ \text_put_sp: or~\token_to_string:N\vector
+ \text_put_sp: argument}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\parmoderr{0}
+ {Not~in~outer~par~mode}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\fltovf{0}
+ {Too~many~unprocessed~floats}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badcrerr{0}
+ {Bad~use~of~\token_to_string:N\\}
+ {\err_help_return_or_X:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\noitemerr{0}
+ {Something's~wrong--perhaps~a~missing~
+ \token_to_string:N\item}
+ {\err_help_return_or_X:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\notprerr{0}
+ {Can~be~used~only~in~preamble}
+ {\err_help_ignored:}
+ {}
+
+\err_file_close:N\c_kernel_err_tlp
+%<package>
+% \end{macrocode}
+%
+%
+% Show token usage:
+% \begin{macrocode}
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.9 2006/03/19 15:07:47 braams
+% Moved some code to other modules, where it belongs;
+% reverted \c_io_newline to \iow_newline (it'scontents might need to be
+% modified sometine)
+% Example messages are not part of the kernel, only for the package.
+%
+% Revision 1.8 2006/02/15 23:45:46 braams
+% Rearranged the file;
+% implemented \err_fatal:nn and \err_fatal_noline:nn
+% Recode the remaining error definitions for testing purposes
+%
+% Revision 1.7 2006/01/15 09:48:54 braams
+% Mostly textual changes
+%
+% Revision 1.6 2005/12/27 16:01:27 morten
+% Changed RCS information retrieval plus a few minor changes
+%
+% Revision 1.5 2005/05/05 23:45:49 braams
+% Worked on the documentation;
+% added commands \err_info:nn, \err_warn:nn and kernel specific versions
+% of these.
+% Changed \iow_newline: into \c_io_newline; introduced \err_newline: to
+% be used in messages with multiple lines to provide a continuation
+% string.
+% Renamed \style_names_start and \style_names_stop: into \NamesStart:
+% and \NamesStop:.
+%
+% Revision 1.4 2005/05/03 23:34:52 braams
+% Added code that performs the basic function of the old \renewcommand
+% Added a couple of new functions that need to live in other modules
+% Documentation still needs to be corrected
+% The module now basically works
+%
+% Revision 1.3 2005/04/29 22:39:47 braams
+% Another one
+%
+% Revision 1.2 2005/04/29 22:34:39 braams
+% Small typo in the RCS tags
+%
+% Revision 1.1 2005/04/29 22:30:44 braams
+% first version that can be loaded without producing errors.
+% Just a translation from the old stuff, haven't looked at the docu yet \ No newline at end of file