summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/expl3.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/expl3.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/expl3.dtx220
1 files changed, 208 insertions, 12 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/expl3.dtx b/Master/texmf-dist/source/latex/expl3/expl3.dtx
index 2ffb707a1bc..7f8292d609a 100644
--- a/Master/texmf-dist/source/latex/expl3/expl3.dtx
+++ b/Master/texmf-dist/source/latex/expl3/expl3.dtx
@@ -37,7 +37,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: expl3.dtx 1677 2009-11-02 08:24:04Z joseph $
+\GetIdInfo$Id: expl3.dtx 1866 2010-03-23 08:29:27Z joseph $
{L3 Experimental code bundle wrapper}%
%\iffalse
%<*driver>
@@ -310,8 +310,6 @@
% \item[box] box register;
% \item[skip] `rubber' lengths;
% \item[dim] `rigid' lengths;
-% \item[num] A `fake' integer type using only macros. Useful for
-% setting up allocation routines;
% \item[seq] `sequence': a data-type used to implement lists (with
% access at both ends) and stacks;
% \item[prop] property list;
@@ -330,8 +328,46 @@
% characters. It provides two ways to store these token lists: within
% macros and as token registers (toks). \LaTeX3 retains the name `toks'
% for the later, and adopts the name `token list variables' (tl vars)
-% for macros used to store tokens. In most circumstances, the tl var
-% data type is more convenient for storing token lists.
+% for macros used to store tokens.
+%
+%\subsubsection{Variables: guidance}
+%
+% Although \TeX\ provides token registers for certain programming
+% tasks, \LaTeX3 is written so that token list variables can be used
+% for all stored lists of tokens. The \cs{toks_\ldots} functions are
+% therefore for internal use within \LaTeX3 and for supporting
+% \LaTeXe, and should not be needed in new \LaTeX3-based code.
+%
+% Both comma lists and sequences both have similar characteristics.
+% They both use special delimiters to mark out one entry from the
+% next, and are both accessible at both ends. In general, it is
+% easier to create comma lists `by hand' as they can be typed
+% in directly. User input often takes the form of a comma separated
+% list and so there are many cases where this is the obvious
+% data type to use. On the other hand, sequences use special internal
+% tokens to separate entries. This means that they can be used to
+% contain material that comma lists cannot (such as items that may
+% themselves contain commas!). In general, comma lists should be
+% preferred for creating fixed lists inside programs and for
+% handling user input where commas will not occur. On the other
+% hand, sequences should be used to store arbitrary lists of
+% data.
+%
+% \pkg{expl3} implements stacks using the sequence data structure.
+% Thus creating stacks involves first creating a sequence, and
+% then using the sequence functions which work in a stack manner
+% (\cs{seq_push:Nn}, \emph{etc}.).
+%
+% Due to the nature of the underlying \TeX\ implementation, it is
+% possible to assign values to token list variables and comma lists
+% without first declaring them. However, this is \emph{not supported
+% behaviour}. The \LaTeX3 coding convention is that all variables must
+% be declared before use.
+%
+% The expl3 package can be loaded with the "check-declarations" option
+% to verify that all variables are declared before use. This has a
+% performance implication and is therefore intended for testing during
+% development and not for use in production documents.
%
%\subsubsection{Functions: argument specifications}
%
@@ -449,12 +485,25 @@
% name (via~|\csname| \ldots |\endcsname|). This command name is the
% single token that is passed to the function as the argument. Hence
% \begin{quote}
-% "\seq_gpush:cV { g_file_name_stack } \l_tmpa_tl"
+% "\seq_gpush:cV { g_file_name_seq } \l_tmpa_tl"
% \end{quote}
% is equivalent to
% \begin{quote}
-% "\seq_gpush:NV \g_file_name_stack \l_tmpa_tl".
+% "\seq_gpush:NV \g_file_name_seq \l_tmpa_tl".
% \end{quote}
+% Remember that \texttt{c} arguments are \emph{fully expanded} by
+% \TeX\ when creating csnames. This means that (a) the entire
+% argument must be expandable and (b) any variables will be
+% converted to their content. So the preceding examples are also
+% equivalent to
+% \begin{quote}
+% "\tl_new:N \g_file_seq_name_tl" \\
+% "\tl_gset:Nn \g_file_seq_name_tl { g_file_name_seq }" \\
+% "\seq_gpush:cV { \g_file_seq_name_tl } \l_tmpa_tl".
+% \end{quote}
+% (Token list variables are expandable and do not require an
+% accessor function. Other variable types require the appropriate
+% \cs{<var>_use:N} functions to be used in this context.)
% \item[V] Value of a variable.\\
% This means that the contents of the register in question is used as the
% argument, be it an integer, a length-type register, a token list variable
@@ -685,9 +734,6 @@
% This sets up the basic naming scheme and renames all
% the \TeX\ primitives.
% }
-% \explpkg{l3num}{
-% This implements the `fake integer' datatype \texttt{num}.
-% }
% \explpkg{l3prg}{
% Program control structures such as boolean data type |bool|, generic
% do-while loops, case-switches, sorting routines and stepwise loops.
@@ -813,6 +859,12 @@
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
% \end{macrocode}
+%
+% Load \pkg{etex} as otherwise we are likely to get into trouble
+% with registers.
+% \begin{macrocode}
+\RequirePackage{etex}
+% \end{macrocode}
%
% We already loaded \pkg{l3names} at the beginning of the \texttt{dtx} file.
%
@@ -826,7 +878,6 @@
l3basics,
l3expan,
l3tl,
- l3num,
l3intexpr,
l3quark,
l3seq,
@@ -835,9 +886,9 @@
l3prg,
l3clist,
l3token,
- l3io,
l3prop,
l3msg,
+ l3io,
l3skip,
}
% \end{macrocode}
@@ -853,6 +904,151 @@
l3file
}
% \end{macrocode}
+%
+%\begin{macro}{\_l_expl_check_declarations_bool}
+% To indicate that token list variables should exist before
+% assignment, a flag is created and a single option provided.
+% \begin{macrocode}
+\bool_new:N \_l_expl_check_declarations_bool
+\DeclareOption{check-declarations}{
+ \bool_set_true:N \_l_expl_check_declarations_bool
+}
+\ProcessOptions \scan_stop:
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\_tl_check_exists:N}
+% If the option is active, redefine token list variable functions to
+% be picky.
+% \begin{macrocode}
+\bool_if:NT \_l_expl_check_declarations_bool {
+ \msg_kernel_new:nnnn { check } { non-declared-variable }
+ { The~variable~#1~has~not~been~declared~\msg_line_context:. }
+ {
+ Checking~is~active,~and~you~have~tried~do~so~something~like: \\
+ \c_space_tl \c_space_tl \tl_set:Nn #1 ~
+ \iow_char:N \{ ~ ... ~ \iow_char:N \} \\
+ without~first~having: \\
+ \c_space_tl \c_space_tl \tl_new:N #1 \\
+ \\
+ LaTeX~will~create~the~variable~and~continue.
+ }
+ \cs_set_protected:Npn \_tl_check_exists:N #1
+ {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_error:nnx { check } { non-declared-variable }
+ { \token_to_str:N #1 }
+ }
+ }
+ \cs_set_protected:Npn \tl_set:Nn #1#2
+ {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_set:Nx #1#2
+ {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_gset:Nn #1#2
+ {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_gset:Nx #1#2
+ {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_set_eq:NN #1#2
+ {
+ \_tl_check_exists:N #1
+ \_tl_check_exists:N #2
+ \cs_set_eq:NN #1 #2
+ }
+ \cs_set_protected:Npn \tl_gset_eq:NN #1#2
+ {
+ \_tl_check_exists:N #1
+ \_tl_check_exists:N #2
+ \cs_gset_eq:NN #1 #2
+ }
+ \cs_set_protected:Npn \tl_put_right:Nn #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #1 \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_put_right:NV #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #1 \exp_not:V #2 }
+ }
+ \cs_set_protected:Npn \tl_put_right:Nv #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #1 \exp_not:v {#2} }
+ }
+ \cs_set_protected:Npn \tl_put_right:No #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #1 \exp_not:o {#2} }
+ }
+ \cs_set_protected:Npn \tl_put_right:Nx #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #1 #2 }
+ }
+ \cs_set_protected:Npn \tl_gput_right:Nn #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:V #1 \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_gput_right:NV #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:V #1 \exp_not:V #2 }
+ }
+ \cs_set_protected:Npn \tl_gput_right:Nv #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:V #1 \exp_not:v {#2} }
+ }
+ \cs_set_protected:Npn \tl_gput_right:Nx #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:V #1 #2 }
+ }
+ \cs_set_protected:Npn \tl_put_left:Nn #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_put_left:NV #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_put_left:Nv #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:v {#2} \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_put_left:No #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_put_left:Nx #1#2 {
+ \_tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { #2 \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_gput_left:Nn #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_gput_left:NV #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_gput_left:Nv #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:v {#2} \exp_not:V #1 }
+ }
+ \cs_set_protected:Npn \tl_gput_left:Nx #1#2 {
+ \_tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { #2 \exp_not:V #1 }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
%</package>
%
% \end{implementation}