我正在开发宏来格式化执行项目任务的时间估算。我有一个自定义环境来格式化子任务估算,现在我想添加一个总结所有内容的表格。
我在用着tocloft
来创建自定义列表,它对所有子任务条目都按预期工作,但我还想显示完整里程碑的摘要。我现在拥有的所有内容都是正确的,但估算列表中的里程碑摘要是后子任务,而我之前想要的是。如果我将相应的宏放在部分开头,则估算列表中的位置是正确的,但估算本身是不正确的(0 天)。
我怎样才能获得子任务之前的里程碑线并得到正确的估计?
\documentclass[11pt,letterpaper,oneside]{article}
\usepackage{tocloft}
%----------------------------------------------------------------------
% Environment for estimates
%----------------------------------------------------------------------
\newcommand{\listestimatename}{List of Estimates}
\newlistof{estimate}{est}{\listestimatename}
\newlistentry{subestimate}{est}{1}
\setcounter{estdepth}{2}
\cftsetindents{estimate}{1em}{1.5em}
\cftsetindents{subestimate}{2em}{3.8em}
\newcommand{\CurWorkLabel}{}
\newcounter{cntScnWorkEstimate}[section]
\newcounter{cntEnvWorkEstimate}
\newenvironment{workestimate}[1]
{
\small
\renewcommand{\CurWorkLabel}{#1}
\setcounter{cntEnvWorkEstimate}{0}
\begin{tabular}{c l}
\multicolumn{2}{l}{\emph{#1}}\tabularnewline
\hline
}
{
% finish the table
\textbf{\emph{\thecntEnvWorkEstimate\ days}} & \textbf{\emph{Total}}
\end{tabular}
% now add a list of estimates entry
\phantomsection
\addcontentsline{est}{subestimate}
{\protect\numberline{\thesubsection}\CurWorkLabel\ (\thecntEnvWorkEstimate\ days)}
}
\newcommand{\estimate}[2]{%
\addtocounter{cntEnvWorkEstimate}{#1}%
\addtocounter{cntScnWorkEstimate}{#1}%
\emph{#1 days} & #2 \tabularnewline
}
\newcommand{\addsectionestimate}[1]{%
\addcontentsline{est}{estimate}
{\protect\numberline{\thesection}\textbf{#1 Total} (\thecntScnWorkEstimate\ days)}
}
%----------------------------------------------------------------------
% Now the actual document
%----------------------------------------------------------------------
\begin{document}
\listofestimate
\section{Milestone 1}
\subsection{Sub Task 1}
\begin{workestimate}{Subtask1 Estimate}
\estimate{1}{detail A}
\estimate{2}{detail B}
\end{workestimate}
Long description of how this sub task will be carried out.
\subsection{Sub Task 2}
\begin{workestimate}{Subtask 2 Estimate}
\estimate{3}{detail C}
\estimate{4}{detail D}
\end{workestimate}
Long description of how this sub task will be carried out.
\addsectionestimate{Milestone 1}
\end{document}
答案1
您这里的主要问题是您想在打印/显示之前引用某些内容。最方便的方式是通过\label
-\ref
系统(通过.aux
文件)。以下代码通过milestone
环境实现这一点,在末尾设置一个顺序\label
,以捕获您的日计数器的总和。
\documentclass{article}
\usepackage{tocloft}
%----------------------------------------------------------------------
% Environment for estimates
%----------------------------------------------------------------------
\newcommand{\listestimatename}{List of Estimates}
\newlistof{estimate}{est}{\listestimatename}
\newlistentry{subestimate}{est}{1}
\setcounter{estdepth}{2}
\cftsetindents{estimate}{1em}{1.5em}
\cftsetindents{subestimate}{2em}{3.8em}
\newcommand{\CurWorkLabel}{}
\newcounter{cntScnWorkEstimate}[section]
\newcounter{cntEnvWorkEstimate}
\newenvironment{workestimate}[1]{%
\small
\renewcommand{\CurWorkLabel}{#1}%
\setcounter{cntEnvWorkEstimate}{0}%
\begin{tabular}{c l}
\multicolumn{2}{l}{\emph{#1}}\tabularnewline
\hline
}{%
% finish the table
\textbf{\emph{\thecntEnvWorkEstimate\ days}} & \textbf{\emph{Total}}
\end{tabular}
% now add a list of estimates entry
\phantomsection
\addcontentsline{est}{subestimate}
{\protect\numberline{\thesubsection}\CurWorkLabel\ (\thecntEnvWorkEstimate\ days)}
}
\newcommand{\estimate}[2]{%
\addtocounter{cntEnvWorkEstimate}{#1}%
\addtocounter{cntScnWorkEstimate}{#1}%
\emph{#1 days} & #2 \tabularnewline
}
\newcommand{\subtask}{\subsection}
\newcounter{milestone}
\makeatletter
\newenvironment{milestone}[1]{%
\section{#1}%
\stepcounter{milestone}%
\addcontentsline{est}{estimate}
{\protect\numberline{\thesection}\textbf{#1 Total} (\ref{milestone-\themilestone}~days)}%
}{%
\edef\@currentlabel{\thecntScnWorkEstimate}%
\label{milestone-\themilestone}%
}
\makeatother
%----------------------------------------------------------------------
% Now the actual document
%----------------------------------------------------------------------
\begin{document}
\listofestimate
\begin{milestone}{Milestone 1}
\subtask{Sub Task 1}
\begin{workestimate}{Subtask 1 Estimate}
\estimate{1}{detail A}
\estimate{2}{detail B}
\end{workestimate}
Long description of how this sub task will be carried out.
\subtask{Sub Task 2}
\begin{workestimate}{Subtask 2 Estimate}
\estimate{3}{detail C}
\estimate{4}{detail D}
\end{workestimate}
Long description of how this sub task will be carried out.
\end{milestone}
\end{document}
第一次编译时,将\label
写入.aux
。第二次编译通过 选取适当的值\ref
并将其写入.est
(相当于.toc
)。第三次编译现在正确地选取了\ref
并将其显示在估算清单。
每次您想要查看输出时,不需要编译 3 次……只有当 a 的milestone
元素或\estimate
s 的内容发生变化时才需要编译 3 次。
答案2
至少部分解决方案:\addsectionestimate{Milestone 1}
在 之前向上移动\listofestimate
。这会将其放到正确的位置。您可能需要调整 中的计数器\newcommand{\addsectionestimate}
。
截屏:
修改后的代码:
\documentclass[11pt,letterpaper,oneside]{article}
\usepackage{tocloft}
%----------------------------------------------------------------------
% Environment for estimates
%----------------------------------------------------------------------
\newcommand{\listestimatename}{List of Estimates}
\newlistof{estimate}{est}{\listestimatename}
\newlistentry{subestimate}{est}{1}
\setcounter{estdepth}{2}
\cftsetindents{estimate}{1em}{1.5em}
\cftsetindents{subestimate}{2em}{3.8em}
\newcommand{\CurWorkLabel}{}
\newcounter{cntScnWorkEstimate}[section]
\newcounter{cntEnvWorkEstimate}
\newenvironment{workestimate}[1]
{
\small
\renewcommand{\CurWorkLabel}{#1}
\setcounter{cntEnvWorkEstimate}{0}
\begin{tabular}{c l}
\multicolumn{2}{l}{\emph{#1}}\tabularnewline
\hline
}
{
% finish the table
\textbf{\emph{\thecntEnvWorkEstimate\ days}} & \textbf{\emph{Total}}
\end{tabular}
% now add a list of estimates entry
\phantomsection
\addcontentsline{est}{subestimate}
{\protect\numberline{\thesubsection}\CurWorkLabel\ (\thecntEnvWorkEstimate\ days)}
}
\newcommand{\estimate}[2]{%
\addtocounter{cntEnvWorkEstimate}{#1}%
\addtocounter{cntScnWorkEstimate}{#1}%
\emph{#1 days} & #2 \tabularnewline
}
% probably need to adjust counter here
\newcommand{\addsectionestimate}[1]{%
\addcontentsline{est}{estimate}
{\protect\numberline{\thesection}\textbf{#1 Total} (\thecntScnWorkEstimate\ days)}
}
%----------------------------------------------------------------------
% Now the actual document
%----------------------------------------------------------------------
\begin{document}
\addsectionestimate{Milestone 1}% <<==
\listofestimate
\section{Milestone 1}
\subsection{Sub Task 1}
\begin{workestimate}{Subtask1 Estimate}
\estimate{1}{detail A}
\estimate{2}{detail B}
\end{workestimate}
Long description of how this sub task will be carried out.
\subsection{Sub Task 2}
\begin{workestimate}{Subtask 2 Estimate}
\estimate{3}{detail C}
\estimate{4}{detail D}
\end{workestimate}
Long description of how this sub task will be carried out.
\end{document}
根据发起者的评论提出更多建议:好的,我开始明白你的问题了。除了正确编号章节和子章节之外,你还希望获得各种计数结果。让我们一步一步来看看。
我建议解开估计命令:
\newcommand{\estimate}[2]{%
\addtocounter{cntEnvWorkEstimate}{#1}%
\addtocounter{cntScnWorkEstimate}{#1}%
\emph{#1 days} & #2 \tabularnewline%<<==
}
如果您要抑制打印输出\emph{#1 days} & #2 \tabularnewline
,那么您可以首先放置简化的估计命令,以进行计算。您在这里省略了所有部分命令。
假设您可以读出计数结果并将其存储在某个地方,第二步,您可以构建文档结构并读出先前存储的计数结果......这样您就可以创建标题,例如包含天数的标题。
需要强调的是,我们的想法是separate in code: count first, store, print later
。
所以剩下要做的就是找到一个存储解决方案。
如果您有固定数量的部分,那么您需要做的就是定义足够的新计数,例如,在运行估算后预设的计数...使用计算出的估算值。
如果它更具动态性,则可以找到动态存储和检索,或者使其更加静态。
因此基本上你的代码结构将是这样的:
% ...
\newcommand{\estimate}[1]{%
\addtocounter{cntEnvWorkEstimate}{#1}%
\addtocounter{cntScnWorkEstimate}{#1}%
}
\begin{document}
% ...
\begin{workestimate}{Subtask1 Estimate}
\estimate{1}{detail A}
\estimate{2}{detail B}
\end{workestimate}
% store result
% next workestimate environment
% ...
\tableofcontents % instead of \listofestimate
\section{Milestone 1 \theCalculated days}% idea is to literally write the title
\subsection{Sub Task 1 \theOtherCalculated days}
% some output as in the deleted \emph{} part
% ...
\end{document}
希望这可以帮助。
如果没有的话,您至少需要利用所需的双重编译运行,即访问和处理存储在.toc、.aux 等中的信息。
所以我建议努力separate in code
工作;-)