是否有可能在 Latex 中动态生成列表?

是否有可能在 Latex 中动态生成列表?

如上所述,我想知道是否有可能动态地将项目添加到列表中并将其打印在文档的任何位置,而不管定义在哪里。

我在想这样的事情:

\documentclass[a4paper,12pt]{article}
\defineList{MyListName}
\begin{document}
\begin{itemize}
\printlist{MyListName}
\end{itemize}
Lorem ipsum dolor sit amet...
\addToList{MyListName}{\item First}
\addToList{MyListName}{\item Second}
\end{document}

然后就会得到类似这样的结果(本质上,\printlist{MyListName}仅仅充当一个宏,并被列表的内容所取代):

“Lorem ipsum”段落前面的项目符号列表。

当然,如果能够迭代列表项就更加优雅了,但它可能会引入太多的复杂性。

答案1

需要两次通过。根据我的回答提取 LaTex 文档的结构,包括注释,但调整语法以满足 OP 的需求。

可以同时激活多个列表。这里,在 MWE 中,我创建了“xyz”和“pdq”列表。

\documentclass{article}
\let\svaddtocontents\addtocontents
\makeatletter
\newcommand\defineList[1]{%
 \expandafter\def\csname add#1line\endcsname##1##2##3{\addtocontents {##1}{%
  \protect \csname #1line\endcsname {##2}{##3}}}
 \expandafter\def\csname write#1\endcsname{%
  \renewcommand\addtocontents[2]{\relax}%
  \setcounter{section}{0}\noindent%
  \expandafter\def\csname #1line\endcsname####1####2{\expandafter\csname####1\endcsname{####2}}%
  \@starttoc{#1}%
  \setcounter{section}{0}%
  \let\addtocontents\svaddtocontents%
 }%
 \csname add#1line\endcsname{#1}{begin}{itemize}%
 \AtEndDocument{\csname add#1line\endcsname{#1}{end}{itemize}}
}
\newcommand\addToList[2]{\csname add#1line\endcsname{#1}{item}{#2}}
\newcommand\printList[1]{\csname write#1\endcsname}
\makeatother
\begin{document}
%\tableofcontents% CAN UNCOMMMENT TO SEE THAT toc WORKS FINE
\defineList{xyz}
\defineList{pdq}

\section{Introduction}

\addToList{xyz}{First item on my list.}
Text related to why tracking balls is important, blah, blah, blah.   
Blah, blah, blah. 
\addToList{pdq}{First pdq item}

Here is my XYZ list:
\printList{xyz}

\section{Next Section}

\addToList{xyz}{Second item on list}
Text relating the challenges, blah, blah, blah.  
More blah, blah, blah.
\addToList{pdq}{Next pdq item} 

\addToList{xyz}{Third item on list.}
Here is my PDQ list:
\printList{pdq}

Text relating the existing work on tracking balls, blah, blah, blah.  
Blah, blah, blah.

\end{document}

在此处输入图片描述

答案2

您可以使用该.aux文件。

我们用\defineList初始化一个序列变量;每个\addToList命令将.aux相应的条目作为参数写入文件中\chrillofaddtolist

.aux在开始文档处读取文件时,序列将填充上次运行中收集的项目,以便它在文档启动时立即可用。

当文件被读回时,该命令\chrillofaddtolist在文档结束时变为无操作,但我们不需要采取任何行动。.aux

最后,\printList只需传递序列。

作为一种技术解决方法,我添加了一个litemize环境,因此当序列仍然为空时不会引发任何错误。

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\defineList}{m}
 {
  \seq_new:c { g_chrillof_list_#1_seq }
 }
\NewDocumentCommand{\addToList}{mm}
 {
  \iow_shipout:cn { @auxout } { \chrillofaddtolist { #1 } { #2 } }
 }
\NewDocumentCommand{\chrillofaddtolist}{mm}
 {
  \seq_gput_right:cn { g_chrillof_list_#1_seq } { #2 }
 }
\NewDocumentCommand{\printList}{m}
 {
  \seq_use:cn { g_chrillof_list_#1_seq } { }
 }
\AtEndDocument{\cs_set_eq:NN \chrillofaddtolist \use_none:nn }
\ExplSyntaxOff

\makeatletter
\newenvironment{litemize}
 {\let\@noitemerr\relax\itemize}
 {\enditemize}
\makeatother

\defineList{MyListName}

\begin{document}

\begin{litemize}
\printList{MyListName}
\end{litemize}

Lorem ipsum dolor sit amet...

\addToList{MyListName}{\item First}
\addToList{MyListName}{\item Second}

\end{document}

在此处输入图片描述

答案3

软件包sagetex、文档这里,让您可以访问 Python 编程语言。这是使用循环跟踪列表和打印的一种方法。

\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
MyList = ["spring","summer"]
output = r"\begin{itemize}"
for i in range(0,len(MyList)):
  output += r"\item %s"%(MyList[i])
output += r"\end{itemize}"
\end{sagesilent}

\sagestr{output}

Lorem ipsum dolor sit amet...

\begin{sagesilent}
MyList.insert(0,"winter")
MyList.append("fall")
output = r"\begin{itemize}"
for i in range(0,len(MyList)):
  output += r"\item %s"%(MyList[i])
output += r"\end{itemize}"
\end{sagesilent}

\sagestr{output}
\end{document}

结果如下所示: 在此处输入图片描述

“幕后”工作是在sagesilent环境中完成的。原始列表被创建为包含“spring”和“summer”。for 循环创建一个字符串,该字符串将列表放入 itemize 环境中。要将其插入文档,请使用sagestrSAGE 字符串环境。如果我们想将“winter”添加到列表的第一个位置并将“fall”添加到最后一个位置,则命令 MyList.insert(0,"winter") 会将“winter”放在第一个位置(在 Python 中是第零个位置)。命令 MyList.append("fall") 会将“fall”放在列表的末尾,无论它有多长。for 循环会打印出较长的列表,因为 len(MyList) 是列表的长度。

每次额外的代码块有点笨重,但易于阅读和修改。您还可以获得能够插入列表任何部分的好处。sagetex软件包依赖于计算机代数系统 SAGE,它不是 LaTeX 软件包的一部分。它需要下载到您的计算机,或者您可以打开一个免费的Cocalc 账户并从云端工作。

相关内容