“可重置”变量

“可重置”变量

我想在个人包中为一些变量(我甚至不知道是否应该称它们为“变量”)定义宏,这些变量可能由用户定义,也可能不由用户定义。到目前为止,我的方法是这样的:

\newcommand\@varname{}
\newcommand\varname[1]{\renewcommand\@varname{#1}}
\newcommand\printvarname{%
  \ifthenelse{\equal{\@varname}{}}{}{\@varname}}

第一个命令定义一个空的\@<varname>;第二个命令提供一个用户级别\<varname>,设置\@<varname>为用户确定的值;第三个命令检查是否\@<varname>已由用户定义,如果是,则打印它。

由于我要设置很多“变量”,我是否可以有一个\NewResettableCommand{<varname>}(其参数可能需要在没有的情况下设置\)来完成上述所有操作?

顺便提一句:我使用\newcommand(而不是)是因为我在创建包之前在文件\providecommand中运行测试。.tex

答案1

就是这个:

\newcommand{\NewResettableCommand}[1]{%
  \expandafter\newcommand\csname @#1\endcsname{}
  \expandafter\newcommand\csname #1\endcsname[1]{%
    \expandafter\renewcommand\csname @#1\endcsname{##1}}
  \expandafter\newcommand\csname print#1\endcsname{%
    \ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}

\NewResettableCommand{varname}

#1只需用名称代替执行所有相同的操作即可。

但是,不清楚为什么要进行“空性”测试:如果内容为空,则扩展\@varname不会产生任何效果。

然而,使用\renewcommand重新定义\@varname实在是太多了:你重新定义它,所以你不必关心它是否已经定义:

\makeatletter % not when the code is in a package
\newcommand{\NewResettableCommand}[1]{%
  \expandafter\newcommand\csname #1\endcsname[1]{\@namedef{@#1}{##1}}
  \@namedef{@#1}{}
  \expandafter\newcommand\csname print#1\endcsname{%
    \ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}
\makeatother % not when the code is in a package

强制性的 LaTeX3 版本:

\RequirePackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\NewResettableCommand}{ m }
  {
   \tl_new:c { l_nrc_#1_tl }
   \cs_new:cpn { #1 } ##1 { \tl_set:cn { l_nrc_#1_tl } { ##1 } }
   \cs_new:cpn { print #1 }
     {
      \tl_if_empty:cF { l_nrc_#1_tl } { \tl_use:c { l_nrc_#1_tl } }
     }
  }
\ExplSyntaxOff

请注意,这里nrc只是一个任意前缀,您可以随意更改(也许将其统一为您用于包的前缀)。

答案2

您可以利用该软件包的优势etoolbox来避免处理expandafter

\documentclass{article}
\usepackage{etoolbox}
\newrobustcmd*\NewResettableCommand[1]{%
 \ifcsundef{#1}
  {%
    \csdef{#1}##1{\csdef{@#1}{##1}}%
    \csdef{print#1}{%
       \ifcsempty{@#1}%
         {\typeout{****#1 is empty****}}%
         {\csuse{@#1}}%
     }%
  }   
  {\typeout{****#1 is defined****}}%
}
\makeatother

\begin{document}
\NewResettableCommand{varname}

\varname{henrique}\printvarname

\varname{}\printvarname
\end{document}

相关内容