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