ifnum で新しいコマンドの数値を使用する

ifnum で新しいコマンドの数値を使用する

定義したアイテムの数に応じてドキュメントの結果のテキストや外観を変更するために、最初にアイテムのリスト (果物など) を定義する 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 では数値が期待される場所でマクロを使用する場合は拡張可能である必要があり、そのため代入は使用できません。

問題を解決するには 2 つの方法があります。

  1. 最初のステップで課題を実行し、その結果を に使用します\ifnum

  2. 拡張機能で果物の数を数えます。

以下は、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}

ここに画像の説明を入力してください


技術的な情報なので、これを無視して上記のものをそのまま使用することもできます。

私のコメントとは異なり、この回答のコードではバリアントが使用されています。 は L3 の -functions の1 つで設定されていない Vため、とは異なり、 は正しい結果を得るために必要なサニタイズ手順を実行するため、意味的にはよりクリーンなはずです。\fruitclistVN


最初のアプローチでは:

最初のアプローチを機能させるには、実際のコードからそれほど多くの変更を加える必要はありません。直接出力を削除し、代わりに 2 番目のステップでカウンターの値を使用するだけです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}

ここに画像の説明を入力してください

関連情報