将逗号分隔的条目存储在列表中并使用 pgfkeys、pgffor、etoolbox 打印它们

将逗号分隔的条目存储在列表中并使用 pgfkeys、pgffor、etoolbox 打印它们

问题陈述

我想将几个关键字存储在一个列表中,然后打印列表内的所有项目,用逗号分隔,但最后一项也应该用“,和...”分隔。例如,这就是我想要的:

  • 添加“流体”、“计算”和“数值方法”
  • 添加“湍流”
  • 添加“稳定性分析”和“收敛检查”
  • 打印:“流体、计算、数值方法、湍流、稳定性分析和收敛检查”

我的尝试

在浏览了 Stack Exchange 并使用 ChatGPT 之后,我写下了以下内容:

\usepackage{pgfkeys}
\usepackage{pgffor}
\usepackage{etoolbox}

\newcounter{numKeywords}
\def\topicList{}

\newcommand{\addTopic}[1]{%
  \pgfkeys{/topic, #1}%
  \ifx\keyword\empty
    % do nothing
  \else
    \foreach \entry in \keyword {%
      \stepcounter{numKeywords}\listadd\topicList{\entry}
    }
  \fi
}

\pgfkeys{
  /topic/.is family,
  /topic,
  keyword/.store in = \keyword,
}

\newcommand{\printTopics}{%
  \renewcommand{\do}[1]{%
    \ifnumequal{\value{numKeywords}}{1}{%
      and ##1
    }{%
      \addtocounter{numKeywords}{-1}{##1},%
    }
  \dolistloop{\topicList}
}

我的想法是使用 \numKeywords 来计算列表中的关键字数量。然后,当只剩下一个关键字时,除了逗号之外,我还会打印单词“and”。

在主文档中的用法:

\documentclass{article}

% preamble
% ...

\begin{document}

\addTopic{%
  keyword={fluid, computation, numerical methods}
}

\addTopic{%
  keyword={turbulence}
}

\addTopic{%
  keyword={stability analysis, convergence check}
}

\printTopic

\end{document}

这不起作用。我怀疑这是因为以下行中的 \entry 扩展或未扩展:

\stepcounter{numKeywords}\listadd\topicList{\entry}

但我无法排除故障或找出解决方法。有什么想法我应该尝试吗?

谢谢!

答案1

我不会问 ChatGPT,但这并不是因为我已经知道一个更简单的解决方案:机器给出的 LaTeX 答案通常是错误的(或者至少是无用的复杂)。

您可以管理任意数量的列表,并以各种方式处理它们,无需额外的软件包。

\documentclass{article}

\ExplSyntaxOn % enter expl3 programming layer

\NewDocumentCommand{\definelist}{m o}
 {% define lists by name
  \clist_gclear_new:c { g_acat_list_#1_clist }
  \IfValueT { #2 } { \clist_gset:cn { g_acat_list_#1_clist } { #2 } }
 }

\NewDocumentCommand{\addtolist}{m m}
 {
  \clist_gput_right:cn { g_acat_list_#1_clist } { #2 }
 }

\NewExpandableDocumentCommand{\printlist}{m}
 {
  \clist_use:cnnn { g_acat_list_#1_clist } { ~and~ } { ,~ } { ,~and~ }
 }

\NewDocumentCommand{\uselist}{m +m}
 {
  \clist_map_inline:cn { g_acat_list_#1_clist } { #2 }
 }

\ExplSyntaxOff

% initialize the “topics” list with a few items
\definelist{topics}[fluid, computation, numerical methods]

\begin{document}

\addtolist{topics}{turbulence}

\addtolist{topics}{stability analysis,convergence check}

The topics in this paper are \printlist{topics}

The topics in this paper are
\begin{itemize}
\uselist{topics}{\item #1}
\end{itemize}

\end{document}

\printlist只需打印列表(使用连续逗号):参数\clist_use:cnnn

  • 列表名称
  • 如果只有两个项目,则为两个项目之间的分隔符;
  • 项之间的分隔符,除了最后两个(如果有两个以上的话);
  • 如果有多个项目,则为最后两个项目之间的分隔符。

\uselist命令将模板作为其第二个参数,其中当前项用 表示#1

在此处输入图片描述

答案2

一个简单的解决方案。l3 层可以与 PGF 共存,除非您在代码中使用极坐标。这是一个解决方案。花一个下午的时间就可以理解,随着您处理文档的进度,它将为您节省数小时和数天的时间。

%https://tex.stackexchange.com/questions/701345/storing-comma-separated-entries-in-a-list-and-print-them-using-pgfkeys-pgffor
\documentclass{article}
\usepackage{pgfkeys}
\begin{document}
\ExplSyntaxOn
\def\pkgfamilyname{rheza}
\cs_if_exist:NTF \kvset{\ERROR} 
  {
    \pgfkeys{/\pkgfamilyname/.is~family} 
    \def\kvset{\pgfqkeys{/\pkgfamilyname}} 
  }
% Initialize list with some values      
\clist_set:Nn\l_tmpa_clist{keyword1, keyword2, keyword3}
% Define keys
\kvset{list~add/.code =\clist_put_right:Nn\l_tmpa_clist{#1}} 
\kvset{list~print/.code= \clist_use:Nnnn\l_tmpa_clist{,}{,}{~and~}}
% Use a key to add keywords
\kvset{list~add=keyword4}
\kvset{list~add=keyword5}
\clist_use:Nnnn\l_tmpa_clist{,}{,}{~and~}\par
\ExplSyntaxOff
\kvset{list print}
\end{document}

相关内容