有没有办法通过数学计算来指定参数?那么,在我的命令定义中,不是写 #3 来指定第三个参数,有没有办法让 #{1+2} 这样的计算来指定第三个参数?我试过了,但没有用,但是有没有类似的东西可以实现这个功能?
答案1
答案2
这并不是您所要求的,但另一种方法是将所有参数存储在类似数组的结构中,然后通过它们的索引检索各个条目。
在以下示例中,\setargs{{<arg1>}{<arg2>}...}
将每个参数存储在全局宏中。当应使用特定值时,您可以使用 获取该值\getarg{<numexpr>}
,其中<numexpr>
可以是数字、计数器或简单的数学表达式。代码不会对索引进行范围检查。
\documentclass{article}
\makeatletter
\newcommand\setargs[1]{%
\begingroup
\count0=1
\setargs@#1{}\@end
\endgroup
}
\def\setargs@#1#2\@end{%
\expandafter\gdef\csname temp@arg@\the\count0\endcsname{#1}%
\advance\count0 by 1
\if\relax\detokenize{#2}\relax\else
\setargs@#2\@end
\fi
}
\newcommand\getarg[1]{%
\csname temp@arg@\the\numexpr#1\endcsname
}
\makeatother
\def\foo#1#2#3{%
\setargs{{#1}{#2}{#3}}%
\getarg{3}%
\getarg{\value{page}}%
\getarg{1+1}%
}
\begin{document}
\foo{a}{b}{c}
\end{document}
答案3
如果有 ε-TeX 扩展可用,或者有其他仅通过扩展来计算数字的包可用,例如包计算或包bigintcalc,你可以这样做:
\def\PassFirstToSecond#1#2{#2{#1}}
\def\varA{4}
\newcount\cntB
\cntB=-1 \relax
\expandafter\def\expandafter\testA\expandafter#\expandafter1%
\expandafter#\expandafter2\expandafter#\expandafter3\expandafter{%
\expandafter#\the\numexpr\varA+\the\cntB
}%
\show\testA
\expandafter\PassFirstToSecond\expandafter{%
\expandafter#\the\numexpr\varA+\the\cntB\relax
}{\def\testB#1#2#3}%
\show\testB
\edef\testC#1#2#3{%
\expandafter#\the\numexpr\varA+\the\cntB\relax
}%
\show\testC
\csname bye\endcsname
\stop
控制台输出是:
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex)
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
> \testA=macro:
#1#2#3->#3.
l.12 \show\testA
?
> \testB=macro:
#1#2#3->#3.
l.17 \show\testB
?
> \testC=macro:
#1#2#3->#3.
l.22 \show\testC
?
)
No pages of output.
Transcript written on test.log.
工作流程如下:
在进行定义之前,将计算出的参数号扩展至定义文本中。
有多种扩展技巧可用于此目的。
当进行“ \expandafter
-hopping”时,你可以将哈希#
视为任何其他标记。
但请注意,当执行内部定义的宏被扩展时,定义中的定义两个哈希会合并为一个,因此在这种情况下“ \expandafter
-hopping”应该是这样的:...\expandafter##\the\numexpr...
。
如果它只是关于对非分隔=括号嵌套的宏参数列表的元素进行排列,可能删除排列列表中单个参数周围的括号,那么我建议使用一些\romannumeral
基于扩展的接口。
我在第二个回答中对此进行了详细阐述。
答案4
这是我承诺的第二个答案
如果它只是关于对非分隔=括号嵌套的宏参数列表的元素进行排列,可能删除排列列表中围绕单个参数的括号,那么我建议使用一些\romannumeral
基于扩展的接口,例如:
\SelectArgsInBraces{⟨list of numbers {N_1}{N_2}..{N_L}⟩}%
{⟨list of undelimited arguments⟩}
→
{⟨list of problematic numbers⟩}%
{%⟨list of selected arguments⟩:
{⟨N_1-th element of the ⟨list of undelimited arguments⟩⟩}%
{⟨N_2-th element of the ⟨list of undelimited arguments⟩⟩}%
...
{⟨N_L-th element of the ⟨list of undelimited arguments⟩⟩}%
}
各自
\SelectArgsWithoutBraces{⟨list of numbers {N_1}{N_2}..{N_L}⟩}%
{⟨list of undelimited arguments⟩}
→
{⟨list of problematic numbers⟩}%
{%⟨list of selected arguments⟩:
⟨N_1-th element of the ⟨list of undelimited arguments⟩⟩%
⟨N_2-th element of the ⟨list of undelimited arguments⟩⟩%
...
⟨N_L-th element of the ⟨list of undelimited arguments⟩⟩%
}
保存了其中第- 个元素不存在的⟨list of problematic numbers⟩
数字的列表。N_P
N_P
⟨list of undelimited arguments⟩
这两个列表可以传递给处理两个参数的宏。这里, 将⟨list of problematic numbers⟩
是第一个参数, 将⟨list of selected arguments⟩
是第二个参数。如果您希望在传递 时忽略有问题的数字⟨list of selected arguments⟩
,则此类宏可以简单地输出其第二个参数。如果该列表不为空,此类宏也可以评估其第一个参数/ ,⟨list of problematic numbers⟩
以传递更详细的错误消息。
例如,
\SelectArgsInBraces{%
% list of numbers {N_1}{N_2}..{N_L}
{4}{1}{3}{23}{4}{15}{17}%
}{%
% list of undelimited arguments:
{one}{two}{three}{four}{five}{six}{seven}{eight}%
{nine}{ten}{eleven}{twelve}{thirteen}{fourteen}{fifteen}%
}%
→
{{23}{17}}{{four}{one}{three}{four}{fifteen}}%
(⟨list of problematic numbers⟩
包含数字 23 和 17,因为⟨list of undelimited arguments⟩
在这种情况下既没有第 23 个元素,也没有第 17 个元素。
各自
\SelectArgsWithoutBraces{%
% list of numbers {N_1}{N_2}..{N_L}
{4}{1}{3}{23}{4}{15}{17}%
}{%
% list of undelimited arguments:
{one }{two }{three }{four }{five }{six }{seven }{eight }%
{nine }{ten }{eleven }{twelve }{thirteen }{fourteen }{fifteen }%
}%
→
{{23}{17}}{four one three four fifteen }%
(⟨list of problematic numbers⟩
包含数字 23 和 17,因为⟨list of K undelimited arguments⟩
在这种情况下既没有第 23 个元素,也没有第 17 个元素。
这样的宏还可以用于从参数列表中排列/乘以/删除参数。
在下面的编码示例中,我以一种在宏扩展期间通过评估数字N_1
、、N_2
..的方式实现了事物。N_L
\number
其优点是:
你可以用任何能扩展为有效 TeX 的表达式来提供数字 -⟨数字⟩-数量。
例如,就 ε-TeX 而言\numexpr
。
例如,就包 intcalc/bigintcalc 的宏而言。
缺点是:
如果这样的表达式不能计算出有效的 TeX-,你就会面临各种难以理解的错误消息。⟨数字⟩-数量。
(在所有情况下,测试都会预测任意的标记序列是否评估为有效的 TeX-⟨数字⟩-数量是不可行的:任意的 token 序列意味着可以执行任意基于扩展的算法。因此,人们面临着停机问题。
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@stopromannumeral, \UD@firstoftwo, \UD@secondoftwo, \UD@exchange,
%% \UD@PassFirstToSecond, \UD@CheckWhetherNull
%%=============================================================================
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\@firstoftwo}%
}%
%%=============================================================================
%% Extract K-th inner undelimited argument:
%%
%% \ExtractKthArgInBraces{<integer K>}%
%% {<tokens in case list of undelimited args doesn't have a k-th argument>}%
%% {<list of undelimited arguments>}
%%
%% In case there is no K-th argument in <list of indelimited arguments> :
%% <tokens in case list of undelimited args doesn't have a k-th argument>
%% In case there is a K-th argument in <list of indelimited arguments> :
%% Does deliver that K-th argument nested in braces.
%% If you leave <tokens in case list of undelimited args doesn't have a k-th argument> empty,
%% then the case of there not being a k-th-argument in the list can be cranked out as then
%% only in case of there not being a k-th-argument nothing/emptiness is returned by
%% \ExtractKthArgInBraces.
%%
%% Examples:
%%
%% \ExtractKthArgInBraces{0}{not available}{ABCDE} yields: not available
%%
%% \ExtractKthArgInBraces{3}{not available}{ABCDE} yields: {C}
%%
%% \ExtractKthArgInBraces{3}{not available}{AB{CD}E} yields: {CD}
%%
%% \ExtractKthArgInBraces{4}{not available}{{001}{002}{003}{004}{005}} yields: {004}
%%
%% \ExtractKthArgInBraces{6}{not available}{{001}{002}{003}} yields: not available
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps/after two "hits" from \expandafter.
%%
%%
%% \ExtractKthArgWithoutBraces{<integer K>}
%% {<tokens in case list of undelimited args doesn't have a k-th argument>}%
%% {<list of undelimited arguments>}
%%
%% In case there is no K-th argument in <list of indelimited arguments> :
%% <tokens in case list of undelimited args doesn't have a k-th argument>
%% In case there is a K-th argument in <list of indelimited arguments> :
%% Does deliver that K-th argument with one level of surrounding braces
%% removed if present.
%%
%% Examples:
%%
%% \ExtractKthArgWithoutBraces{0}{not available}{ABCDE} yields: not available
%%
%% \ExtractKthArgWithoutBraces{3}{not available}{ABCDE} yields: C
%%
%% \ExtractKthArgWithoutBraces{3}{not available}{AB{CD}E} yields: CD
%%
%% \ExtractKthArgWithoutBraces{4}{not available}{{001}{002}{003}{004}{005}} yields: 004
%%
%% \ExtractKthArgWithoutBraces{6}{not available}{{001}{002}{003}} yields: not available
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps/after two "hits" from \expandafter.
%%.............................................................................
\newcommand\ExtractKthArgInBraces[1]{%
% #1: <integer number K>
\romannumeral\expandafter\UD@ExtractKthArgCheck\expandafter{\romannumeral\number\number#1 000}{{}}%
}%
\newcommand\ExtractKthArgWithoutBraces[1]{%
% #1: <integer number K>
\romannumeral\expandafter\UD@ExtractKthArgCheck\expandafter{\romannumeral\number\number#1 000}{}%
}%
\newcommand\UD@ExtractKthArgCheck[4]{%
% #1: In case K is not positive: empty.
% In case K is positive: Letters m whose amount corresponds to
% <integer number K>
% #2: <brace removal indicator; if empty, then one level of braces gets removed>
% #3: <tokens in case list of undelimited args doesn't have a k-th argument>
% #4: <list of undelimited arguments>
\UD@CheckWhetherNull{#1}{%
% K is not positive, thus there is no K-th element.
\UD@stopromannumeral#3%
}{%
% K is positive, thus let's start the loop for removing elements until
% either the list is empty or the (formerly) K-th argument is the first
% argument of the list.
\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}{#2}{#3}{#4}%
}%
}%
\begingroup
\def\UD@ExtractFirstArgLoop#1{%
% #1 is frozen-\relax
\endgroup
\@ifdefinable\UD@RemoveTillFrozenrelax{\long\def\UD@RemoveTillFrozenrelax##1##2#1{{##1}}}%
\newcommand\UD@ExtractFirstArgWithoutBraces[1]{\romannumeral\UD@ExtractFirstArgLoop{##1#1}{}}%
\newcommand\UD@ExtractFirstArgInBraces[1]{\romannumeral\UD@ExtractFirstArgLoop{##1#1}{{}}}%
\newcommand\UD@ExtractKthArgLoop[4]{%
% ##1: Letters m
% ##2: <brace removal indicator; if empty, then one level of braces gets removed>
% ##3: <tokens in case list of undelimited args doesn't have a k-th argument>
% ##4: <list of undelimited arguments>
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo##4{}{}}{%
% The remaining <list of undelimited arguments> is blank, i.e. empty or
% only holding spaces, thus there is no K-th argument in that list.
\UD@stopromannumeral##3%
}{%
\UD@CheckWhetherNull{##1}{%
% There are no letters "m" left, thus the now first argument of the
% remaining <list of undelimited arguments> is the (formerly) K-th
% argument to extract, thus let's now start the loop for removing the
% elements behind it while keeping it:
\UD@ExtractFirstArgLoop{##4#1}{##2}%
}{%
% There are still letters "m" in #1, thus you still need to remove
% elements both from the remaining <list of undelimited arguments> and
% from the list of letters "m":
\expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}##4}%
{\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}##1}{##2}{##3}}%
}%
}%
}%
}%
\expandafter\expandafter\expandafter\UD@ExtractFirstArgLoop
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}%
%% Usage of frozen-\relax as delimiter is for speeding things up by reducing the
%% amount of iterations needed. I chose frozen-\relax because David Carlisle
%% pointed out in <https://tex.stackexchange.com/a/578877>
%% that frozen-\relax cannot be (re)defined in terms of \outer and cannot be
%% affected by \uppercase/\lowercase.
%%
%% \UD@ExtractFirstArg's argument may contain frozen-\relax:
%% The only effect is that internally more iterations are needed for
%% obtaining the result.
\newcommand\UD@ExtractFirstArgLoop[2]{%
% \UD@ExtractFirstArgLoop with each element of a list of frozen-\relax-
% delimited list splits the first undelimited component, keeps it, nested
% in curly braces (which implies that in the next removal-iteration it will
% again be the first component), and throws away the remainder and the
% frozen-\relax-Delimiter. As it is ensured that at the beginning of the loop
% the list has a trailing frozen-\relax, at some stage, when all
% frozen-\relax-elements were processed, only the very first undelimited
% component of the list remains.
% This way using frozen-\relax is not forbidden to the user if s/he insists in
% doing so.
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{%
\UD@CheckWhetherNull{#2}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo#1{}%
}{\UD@stopromannumeral#1}%
}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillFrozenrelax#1}{#2}}%
}%
%% End of code for \ExtractKthArgInBraces/\ExtractKthArgWithoutBraces.
%%=============================================================================
%% Select several arguments from a list of undelimited arguments:
%%
%% \SelectArgsInBraces{<list of numbers {N_1}..{N_L}>}%
%% {<list of undelimited arguments>}%
%% yields:
%% {<list of problematic elements>}%
%% {% <list of selected elements>:
%% {N_1-th element of <list of undelimited arguments>}%
%% ..
%% {N_L-th element of <list of undelimited arguments>}%
%% }%
%% , each element nested in braces.
%%
%% \SelectArgsWithoutBraces{<list of numbers {N_1}..{N_L}>}%
%% {<list of undelimited arguments>}%
%% yields:
%% {<list of problematic elements>}%
%% {% <list of selected elements>:
%% N_1-th element of <list of undelimited arguments>%
%% ..
%% N_L-th element of <list of undelimited arguments>%
%% }%
%% , each element without outermost surrounding braces if previously present.
%%
%% Elements can be selected several times.
%% Usually the <list of problematic elements> should be empty.
%% In case some number N_P denotes an element which the list does not have,
%% that number N_P is in the <list of problematic elements>. Duplicates in
%% that list are not checked.
%% If the <list of selected elements> is empty, this means that the
%% <list of numbers {N_1}..{N_L}> did not denote elements which the
%% <list of undelimited arguments> does have.
%%
%% \SelectArgsInBraces/\SelectArgsWithoutBraces forms a tail-recursive loop
%% for calling \ExtractKthArgInBraces.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps/after two "hits" from \expandafter.
%%.............................................................................
\newcommand\SelectArgsInBraces[2]{%
% #1 = <list of numbers N_1..N_L>
% #2 = <list of undelimited arguments>
\romannumeral\InnerSelectArgs{}{}{#1}{#2}{{}}%
}%
\newcommand\SelectArgsWithoutBraces[2]{%
% #1 = <list of numbers N_1..N_L>
% #2 = <list of undelimited arguments>
\romannumeral\InnerSelectArgs{}{}{#1}{#2}{}%
}%
%%-----------------------------------------------------------------------------
%% \InnerSelectArgs{<list of problematic numbers>}%
%% {<list of selected arguments>}%
%% {<list of numbers {N_1}..{N_L}>}%
%% {<list of undelimited arguments>}%
%% {<brace-nesting-indicator;
%% if empty, then elements shall not be surrounded by braces>}%
%%.............................................................................
\newcommand\InnerSelectArgs[5]{%
%% #1 = <list of problematic elements>
%% #2 = <list of selected arguments>
%% #3 = <list of numbers {N_1}..{N_L}>
%% #4 = <list of undelimited arguments>
%% #5 = <brace-nesting-indicator;
%% if empty, then elements shall not be surrounded by braces>}%
\expandafter\UD@CheckWhetherNull
\expandafter{\UD@firstoftwo#3{}{}}{\UD@stopromannumeral{#1}{#2}}{%
\expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}#3}{%
\expandafter\UD@CheckWhetherNull\expandafter{%
\romannumeral
\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter\expandafter
\UD@stopromannumeral
\expandafter\expandafter\expandafter\ExtractKthArgInBraces
\UD@ExtractFirstArgInBraces{#3}{}{#4}%
}{%
\UD@PassFirstToSecond{#2}{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\UD@ExtractFirstArgInBraces{#3}{\UD@stopromannumeral#1}%
}{\InnerSelectArgs}%
}%
}{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral
\UD@CheckWhetherNull{#5}{\expandafter\UD@exchange}%
{\expandafter\UD@PassFirstToSecond}%
\romannumeral
\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter\expandafter
\UD@stopromannumeral
\expandafter\expandafter\expandafter\ExtractKthArgInBraces
\UD@ExtractFirstArgInBraces{#3}{}{#4}{\UD@stopromannumeral#2}%
}{%
\UD@PassFirstToSecond{#1}{\InnerSelectArgs}%
}%
}%
}{#4}{#5}%
}%
}%
%%=============================================================================
%%=============================================================================
%% Error-message in case the <list of numbers {N_1}..{N_L}> denotes elements
%% which the <list of undelimited arguments> does not have:
%%.............................................................................
%% \UD@InvalidArgSpecifiersError{<name of command which triggers the
%% error-message>}%
%% {<list of problematic elements>}%
%% {<syntax descriptor of argument that holds
%% <list of undelimited arguments> >}%
%% {<syntax descriptor of argument that holds
%% <list of numbers {N_1}..{N_L}> >}%
%% <syntax descriptor of...> is to hold a phrase like fifth non-optional".
\newcommand\UD@InvalidArgSpecifiersError[4]{%
\begingroup
\toks@{#2}%
\GenericError{%
\@backslashchar#1\space\@spaces
}{%
\@backslashchar#1-error\on@line:\MessageBreak
Invalid arguments `\the\toks@' specified%
}{%
See the comments of this file for explanation.%
}{%
The #3 argument of \@backslashchar#1 holds a list of%
\MessageBreak
non-delimited arguments whereof elements can be selected via the%
\MessageBreak
number-list in the #4 argument.%
\MessageBreak
Seems the number-list in the #4 argument denotes%
\MessageBreak
arguments which the list in the #3 argument does not have.%
}%
\endgroup
}%
%%=============================================================================
%% Now for the sake of having fun a user-level-macro where you can specify
%% a <list of numbers {N_1}..{N_L}> and a <list of undelimited arguments>
%% and which throws an error-message in case <list of numbers {N_1}..{N_L}>
%% denotes arguments which the <list of undelimited arguments> does not
%% have and which defines the macro `\tempa` to expand to the resulting
%% <list of selected arguments> and which then displays the meaning
%% of \tempa:
\newcommand\ShowBracedSelection[2]{%
\expandafter\expandafter\expandafter\ShowSelection
\SelectArgsInBraces{#1}{#2}{ShowBracedSelection}%
}%
\newcommand\ShowNonBracedSelection[2]{%
\expandafter\expandafter\expandafter\ShowSelection
\SelectArgsWithoutBraces{#1}{#2}{ShowNonBracedSelection}%
}%
\newcommand\ShowSelection[3]{%
\UD@CheckWhetherNull{#1}{}{%
\UD@InvalidArgSpecifiersError{#3}{#1}%
{second non-delimited}%
{first non-delimited}%
}%
\begingroup
\toks@{#2}%
\edef\tempa{\the\toks@}%
\texttt{\string\tempa: \meaning\tempa}%
\endgroup
}%
%%=============================================================================
%% Now a helper-macro for the test-suite:
\newcommand\performtest[1]{%
\begingroup
\toks@\expandafter\expandafter\expandafter{#1}%
\edef\tempa{\the\toks@}%
\texttt{\expandafter\strip@prefix\meaning\tempa}%
\endgroup
}%
\makeatother
\documentclass[landscape]{article}
\expandafter\ifx\csname pdfpagewidth\endcsname\relax\else\pdfpagewidth=\paperwidth\fi
\expandafter\ifx\csname pagewidth\endcsname\relax\else\pagewidth=\paperwidth\fi
\expandafter\ifx\csname pdfpageheight\endcsname\relax\else\pdfpageheight=\paperheight\fi
\expandafter\ifx\csname pageheight\endcsname\relax\else\pageheight=\paperheight\fi
\oddsidemargin=1cm %
\textwidth=\paperwidth
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in %
\advance\oddsidemargin-\hoffset %
\evensidemargin=\oddsidemargin
\topmargin=1cm %
\textheight=\paperheight
\advance\paperheight-2\topmargin
\advance\topmargin-1in %
\advance\topmargin-\voffset
\headheight=0ex %
\headsep=0ex %
\footnotesep=.66cm %
\pagestyle{empty}%
\parindent=0ex %
\frenchspacing
\begin{document}
\verb|\ExtractKthArgWithoutBraces{-1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{-1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{0}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{0}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{2}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{2}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{3}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{3}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{4}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{4}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{12}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{12}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgWithoutBraces{14}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgWithoutBraces{14}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\verb|\ExtractKthArgInBraces{-1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{-1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{0}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{0}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{1}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{2}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{2}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{3}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{3}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{4}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{4}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{12}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{12}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}\\
\verb|\ExtractKthArgInBraces{14}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\ExtractKthArgInBraces{14}{not available}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\verb|\SelectArgsInBraces{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\SelectArgsInBraces{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}%
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\verb|\SelectArgsWithoutBraces{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\performtest{\SelectArgsWithoutBraces{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}}%
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\verb|\ShowBracedSelection{{1}{7}{5}{5}{5}{12}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\ShowBracedSelection{{1}{7}{5}{5}{5}{12}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\verb|\ShowNonBracedSelection{{1}{7}{5}{5}{5}{12}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\ShowNonBracedSelection{{1}{7}{5}{5}{5}{12}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\message{^^JThe next test is expected to throw an error message.%
^^JSo don't be frightened.%
^^JPress return to continue.}\immediate\read-1to\tempa
\verb|\ShowBracedSelection{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\ShowBracedSelection{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
\message{^^JThe next test is expected to throw an error message.%
^^JSo don't be frightened.%
^^JPress return to continue.}\immediate\read-1to\tempa
\verb|\ShowNonBracedSelection{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}|:
\ShowNonBracedSelection{{-1}{0}{1}{7}{5}{5}{5}{12}{14}}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
Permute some arguments without brace-removal :
\verb|\ShowBracedSelection{{2}{7}{4}{1}{6}{3}{5}}{{one}{two}{three}{four}{five}{six}{seven}}|:
\ShowBracedSelection{{2}{7}{4}{1}{6}{3}{5}}{{one}{two}{three}{four}{five}{six}{seven}}
\hrulefill\vspace*{-\dp\strutbox}\vspace*{\ht\strutbox}%
Permute some arguments with brace-removal :
\verb|\ShowNonBracedSelection{{2}{7}{4}{1}{6}{3}{5}}{{one}{two}{three}{four}{five}{six}{seven}}|:
\ShowNonBracedSelection{{2}{7}{4}{1}{6}{3}{5}}{{one}{two}{three}{four}{five}{six}{seven}}
\end{document}
%% AUTHOR
%%
%% Ulrich W. Diez ([email protected])
%%
%% LICENCE AND COPYRIGHT
%%
%% Copyright (C) 2019 - 2022 by Ulrich W. Diez ([email protected])
%%..............................................................................
%% This work may be distributed and/or modified under the conditions of the
%% LaTeX Project Public Licence (LPPL), either version 1.3 of this license or
%% (at your option) any later version.
%% (The latest version of this license is in:
%% http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 1999/12/01 or later.)
%% The author of this work is Ulrich Diez.
%% This work has the LPPL maintenance status 'not maintained'.
%% Usage of any/every component of this work is at your own risk.
%% There is no warranty - neither for probably included documentation nor for
%% any other part/component of this work.
%% If something breaks, you usually may keep the pieces.
%%//////////////////////////////////////////////////////////////////////////////
此示例的 pdf 输出为:
此示例的控制台输出为: