我正在尝试创建一个 Latex 文档,在该文档中我在开头定义一个项目列表(例如水果),以便根据我定义的项目数量更改文档的生成文本/外观。
因此我定义了一个\newcommand{\length}
用于计算物品(水果)数量并“返回”该数量的函数。
这个最小(非)工作示例应该可以说明我想要实现的目标:
\documentclass{article}
\makeatletter
\newcounter{numlength}%
\newcommand{\length}[1]{%
\setcounter{numlength}{0}%
\@for\element:=#1\do{\stepcounter{numlength}}%
\value{numlength}% Variant 1
% \arabic{numlength}% Variant 2
% \thenumlength% Variant 3
}
\makeatother
\def\fruits{apple,banana,mango}
\begin{document}
\section{Fruits}
Number of fruits: \length{\fruits}
\\There \ifnum\length{\fruits}=1 is just a single fruit\else are multiple fruits\fi on my list:
\\\fruits
\end{document}
在我的文本()中打印数字Number of fruits: \length{\fruits}
仅适用于变体 2 和 3(我理解),但无论我使用哪种变体,使用中的数字\ifnum
都不起作用。
需要明确的是:我对打印物品(水果)本身的好方法不感兴趣;我主要关心的是在\newcommand{\length}
某种\ifnum
条件下使用我“计算”的数字。
此外,如果可能的话,我不想使用任何包(\usepackage
)。
如果您需要更多信息,请告诉我,提前谢谢您!
答案1
正如@DavidCarlisle 在他的评论中指出的那样,如果您想在 TeX 需要数字的地方使用宏,那么在 TeX 中您需要可扩展,因此您不能使用赋值。
有两种方法可以解决您的问题:
先完成作业,然后将结果用于你的
\ifnum
。使用可扩展函数来计算水果的数量。
下面使用 L3 中的函数/宏来执行后者:
\documentclass{article}
\ExplSyntaxOn
\cs_generate_variant:Nn \clist_count:n { V }
\cs_new_eq:NN \length \clist_count:V
\ExplSyntaxOff
\newcommand*\fruits{apple,banana,mango}
\begin{document}
\section{Fruits}
Number of fruits: \length{\fruits}
\\There \ifnum\length{\fruits}=1 is just a single fruit\else are multiple fruits\fi on my list:
\\\fruits
\end{document}
技术信息,您可能希望忽略这一点并简单地使用上述内容:
与我的评论不同,这个答案中的代码使用了一个V
变体,因为你的\fruit
没有设置 clist
L3 的其中一个函数,所以这在语义上应该更干净,因为V
将执行正确结果所必需的清理步骤,与不同N
。
第一种方法:
为了使第一种方法有效,您不需要对实际代码进行太多更改。您只需删除直接输出,然后在第二步中使用计数器的值numlength
:
\documentclass{article}
\makeatletter
\newcounter{numlength}%
\newcommand{\length}[1]{%
\setcounter{numlength}{0}%
\@for\element:=#1\do{\stepcounter{numlength}}%
}
\makeatother
\def\fruits{apple,banana,mango}
\begin{document}
\section{Fruits}
Number of fruits: \length{\fruits}\arabic{numlength}
\\There \length\fruits\ifnum\value{numlength}=1 is just a single fruit\else are multiple fruits\fi on my list:
\\\fruits
\end{document}
(输出如上)
答案2
正如其他人已经解释的那样,您首先必须将长度存储在宏中,然后使用\ifnum
。 但该方法很麻烦,而且本身不可扩展。
我建议一种不需要的方法\def
,这样您就不会冒险破坏现有命令(并“发明”新的命令)。
您还可以向列表添加内容,并根据元素数量进行更复杂的分支。列表应该是非空的。
请注意,它\branchonlist
是完全可扩展的。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\definelist}{mm}
{
\clist_clear_new:c { l_lennart_list_#1_clist }
\clist_set:cn { l_lennart_list_#1_clist } { #2 }
}
\NewDocumentCommand{\appendtolist}{mm}
{
\clist_put_right:cn { l_lennart_list_#1_clist } { #2 }
}
\NewExpandableDocumentCommand{\listlength}{m}
{
\clist_count:c { l_lennart_list_#1_clist }
}
\NewExpandableDocumentCommand{\branchonlist}{mmm}
{% #1 = list name, #2 = cases, #3 = no match
\int_case:nnF { \clist_count:c { l_lennart_list_#1_clist } } { #2 } { #3 }
}
\ExplSyntaxOff
\definelist{fruits}{apple,mango,banana}
\definelist{animals}{gnu,gnat}
\definelist{letters}{a}
\begin{document}
Number of fruits: \listlength{fruits}
\branchonlist{fruits}{
{1}{There is just a single fruit}
}{There are multiple fruits}
\bigskip
Number of animals: \listlength{animals}
\branchonlist{animals}{
{1}{There is just a single animal}
{2}{There are two animals}
}{There are multiple animals}
\bigskip
Number of letters: \listlength{letters}
\branchonlist{letters}{
{1}{There is just a single letter}
{2}{There are two letters}
{3}{There are three letters}
}{There are multiple letters}
\bigskip
\appendtolist{letters}{b}
Number of letters: \listlength{letters}
\branchonlist{letters}{
{1}{There is just a single letter}
{2}{There are two letters}
{3}{There are three letters}
}{There are multiple letters}
\bigskip
\appendtolist{letters}{c}
Number of letters: \listlength{letters}
\branchonlist{letters}{
{1}{There is just a single letter}
{2}{There are two letters}
{3}{There are three letters}
}{There are multiple letters}
\bigskip
\appendtolist{letters}{d}
Number of letters: \listlength{letters}
\branchonlist{letters}{
{1}{There is just a single letter}
{2}{There are two letters}
{3}{There are three letters}
}{There are multiple letters}
\end{document}