如上所述,我想知道是否有可能动态地将项目添加到列表中并将其打印在文档的任何位置,而不管定义在哪里。
我在想这样的事情:
\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}
仅仅充当一个宏,并被列表的内容所取代):
当然,如果能够迭代列表项就更加优雅了,但它可能会引入太多的复杂性。
答案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 环境中。要将其插入文档,请使用sagestr
SAGE 字符串环境。如果我们想将“winter”添加到列表的第一个位置并将“fall”添加到最后一个位置,则命令 MyList.insert(0,"winter") 会将“winter”放在第一个位置(在 Python 中是第零个位置)。命令 MyList.append("fall") 会将“fall”放在列表的末尾,无论它有多长。for 循环会打印出较长的列表,因为 len(MyList) 是列表的长度。
每次额外的代码块有点笨重,但易于阅读和修改。您还可以获得能够插入列表任何部分的好处。sagetex
软件包依赖于计算机代数系统 SAGE,它不是 LaTeX 软件包的一部分。它需要下载到您的计算机,或者您可以打开一个免费的Cocalc 账户并从云端工作。