宏在 Itemize-Block 中不起作用

宏在 Itemize-Block 中不起作用

我想为我们的一位客户写一份工作量估算表。客户想要进行一些更改,因此我估算了每次更改所需的时间。我可以手动汇总工作量,但这似乎不太顺利,所以我尝试了以下方法:

我在文档顶部添加了以下内容:

\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

如果您还想支持非整数值,只需将所有更改intfp

\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}

在此处输入图片描述

相关内容