我想创建一个自定义列表环境,收集这些列表的内容并将其放在文档的开头。
\begin{objectives}
\item See no evil.
\end{objectives}
lots of stuff 1
\begin{objectives}
\item Hear no evil.
\end{objectives}
lots of stuff 2
\begin{objectives}
\item Speak no evil.
\end{objectives}
lots of stuff 3
我希望定义目标环境,以便上述命令具有与
\begin{enumerate}
\item See no evil.
\item Hear no evil.
\item Speak no evil.
\end{enumerate}
lots of stuff 1
lots of stuff 2
lots of stuff 3
(我不能手动将目标移动到文档开头的原因是我的内容分布在多个文件中,这些文件将按菜单组合。)我知道我可以使用包collect
通过定义来获取文档末尾的列表
\usepackage{collect}
\definecollection{ob}
\newenvironment{objective}{%
\collect{ob}{}{}}{\endcollect}
..earlier content..
\begin{enumerate}
\includecollection{ob}
\end{enumerate}
看来解决方案需要依赖于\immediate\write\tempfile{}
创建一个临时文件来存储内容。但是,我每次创建临时文件的尝试只有将列表放在最后才会成功。
我知道可以将内容集中放在文档开头,因为目录或图表列表就是这么做的。我还没搞清楚包todonotes
或tocloft
包中的代码。
您能给我指明正确的方向吗?
答案1
您可以使用内置机制来制作目录:
\documentclass{article}
\usepackage{environ}
\usepackage{lipsum} % just for the example
\makeatletter
\newcommand{\printobjectives}{%
\section*{Objectives}
\begin{enumerate}
\def\@noitemerr{\@latex@warning{Empty objective list}}%
\@starttoc{obj}
\end{enumerate}
}
\newcommand{\l@obj}[2]{#1}
\makeatother
\NewEnviron{objectives}
{%
\addcontentsline{obj}{obj}{%
\noexpand\unexpanded{\unexpanded\expandafter{\BODY}}%
}%
}
\begin{document}
\printobjectives
\section{Main}
\begin{objectives}
\item See no evil.
\end{objectives}
\lipsum[2]
\begin{objectives}
\item Hear no evil.
\end{objectives}
\lipsum[3]
\begin{objectives}
\item Speak no evil.
\end{objectives}
\lipsum[4]
\end{document}
如果你加载hyperref
,但不需要目标列表的超链接,请这样做
\let\originalcontentsline\contentsline
\usepackage{hyperref}
(第一行是为了保留 的原意)将和之间\contentsline
的代码改为\makeatletter
\makeatother
\makeatletter
\newcommand{\printobjectives}{%
\section*{Objectives}
\begin{enumerate}
\let\contentsline\originalcontentsline
\def\@noitemerr{\@latex@warning{Empty objective list}}%
\@starttoc{obj}
\end{enumerate}
}
\newcommand{\l@obj}[3]{#1}
\makeatother