我想为我们的一位客户写一份工作量估算表。客户想要进行一些更改,因此我估算了每次更改所需的时间。我可以手动汇总工作量,但这似乎不太顺利,所以我尝试了以下方法:
我在文档顶部添加了以下内容:
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand\FullEffort{0}
\newcommand{\AddEffort}[1]{
\pgfmathparse{\FullEffort+#1}
\renewcommand{\FullEffort}{\pgfmathresult}
}
在我的文档的最后我测试了这样的功能:
\section{Summary}
\AddEffort{5}
\AddEffort{2}
Full Effort: \FullEffort\ h
打印出来Full Effort: 7 h
似乎可以工作。
但是一旦我使用\AddEffort{x}
里面的东西,\begin{itemize}
它就不会增加小时数。
\section{Security}
\subsection{Reset Passwords via Email}
\begin{itemize}
\item \textbf{Problem}\\
Current admins can change the password of users.
\item \textbf{Solution}\\
Send an email with the new password to the accounts-email.
\item \textbf{Effort}\\
5 h \AddEffort{5}
\end{itemize}
\AddEffort{5}
上面的内容被itemize
忽略。并且Full Effort: 7 h
仍然打印在文档末尾。
答案1
下面的代码
\newcommand\FullEffort{0}
\newcommand{\AddEffort}[1]{
\pgfmathparse{\FullEffort+#1}
\renewcommand{\FullEffort}{\pgfmathresult}
}
有两个问题:
之后
\AddEffort
\FullEffort
扩展为\pgfmathresult
。此宏确实包含结果,但只在 之后\AddEffort
。每个进一步的无关调用\pgfmathparse
都将覆盖\pgfmathresult
,然后\FullEffort
也会更改其结果。可以使用 来修复此问题\let
。然后\FullEffort
将具有 的含义\pgfmathresult
,并且\pgfmathresult
可以在之后更改。\let\FullEffort\pgfmathresult
的效果
\renewcommand
是局部的。如果\FullEffort
在组内更改,并且环境类似于itemize
这样的组,则当组结束时,将恢复组开始之前的先前含义。由于您希望在文档末尾获得总结果,因此\FullEffort
应该是全局资源:\global\let\FullEffort\pgfmathresult
现在,
\AddEffort
可以在群组内使用,并且\FullEffort
在关闭群组后仍保留其含义。
概括:
\newcommand\FullEffort{0}
\newcommand{\AddEffort}[1]{% comment line ends to avoid unwanted spaces
\pgfmathparse{\FullEffort+#1}%
\global\let\FullEffort\pgfmathresult
}
答案2
Heiko 提到了您的代码的两个问题。第三个问题是,如果您只想将数字推进到数字,则无需加载 tikz。我们有\advance
原始函数,我们不需要加载数万行代码(当然,当我们接受 2*10^9 作为最大数字的限制时)。
\newcount\tmpnum
\def\FullEffort{0}
\def\AddEffort#1{\tmpnum=\FullEffort
\advance\tmpnum by#1
\xdef\FullEffort{\the\tmpnum}%
}
或者使用 eTeX 原语(eTeX 在 LaTeX 中已激活):
\def\FullEffort{0}
\def\AddEffort#1{\xdef\FullEffort{\the\numexpr\FullEffort+#1}}
答案3
有了expl3
更清晰的语法:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand\FullEffort{}
{% print the value (it's fully expandable)
\int_to_arabic:n { \g_chibi_effort_int }
}
\NewDocumentCommand{\AddEffort}{m}
{% globally update the variable's value
\int_gadd:Nn \g_chibi_effort_int { #1 }
}
\int_new:N \g_chibi_effort_int % allocate the variable
\ExplSyntaxOff
\begin{document}
\section{Summary}
\AddEffort{5}
\AddEffort{2}
Full Effort: \FullEffort\ h
Which prints Full Effort: 7 h so it seems to work.
\section{Security}
\subsection{Reset Passwords via Email}
\begin{itemize}
\item \textbf{Problem}\\
Current admins can change the password of users.
\item \textbf{Solution}\\
Send an email with the new password to the accounts-email.
\item \textbf{Effort}\\
5 h \AddEffort{5}
\end{itemize}
Full Effort: \FullEffort.
\end{document}
该命令\FullEffort
仅打印由(全局)更新的计数器(整数变量)的值\AddEffort
。
如果您还想支持非整数值,只需将所有更改int
为fp
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand\FullEffort{}
{
\fp_eval:n { \g_chibi_effort_fp }
}
\NewDocumentCommand{\AddEffort}{m}
{
\fp_gadd:Nn \g_chibi_effort_fp { #1 }
}
\fp_new:N \g_chibi_effort_fp
\ExplSyntaxOff
\begin{document}
\section{Summary}
\AddEffort{5}
\AddEffort{2.5}
Full Effort: \FullEffort\ h
Which prints Full Effort: 7.5 h so it seems to work.
\section{Security}
\subsection{Reset Passwords via Email}
\begin{itemize}
\item \textbf{Problem}\\
Current admins can change the password of users.
\item \textbf{Solution}\\
Send an email with the new password to the accounts-email.
\item \textbf{Effort}\\
4.5 h \AddEffort{4.5}
\end{itemize}
Full Effort: \FullEffort.
\end{document}