如何使 \def 定义的命令表现得像字符串?

如何使 \def 定义的命令表现得像字符串?

我在设计一个复杂的图像嵌入命令时发现了这个问题,从下面代码中定义的各种辅助命令的名称中或许可以猜到这一点:代码的结构也反映了设计的复杂性。\multipicts下面的命令通过使用命令接受可变数量的参数 \forcsvlist。每个参数由一对用花括号括起来的逗号分隔的变量组成。第一个变量是 .jpg、.png、.ps 或 .eps 图像的名称,而第二个变量是定义同一图像的裁剪边距的字符串:这些变量分别作为\showpicname和传递\showcroplims命令传递给\includegraphics命令,方式如下

\includegraphics[width=\linewidth,keepaspectratio,trim=\noexpand\showcroplims, clip]{\noexpand\showpicname}

但是,下面的测试代码并没有做到这一点,它仅限于定义\showpicname\showcroplims

\documentclass[a4paper, 12pt, oneside]{paper} % Preamble

% structure settings
\usepackage{etoolbox}  
\usepackage{ifthen}    
\newcounter{cmdargs}   % Number of variable arguments for user defined commands
\newcounter{argnum}    % index of an argument in a list
\newcommand{\showpicname}{{\picn@me}}    % First parameter of the argument couple to be extracted
\newcommand{\showcroplims}{{\crop@lims}} % Second parameter of the argument couple to be extracted
\pagestyle{empty}

\newcommand*{\argscount}[1]{% 
  \stepcounter{cmdargs}
}

\newcommand*{\xpargs}[1]{% Arguments expander
  \stepcounter{argnum}
  \ifthenelse{\value{argnum}=1}
  {\gdef\picn@me{#1}}  % If the value of argnum is 1 then the parameter parsed is the picture name
  {\gdef\crop@lims{#1}} % Otherwise it is the crop margin string
}

\newcommand*{\addimage}[1]{% Image insertion (via multipicts)
  \setcounter{argnum}{0}
  \forcsvlist{\xpargs}{#1}\\
  The argument is\ \{#1\}:\\
  The parameters of the argument are\ \noexpand{\showpicname}\ and\ \noexpand{\showcroplims}.\\
  \setcounter{argnum}{0}
}

\newcommand{\multipicts}[1]{% Multipicture environment
  \setcounter{cmdargs}{0}
  \forcsvlist{\argscount}{#1} % Count the arguments of invocation
  \forcsvlist{\addimage}{#1}\\% Embed the "image"
  This is a test: the number of iterations done is \arabic{cmdargs}.
}


\begin{document}

\noindent
First call of the macro:\\
\noindent
\multipicts{{a,0.5cm 0.5cm 0.5cm 0.5cm},{b,c},{c,d},{d,e}}\\[2ex]


\noindent
Second call of the macro:\\
\noindent
\multipicts{{2016-05-11_Valvola_intercettazione_lucchettata-low_dim.jpg,0.5cm 0.5cm 0.5cm 0.5cm},{b,c},{c,d},{d,e}}

\end{document}

下图显示了此代码的编译结果 在此处输入图片描述

\pic@name是一个简单的字母字符时,一切似乎都很好,而当它是真正的图片名称时,命令就会中断。下划线“_”似乎被解释为数学模式命令,尽管\noexpand为了避免这种情况而放置了下划线。总之,我的问题是:我怎样才能让这样的命令表现得像简单的字符串?

答案1

我算出了对 egreg 的问题的评论中的建议,即我\detokenize在需要的地方使用了命令:特别地,请注意,我必须使用命令两次,一次是在宏中\pic@name分配的值时,一次是在解析的参数时,以便“停用”这对参数。\gdef\xpargs\addimage

\documentclass[a4paper, 12pt, oneside]{paper}

% Preamble

% structure settings
\usepackage{calc}      % programmer's tools of the trade
\usepackage{etoolbox}  % programmer's tools of the trade, II
\usepackage{ifthen}    % programmer's tools of the trade, III
\newcounter{cmdargs}   % Number of variable arguments for user defined commands
\newcounter{argnum}    % index of an argument in a list
\newcommand{\showpicname}{{\picn@me}}    % First parameter of the argument couple to be extracted
\newcommand{\showcroplims}{{\crop@lims}} % Second parameter of the argument couple to be extracted
\pagestyle{empty}

\newcommand*{\argscount}[1]{% 
  \stepcounter{cmdargs}
}

\newcommand*{\xpargs}[1]{% Arguments expander
  \stepcounter{argnum}
  \ifthenelse{\value{argnum}=1}
  {\gdef\picn@me{\detokenize{#1}}}  % If the value of argnum is 1 then the parameter parsed is the first one
  {\gdef\crop@lims{#1}} % Otherwise it is the second
}

\newcommand*{\addimage}[1]{% Image insertion (via multipicts)
  \setcounter{argnum}{0}
  \forcsvlist{\xpargs}{#1}\\
  The argument is\ \{\detokenize{#1}\}:\\
  The parameters of the argument are \showpicname\ and \showcroplims.\\
  \setcounter{argnum}{0}
}

\newcommand{\multipicts}[1]{% Multipicture environment
  \setcounter{cmdargs}{0}
  \forcsvlist{\argscount}{#1} % Count the arguments of invocation
  \forcsvlist{\addimage}{#1}\\% Embed the "image"
  This is a test: the number of iterations done is \arabic{cmdargs}.
}


\begin{document}

\noindent
First call of the macro:\\
\noindent
\multipicts{{a,0.5cm 0.5cm 0.5cm 0.5cm},{b,c},{c,d},{d,e}}\\[2ex]


\noindent
Second call of the macro:\\
\noindent
\multipicts{{2016-05-11_Valvola_intercettazione_lucchettata-low_dim.jpg,0.5cm 0.5cm 0.5cm 0.5cm},{b,c},{c,d},{d,e}}

\end{document}

这是我运行代码后得到的结果:

在此处输入图片描述

最后,我必须说,现在我完全同意 egreg 的观点:使用 LaTEX 时,更简单的方法是不要使用虚拟程序来测试算法,而是直接尝试。在我看来,这是 LaTEX 命令特殊结构的结果。

相关内容