summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-10-14 22:32:58 +0000
committerKarl Berry <karl@freefriends.org>2015-10-14 22:32:58 +0000
commit0346eca0b9378bffafb6b32579dd4542b71b57f5 (patch)
treef9a5b79922bd74de6945c98e47f9b1d3009da982 /Master/texmf-dist/source/latex/l3kernel
parent6028cf981b015fefcf1205f6cba193542627ddbf (diff)
l3 (14oct15)
git-svn-id: svn://tug.org/texlive/trunk@38642 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/expl3.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx3
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx179
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3msg.dtx39
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3names.dtx42
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prg.dtx111
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx28
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3token.dtx327
8 files changed, 384 insertions, 349 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
index 753aeb0ec53..42ff1e3e4f4 100644
--- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
@@ -36,8 +36,8 @@
%<*driver|generic|package>
\def\ExplFileName{expl3}
\def\ExplFileDescription{L3 programming layer}
-\def\ExplFileDate{2015/09/27}
-\def\ExplFileVersion{6111}
+\def\ExplFileDate{2015/10/14}
+\def\ExplFileVersion{6210}
%</driver|generic|package>
%<*driver>
\documentclass[full]{l3doc}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
index 29d0a01caa8..69556596190 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
@@ -145,7 +145,7 @@
% \end{macro}
% \end{macro}
% \end{macro}
-\GetIdInfo$Id: l3bootstrap.dtx 5983 2015-09-10 18:57:56Z joseph $
+\GetIdInfo$Id: l3bootstrap.dtx 6139 2015-09-30 14:02:38Z bruno $
{L3 Bootstrap code}
%</driver|package>
%<*driver>
@@ -609,6 +609,7 @@
\catcode 9 = 9\relax
\catcode 32 = 9\relax
\catcode 34 = 12\relax
+\catcode 38 = 4\relax
\catcode 58 = 11\relax
\catcode 94 = 7\relax
\catcode 95 = 11\relax
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
index 6c65d33db05..d9a3202c949 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
@@ -38,7 +38,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3candidates.dtx 6039 2015-09-23 12:41:26Z joseph $
+\GetIdInfo$Id: l3candidates.dtx 6208 2015-10-09 20:01:54Z joseph $
{L3 Experimental additions to l3kernel}
%</driver|package>
%<*driver>
@@ -576,6 +576,98 @@
%
% \section{Additions to \pkg{l3prg}}
%
+% Minimal (lazy) evaluation can be obtained using the functions
+% \cs{bool_all_p:n}, \cs{bool_and_p:nn}, \cs{bool_any_p:n}, or
+% \cs{bool_or_p:nn}, which only evaluate their boolean expression
+% arguments when they are needed to determine the resulting truth
+% value. For example, when evaluating the boolean expression
+% \begin{verbatim}
+% \bool_and_p:nn
+% {
+% \bool_any_p:n
+% {
+% { \int_compare_p:n { 2 = 3 } }
+% { \int_compare_p:n { 4 <= 4 } }
+% { \int_compare_p:n { 1 = \error } } % is skipped
+% }
+% }
+% { ! \int_compare_p:n { 2 = 4 } }
+% \end{verbatim}
+% the line marked with |is skipped| is not expanded because the result
+% of \cs{bool_any_p:n} is known once the second boolean expression is
+% found to be logically \texttt{true}. On the other hand, the last
+% line is expanded because its logical value is needed to determine the
+% result of \cs{bool_and_p:nn}.
+%
+% \begin{function}[EXP, added = 2015-09-28]{\bool_all_p:n}
+% \begin{syntax}
+% \cs{bool_all_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
+% \end{syntax}
+% Implements the \enquote{And} operation on the \meta{boolean
+% expressions}, hence is \texttt{true} if all of them are
+% \texttt{true} and \texttt{false} if any of them is \texttt{false}.
+% Contrarily to the infix operator |&&|, only the \meta{boolean
+% expressions} which are needed to determine the result of
+% \cs{bool_all_p:n} will be evaluated. See also \cs{bool_and_p:nn}
+% when there are only two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-28]{\bool_and_p:nn}
+% \begin{syntax}
+% \cs{bool_and_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \end{syntax}
+% Implements the \enquote{And} operation between two boolean
+% expressions, hence is \texttt{true} if both are \texttt{true}.
+% Contrarily to the infix operator |&&|, the \meta{boolexpr_2} will
+% only be evaluated if it is needed to determine the result of
+% \cs{bool_and_p:nn}. See also \cs{bool_all_p:n} when there are more
+% than two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-28]{\bool_any_p:n}
+% \begin{syntax}
+% \cs{bool_any_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
+% \end{syntax}
+% Implements the \enquote{Or} operation on the \meta{boolean
+% expressions}, hence is \texttt{true} if any of them is
+% \texttt{true} and \texttt{false} if all of them are \texttt{false}.
+% Contrarily to the infix operator \verb"||", only the \meta{boolean
+% expressions} which are needed to determine the result of
+% \cs{bool_any_p:n} will be evaluated. See also \cs{bool_or_p:nn}
+% when there are only two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]{\bool_not_p:n}
+% \begin{syntax}
+% \cs{bool_not_p:n} \Arg{boolean expression}
+% \end{syntax}
+% Function version of |!(|\meta{boolean expression}|)| within a boolean
+% expression.
+% \end{function}
+%
+% \begin{function}[EXP, added = 2015-09-28]{\bool_or_p:nn}
+% \begin{syntax}
+% \cs{bool_or_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \end{syntax}
+% Implements the \enquote{Or} operation between two boolean
+% expressions, hence is \texttt{true} if either one is \texttt{true}.
+% Contrarily to the infix operator \verb"||", the \meta{boolexpr_2}
+% will only be evaluated if it is needed to determine the result of
+% \cs{bool_or_p:nn}. See also \cs{bool_any_p:n} when there are more
+% than two \meta{boolean expressions}.
+% \end{function}
+%
+% \begin{function}[EXP, updated = 2012-07-08]{\bool_xor_p:nn}
+% \begin{syntax}
+% \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
+% \end{syntax}
+% Implements an \enquote{exclusive or} operation between two boolean
+% expressions. There is no infix operation for this logical
+% operator.
+% \end{function}
+%
+
+%
% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\bool_log:N, \bool_log:c}
% \begin{syntax}
% \cs{bool_log:N} \meta{boolean}
@@ -1057,7 +1149,7 @@
% \end{itemize}
% and other values will raise an error.
%
-% The \meta{catcode} may be any one valid for the engine in use. Note
+% The \meta{charcode} may be any one valid for the engine in use. Note
% however that for \XeTeX{} releases prior to 0.99992 only the 8-bit
% range ($0$ to $255$) is accepted due to engine limitations.
% \end{function}
@@ -2484,6 +2576,86 @@
%<@@=bool>
% \end{macrocode}
%
+% \begin{macro}{\bool_all_p:n}
+% \begin{macro}[aux]{\@@_all_aux:n}
+% Go through the list of expressions, stopping whenever an expression
+% is \texttt{false}. If the end is reached without finding any
+% \texttt{false} expression, then the result is \texttt{true}.
+% \begin{macrocode}
+\cs_new:Npn \bool_all_p:n #1
+ { \@@_all_aux:n #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \@@_all_aux:n #1
+ {
+ \quark_if_recursion_tail_stop_do:nn {#1} { \c_true_bool }
+ \bool_if:nF {#1}
+ { \use_i_delimit_by_q_recursion_stop:nw { \c_false_bool } }
+ \@@_all_aux:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bool_and_p:nn}
+% Only evaluate the second expression if the first is \texttt{true}.
+% \begin{macrocode}
+\cs_new:Npn \bool_and_p:nn #1#2
+ { \bool_if:nTF {#1} { \bool_if_p:n {#2} } { \c_false_bool } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_any_p:n}
+% \begin{macro}[aux]{\@@_any_aux:n}
+% Go through the list of expressions, stopping whenever an expression
+% is \texttt{true}. If the end is reached without finding any
+% \texttt{true} expression, then the result is \texttt{false}.
+% \begin{macrocode}
+\cs_new:Npn \bool_any_p:n #1
+ { \@@_any_aux:n #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \@@_any_aux:n #1
+ {
+ \quark_if_recursion_tail_stop_do:nn {#1} { \c_false_bool }
+ \bool_if:nT {#1}
+ { \use_i_delimit_by_q_recursion_stop:nw { \c_true_bool } }
+ \@@_any_aux:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bool_not_p:n}
+% \UnitTested
+% The Not variant just reverses the outcome of \cs{bool_if_p:n}. Can
+% be optimized but this is nice and simple and according to the
+% implementation plan. Not even particularly useful to have it when
+% the infix notation is easier to use.
+% \begin{macrocode}
+\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_or_p:nn}
+% Only evaluate the second expression if the first is \texttt{false}.
+% \begin{macrocode}
+\cs_new:Npn \bool_or_p:nn #1#2
+ { \bool_if:nTF {#1} { \c_true_bool } { \bool_if_p:n {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_xor_p:nn}
+% \UnitTested
+% Exclusive or. If the boolean expressions have same truth value,
+% return false, otherwise return true.
+% \begin{macrocode}
+\cs_new:Npn \bool_xor_p:nn #1#2
+ {
+ \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} }
+ \c_false_bool
+ \c_true_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
% \begin{macro}{\bool_log:N, \bool_log:c, \bool_log:n}
% Redirect output of \cs{bool_show:N} to the log.
% \begin{macrocode}
@@ -4418,7 +4590,8 @@
\char_set_lccode:nn { 32 } {#1}
\exp_args:Nx \tex_lowercase:D
{
- \tl_const:cn { c_@@_ \__int_to_roman:w #1 _tl }
+ \tl_const:Nn
+ \exp_not:c { c_@@_ \__int_to_roman:w #1 _tl }
{ \exp_not:o \l_@@_tmp_tl }
}
}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
index 7ff417961b5..c4cce9a58aa 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3msg.dtx 6037 2015-09-23 12:41:15Z joseph $
+\GetIdInfo$Id: l3msg.dtx 6113 2015-09-28 21:30:11Z bruno $
{L3 Messages}
%</driver|package>
%<*driver>
@@ -2005,31 +2005,30 @@
% (with category code $7$) and keep tokens until that space character,
% dropping everything else until \cs{q_stop}. The \cs{exp_end:} prevents
% losing braces around the user-inserted text if any, and stops the
-% expansion of \cs{exp:w}.
+% expansion of \cs{exp:w}. One group is used to keep the settings
+% for \tn{lowercase} local and the other one is used to prevent
+% |\LaTeX3~error:| from being equal to \cs{scan_stop:}.
% \begin{macrocode}
\group_begin:
-\char_set_catcode_math_superscript:N \^
-\char_set_lccode:nn { `^ } { `\ }
-\char_set_lccode:nn { `L } { `L }
-\char_set_lccode:nn { `T } { `T }
-\char_set_lccode:nn { `X } { `X }
-\tex_lowercase:D
+\cs_set_protected:Npn \@@_tmp:w #1#2
{
- \cs_new:Npx \@@_expandable_error:n #1
+ \group_end:
+ \cs_new:Npn \@@_expandable_error:n ##1
{
- \exp_not:n
- {
- \exp:w
- \exp_after:wN \exp_after:wN
- \exp_after:wN \@@_expandable_error:w
- \exp_after:wN \exp_after:wN
- \exp_after:wN \exp_end:
- }
- \exp_not:N \use:n { \exp_not:c { LaTeX3~error: } ^ #1 } ^
+ \exp:w
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_expandable_error:w
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_end:
+ \use:n { #2 #1 ##1 } #1
}
- \cs_new:Npn \@@_expandable_error:w #1 ^ #2 ^ { #1 }
+ \cs_new:Npn \@@_expandable_error:w ##1 #1 ##2 #1 {##1}
}
-\group_end:
+\group_begin:
+\char_set_catcode_math_superscript:N \^
+\char_set_lccode:nn { `^ } { `\ }
+\tex_lowercase:D
+ { \group_end: \exp_args:NNc \@@_tmp:w ^ } { LaTeX3~error: }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
index 6b3dafbc2b3..f7d7ed4e2ee 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3names.dtx 6108 2015-09-27 08:58:42Z joseph $
+\GetIdInfo$Id: l3names.dtx 6209 2015-10-10 19:51:42Z joseph $
{L3 Namespace for primitives}
%</driver|package>
%<*driver>
@@ -611,11 +611,9 @@
\__kernel_primitive:NN \pdfoutput \pdftex_pdfoutput:D
\__kernel_primitive:NN \pdfpageattr \pdftex_pdfpageattr:D
\__kernel_primitive:NN \pdfpagebox \pdftex_pdfpagebox:D
- \__kernel_primitive:NN \pdfpageheight \pdftex_pdfpageheight:D
\__kernel_primitive:NN \pdfpageref \pdftex_pdfpageref:D
\__kernel_primitive:NN \pdfpageresources \pdftex_pdfpageresources:D
\__kernel_primitive:NN \pdfpagesattr \pdftex_pdfpagesattr:D
- \__kernel_primitive:NN \pdfpagewidth \pdftex_pdfpagewidth:D
\__kernel_primitive:NN \pdfrefobj \pdftex_pdfrefobj:D
\__kernel_primitive:NN \pdfrefxform \pdftex_pdfrefxform:D
\__kernel_primitive:NN \pdfrefximage \pdftex_pdfrefximage:D
@@ -639,6 +637,8 @@
% \end{macrocode}
% While these are not.
% \begin{macrocode}
+ \__kernel_primitive:NN \ifpdfabsdim \pdftex_ifabsdim:D
+ \__kernel_primitive:NN \ifpdfabsnum \pdftex_ifabsnum:D
\__kernel_primitive:NN \ifpdfprimitive \pdftex_ifprimitive:D
\__kernel_primitive:NN \pdfadjustspacing \pdftex_adjustspacing:D
\__kernel_primitive:NN \pdfcopyfont \pdftex_copyfont:D
@@ -657,6 +657,8 @@
\__kernel_primitive:NN \pdfmapline \pdftex_mapline:D
\__kernel_primitive:NN \pdfnoligatures \pdftex_noligatures:D
\__kernel_primitive:NN \pdfnormaldeviate \pdftex_normaldeviate:D
+ \__kernel_primitive:NN \pdfpageheight \pdftex_pageheight:D
+ \__kernel_primitive:NN \pdfpagewidth \pdftex_pagewidth:D
\__kernel_primitive:NN \pdfpkmode \pdftex_pkmode:D
\__kernel_primitive:NN \pdfpkresolution \pdftex_pkresolution:D
\__kernel_primitive:NN \pdfprimitive \pdftex_primitive:D
@@ -753,9 +755,7 @@
% \end{macrocode}
% Primitives from \LuaTeX{}, some of which have been ported back to
% \XeTeX{}. Notice that \tn{expanded} was intended for \pdfTeX{}~1.50 but
-% as that was not released we call this a \LuaTeX{} primitive. Primitives
-% which are aliases are covered only once, so for example \tn{pdfpageheight}
-% covers \tn{pageheight} as well.
+% as that was not released we call this a \LuaTeX{} primitive.
% \begin{macrocode}
\__kernel_primitive:NN \alignmark \luatex_alignmark:D
\__kernel_primitive:NN \aligntab \luatex_aligntab:D
@@ -771,6 +771,7 @@
\__kernel_primitive:NN \expanded \luatex_expanded:D
\__kernel_primitive:NN \fontid \luatex_fontid:D
\__kernel_primitive:NN \formatname \luatex_formatname:D
+ \__kernel_primitive:NN \hyphenationmin \luatex_hypenationmin:D
\__kernel_primitive:NN \gleaders \luatex_gleaders:D
\__kernel_primitive:NN \initcatcodetable \luatex_initcatcodetable:D
\__kernel_primitive:NN \latelua \luatex_latelua:D
@@ -1037,7 +1038,7 @@
% (depending on the format-building date). There are a few primitives
% that get the right names anyway so are missing here!
% \begin{macrocode}
-\etex_ifdefined:D \luatexcatcodetable
+\etex_ifdefined:D \luatexsuppressfontnotfounderror
\tex_let:D \luatex_alignmark:D \luatexalignmark
\tex_let:D \luatex_aligntab:D \luatexaligntab
\tex_let:D \luatex_attribute:D \luatexattribute
@@ -1079,10 +1080,6 @@
% \begin{macrocode}
\tex_let:D \luatex_bodydir:D \luatexbodydir
\tex_let:D \luatex_boxdir:D \luatexboxdir
- \tex_let:D \luatex_chardp:D \luatexchardp
- \tex_let:D \luatex_charht:D \luatexcharht
- \tex_let:D \luatex_charit:D \luatexcharit
- \tex_let:D \luatex_charwd:D \luatexcharwd
\tex_let:D \luatex_leftghost:D \luatexleftghost
\tex_let:D \luatex_localbrokenpenalty:D \luatexlocalbrokenpenalty
\tex_let:D \luatex_localinterlinepenalty:D \luatexlocalinterlinepenalty
@@ -1139,12 +1136,27 @@
\tex_fi:D
% \end{macrocode}
% Up to v0.80, \LuaTeX{} defines the \pdfTeX{} version data: rather
-% confusing.
+% confusing. Removing them means that \cs{pdftex_pdftexversion:D} is
+% a marker for \pdfTeX{} alone: useful in engine-dependent code later.
% \begin{macrocode}
\etex_ifdefined:D \luatex_luatexversion:D
- \tex_let:D \pdftex_pdftexbanner:D \tex_undefined:D
- \tex_let:D \pdftex_pdftexbanner:D \tex_undefined:D
- \tex_let:D \pdftex_pdftexversion:D \tex_undefined:D
+ \tex_let:D \pdftex_pdftexbanner:D \tex_undefined:D
+ \tex_let:D \pdftex_pdftexrevision:D \tex_undefined:D
+ \tex_let:D \pdftex_pdftexversion:D \tex_undefined:D
+\tex_fi:D
+% \end{macrocode}
+% From v0.81, \LuaTeX{} drops the |pdf| prefix in some cases.
+% \begin{macrocode}
+\etex_ifdefined:D \lastxpos
+ \tex_let:D \pdftex_lastxpos:D \lastxpos
+ \tex_let:D \pdftex_lastypos:D \lastypos
+ \tex_let:D \pdftex_normaldeviate:D \normaldeviate
+ \tex_let:D \pdftex_pageheight:D \pageheight
+ \tex_let:D \pdftex_pagewith:D \pagewidth
+ \tex_let:D \pdftex_randomseed:D \randomseed
+ \tex_let:D \pdftex_setrandomseed:D \setrandomseed
+ \tex_let:D \pdftex_savepos:D \savepos
+ \tex_let:D \pdftex_uniformdeviate:D \uniformdeviate
\tex_fi:D
% \end{macrocode}
%
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
index 9acff26f534..1fc47d225b9 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3prg.dtx 5983 2015-09-10 18:57:56Z joseph $
+\GetIdInfo$Id: l3prg.dtx 6208 2015-10-09 20:01:54Z joseph $
{L3 Control structures}
%</driver|package>
%<*driver>
@@ -72,9 +72,7 @@
% performs a series of tests, possibly involving assignments and
% calling other functions that do not read further ahead in the input
% stream. After processing the input, a \emph{state} is returned. The
-% typical states returned are \meta{true} and \meta{false} but other
-% states are possible, say an \meta{error} state for erroneous
-% input, \emph{e.g.}, text as input in a function comparing integers.
+% states returned are \meta{true} and \meta{false}.
%
% \LaTeX3 has two forms of conditional flow processing based
% on these states. The first form is predicate functions that turn the
@@ -87,8 +85,12 @@
% input stream based on the result of the testing as in
% \cs{cs_if_free:NTF} which also takes one argument (the |N|) and then
% executes either \texttt{true} or \texttt{false} depending on the
-% result. Important to note here is that the arguments are executed
-% after exiting the underlying |\if...\fi:| structure.
+% result.
+%
+% \begin{texnote}
+% The arguments are executed after exiting the underlying
+% |\if...\fi:| structure.
+% \end{texnote}
%
% \section{Defining a set of conditional functions}
% \label{sec:l3prg:new-conditional-functions}
@@ -140,7 +142,7 @@
% which will supply either a logical \texttt{true} or logical
% \texttt{false}. This function is intended for use in cases where
% one or more logical tests are combined to lead to a final outcome.
-% This function will not work properly for \texttt{protected}
+% This function cannot be defined for \texttt{protected}
% conditionals.
% \item \cs{\meta{name}:\meta{arg spec}T} --- a function with one more
% argument than the original \meta{arg spec} demands. The \meta{true
@@ -192,7 +194,7 @@
% \begin{syntax}
% \cs{prg_new_eq_conditional:NNn} \cs{\meta{name_1}:\meta{arg spec_1}} \cs{\meta{name_2}:\meta{arg spec_2}} \Arg{conditions}
% \end{syntax}
-% These functions copies a family of conditionals. The \texttt{new} version
+% These functions copy a family of conditionals. The \texttt{new} version
% will check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas
% the \texttt{set} version will not (\emph{cf.}~\cs{cs_set:Npn}). The
% conditionals copied are depended on the comma-separated list of
@@ -208,7 +210,7 @@
% These `return' functions define the logical state of a conditional statement.
% They appear within the code for a conditional
% function generated by \cs{prg_set_conditional:Npnn}, \emph{etc}, to indicate
-% when a true or false branch has been taken.
+% when a true or false branch should be taken.
% While they may appear multiple times each within the code of such conditionals,
% the execution of the conditional must result in the expansion of one of these
% two functions \emph{exactly once}.
@@ -357,22 +359,23 @@
% of predicate functions and boolean variables, return boolean
% \meta{true} or \meta{false}. It supports the logical operations And,
% Or and Not as the well-known infix operators |&&|, \verb"||" and |!|
-% with their usual precedences. In
+% with their usual precedences (namely, |&&| binds more tightly than
+% \verb"||"). In
% addition to this, parentheses can be used to isolate
% sub-expressions. For example,
% \begin{verbatim}
% \int_compare_p:n { 1 = 1 } &&
% (
% \int_compare_p:n { 2 = 3 } ||
-% \int_compare_p:n { 4 = 4 } ||
-% \int_compare_p:n { 1 = \error } % is skipped
+% \int_compare_p:n { 4 <= 4 } ||
+% \str_if_eq_p:nn { abc } { def }
% ) &&
-% ! ( \int_compare_p:n { 2 = 4 } )
+% ! \int_compare_p:n { 2 = 4 }
% \end{verbatim}
-% is a valid boolean expression. Note that minimal evaluation is
-% carried out whenever possible so that whenever a truth value cannot
-% be changed any more, the remaining tests within the current group
-% are skipped.
+% is a valid boolean expression.
+%
+% At present, the infix operators |&&| and \verb"||" perform lazy
+% evaluation as well, but this will change in a future release.
%
% \begin{function}[EXP, pTF, updated = 2012-07-08]{\bool_if:n}
% \begin{syntax}
@@ -384,45 +387,10 @@
% \meta{boolean expression} should consist of a series of predicates
% or boolean variables with the logical relationship between these
% defined using |&&| (\enquote{And}), \verb"||" (\enquote{Or}),
-% |!| (\enquote{Not}) and parentheses. Minimal evaluation is used
-% in the processing, so that once a result is defined there is
-% not further expansion of the tests. For example
-% \begin{verbatim}
-% \bool_if_p:n
-% {
-% \int_compare_p:nNn { 1 } = { 1 }
-% &&
-% (
-% \int_compare_p:nNn { 2 } = { 3 } ||
-% \int_compare_p:nNn { 4 } = { 4 } ||
-% \int_compare_p:nNn { 1 } = { \error } % is skipped
-% )
-% &&
-% ! \int_compare_p:nNn { 2 } = { 4 }
-% }
-% \end{verbatim}
-% will be \texttt{true} and will not evaluate
-% |\int_compare_p:nNn { 1 } = { \error }|. The logical Not applies to
+% |!| (\enquote{Not}) and parentheses. The logical Not applies to
% the next predicate or group.
% \end{function}
%
-% \begin{function}[EXP, updated = 2012-07-08]{\bool_not_p:n}
-% \begin{syntax}
-% \cs{bool_not_p:n} \Arg{boolean expression}
-% \end{syntax}
-% Function version of |!(|\meta{boolean expression}|)| within a boolean
-% expression.
-% \end{function}
-%
-% \begin{function}[EXP, updated = 2012-07-08]{\bool_xor_p:nn}
-% \begin{syntax}
-% \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
-% \end{syntax}
-% Implements an \enquote{exclusive or} operation between two boolean
-% expressions. There is no infix operation for this logical
-% operator.
-% \end{function}
-%
% \section{Logical loops}
%
% Loops using either boolean expressions or stored boolean values.
@@ -568,17 +536,17 @@
%
% \begin{function}[EXP]{\if_predicate:w}
% \begin{syntax}
-% "\if_predicate:w" <predicate> <true code> "\else:" <false code> "\fi:"
+% \cs{if_predicate:w} \meta{predicate} \meta{true code} \cs{else:} \meta{false code} \cs{fi:}
% \end{syntax}
% This function takes a predicate function and
% branches according to the result. (In practice this function would also
-% accept a single boolean variable in place of the <predicate> but to make the
-% coding clearer this should be done through "\if_bool:N".)
+% accept a single boolean variable in place of the \meta{predicate} but to make the
+% coding clearer this should be done through \cs{if_bool:N}.)
% \end{function}
%
% \begin{function}[EXP]{\if_bool:N}
% \begin{syntax}
-% "\if_bool:N" <boolean> <true code> "\else:" <false code> "\fi:"
+% \cs{if_bool:N} \meta{boolean} \meta{true code} \cs{else:} \meta{false code} \cs{fi:}
% \end{syntax}
% This function takes a boolean variable and
% branches according to the result.
@@ -664,7 +632,7 @@
% \section{\pkg{l3prg} implementation}
%
% \TestFiles{m3prg001.lvt,m3prg002.lvt,m3prg003.lvt}
-%%
+%
% \begin{macrocode}
%<*initex|package>
% \end{macrocode}
@@ -1128,7 +1096,7 @@
% \begin{macro}[aux]+\@@_&_1:w+
% \begin{macro}[aux]+\@@_|_0:w+
% Two cases where we simply continue scanning. We must remove the
-% second "&" or \verb"|".
+% second |&| or \verb"|".
% \begin{macrocode}
\cs_new_nopar:cpn { @@_&_1:w } & { \@@_get_next:NN \use_i:nn }
\cs_new_nopar:cpn { @@_|_0:w } | { \@@_get_next:NN \use_i:nn }
@@ -1237,31 +1205,6 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\bool_not_p:n}
-% \UnitTested
-% The Not variant just reverses the outcome of \cs{bool_if_p:n}. Can
-% be optimized but this is nice and simple and according to the
-% implementation plan. Not even particularly useful to have it when
-% the infix notation is easier to use.
-% \begin{macrocode}
-\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\bool_xor_p:nn}
-% \UnitTested
-% Exclusive or. If the boolean expressions have same truth value,
-% return false, otherwise return true.
-% \begin{macrocode}
-\cs_new:Npn \bool_xor_p:nn #1#2
- {
- \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} }
- \c_false_bool
- \c_true_bool
- }
-% \end{macrocode}
-% \end{macro}
-%
% \subsection{Logical loops}
%
% \begin{macro}{\bool_while_do:Nn, \bool_while_do:cn}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
index 5ffb9ffdf33..57bfe04f3d7 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3tl.dtx 6037 2015-09-23 12:41:15Z joseph $
+\GetIdInfo$Id: l3tl.dtx 6121 2015-09-29 20:31:06Z bruno $
{L3 Token lists}
%</driver|package>
%<*driver>
@@ -1833,14 +1833,16 @@
% If on the one hand it is found within the \meta{token list}, then
% |##1| cannot contain the \meta{delimiter}~|#1| that we worked so
% hard to obtain, thus \cs{@@_replace_wrap:w} gets~|##1| as its own
-% argument~|##1|, and wraps it using \cs{exp_not:o} for consumption by
+% argument~|##1|, and protects it against
% the \texttt{x}-expanding assignment. It also finds \cs{exp_not:n}
% as~|##2| and does nothing to it, thus letting through \cs{exp_not:n}
-% \Arg{replacement} into the assignment. (Note that
+% \Arg{replacement} into the assignment. Note that
% \cs{@@_replace_next:w} and \cs{@@_replace_wrap:w} are always called
-% followed by \cs{prg_do_nothing:} to avoid losing braces when
-% grabbing delimited arguments, hence the use of \cs{exp_not:o} rather
-% than \cs{exp_not:n}.) Afterwards, \cs{@@_replace_next:w} is called
+% followed by two empty brace groups. These are safe because no
+% delimiter can match them. They prevent losing braces when grabbing
+% delimited arguments, but require the use of \cs{exp_not:o} and
+% \cs{use_none:nn}, rather than simply \cs{exp_not:n}.
+% Afterwards, \cs{@@_replace_next:w} is called
% to repeat the replacement, or \cs{@@_replace_wrap:w} if we only want
% a single replacement. In this second case, |##1| is the
% \meta{remaining tokens} in the \meta{token list} and |##2| is some
@@ -1850,9 +1852,9 @@
%
% If on the other hand the argument~|##1| of \cs{@@_replace_next:w} is
% delimited by the trailing \meta{pattern}~|#5|, then |##1| is
-% \enquote{\cs{prg_do_nothing:} \meta{token list} \meta{delimiter}
+% \enquote{\{ \} \{ \} \meta{token list} \meta{delimiter}
% \Arg{ending code}}, hence \cs{@@_replace_wrap:w} finds
-% \enquote{\cs{prg_do_nothing:} \meta{token list}} as |##1| and the
+% \enquote{\{ \} \{ \} \meta{token list}} as |##1| and the
% \meta{ending code} as~|##2|. It leaves the \meta{token list} into
% the assignment and unbraces the \meta{ending code} which removes
% what remains (essentially the \meta{delimiter} and
@@ -1861,25 +1863,27 @@
\cs_new_protected:Npn \@@_replace_auxii:nNNNnn #1#2#3#4#5#6
{
\group_align_safe_begin:
- \cs_set:Npn \@@_replace_wrap:w ##1 #1 ##2 { \exp_not:o {##1} ##2 }
+ \cs_set:Npn \@@_replace_wrap:w ##1 #1 ##2
+ { \exp_not:o { \use_none:nn ##1 } ##2 }
\cs_set:Npx \@@_replace_next:w ##1 #5
{
\exp_not:N \@@_replace_wrap:w ##1
\exp_not:n { #1 }
\exp_not:n { \exp_not:n {#6} }
- \exp_not:n { #2 \prg_do_nothing: }
+ \exp_not:n { #2 { } { } }
}
#3 #4
{
\exp_after:wN \@@_replace_next:w
- \exp_after:wN \prg_do_nothing: #4
+ \exp_after:wN { \exp_after:wN }
+ \exp_after:wN { \exp_after:wN }
+ #4
#1
{
\if_false: { \fi: }
\exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
}
#5
- \q_recursion_stop
}
\group_align_safe_end:
}
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
index 9699b2492eb..0075c4abfeb 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3token.dtx 6040 2015-09-23 12:41:32Z joseph $
+\GetIdInfo$Id: l3token.dtx 6114 2015-09-28 21:32:37Z bruno $
{L3 Experimental token manipulation}
%</driver|package>
%<*driver>
@@ -1668,240 +1668,143 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[aux]
+% {
+% \@@_delimit_by_char":w,
+% \@@_delimit_by_count:w,
+% \@@_delimit_by_dimen:w,
+% \@@_delimit_by_macro:w,
+% \@@_delimit_by_muskip:w,
+% \@@_delimit_by_skip:w,
+% \@@_delimit_by_toks:w,
+% }
+% These auxiliary functions are used below to define some
+% conditionals which detect whether the \tn{meaning} of their
+% argument begins with a particular string. Each auxiliary takes an
+% argument delimited by a string, a second one delimited by
+% \cs{q_stop}, and returns the first one and its delimiter.
+% This result will eventually be compared to another string.
+% \begin{macrocode}
+\group_begin:
+\cs_set_protected:Npn \@@_tmp:w #1
+ {
+ \use:x
+ {
+ \cs_new:Npn \exp_not:c { @@_delimit_by_ #1 :w }
+ ####1 \tl_to_str:n {#1} ####2 \exp_not:N \q_stop
+ { ####1 \tl_to_str:n {#1} }
+ }
+ }
+\@@_tmp:w { char" }
+\@@_tmp:w { count }
+\@@_tmp:w { dimen }
+\@@_tmp:w { macro }
+\@@_tmp:w { muskip }
+\@@_tmp:w { skip }
+\@@_tmp:w { toks }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[pTF]
% {
% \token_if_chardef:N, \token_if_mathchardef:N,
+% \token_if_long_macro:N,
+% \token_if_protected_macro:N, \token_if_protected_long_macro:N,
% \token_if_dim_register:N, \token_if_int_register:N,
% \token_if_muskip_register:N,
% \token_if_skip_register:N, \token_if_toks_register:N,
-% \token_if_long_macro:N,
-% \token_if_protected_macro:N, \token_if_protected_long_macro:N,
% }
-% \begin{macro}[aux]
-% {
-% \@@_if_chardef:w,
-% \@@_if_dim_register:w,
-% \@@_if_int_register:w,
-% \@@_if_muskip_register:w,
-% \@@_if_skip_register:w,
-% \@@_if_toks_register:w,
-% \@@_if_protected_macro:w,
-% \@@_if_long_macro:w,
-% }
-% Most of these functions have to check the meaning of the token in
-% question so we need to do some checkups on which characters are
-% output by \cs{token_to_meaning:N}. As usual, these characters have
-% catcode 12 so we must do some serious substitutions in the code
-% below\dots
+% Each of these conditionals tests whether its argument's
+% \tn{meaning} starts with a given string. This is essentially done
+% by having an auxiliary grab an argument delimited by the string and
+% testing whether the argument was empty. Of course, a copy of this
+% string must first be added to the end of the \tn{meaning} to avoid
+% a runaway argument in case it does not contain the string. Two
+% complications arise. First, the escape character is not fixed, and
+% cannot be included in the delimiter of the auxiliary function (this
+% function cannot be defined on the fly because tests must remain
+% expandable): instead the first argument of the auxiliary (plus the
+% delimiter to avoid complications with trailing spaces) is compared
+% using \cs{__str_if_eq_x_return:nn} to the result of applying
+% \cs{token_to_str:N} to a control sequence. Second, the
+% \tn{meaning} of primitives such as \tn{dimen} or \tn{dimendef}
+% starts in the same way as registers such as
+% \tn{dimen}\texttt{123}, so they must be tested for.
+%
+% Characters used as delimiters must have catcode~$12$
+% and are obtained through \cs{tl_to_str:n}. This requires doing all
+% definitions within \texttt{x}-expansion. The temporary function
+% \cs{@@_tmp:w} used to define each conditional receives three
+% arguments: the name of the conditional, the auxiliary's delimiter
+% (also used to name the auxiliary), and the string to which one
+% compares the auxiliary's result. Note that the \tn{meaning} of a
+% protected long macro starts with |\protected\long macro|, with no
+% space after |\protected| but a space after |\long|, hence the
+% mixture of \cs{token_to_str:N} and \cs{tl_to_str:n}.
+%
+% For the first five conditionals, \cs{cs_if_exist:cT} turns out to
+% be \texttt{false}, and the code boils down to a string comparison
+% between the result of the auxiliary on the \tn{meaning} of the
+% conditional's argument~|####1|, and~|#3|. Both are evaluated at
+% run-time, as this is important to get the correct escape character.
+%
+% The other five conditionals have additional code that compares the
+% argument~|####1| to two \TeX{} primitives which would wrongly be
+% recognized as registers otherwise. Despite using \TeX{}'s
+% primitive conditional construction, this does not break
+% when~|####1| is itself a conditional, because branches of the
+% conditionals are only skipped if |####1|~is one of the two
+% primitives that are tested for (which are not \TeX{} conditionals).
% \begin{macrocode}
\group_begin:
- \char_set_lccode:nn { `T } { `T }
- \char_set_lccode:nn { `F } { `F }
- \char_set_lccode:nn { `X } { `n }
- \char_set_lccode:nn { `Y } { `t }
- \char_set_lccode:nn { `Z } { `d }
- \tl_map_inline:nn { A C E G H I K L M O P R S U X Y Z R " }
- { \char_set_catcode:nn { `#1 } \c_twelve }
-% \end{macrocode}
-% We convert the token list to lower case and restore the catcode and
-% lowercase code changes.
-% \begin{macrocode}
-\tex_lowercase:D
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
{
- \group_end:
-% \end{macrocode}
-% First up is checking if something has been defined with
-% \tn{chardef} or \tn{mathchardef}. This is easy since \TeX{}
-% thinks of such tokens as hexadecimal so it stores them as
-% |\char"|\meta{hex~number} or |\mathchar"|\meta{hex~number}.
-% Grab until the first occurrence of |char"|, and compare what
-% precedes with |\| or |\math|. In fact, the escape character
-% may not be a backslash, so we compare with the result of
-% converting some other control sequence to a string, namely
-% |\char| or |\mathchar| (the auxiliary adds the |char| back).
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_chardef:N #1 { p , T , F , TF }
- {
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_chardef:w
- \token_to_meaning:N #1 CHAR" \q_stop
- }
- { \token_to_str:N \char }
- }
- \prg_new_conditional:Npnn \token_if_mathchardef:N #1 { p , T , F , TF }
+ \use:x
{
- \__str_if_eq_x_return:nn
+ \prg_new_conditional:Npnn \exp_not:c { token_if_ #1 :N } ####1
+ { p , T , F , TF }
{
- \exp_after:wN \@@_if_chardef:w
- \token_to_meaning:N #1 CHAR" \q_stop
- }
- { \token_to_str:N \mathchar }
- }
- \cs_new:Npn \@@_if_chardef:w #1 CHAR" #2 \q_stop { #1 CHAR }
-% \end{macrocode}
-% Dim registers are a bit more difficult since their \tn{meaning}
-% has the form \tn{dimen}\meta{number}, and we must take care of the
-% two primitives \tn{dimen} and \tn{dimendef}.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_dim_register:N #1 { p , T , F , TF }
- {
- \if_meaning:w \tex_dimen:D #1
- \prg_return_false:
- \else:
- \if_meaning:w \tex_dimendef:D #1
- \prg_return_false:
- \else:
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_dim_register:w
- \token_to_meaning:N #1 ZIMEX \q_stop
- }
- { \token_to_str:N \ }
- \fi:
- \fi:
- }
- \cs_new:Npn \@@_if_dim_register:w #1 ZIMEX #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Integer registers are one step harder since constants are implemented
-% differently from variables, and we also have to take care of the
-% primitives \tn{count} and \tn{countdef}.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_int_register:N #1 { p , T , F , TF }
- {
- % \token_if_chardef:NTF #1 { \prg_return_true: }
- % {
- % \token_if_mathchardef:NTF #1 { \prg_return_true: }
- % {
- \if_meaning:w \tex_count:D #1
- \prg_return_false:
- \else:
- \if_meaning:w \tex_countdef:D #1
- \prg_return_false:
- \else:
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_int_register:w
- \token_to_meaning:N #1 COUXY \q_stop
- }
- { \token_to_str:N \ }
- \fi:
- \fi:
- % }
- % }
- }
- \cs_new:Npn \@@_if_int_register:w #1 COUXY #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Muskip registers are done the same way as the dimension registers.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_muskip_register:N #1
- { p , T , F , TF }
- {
- \if_meaning:w \tex_muskip:D #1
- \prg_return_false:
- \else:
- \if_meaning:w \tex_muskipdef:D #1
- \prg_return_false:
- \else:
- \__str_if_eq_x_return:nn
+ \cs_if_exist:cT { tex_ #2 :D }
{
- \exp_after:wN \@@_if_muskip_register:w
- \token_to_meaning:N #1 MUSKIP \q_stop
+ \exp_not:N \if_meaning:w ####1 \exp_not:c { tex_ #2 :D }
+ \exp_not:N \prg_return_false:
+ \exp_not:N \else:
+ \exp_not:N \if_meaning:w ####1 \exp_not:c { tex_ #2 def:D }
+ \exp_not:N \prg_return_false:
+ \exp_not:N \else:
}
- { \token_to_str:N \ }
- \fi:
- \fi:
- }
- \cs_new:Npn \@@_if_muskip_register:w #1 MUSKIP #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Skip registers.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_skip_register:N #1
- { p , T , F , TF }
- {
- \if_meaning:w \tex_skip:D #1
- \prg_return_false:
- \else:
- \if_meaning:w \tex_skipdef:D #1
- \prg_return_false:
- \else:
- \__str_if_eq_x_return:nn
+ \exp_not:N \__str_if_eq_x_return:nn
{
- \exp_after:wN \@@_if_skip_register:w
- \token_to_meaning:N #1 SKIP \q_stop
+ \exp_not:N \exp_after:wN
+ \exp_not:c { @@_delimit_by_ #2 :w }
+ \exp_not:N \token_to_meaning:N ####1
+ ? \tl_to_str:n {#2} \exp_not:N \q_stop
}
- { \token_to_str:N \ }
- \fi:
- \fi:
- }
- \cs_new:Npn \@@_if_skip_register:w #1 SKIP #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Toks registers.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_toks_register:N #1
- { p , T , F , TF }
- {
- \if_meaning:w \tex_toks:D #1
- \prg_return_false:
- \else:
- \if_meaning:w \tex_toksdef:D #1
- \prg_return_false:
- \else:
- \__str_if_eq_x_return:nn
+ { \exp_not:n {#3} }
+ \cs_if_exist:cT { tex_ #2 :D }
{
- \exp_after:wN \@@_if_toks_register:w
- \token_to_meaning:N #1 YOKS \q_stop
+ \exp_not:N \fi:
+ \exp_not:N \fi:
}
- { \token_to_str:N \ }
- \fi:
- \fi:
- }
- \cs_new:Npn \@@_if_toks_register:w #1 YOKS #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Protected macros.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_protected_macro:N #1
- { p , T , F , TF }
- {
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_protected_macro:w
- \token_to_meaning:N #1 PROYECYEZ~MACRO \q_stop
}
- { \token_to_str:N \ }
}
- \cs_new:Npn \@@_if_protected_macro:w
- #1 PROYECYEZ~MACRO #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Long macros and protected long macros share an auxiliary.
-% \begin{macrocode}
- \prg_new_conditional:Npnn \token_if_long_macro:N #1 { p , T , F , TF }
- {
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_long_macro:w
- \token_to_meaning:N #1 LOXG~MACRO \q_stop
- }
- { \token_to_str:N \ }
- }
- \prg_new_conditional:Npnn \token_if_protected_long_macro:N #1
- { p , T , F , TF }
- {
- \__str_if_eq_x_return:nn
- {
- \exp_after:wN \@@_if_long_macro:w
- \token_to_meaning:N #1 LOXG~MACRO \q_stop
- }
- { \token_to_str:N \protected \token_to_str:N \ }
- }
- \cs_new:Npn \@@_if_long_macro:w #1 LOXG~MACRO #2 \q_stop { #1 ~ }
-% \end{macrocode}
-% Finally the \cs{tex_lowercase:D} ends!
-% \begin{macrocode}
}
+\@@_tmp:w { chardef } { char" } { \token_to_str:N \char" }
+\@@_tmp:w { mathchardef } { char" } { \token_to_str:N \mathchar" }
+\@@_tmp:w { long_macro } { macro } { \tl_to_str:n { \long } macro }
+\@@_tmp:w { protected_macro } { macro }
+ { \tl_to_str:n { \protected } macro }
+\@@_tmp:w { protected_long_macro } { macro }
+ { \token_to_str:N \protected \tl_to_str:n { \long } macro }
+\@@_tmp:w { dim_register } { dimen } { \token_to_str:N \dimen }
+\@@_tmp:w { int_register } { count } { \token_to_str:N \count }
+\@@_tmp:w { muskip_register } { muskip } { \token_to_str:N \muskip }
+\@@_tmp:w { skip_register } { skip } { \token_to_str:N \skip }
+\@@_tmp:w { toks_register } { toks } { \token_to_str:N \toks }
+\group_end:
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[pTF]{\token_if_primitive:N}
% \begin{macro}[aux]{\@@_if_primitive:NNw,