如何使用替代命令定义创建新命令?即非替代参数

如何使用替代命令定义创建新命令?即非替代参数

我想要这样的东西:

\newcommand{\MyCommand}{default definition}{definition}

想要这个的背景如下:我正在为不同的客户制作自动报告,并在制作报告时定义各种特定于客户的文本变量。因此,这些文本变量应该在我的 latex 模板文件中定义,例如:

\newcommand{\CustomerName}{LackingCustomerName}{}% 

应在报告中编译为“...LackingCustmerName....”

尽管

\newcommand{\CustomerName}{LackingCustomerName}{Coca Cole Inc.}% 

应在报告中编制为“...Coca Cola Inc....”。

通过在“缺少...名称”形式中包含默认定义,可以在编译的文本中轻松看到哪些文本变量尚未定义。

答案1

定义通用接口

\newcommand{\newcustomer}[2]{%
  \if\relax\detokenize{#2}\relax
    % arg #2 is empty
    \newcommand{#1}{No value for \texttt{\string#1} has been defined}%
  \else
    \newcommand{#1}{#2}%
  \fi}

然后你可以做

\newcustomer{\CustomerNameOne}{}
\newcustomer{\CustomerNameTwo}{ACME Inc.}

将“无值...”更改为您喜欢的值。

为了忽略空格,\newcustomer{\Xyz}{ }您必须“消除空格”。由于您的论证只会产生文本,因此最简单的方法是测量它所占的空间:

\newcommand{\newcustomer}[2]{%
  \sbox0{\ignorespaces#2\unskip}%
  \ifdim\wd0=0pt
    % arg #2 is empty or only spaces
    \newcommand{#1}{No value for \texttt{\string#1} has been defined}%
  \else
    \newcommand{#1}{#2}%
  \fi}

为了仅获取CustomerNameOne(不带反斜杠),你可以说

\newcommand{\newcustomer}[2]{%
  \sbox0{\ignorespaces#2\unskip}%
  \ifdim\wd0=0pt
    % arg #2 is empty or only spaces
    \newcommand{#1}{No value for \getname{#1} has been defined}%
  \else
    \newcommand{#1}{#2}%
  \fi}
\makeatletter
\newcommand\getname[1]{\expandafter\@gobble\string#1}
\makeatother

答案2

您可以将一个值定义为默认值,然后根据需要重新定义它:

\newcommand{\CustomerName}{LackingCustomerName}

% ...
\renewcommand{\CustomerName}{Coca Cole Inc.}

\title但是,对于这样的变量(比较等),通常的方法\author是使用内部宏并让它\CustomerName定义:

\newcommand{\CustomerName}[1]{\def\@CustomerName{#1}}
% Or maybe:
% \newcommand{\CustomerName}[1]{\def\theCustomerName{#1}}
\CustomerName{LackingCustomerName}%  default value

% ...
\CustomerName{Coca Cola Inc}

然后排版客户名称使用:

Customer: \@CustomerName     % if only used internally in your package/class
% or
Customer: \theCustomerName   % if also used directly in the document

答案3

对于您描述的问题,您可以保留正常的定义,但稍后用 覆盖它们\renewcommand。例如,您可以

\newcommand{\CustomerName}{LackingCustomerName}

在你的序言中(可能在不同的文件中)。然后你可以在报告中使用例如“覆盖”变量

\renewcommand{\CustomerName}{Coca Cola Inc.}

不过,我会用不同的方式来做:我只是不定义“默认” \CustomerName...这样,编译器就会因为忘记设置变量而向你尖叫。

您还可以做的是创建所需的所有命令,但将它们设置为如下命令:

\PackageError{Customer Template}{forgot to redefine \CustomerName}{Please overwrite \\CustomerName by using \renewcommand}
\PackageWarning{Customer Template}{forgot to redefine \\CustomerName, boilerplate still in the file}
\PackageInfo{Customer Template}{forgot to redefine \\CustomerName, boilerplate still in the file}

这可能会大大降低忘记重新定义命令的风险,并最终将报告发送给名为“LackingCustomerName”的人

梅威瑟:

\documentclass[11pt]{article}

\newcommand{\CustomerName}{\PackageError{mypack}{blub}{blub}}
\renewcommand{\CustomerName}{Coca Cola Inc.}

\begin{document}
\CustomerName
\end{document} 

相关内容