我的问题是关于读取和使用自定义创建的命令的参数\def
。
假设我有命令\mytestcommand
,并且我想读取和使用它的参数(可选和强制的未知数字)
我有代码:
\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\newcounter{NumOptionalArgFound}
\newcounter{NumMandatoryArgFound}
\xdef\MaxMandArgs{3}
\makeatletter
\def\SearchForOptional{%
\@ifnextchar[%
{\FoundOptional}
{\relax}
}
\def\FoundOptional[#1]{%
\stepcounter{NumOptionalArgFound}%
\xdef\curOptArg{#1}%
\global\expandafter\let\csname OptionalArgument\arabic{NumOptionalArgFound}\endcsname\curOptArg%
\@ifnextchar[%
{\FoundOptional}
{\SearchForMandatory}
}
\def\SearchForMandatory{%
\@ifnextchar\bgroup%
{\CheckIfMandatory}
{\relax}
}
\def\CheckIfMandatory#1{%
\ifnum\pdf@strcmp{#1}{\bgroup}=0%
#1%
\else
\ifnum\arabic{NumMandatoryArgFound}<\MaxMandArgs%
\stepcounter{NumMandatoryArgFound}%
\xdef\curManArg{#1}%
\global\expandafter\let\csname MandatoryArgument\arabic{NumMandatoryArgFound}\endcsname\curManArg%
\expandafter\expandafter\expandafter\SearchForMandatory%
\else
#1%
\fi
\fi
}
\makeatother
\def\mytestcommand{
\xdef\MaxMandArgs{2}
\SearchForOptional
}
\def\printArgs{
\foreach \i in {1,...,\theNumOptionalArgFound}{
Opt Arg \i: \csname OptionalArgument\i\endcsname\par
}
\foreach \i in {1,...,\theNumMandatoryArgFound}{
Mand Arg \i: \csname MandatoryArgument\i\endcsname\par
}
}
\begin{document}
\mytestcommand[Optional 1][Optional Second]{first Mand}{second Mand}{thirdMand}\bgroup noMand \egroup
\printArgs
\end{document}
此代码运行良好,并查找并保存了 ot 的可选和强制参数。我的问题是,如果我尝试使用定义中的计数器或参数之一,则\mytestcommand
无法找到数字或参数。
更具体地说,我想在定义\printArgs
中使用命令\mytestcommand
......(这样我就可以知道我能够使用命令定义中的参数)。
\mytestcommand
如果我将的定义更改为:就会出现问题:
\def\mytestcommand{
\xdef\MaxMandArgs{2}
\SearchForOptional
\printArgs
}
谢谢=谢谢
附言:我正在寻找 LaTeX2e 解决方案,但 LaTeX3 可能对其他用户有帮助...我不想使用我知道存在用于此类工作的软件包,但如果可能的话,像我这样的“主要” LaTeX 命令...
答案1
答案2
像这样。
\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\newcounter{NumOptionalArgFound}
\newcounter{NumMandatoryArgFound}
\newcommand\MaxMandArgs{3}% default value
\makeatletter
\newcommand\SearchForArguments {%
\setcounter{NumOptionalArgFound}{0}%
\setcounter{NumMandatoryArgFound}{0}%
\@SearchForOptional
}
% fetching optional arguments
\newcommand\@SearchForOptional{%
\kernel@ifnextchar[\@FoundOptional\@SearchForMandatory
}
\def\@FoundOptional[#1]{%
\stepcounter{NumOptionalArgFound}%
\global\@namedef{OptionalArgument\arabic{NumOptionalArgFound}}{#1}%
\@SearchForOptional
}
% fetching mandatory arguments
% I do not quite understand this \bgroup business but aiming
% to be close to OP. It actually complicates things a lot because
% one can not use a \futurelet to distinguish \bgroup from {
\newcommand\@SearchForMandatory[1]{%
\edef\@tempKola{\detokenize{#1}}%
\edef\@tempKolb{\detokenize{\bgroup}}%
\ifx\@tempKola\@tempKolb
\expandafter\@firstofone
\else
\ifnum\value{NumMandatoryArgFound}<\MaxMandArgs %<- must leave a space
\stepcounter{NumMandatoryArgFound}%
\expandafter\expandafter\expandafter\@GetMandatoryAndGoOn
\else
\expandafter\expandafter\expandafter\@firstofone
\fi
\fi {#1}%
}
\newcommand\@GetMandatoryAndGoOn[1]{%
\global\@namedef{MandatoryArgument\arabic{NumMandatoryArgFound}}{#1}%
\@SearchForMandatory
}
\makeatother
\newcommand\printArgs{{\color{blue}%
Value of MaxMandArgs: \MaxMandArgs
\ifnum\value{NumOptionalArgFound}>0
\foreach \i in {1,...,\theNumOptionalArgFound}{%
Opt Arg \i: \csname OptionalArgument\i\endcsname\par
}\fi
\ifnum\value{NumMandatoryArgFound}>0
\foreach \i in {1,...,\theNumMandatoryArgFound}{%
Mand Arg \i: \csname MandatoryArgument\i\endcsname\par
}\fi
}}
\newcommand\mytestcommand[1]{\gdef\MaxMandArgs{#1}\SearchForArguments}
\begin{document}
\mytestcommand{2}[Optional 1][Optional Second]{first Mand}{second Mand}{third Mand}\bgroup noMand \egroup
\printArgs
\mytestcommand{3}[O1][O2][O3][O4]{M1}{M2}{M3}{M4}{M5}\bgroup STOP\egroup
\printArgs
\end{document}
黑色部分是未被视为事物的一部分。
可以修改上面的宏以不吞掉它标识为可选或强制的参数。
xparse
这里似乎指出了一个名为的强大软件包。
与
\mytestcommand{6}[O1][O2][O3][O4]{M1}{M2}{M3}{M4}{M5}\bgroup STOP\egroup
\printArgs