我正在嘗試建立 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}