summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-08-12 23:14:34 +0000
committerKarl Berry <karl@freefriends.org>2011-08-12 23:14:34 +0000
commitc9172879c19139ba8d262e615a535073caea2e54 (patch)
tree3d907d4933b43fbc204a7069106fb6715601824f /Master/texmf-dist/source
parent3affad3394ee81c3f5ba136242d5d56949254515 (diff)
l3kernel (11aug11)
git-svn-id: svn://tug.org/texlive/trunk@23524 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/expl3.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx59
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx61
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3box.dtx8
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3final.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx29
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prg.dtx5
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3skip.dtx11
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx234
9 files changed, 319 insertions, 98 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
index 443c87b3916..9f7a8a698aa 100644
--- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
@@ -35,8 +35,10 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: expl3.dtx 2478 2011-06-19 21:34:23Z joseph $
- {L3 Experimental code bundle wrapper}
+\def\ExplFileName{expl3}
+\def\ExplFileDescription{L3 Experimental code bundle wrapper}
+\def\ExplFileDate{2011/08/10}
+\def\ExplFileVersion{2535}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
index 8e175a2e74d..5fe3d23d968 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3alloc.dtx 2478 2011-06-19 21:34:23Z joseph $
+\GetIdInfo$Id: l3alloc.dtx 2528 2011-08-09 09:10:06Z joseph $
{L3 Experimental register allocation}
%</driver|package>
%<*driver>
@@ -165,6 +165,63 @@
}
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\int_eval:n}
+% For bootstrapping purposes, a definition of \cs{int_eval:n} is needed
+% in terms of primitives. This is replaced in \pkg{l3int} with a clearer
+% one.
+% \begin{macrocode}
+\cs_new:Npn \int_eval:n #1 { \tex_number:D \etex_numexpr:D #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {box_new:N, \dim_new:N, \int_new:N, \muskip_new:N \skip_new:N}
+% To get everything to work correctly for inserts, some register types
+% need to have their allocators set up \enquote{early}. It therefore
+% makes sense to collect most of them together here.
+% \begin{macrocode}
+\alloc_new:nnnN { box } \c_zero \c_max_register_int \tex_mathchardef:D
+\alloc_new:nnnN { dim } \c_zero \c_max_register_int \tex_dimendef:D
+\alloc_new:nnnN { int } { 11 } \c_max_register_int \tex_countdef:D
+\alloc_new:nnnN { muskip } \c_zero \c_max_register_int \tex_muskipdef:D
+\alloc_new:nnnN { skip } \c_zero \c_max_register_int \tex_skipdef:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\insert_new:N}
+% \begin{macro}[aux]{\alloc_reserve_insert:n}
+% For inserts, there is a need to reserve space in various other registers.
+% \begin{macrocode}
+\alloc_new:nnnN { insert } { 221 } { 254 } \tex_chardef:D
+\group_begin:
+ \cs_set_protected_nopar:Npn \alloc_reserve_insert:n #1
+ {
+ \tex_ifnum:D #1 > \c_insert_allocation_max_tl \scan_stop:
+ \exp_after:wN \use_none:n
+ \tex_else:D
+ \exp_after:wN \use:n
+ \tex_fi:D
+ {
+ \seq_put_right:Nn \g_box_allocation_seq {#1}
+ \seq_put_right:Nn \g_dim_allocation_seq {#1}
+ \seq_put_right:Nn \g_int_allocation_seq {#1}
+ \seq_put_right:Nn \g_skip_allocation_seq {#1}
+ \exp_args:Nf \alloc_reserve_insert:n
+ { \etex_numexpr:D #1 + 1 \scan_stop: }
+ }
+ }
+ \alloc_reserve_insert:n { 221 }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Box $255$ is reserved by \TeX{} for output, so is protected here from
+% use by the allocator.
+% \begin{macrocode}
+\seq_put_right:Nn \g_box_allocation_seq { 255 }
+% \end{macrocode}
%
% \begin{macro}[int]{\alloc_reg:nNN}
% This internal macro performs the actual allocation.
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
index 69aaf46357b..ee971e3b09b 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
@@ -34,13 +34,56 @@
%% -----------------------------------------------------------------------
%
%<*package>
-\def\GetIdInfo$%
- Id: #1 #2 #3-#4-#5 #6 #7 $#8%
+\protected\def\GetIdInfo
+ {
+ \begingroup
+ \catcode 32 = 10 \relax
+ \GetIdInfoAuxI
+ }
+\protected\def\GetIdInfoAuxI$#1$#2%
+ {
+ \def\tempa{#1}%
+ \def\tempb{Id}%
+ \ifx\tempa\tempb
+ \def\tempa
+ {%
+ \endgroup
+ \def\ExplFileDate{9999/99/99}%
+ \def\ExplFileDescription{#2}%
+ \def\ExplFileName{[unknown name]}%
+ \def\ExplFileExtension{[unknown extension]}%
+ \def\ExplFileVersion{999}%
+ }%
+ \else
+ \def\tempa
+ {%
+ \endgroup
+ \GetIdInfoAuxII$#1${#2}%
+ }%
+ \fi
+ \tempa
+ }
+\protected\def\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6 #7 #8$#9%
{%
- \def\ExplFileDate{#3/#4/#5}%
- \def\ExplFileVersion{#2}%
+ \def\ExplFileName{#2}%
+ \def\ExplFileExtension{#3}%
+ \def\ExplFileVersion{#4}%
+ \def\ExplFileDescription{#9}%
+ \GetIdInfoAuxIII#5\relax#3\relax#5\relax#6\relax
}
-\GetIdInfo$Id: l3bootstrap.dtx 2478 2011-06-19 21:34:23Z joseph $
+\protected\def\GetIdInfoAuxIII#1#2#3#4#5#6\relax
+ {%
+ \ifx#5/%
+ \expandafter\GetIdInfoAuxCVS
+ \else
+ \expandafter\GetIdInfoAuxSVN
+ \fi
+ }
+\protected\def\GetIdInfoAuxCVS#1,v\relax#2\relax#3\relax
+ {\def\ExplFileDate{#2}}
+\protected\def\GetIdInfoAuxSVN#1\relax#2-#3-#4\relax#5Z\relax
+ {\def\ExplFileDate{#2/#3/#4}}
+\GetIdInfo$Id: l3bootstrap.dtx 2519 2011-08-08 09:35:54Z mittelba $
{L3 experimental bootstrap code}
%</package>
%<*driver>
@@ -332,10 +375,10 @@
\def\tempa
{%
\endgroup
- \def\ExplFileDate{0000/00/00}%
+ \def\ExplFileDate{9999/99/99}%
\def\ExplFileDescription{#2}%
- \def\ExplFileName{[unknown~name]}%
- \def\ExplFileVersion{000}%
+ \def\ExplFileName{[unknown name]}%
+ \def\ExplFileVersion{999}%
}%
\else
\def\tempa
@@ -644,4 +687,4 @@
%
% \end{implementation}
%
-% \PrintIndex \ No newline at end of file
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
index 1947f85b356..85313ce8791 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3box.dtx 2478 2011-06-19 21:34:23Z joseph $
+\GetIdInfo$Id: l3box.dtx 2526 2011-08-09 08:58:42Z joseph $
{L3 Experimental boxes}
%</driver|package>
%<*driver>
@@ -723,7 +723,7 @@
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\package_check_loaded_expl:
-%<*initex|package>
+%</package>
% \end{macrocode}
%
% The code in this module is very straight forward so I'm not going to
@@ -737,10 +737,6 @@
% Defining a new \meta{box} register: remember that box $255$ is not
% generally available.
% \begin{macrocode}
-%<*initex>
-\alloc_new:nnnN { box } \c_zero \c_max_register_int \tex_mathchardef:D
-\seq_put_right:Nn \g_box_allocation_seq {255}
-%</initex>
%<*package>
\cs_new_protected:Npn \box_new:N #1
{
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
index bc37e2aaee4..1645cbcd487 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3final.dtx 2478 2011-06-19 21:34:23Z joseph $
+\GetIdInfo$Id: l3final.dtx 2499 2011-07-29 12:49:30Z joseph $
{L3 Experimental format finalisation}
%</driver|package>
%<*driver>
@@ -95,7 +95,7 @@
{
\char_set_catcode_space:n { 9 }
\char_set_catcode_space:n { 32 }
- \char_set_catcode_math_subscript:n { 94 }
+ \char_set_catcode_math_subscript:n { 95 }
\char_set_catcode_other:n { 58 }
\char_set_catcode_active:n { 126 }
\tex_endlinechar:D = 13 \scan_stop:
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
index 70264286d27..91dc8e798ce 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3int.dtx 2478 2011-06-19 21:34:23Z joseph $
+\GetIdInfo$Id: l3int.dtx 2526 2011-08-09 08:58:42Z joseph $
{L3 Experimental integers}
%</driver|package>
%<*driver>
@@ -930,12 +930,12 @@
% Here are the remaining primitives for number comparisons and
% expressions.
% \begin{macrocode}
-\cs_set_eq:NN \int_value:w \tex_number:D
-\cs_set_eq:NN \int_eval:w \etex_numexpr:D
-\cs_new_eq:NN \int_eval_end: \tex_relax:D
-\cs_new_eq:NN \if_num:w \tex_ifnum:D
-\cs_set_eq:NN \if_int_odd:w \tex_ifodd:D
-\cs_new_eq:NN \if_case:w \tex_ifcase:D
+\cs_new_eq:NN \int_value:w \tex_number:D
+\cs_new_eq:NN \int_eval:w \etex_numexpr:D
+\cs_new_eq:NN \int_eval_end: \tex_relax:D
+\cs_new_eq:NN \if_num:w \tex_ifnum:D
+\cs_new_eq:NN \if_int_odd:w \tex_ifodd:D
+\cs_new_eq:NN \if_case:w \tex_ifcase:D
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -948,10 +948,16 @@
%
% \begin{macro}{\int_eval:n}
% Wrapper for \cs{int_eval:w}. Can be used in an integer expression
-% or directly in the input stream.
+% or directly in the input stream. In format mode, there is already
+% a definition in \pkg{l3alloc} for bookstrapping, which is therefore
+% corrected to the \enquote{real} version here.
% \begin{macrocode}
-\cs_new:Npn \int_eval:n #1
- { \int_value:w \int_eval:w #1 \int_eval_end: }
+%<*initex>
+\cs_set:Npn \int_eval:n #1 { \int_value:w \int_eval:w #1 \int_eval_end: }
+%</initex>
+%<*package>
+\cs_new:Npn \int_eval:n #1 { \int_value:w \int_eval:w #1 \int_eval_end: }
+%</package>
% \end{macrocode}
% \end{macro}
%
@@ -1058,9 +1064,6 @@
% Two ways to do this: one for the format and one for the \LaTeXe{}
% package.
% \begin{macrocode}
-%<*initex>
-\alloc_new:nnnN { int } { 11 } { \c_max_register_int } \tex_countdef:D
-%</initex>
%<*package>
\cs_new_protected_nopar:Npn \int_new:N #1
{
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
index b4cf9368f2a..58175b05561 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3prg.dtx 2495 2011-07-06 16:57:08Z bruno $
+\GetIdInfo$Id: l3prg.dtx 2509 2011-08-07 11:21:26Z bruno $
{L3 Experimental control structures}
%</driver|package>
%<*driver>
@@ -1767,7 +1767,8 @@
%
% \begin{macro}[pTF]{\mode_if_math:}
% \UnitTested
-% For testing math mode: without \cs{} things go wrong in alignments.
+% For testing math mode: without \cs{scan_align_safe_stop:}
+% things go wrong in alignments.
% \begin{macrocode}
\prg_new_conditional:Npnn \mode_if_math: { p , T , F , TF }
{
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
index ecd3ca2e397..9145e7d59cf 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3skip.dtx 2478 2011-06-19 21:34:23Z joseph $
+\GetIdInfo$Id: l3skip.dtx 2526 2011-08-09 08:58:42Z joseph $
{L3 Experimental dimensions and skips}
%</driver|package>
%<*driver>
@@ -928,9 +928,6 @@
% \begin{macro}{\dim_new:N,\dim_new:c}
% Allocating \meta{dim} registers \ldots
% \begin{macrocode}
-%<*initex>
-\alloc_new:nnnN { dim } \c_zero \c_max_register_int \tex_dimendef:D
-%</initex>
%<*package>
\cs_new_protected_nopar:Npn \dim_new:N #1
{
@@ -1327,9 +1324,6 @@
% \begin{macro}{\skip_new:N,\skip_new:c}
% Allocation of a new internal registers.
% \begin{macrocode}
-%<*initex>
-\alloc_new:nnnN { skip } \c_zero \c_max_register_int \tex_skipdef:D
-%</initex>
%<*package>
\cs_new_protected_nopar:Npn \skip_new:N #1
{
@@ -1526,9 +1520,6 @@
% \begin{macro}{\muskip_new:N, \muskip_new:c}
% And then we add muskips.
% \begin{macrocode}
-%<*initex>
-\alloc_new:nnnN { muskip } \c_zero \c_max_register_int \tex_muskipdef:D
-%</initex>
%<*package>
\cs_new_protected_nopar:Npn \muskip_new:N #1
{
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
index a7f292d14c7..149f4a487ba 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3tl.dtx 2498 2011-07-09 17:51:47Z joseph $
+\GetIdInfo$Id: l3tl.dtx 2534 2011-08-10 18:21:44Z joseph $
{L3 Experimental token lists}
%</driver|package>
%<*driver>
@@ -768,44 +768,87 @@
% \begin{syntax}
% \cs{tl_head:n} \Arg{tokens}
% \end{syntax}
-% Leaves only the first \meta{token} in \meta{tokens} in the input
-% stream, discarding the remainder.
+% Leaves in the input stream the first non-space token from the
+% \meta{tokens}. Any leading space tokens will be discarded, and thus for
+% example
+% \begin{verbatim}
+% \tl_head:n { abc }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_head:n { ~ abc }
+% \end{verbatim}
+% will both leave |a| in the input stream.
+% An empty list of \meta{tokens} or one which consists
+% only of space (category code $10$) tokens will result in \cs{tl_head:n}
+% leaving nothing in the input stream.
% \end{function}
%
% \begin{function}[EXP]{\tl_head:w}
% \begin{syntax}
-% \cs{tl_head:w} \Arg{tokens} \cs{q_stop}
+% \cs{tl_head:w} \meta{tokens} \cs{q_stop}
% \end{syntax}
-% Leaves only the first \meta{token} in \meta{tokens} in the input
-% stream, discarding the remainder. This function requires only a
-% single expansion, and so is suitable for use inside an
-% \texttt{o}-type expansion. In general \cs{tl_head:n} should be
-% preferred.
+% Leaves in the input stream the first non-space token from the
+% \meta{tokens}. An empty list of \meta{tokens} or one which consists
+% only of space (category code $10$) tokens will result in an error, and
+% thus \meta{tokens} must \emph{not} be \enquote{blank} as determined by
+% \cs{tl_if_blank:n(TF)}. This function requires only a single expansion,
+% and thus is suitable for use within an \texttt{o}-type expansion. In
+% general, \cs{tl_head:n} should be preferred if the number of expansions
+% is not critical.
+% \end{function}
+%
+% \begin{function}[EXP]{\str_head:n}
+% \begin{syntax}
+% \cs{str_head:n} \Arg{tokens}
+% \end{syntax}
+% Converts the \meta{tokens} into a string, as described for
+% \cs{tl_to_str:n}, and then leaves the first character of this string
+% in the input stream; the first character may be a space. If the
+% \meta{tokens} argument is entirely empty, \cs{scan_stop:} will be left in
+% the input stream.
% \end{function}
%
% \begin{function}[EXP]{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
% \begin{syntax}
% \cs{tl_tail:n} \Arg{tokens}
% \end{syntax}
-% Discards the first \meta{token} of the \meta{tokens} and leaves the
-% remainder in the input stream.
+% Discards the all leading space tokens and the first non-space token
+% in the \meta{tokens}, and leaves the remaining tokens in the
+% input stream. Thus for example
+% \begin{verbatim}
+% \tl_tail:n { abc }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_tail:n { ~ abc }
+% \end{verbatim}
+% will both leave |bc| in the input stream.
+% An empty list of \meta{tokens} or one which consists
+% only of space (category code $10$) tokens will result in \cs{tl_tail:n}
+% leaving nothing in the input stream.
% \end{function}
%
% \begin{function}[EXP]{\tl_tail:w}
% \begin{syntax}
% \cs{tl_tail:w} \Arg{tokens} \cs{q_stop}
% \end{syntax}
-% Discards the first \meta{token} of the \meta{tokens} and leaves the
-% remainder in the input stream. This function requires only a
-% single expansion, and so is suitable for use inside an
-% \texttt{o}-type expansion. In general \cs{tl_tail:n} should be
-% preferred.
+% Discards the all leading space tokens and the first non-space token
+% in the \meta{tokens}, and leaves the remaining tokens in the
+% input stream.
+% An empty list of \meta{tokens} or one which consists
+% only of space (category code $10$) tokens will result in an error, and
+% thus \meta{tokens} must \emph{not} be \enquote{blank} as determined by
+% \cs{tl_if_blank:n(TF)}. This function requires only a single expansion,
+% and thus is suitable for use within an \texttt{o}-type expansion. In
+% general, \cs{tl_tail:n} should be preferred if the number of expansions
+% is not critical.
% \end{function}
%
% \begin{function}[EXP,pTF]{\tl_if_head_eq_catcode:nN}
% \begin{syntax}
-% \cs{tl_if_head_eq_catcode_p:n} \Arg{token list} \meta{test token}
-% \cs{tl_if_head_eq_catcode:nTF} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_catcode_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_catcode:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the first \meta{token} in the \meta{token list} has the same
@@ -820,8 +863,8 @@
% \begin{function}[EXP,pTF]
% {\tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:fN}
% \begin{syntax}
-% \cs{tl_if_head_eq_charcode_p:n} \Arg{token list} \meta{test token}
-% \cs{tl_if_head_eq_charcode:nTF} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_charcode_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_charcode:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the first \meta{token} in the \meta{token list} has the same
@@ -835,8 +878,8 @@
%
% \begin{function}[EXP,pTF]{\tl_if_head_eq_meaning:nN}
% \begin{syntax}
-% \cs{tl_if_head_eq_meaning_p:n} \Arg{token list} \meta{test token}
-% \cs{tl_if_head_eq_meaning:nTF} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_meaning_p:nN} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_meaning:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the first \meta{token} in the \meta{token list} has the same
@@ -976,7 +1019,7 @@
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the token list consists of exactly one token, i.e.,
-% is either a single space character or a single ``normal'' token.
+% is either a single space character or a single \enquote{normal} token.
% Token groups are not single tokens. The branching
% versions leaves either \meta{true code} or \meta{false code}
% in the input stream, as appropriate to the truth of the test and
@@ -1922,12 +1965,16 @@
% \begin{macro}{\tl_head:w}
% \begin{macro}{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
% \begin{macro}{\tl_tail:w}
-% These functions pick up either the head or the tail of a list.
+% These functions pick up either the head or the tail of a list. The
+% \texttt{n}-type implementation needs a test in order to avoid run-away
+% arguments occurring with blank input.
% \begin{macrocode}
-\cs_new:Npn \tl_head:n #1 { \tl_head:w #1 \q_stop }
-\cs_new:Npn \tl_tail:n #1 { \tl_tail:w #1 \q_stop }
\cs_new:Npn \tl_head:w #1#2 \q_stop {#1}
\cs_new:Npn \tl_tail:w #1#2 \q_stop {#2}
+\cs_new:Npn \tl_head:n #1
+ { \tl_if_blank:nF {#1} { \tl_head:w #1 \q_stop } }
+\cs_new:Npn \tl_tail:n #1
+ { \tl_if_blank:nF {#1} { \tl_tail:w #1 \q_stop } }
\cs_generate_variant:Nn \tl_head:n { V , v , f }
\cs_generate_variant:Nn \tl_tail:n { V , v , f }
% \end{macrocode}
@@ -1936,54 +1983,135 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\str_head:n}
+% \begin{macro}[aux]{\str_head_aux:w}
+% After \cs{tl_to_str:n}, we have a list of character tokens,
+% all with category code 12, except the space, which has category
+% code 10. Directly using \cs{tl_head:w} would thus lose leading spaces.
+% Instead, we take an argument delimited by an explicit space, and
+% then only use \cs{tl_head:w}. If the string started with a
+% space, then the argument of \cs{str_head_aux:w} is empty, and
+% the function correctly returns a space character. Otherwise,
+% it returns the first token of |#1|, which is the first token
+% of the string. If the string is empty, we return
+% \cs{scan_stop:}.
+% \begin{macrocode}
+\cs_new:Npn \str_head:n #1
+ {
+ \exp_after:wN \str_head_aux:w
+ \tl_to_str:n {#1}
+ { \scan_stop: } ~ \q_stop
+ }
+\cs_new_nopar:Npn \str_head_aux:w #1 ~ %
+ { \tl_head:w #1 { ~ } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}[pTF]{\tl_if_head_eq_meaning:nN}
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:nN}
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:fN}
% \begin{macro}[pTF]{\tl_if_head_eq_catcode:nN}
-% When we want to check if the first token of a list equals something
-% specific it is usually either to see if it is a control sequence or
-% a character. Hence we make two different functions as the internal
-% test is different.
-% \cs{tl_if_head_meaning_eq:nNTF} uses \cs{if_meaning:w} and will
-% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
-% \cs{tl_if_head_char_eq:nNTF} on the other hand only compares
-% character codes so would regard |b|$\sb{11}$ and |b|$\sb{12}$ as
-% equal but would also regard two primitives as equal.
+% Accessing the first token of a token list is tricky in two cases:
+% when it has category code 1 (begin-group token), or when it is
+% an explicit space, with category code 10 and character code 32.
+%
+% Forgetting temporarily about this issue we would use the
+% following test in \cs{tl_if_head_eq_charcode:nN}. Here,
+% an empty |#1| argument yields \cs{q_nil}, otherwise the
+% first token of the token list.
+% \begin{verbatim}
+% \if_charcode:w
+% \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop
+% \exp_not:N #2
+% \end{verbatim}
+% The special cases are detected by comparing |#1| with
+% \cs{use:n}~|#1| (the extra |?| takes care of empty arguments).
+% In those cases, the first token is a character, and
+% since we only care about its character code, we can
+% use \cs{str_head:n} to access it (this works even if
+% it is a space character).
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
{
- \exp_after:wN \if_meaning:w \tl_head:w #1 \q_stop #2
+ \if_charcode:w
+ \exp_not:N #2
+ \str_if_eq:onTF { \use:n #1 ? } { #1 ? }
+ { \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop }
+ { \str_head:n {#1} }
\prg_return_true:
\else:
\prg_return_false:
\fi:
}
+\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
% \end{macrocode}
-% For the charcode and catcode versions we insert |\exp_not:N| in
-% front of both tokens. If you need them to expand fully as \TeX{}
-% does itself with these you can use an |f| type expansion.
+% For \cs{tl_if_head_eq_catcode:nN}, again we detect special
+% cases with a \cs{str_if_eq:onTF} test. Then we need to test
+% if the first token is a begin-group token or an explicit
+% space token, and produce the relevant token, either
+% \cs{c_group_begin_token} or \cs{c_space_token}.
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1 #2 { p , T , F , TF }
{
- \exp_after:wN \if:w
- \exp_after:wN \exp_not:N \tl_head:w #1 \q_stop \exp_not:N #2
+ \if_catcode:w
+ \exp_not:N #2
+ \str_if_eq:onTF { \use:n #1 ? } { #1 ? }
+ { \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop }
+ {
+ \tl_if_head_begin_group:nTF {#1}
+ { \c_group_begin_token }
+ { \c_space_token }
+ }
\prg_return_true:
\else:
\prg_return_false:
\fi:
- }
-\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { f }
-\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { f }
-\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
-\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
+ }
% \end{macrocode}
-% And now catcodes:
+% For \cs{tl_if_head_eq_meaning:nN}, again, detect special cases.
+% In the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N}
+% this time, since \cs{if_meaning:w} causes no expansion.
+% In the special cases, we know that the first token is a character,
+% hence \cs{if_charcode:w} and \cs{if_catcode:w} together are enough.
+% We combine them in some order, hopefully faster than the reverse.
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
{
- \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N
- \tl_head:w #1 \q_stop \exp_not:N #2
- \prg_return_true: \else: \prg_return_false: \fi:
+ \str_if_eq:onTF { \use:n #1 ? } { #1 ? }
+ { \tl_if_head_eq_meaning_aux_normal:nN }
+ { \tl_if_head_eq_meaning_aux_special:nN }
+ {#1} #2
+ }
+\cs_new:Npn \tl_if_head_eq_meaning_aux_normal:nN #1 #2
+ {
+ \exp_after:wN \if_meaning:w \tl_head:w #1 \q_nil \q_stop #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \tl_if_head_eq_meaning_aux_special:nN #1 #2
+ {
+ \if_charcode:w \str_head:n {#1} \exp_not:N #2
+ \exp_after:wN \use:n
+ \else:
+ \prg_return_false:
+ \exp_after:wN \use_none:n
+ \fi:
+ {
+ \if_catcode:w \exp_not:N #2
+ \tl_if_head_begin_group:nTF {#1}
+ { \c_group_begin_token }
+ { \c_space_token }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
}
% \end{macrocode}
% \end{macro}