读取我的命令的参数并在命令中使用它们

读取我的命令的参数并在命令中使用它们

我的问题是关于读取和使用自定义创建的命令的参数\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

添加一个x来查看问题:

\def\SearchForOptimal{%
   \@ifnextchar[%
   {\FoundOptimal}%
   {x\relax}%
}

‘x’ 标记位置

本例中的下一个字符是\而非[。因此,使用“如果为假”条件,x\relax

请注意,该问题与参数的使用无关。尝试

\def\mytestcommand{%
\xdef\MaxMandArgs{2}%
\SearchForOptimal
x
}

以供比较。按照你的\SearchForOptimal写法,它必须是 中的最后一件事\mytestcommand

答案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

在此处输入图片描述

相关内容