我对 LaTeX 还很陌生,而且我是一名软件工程师,所以请耐心等待。
我正在尝试创建可以通过使用某些命令生成的项目列表以添加到该列表中,但我不知道如何做到这一点。
本质上我希望能够做这样的事情......
\def\list{}
\newcommand{\createlist}{
\begin{description}
\list{}
\end{description}
}
\newcommand{\addtolist}[2]{
\edef\list{\list{}\item[#1]{#2}}
%\edef\list{\list{}#1 - #2}
}
\addtolist{Thing 1}{blah blah blah}
\addtolist{Thing 2}{other thing}
\createlist{}
如果我使用注释掉的 \edef,此代码将编译并运行,但我还想生成 \item 标签,但这不起作用并导致崩溃。有没有合适的方法来实现这一点?
作为一名程序员,我的本能是创建一个数组并将每一行新内容推入其中,以便可以循环并打印到环境内的项目中,但我就是无法弄清楚这一点。
答案1
OP 代码的第一个大问题是重新定义\list
,这是用于制作各种列表(例如description
环境)的广泛使用的代码。哎呀。所以我将其重命名为\llist
,以便保持列表制作的\list
完整性。
然后,我还使用\g@addto@macro
而不是来\edef
构建列表项,因为我觉得这是一种更安全的方法。
\documentclass{article}
\begin{document}
\newcommand\llist{}
\newcommand{\createlist}{
\begin{description}
\llist{}
\end{description}
}
\makeatletter
\newcommand{\addtolist}[2]{
\g@addto@macro\llist{\item[#1]{#2}}
}
\addtolist{Thing 1}{blah blah blah}
\addtolist{Thing 2}{other thing}
\createlist{}
\end{document}
答案2
以下代码是否提供了您想要的内容?
\RequirePackage{xparse}
\documentclass{article}
\newcommand\ItemContainer{}%
\NewDocumentCommand\ResetItemContainer{}{%
\gdef\ItemContainer{}%
}%
\makeatletter
\newcommand\AddtoItemContainer[2][]{%
\@bsphack
% use \xdef .. \unexpanded to avoid hash-reducing within \ItemContainer's definition.
\xdef\ItemContainer{%
\unexpanded\expandafter{\ItemContainer\item}\IfNoValueF{#1}{\unexpanded{[{#1}]}}\unexpanded{#2}%
}%
% \@esphack should be safe as -afaik - \edef doesn't affect \lastskip.
\@esphack
}%
\makeatother
\NewDocumentCommand\PrintItemContainer{}{%
\begin{description}\ItemContainer\end{description}%
}%
\newcounter{ThingCounter}
\begin{document}
\ResetItemContainer
\AddtoItemContainer[\refstepcounter{ThingCounter}Thing~\theThingCounter]{thing}%
\AddtoItemContainer[\refstepcounter{ThingCounter}Thing~\theThingCounter]{other thing}%
\AddtoItemContainer[\refstepcounter{ThingCounter}Thing~\theThingCounter]{yet another thing}%
\PrintItemContainer
\end{document}
答案3
使用 非常容易expl3
,它自 2020-10-01 起包含在 LaTeX 内核中(如果您有早期版本,则需要添加\usepackage{xparse}
)。
\documentclass{article}
\ExplSyntaxOn
\seq_new:N \l_srour_list_seq
\NewDocumentCommand{\addtolist}{mm}
{
\seq_put_right:Nn \l_srour_list_seq { \item[#1] #2 }
}
\NewDocumentCommand{\uselist}{}
{
\begin{description}
\seq_use:Nn \l_srour_list_seq { }
\end{description}
}
\ExplSyntaxOff
\begin{document}
\addtolist{Thing 1}{blah blah blah}
\addtolist{Thing 2}{other thing}
\uselist
\end{document}
这将遵循标准作用域规则。如果您需要\addtolist
在环境内进行分配,则它们必须是全局的。将代码更改为
\documentclass{article}
\ExplSyntaxOn
\seq_new:N \g_srour_list_seq
\NewDocumentCommand{\addtolist}{mm}
{
\seq_gput_right:Nn \g_srour_list_seq { \item[#1] #2 }
}
\NewDocumentCommand{\uselist}{}
{
\begin{description}
\seq_use:Nn \g_srour_list_seq { }
\end{description}
}
\ExplSyntaxOff
\begin{document}
\addtolist{Thing 1}{blah blah blah}
\addtolist{Thing 2}{other thing}
\uselist
\end{document}
这些项目被添加到一个序列变量中,您可以随时使用该变量。第二个参数\seq_use:Nn
指定应在序列项目之间插入的内容,在本例中为空。