From 476ef285597d50560f829ffd64532d75d937d06a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 28 Jul 2013 21:53:53 +0000 Subject: latex3 (28jul13) git-svn-id: svn://tug.org/texlive/trunk@31299 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/source/latex/l3kernel/l3basics.dtx | 233 +++++++++------------ 1 file changed, 95 insertions(+), 138 deletions(-) (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx') diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index b00dee6ec9e..a43c8fec53f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3basics.dtx 4521 2013-07-09 11:45:31Z joseph $ +\GetIdInfo$Id: l3basics.dtx 4581 2013-07-28 08:38:50Z joseph $ {L3 Basic definitions} % %<*driver> @@ -1122,26 +1122,30 @@ % is logically \texttt{true}. % \end{function} % -% \begin{function}[added = 2012-06-03, EXP]{\str_case:nnn, \str_case:onn} +% \begin{function}[added = 2013-07-24, EXP, TF]{\str_case:nn, \str_case:on} % \begin{syntax} -% \cs{str_case:nnn} \Arg{test string} \\ +% \cs{str_case:nnTF} \Arg{test string} \\ % ~~|{| \\ % ~~~~\Arg{string case_1} \Arg{code case_1} \\ % ~~~~\Arg{string case_2} \Arg{code case_2} \\ % ~~~~\ldots \\ % ~~~~\Arg{string case_n} \Arg{code case_n} \\ % ~~|}| \\ -% ~~\Arg{else code} +% ~~\Arg{true code} +% ~~\Arg{false code} % \end{syntax} % This function compares the \meta{test string} in turn with each % of the \meta{string cases}. If the two are equal (as described for % \cs{str_if_eq:nnTF} then the -% associated \meta{code} is left in the input stream. If none of -% the tests are \texttt{true} then the \texttt{else code} will be -% left in the input stream. +% associated \meta{code} is left in the input stream. If any of the +% cases are matched, the \meta{true code} is also inserted into the +% input stream (after the code for the appropriate case), while if none +% match then the \meta{false code} is inserted. The function +% \cs{str_case:nn}, which does nothing if there is no match, is also +% available. % \end{function} % -% \begin{function}[added = 2012-06-05, EXP]{\str_case_x:nnn} +% \begin{function}[added = 2013-07-24, EXP, TF]{\str_case_x:nn} % \begin{syntax} % \cs{str_case_x:nnn} \Arg{test string} \\ % ~~|{| \\ @@ -1150,15 +1154,20 @@ % ~~~~\ldots \\ % ~~~~\Arg{string case_n} \Arg{code case_n} \\ % ~~|}| \\ -% ~~\Arg{else code} +% ~~\Arg{true code} +% ~~\Arg{false code} % \end{syntax} % This function compares the full expansion of the \meta{test string} % in turn with the full expansion of the \meta{string cases}. If the two % full expansions are equal (as described for \cs{str_if_eq:nnTF} then the -% associated \meta{code} is left in the input stream. If none of the tests -% are \texttt{true} then the \texttt{else code} will be left in the input -% stream. The \meta{test string} is expanded in each comparison, and must -% always yield the same result: for example, random numbers should +% associated \meta{code} is left in the input stream. If any of the +% cases are matched, the \meta{true code} is also inserted into the +% input stream (after the code for the appropriate case), while if none +% match then the \meta{false code} is inserted. The function +% \cs{str_case_x:nn}, which does nothing if there is no match, is also +% available. +% The \meta{test string} is expanded in each comparison, and must +% always yield the same result: for example, random numbers must % not be used within this string. % \end{function} % @@ -1350,12 +1359,13 @@ % % \begin{function}{\__prg_case_end:nw} % \begin{syntax} -% \cs{__prg_case_end:nw} \Arg{code} \meta{tokens} \cs{q_recursion_stop} +% \cs{__prg_case_end:nw} \Arg{code} \meta{tokens} \cs{q_mark} \Arg{true code} \cs{q_mark} \Arg{false code} \cs{q_stop} % \end{syntax} -% Used to terminate case statements (\cs{int_case:nnn}, \emph{etc.}) +% Used to terminate case statements (\cs{int_case:nnTF}, \emph{etc.}) % by removing trailing \meta{tokens} and the end marker -% \cs{q_recursion_stop}, and inserting the \meta{code} for the successful -% case. +% \cs{q_stop}, inserting the \meta{code} for the successful +% case (if one is found) and either the \texttt{true code} or +% \texttt{false code} for the over all outcome, as appropriate. % \end{function} % % \begin{function}{\__str_if_eq_x_return:nn} @@ -3071,28 +3081,70 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\str_case:nnn, \str_case_x:nnn} +% \begin{macro}[EXP]{\str_case:nn, \str_case_x:nn} +% \begin{macro}[EXP, TF]{\str_case:nn, \str_case_x:nn} +% \begin{macro}[EXP, aux]{\__str_case:nnTF, \__str_case_x:nnTF} % \begin{macro}[int, EXP]{\__prg_case_end:nw} % \begin{macro}[aux, EXP] % {\__str_case:nw, \__str_case_x:nw, \__str_case_end:nw} -% No calculations for strings, otherwise no surprises. -% \begin{macrocode} -\cs_new:Npn \str_case:nnn #1#2#3 +% The aim here is to allow the case statement to be evaluated +% using a known number of expansion steps (two), and without +% needing to use an explicit \enquote{end of recursion} marker. +% That is achieved by using the test input as the final case, +% as this will always be true. The trick is then to tidy up +% the output such that the appropriate case code plus either +% the \texttt{true} or \texttt{false} branch code is inserted. +% \begin{macrocode} +\cs_new:Npn \str_case:nn #1#2 + { + \tex_romannumeral:D + \__str_case:nnTF {#1} {#2} { } { } + } +\cs_new:Npn \str_case:nnT #1#2#3 { \tex_romannumeral:D - \__str_case:nw {#1} #2 {#1} {#3} \q_recursion_stop + \__str_case:nnTF {#1} {#2} {#3} { } } +\cs_new:Npn \str_case:nnF #1#2 + { + \tex_romannumeral:D + \__str_case:nnTF {#1} {#2} { } + } +\cs_new:Npn \str_case:nnTF #1#2 + { + \tex_romannumeral:D + \__str_case:nnTF {#1} {#2} + } +\cs_new:Npn \__str_case:nnTF #1#2#3#4 + { \__str_case:nw {#1} #2 {#1} { } \q_mark {#3} \q_mark {#4} \q_stop } \cs_new:Npn \__str_case:nw #1#2#3 { \str_if_eq:nnTF {#1} {#2} { \__str_case_end:nw {#3} } { \__str_case:nw {#1} } } -\cs_new:Npn \str_case_x:nnn #1#2#3 +\cs_new:Npn \str_case_x:nn #1#2 + { + \tex_romannumeral:D + \__str_case_x:nnTF {#1} {#2} { } { } + } +\cs_new:Npn \str_case_x:nnT #1#2#3 + { + \tex_romannumeral:D + \__str_case_x:nnTF {#1} {#2} {#3} { } + } +\cs_new:Npn \str_case_x:nnF #1#2 + { + \tex_romannumeral:D + \__str_case_x:nnTF {#1} {#2} { } + } +\cs_new:Npn \str_case_x:nnTF #1#2 { \tex_romannumeral:D - \__str_case_x:nw {#1} #2 {#1} {#3} \q_recursion_stop + \__str_case_x:nnTF {#1} {#2} } +\cs_new:Npn \__str_case_x:nnTF #1#2#3#4 + { \__str_case_x:nw {#1} #2 {#1} { } \q_mark {#3} \q_mark {#4} \q_stop } \cs_new:Npn \__str_case_x:nw #1#2#3 { \str_if_eq_x:nnTF {#1} {#2} @@ -3100,15 +3152,26 @@ { \__str_case_x:nw {#1} } } % \end{macrocode} -% Here, |#1| will be the code needed, |#2| will be any remaining case -% or cases, and the \cs{c_zero} stops the \tn{romannumeral}. -% \begin{macrocode} -\cs_new:Npn \__prg_case_end:nw #1#2 \q_recursion_stop { \c_zero #1 } +% To tidy up the recursion, there are two outcomes. If there was a hit to +% one of the cases searched for, then |#1| will be the code to insert, +% |#2| will be the \emph{next} case to check on and |#3| will be all of +% the rest of the cases code. That means that |#4| will be the \texttt{true} +% branch code, and |#5| will be tidy up the spare \cs{q_mark} and the +% \texttt{false} branch. On the other hand, if none of the cases matched +% then we arrive here using the \enquote{termination} case of comparing +% the search with itself. That means that |#1| will be empty, |#2| will be +% the first \cs{q_mark} and so |#4| will be the \texttt{false} code (the +% \texttt{true} code is mopped up by |#3|). +% \begin{macrocode} +\cs_new:Npn \__prg_case_end:nw #1#2#3 \q_mark #4#5 \q_stop + { \c_zero #1 #4 } \cs_new_eq:NN \__str_case_end:nw \__prg_case_end:nw % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % % \subsection{Breaking out of mapping functions} % @@ -3150,117 +3213,11 @@ % % \subsection{Deprecated functions} % -% Deprecated on 2011-05-27, for removal by 2011-08-31. -% -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \cs_gnew_nopar:Npn \cs_new_nopar:Npn -\cs_new_eq:NN \cs_gnew:Npn \cs_new:Npn -\cs_new_eq:NN \cs_gnew_protected_nopar:Npn \cs_new_protected_nopar:Npn -\cs_new_eq:NN \cs_gnew_protected:Npn \cs_new_protected:Npn -\cs_new_eq:NN \cs_gnew_nopar:Npx \cs_new_nopar:Npx -\cs_new_eq:NN \cs_gnew:Npx \cs_new:Npx -\cs_new_eq:NN \cs_gnew_protected_nopar:Npx \cs_new_protected_nopar:Npx -\cs_new_eq:NN \cs_gnew_protected:Npx \cs_new_protected:Npx -\cs_new_eq:NN \cs_gnew_nopar:cpn \cs_new_nopar:cpn -\cs_new_eq:NN \cs_gnew:cpn \cs_new:cpn -\cs_new_eq:NN \cs_gnew_protected_nopar:cpn \cs_new_protected_nopar:cpn -\cs_new_eq:NN \cs_gnew_protected:cpn \cs_new_protected:cpn -\cs_new_eq:NN \cs_gnew_nopar:cpx \cs_new_nopar:cpx -\cs_new_eq:NN \cs_gnew:cpx \cs_new:cpx -\cs_new_eq:NN \cs_gnew_protected_nopar:cpx \cs_new_protected_nopar:cpx -\cs_new_eq:NN \cs_gnew_protected:cpx \cs_new_protected:cpx -% -% \end{macrocode} -% -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \cs_gnew_eq:NN \cs_new_eq:NN -\cs_new_eq:NN \cs_gnew_eq:cN \cs_new_eq:cN -\cs_new_eq:NN \cs_gnew_eq:Nc \cs_new_eq:Nc -\cs_new_eq:NN \cs_gnew_eq:cc \cs_new_eq:cc -% -% \end{macrocode} -% -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \cs_gundefine:N \cs_undefine:N -\cs_new_eq:NN \cs_gundefine:c \cs_undefine:c -% -% \end{macrocode} -% -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \group_execute_after:N \group_insert_after:N -% -% \end{macrocode} -% -% Deprecated 2011-09-06, for removal by 2011-12-31. -% -% \begin{variable} -% { -% \c_pdftex_is_engine_bool, \c_luatex_is_engine_bool, -% \c_xetex_is_engine_bool -% } -% Predicates are better -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \c_luatex_is_engine_bool \luatex_if_engine_p: -\cs_new_eq:NN \c_pdftex_is_engine_bool \pdftex_if_engine_p: -\cs_new_eq:NN \c_xetex_is_engine_bool \xetex_if_engine_p: -% -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP] -% { -% \use_i_after_fi:nw, -% \use_i_after_else:nw, -% \use_i_after_or:nw, -% \use_i_after_orelse:nw -% } -% These functions return the first argument after ending the conditional. -% This is rather specialized, and we want to de-emphasize the use of -% primitive \TeX{} conditionals. -% \begin{macrocode} -%<*deprecated> -\cs_set:Npn \use_i_after_fi:nw #1 \fi: { \fi: #1 } -\cs_set:Npn \use_i_after_else:nw #1 \else: #2 \fi: { \fi: #1 } -\cs_set:Npn \use_i_after_or:nw #1 \or: #2 \fi: { \fi: #1 } -\cs_set:Npn \use_i_after_orelse:nw #1#2#3 \fi: { \fi: #1 } -% -% \end{macrocode} -% \end{macro} -% -% Deprecated 2011-09-07, for removal by 2011-12-31. -% -% \begin{macro}{\cs_set_eq:NwN} -% \begin{macrocode} -%<*deprecated> -\tex_let:D \cs_set_eq:NwN \tex_let:D -% -% \end{macrocode} -% \end{macro} -% -% Deprecated 2012-06-05 for removal after 2012-12-31. -% -% \begin{macro}[pTF, EXP]{\str_if_eq:xx} -% Not really true \texttt{x}-type expansion -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \str_if_eq_p:xx \str_if_eq_x_p:nn -\cs_new_eq:NN \str_if_eq:xxT \str_if_eq_x:nnT -\cs_new_eq:NN \str_if_eq:xxF \str_if_eq_x:nnF -\cs_new_eq:NN \str_if_eq:xxTF \str_if_eq_x:nnTF -% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\chk_if_free_cs:N} +% \begin{macro}{\str_case:nnn, \str_case_x:nnn} +% Deprecated 2013-07-15. % \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \chk_if_free_cs:N \__chk_if_free_cs:N -% +\cs_new_eq:NN \str_case:nnn \str_case:nnF +\cs_new_eq:NN \str_case_x:nnn \str_case_x:nnF % \end{macrocode} % \end{macro} % -- cgit v1.2.3