如何访问和存储计数器的当前值?

如何访问和存储计数器的当前值?

我的计数器正在通过命令更新,我想在特定点保存该计数器的当前值 + 1,以便稍后能够将其打印出来。

\newcounter{counterA}
\newcounter{tempcounter}

\def\storevalue#1{
  \setcounter{tempcounter}{\value{counterA}}
  \refstepcounter{tempcounter}

  \def\tempA{\arabic{tempcounter}}
  \let\tempB\tempA

  \expandafter\def\csname data:\string#1\endcsname{\textbf{Value \tempB}}%
}

\def\getvalue#1{\csname data:\string#1\endcsname}

在我的文档正文中,我会有类似

\refstepcounter{counterA}
\storevalue\vala
\refstepcounter{counterA}
\refstepcounter{counterA}
\storevalue\valb
\refstepcounter{counterA}
\storevalue\valc

\getvalue\vala

\getvalue\valc

\getvalue\valb

我希望这是 pdf 中的输出

Value 2

Value 5

Value 4

答案1

不需要“奇怪的”“扩展”,如果\label使用,存储工具已经存在,如果需要可扩展检索,则\getrefnumber来自refcount包,否则会回退到\ref而不是\getrefnumber

在此处输入图片描述

\documentclass{article}
\usepackage{refcount}

\newcounter{counterA}
\newcounter{tempcounter}

\newcommand{\storevalue}[1]{%
  \setcounter{tempcounter}{\value{counterA}}%
  \refstepcounter{tempcounter}\label{#1}%
}

\newcommand{\getvalue}[1]{\getrefnumber{#1}}

\begin{document}

\refstepcounter{counterA}% Should be 1 now
\storevalue{vala}% Store 2
\refstepcounter{counterA}
\refstepcounter{counterA}
\storevalue{valb}% Store 4 
\refstepcounter{counterA}
\storevalue{valc} % Store 5

\getvalue{vala} % 2

\getvalue{valc} % 5

\getvalue{valb} % 4

\end{document}

答案2

像这样?我扩展了存储的值,而不是仅仅为其分配一个可改变的宏。

\documentclass{article}
\newcounter{counterA}

\def\storevalue#1{

  \edef\tempA{\the\numexpr\value{counterA}+1}

  \expandafter\edef\csname data:\string#1\endcsname{\noexpand\textbf{Value \tempA}}%
}

\def\getvalue#1{\csname data:\string#1\endcsname}

\begin{document}
\refstepcounter{counterA}
\storevalue\vala
\refstepcounter{counterA}
\refstepcounter{counterA}
\storevalue\valb
\refstepcounter{counterA}
\storevalue\valc

\getvalue\vala

\getvalue\valc

\getvalue\valb
\end{document}

在此处输入图片描述

答案3

注意定义中的结束行和空行。

您正在执行不必要的任务,并且在定义时错过了关键的扩展\data:<name>

我避免使用伪控制序列,而更喜欢简单的名称,但这取决于你。

\documentclass{article}

\newcounter{counterA}
\newcounter{tempcounter}

\newcommand\storevalue[1]{%
  \setcounter{tempcounter}{\value{counterA}}%
  \stepcounter{tempcounter}%
  % the following must be \edef or \protected@edef if you have
  % more material that would fail in \edef such as \textbf
  \expandafter\edef\csname data:#1\endcsname{%
    \noexpand\textbf{Value \arabic{tempcounter}}%
  }%
}
\newcommand\getvalue[1]{\csname data:#1\endcsname}

\begin{document}

\refstepcounter{counterA}
\storevalue{vala}
\refstepcounter{counterA}
\refstepcounter{counterA}
\storevalue{valb}
\refstepcounter{counterA}
\storevalue{valc}

\getvalue{vala}

\getvalue{valc}

\getvalue{valb}

\end{document}

在此处输入图片描述

答案4

为了保存计数器值并在整个文档中检索它们,LaTeX 2ε 内核提供了\label- -\ref机制。Heiko Oberdiek 的软件包引用计数如果需要的话,提供可扩展地检索事物的方法。

但所有这些都仅限于保存和检索由\refstepcounter-command 步进的计数器的值。

⟨number⟩可以通过 Heiko Oberdiek 的包来实现保存和检索任意数据参考值

什么⟨number⟩电子书第24章 垂直模式总结以及ε-TeX 手册, 部分5.1 与模式无关的命令

A⟨number⟩不一定需要来自 LaTeX 计数器。

例如, A⟨number⟩也可以是求值数字类型表达式的结果,即\numexpr-构造。\numexpr可用于计算。类似表达式\numexpr的解释如下ε-TeX 手册, 部分3.5 表达式



下面的示例提供了以下宏:

\StoreNumber{⟨label⟩}%
            {⟨number⟩}

\StoreNumber评估⟨number⟩并创建一个 zref-referencing-label,其名称⟨label⟩用于检索该评估的结果。


\StorePrefixAndNumberAndPostfix{⟨label⟩}%
                               {⟨prefix phrase⟩}%
                               {⟨number⟩}%
                               {⟨postfix phrase⟩}

\StorePrefixAndNumberAndPostfix评估⟨number⟩并创建一个 zref-referencing-label,其名称⟨label⟩用于检索该评估的结果。通过相同的 zref-referencing-label,您还可以检索⟨prefix phrase⟩⟨postfix phrase⟩。这两个短语以“去标记化方式”存储。即,在创建 zref-referencing-label 时不会对其进行扩展/评估。


\RetrieveNumber{⟨label⟩}

\RetrieveNumber检索⟨number⟩与 zref-referencing-label 关联的内容⟨label⟩


\RetrievePrefix{⟨label⟩}

\RetrievePrefix检索⟨prefix phrase⟩与 zref-referencing-label 关联的内容⟨label⟩


\RetrievePostfix{⟨label⟩}

\RetrievePostfix检索⟨postfix phrase⟩与 zref-referencing-label 关联的内容⟨label⟩


\RetrievePrefixAndNumberAndPostfix{⟨label⟩}

\RetrievePrefixAndNumberAndPostfix检索

  • ⟨prefix phrase⟩与 zref-referencing-label 关联的⟨label⟩
  • ⟨number⟩与 zref-referencing-label 关联的⟨label⟩
  • ⟨postfix phrase⟩与 zref-referencing-label 关联的⟨label⟩

就这些宏而言,你可以定义宏

\storevalue{⟨label⟩}

\getvalue{⟨label⟩}

counterA用于保存和检索将值增加1的结果:

\DeclareRobustCommand\storevalue[1]{%
  \StoreNumber{#1}{\the\numexpr\value{counterA}+1\relax}%
}%
\DeclareRobustCommand\getvalue[1]{\textbf{Value \RetrieveNumber{#1}}}%

\label与--机制相关的所有内容一样,\ref至少需要两次 LaTeX 运行才能使一切正确无误。



\documentclass[landscape]{article}

%--<stuff only needed for making the example looking good>-----------------
\usepackage{textcomp}
\usepackage{amstext}
\expandafter\ifx\csname pdfpagewidth\endcsname\relax\else
  \pdfpagewidth=\paperwidth
  \pdfpageheight=\paperheight
\fi
\expandafter\ifx\csname pagewidth\endcsname\relax\else
  \pagewidth=\paperwidth
  \pageheight=\paperheight
\fi
\textwidth=\paperwidth
\advance\textwidth by -2cm
\oddsidemargin=1cm
\advance\oddsidemargin by -1in
\advance\oddsidemargin by -\hoffset
\evensidemargin=\oddsidemargin
\textheight\paperheight
\advance\textheight by -2cm
\topmargin=1cm
\advance\topmargin by -1in
\advance\topmargin by -\voffset
\pagestyle{empty}%
\headheight=0pt
\headsep=0pt
\parindent=0ex
\parskip=\medskipamount
\newenvironment{makeverbatimnice}{\topsep=0ex\partopsep=0ex\ignorespaces}{}%
\newcommand\ThingsName[1]{\textsf{``#1''}}%
\newcommand\meta[1]{\textit{\textlangle#1\textrangle}}%
%--<eof stuff only needed for making the example looking good>-------------
%
%--<stuff needed for implementing the user-macros>-------------------------
\usepackage{zref}
\makeatletter
% My variant of \@bsphack / \@esphack.
\newskip\MYNAMESPACE@savsk
\newcommand*\MYNAMESPACE@bsphack{%
  \relax
  \ifhmode\MYNAMESPACE@savsk\lastskip\@savsk\lastskip\@savsf\spacefactor\fi
}%
\newcommand*\MYNAMESPACE@esphack{%
  \relax
  \ifhmode
    \spacefactor\@savsf
    \ifdim\@savsk>\z@
      \ifdim\lastskip=\z@\nobreak\hskip\z@skip\fi
      % The following \hskips are used for restoring \lastskip.
      % I hope there are no evil side-effects. ;-)
      \nobreak\hskip-\MYNAMESPACE@savsk
      \nobreak\hskip\MYNAMESPACE@savsk
      \ignorespaces
    \fi
  \fi
}%
%
\newcommand\MYNAMESPACE@Exchange[2]{#2#1}%
%
\AtBeginDocument{%
  \@ifpackageloaded{hyperref}{%
    \DeclareRobustCommand\MYNAMESPACE@RefUndefText{%
      \texorpdfstring{\nfss@text{\reset@font\bfseries ??}}{??}%
    }%
  }{%
    \DeclareRobustCommand\MYNAMESPACE@RefUndefText{%
      \nfss@text{\reset@font\bfseries ??}%
    }%
  }%
}%
%
\zref@newprop{numbertostore}[0]{0}
\zref@newprop{numberprefix}[]{}
\zref@newprop{numberpostfix}[]{}
%
\DeclareRobustCommand\StorePrefixAndNumberAndPostfix[4]{%
  \MYNAMESPACE@bsphack
  \begingroup
  \zref@setcurrent{numberprefix}{\detokenize{#2}}%
  \zref@setcurrent{numberpostfix}{\detokenize{#4}}%
  \expandafter\MYNAMESPACE@Exchange\expandafter{%
    \expandafter{\the\numexpr\number#3\relax}%
  }{%
    \zref@setcurrent{numbertostore}%
  }%
  \zref@wrapper@immediate{%
    \zref@labelbyprops{#1}{numbertostore,numberprefix,numberpostfix}%
  }%
  \endgroup
  \MYNAMESPACE@esphack
}%
\DeclareRobustCommand\StoreNumber[2]{%
  \MYNAMESPACE@bsphack
  \begingroup
  \expandafter\MYNAMESPACE@Exchange\expandafter{%
    \expandafter{\the\numexpr\number#2\relax}%
  }{%
    \zref@setcurrent{numbertostore}%
  }%
  \zref@wrapper@immediate{%
    \zref@labelbyprops{#1}{numbertostore}%
  }%
  \endgroup
  \MYNAMESPACE@esphack
}%
\DeclareRobustCommand\RetrieveNumber[1]{%
  \zref@refused{#1}%
  \zref@extractdefault{#1}{numbertostore}{\MYNAMESPACE@RefUndefText}%
}%
\DeclareRobustCommand\RetrievePrefix[1]{%
  \zref@refused{#1}%
  \zref@extractdefault{#1}{numberprefix}{\MYNAMESPACE@RefUndefText}%
}%
\DeclareRobustCommand\RetrievePostfix[1]{%
  \zref@refused{#1}%
  \zref@extractdefault{#1}{numberpostfix}{\MYNAMESPACE@RefUndefText}%
}%
\DeclareRobustCommand\RetrievePrefixAndNumberAndPostfix[1]{%
  \zref@refused{#1}%
  \zref@extractdefault{#1}{numberprefix}{}%
  \zref@extractdefault{#1}{numbertostore}{\MYNAMESPACE@RefUndefText}%
  \zref@extractdefault{#1}{numberpostfix}{}%
}%
\makeatother
%--<eof stuff needed for implementing the user-macros>---------------------

\newcounter{counterA}
\newcounter{counterB}

\begin{document}

\hbox to\textwidth{\null\hrulefill\null}%

The \meta{number} stored as \ThingsName{First Stored Number} is retrieved
via \verb|\RetrieveNumber{First Stored Number}|:
\RetrieveNumber{First Stored Number}%

The prefix associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePrefix{Second Stored Number}|:
\RetrievePrefix{Second Stored Number}%

The \meta{number} stored as \ThingsName{Second Stored Number} is retrieved
via \verb|\RetrieveNumber{Second Stored Number}|:
\RetrieveNumber{Second Stored Number}%

The postfix associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePostfix{Second Stored Number}|:
\RetrievePostfix{Second Stored Number}%

Everything associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePrefixAndNumberAndPostfix{Second Stored Number}|:\\
\RetrievePrefixAndNumberAndPostfix{Second Stored Number}

\hbox to\textwidth{\null\hrulefill\null}%

\ThingsName{counterA} is set to 7.
\setcounter{counterA}{7}%

\ThingsName{counterB} is set to 14.
\setcounter{counterB}{14}%

\hbox to\textwidth{\null\hrulefill\null}%

A \meta{number} is stored as \ThingsName{First Stored Number} via
\begin{makeverbatimnice}
\begin{verbatim}
\StoreNumber{First Stored Number}%
            {\the\numexpr\value{counterA}*\value{counterB}/2\relax}%
\end{verbatim}%
\end{makeverbatimnice}%
\StoreNumber{First Stored Number}%
            {\the\numexpr\value{counterA}*\value{counterB}/2\relax}%

\emph{(The expression evaluates to 49 as
\(\text{\texttt{\string\value\string{counterA\string}}}%
\cdot
\text{\texttt{\string\value\string{counterB\string}}}\,/\,2%
=7\cdot14\,/\,2=49\).)}

A prefix phrase, a \meta{number} and a postfix phrase are stored
under \ThingsName{Second Stored Number} via
\begin{makeverbatimnice}
\begin{verbatim}
\StorePrefixAndNumberAndPostfix{Second Stored Number}%
                               {The number }%
                               {\the\numexpr\value{counterB}+3\relax}%
                               { is a prime number.}%
\end{verbatim}%
\end{makeverbatimnice}%
\StorePrefixAndNumberAndPostfix{Second Stored Number}%
                               {The number }%
                               {\the\numexpr\value{counterB}+3\relax}%
                               { is a prime number.}%

\emph{(The expression evaluates to 17 as
\(\text{\texttt{\string\value\string{counterB\string}}}+3=14+3=17\).)}

\hbox to\textwidth{\null\hrulefill\null}%

The \meta{number} stored as \ThingsName{First Stored Number} is retrieved
via \verb|\RetrieveNumber{First Stored Number}|:
\RetrieveNumber{First Stored Number}%

The prefix associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePrefix{Second Stored Number}|:
\RetrievePrefix{Second Stored Number}%

The \meta{number} stored as \ThingsName{Second Stored Number} is retrieved
via \verb|\RetrieveNumber{Second Stored Number}|:
\RetrieveNumber{Second Stored Number}%

The postfix associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePostfix{Second Stored Number}|:
\RetrievePostfix{Second Stored Number}%

Everything associated with the \meta{number} stored as
\ThingsName{Second Stored Number} is retrieved via
\verb|\RetrievePrefixAndNumberAndPostfix{Second Stored Number}|:\\
\RetrievePrefixAndNumberAndPostfix{Second Stored Number}

\hbox to\textwidth{\null\hrulefill\null}%

\newpage

In terms of these macros you can, e.g., define macros \verb|\storevalue|
and \verb|\getvalue| for saving and retrieving specifically the result 
of incrementing the value of \ThingsName{counterA} by 1:
\begin{makeverbatimnice}
\begin{verbatim}
\DeclareRobustCommand\storevalue[1]{%
  \StoreNumber{#1}{\the\numexpr\value{counterA}+1\relax}%
}%
\DeclareRobustCommand\getvalue[1]{\textbf{Value \RetrieveNumber{#1}}}%
\end{verbatim}%
\end{makeverbatimnice}%
\DeclareRobustCommand\storevalue[1]{%
  \StoreNumber{#1}{\the\numexpr\value{counterA}+1\relax}%
}%
\DeclareRobustCommand\getvalue[1]{\textbf{Value \RetrieveNumber{#1}}}%

\hbox to\textwidth{\null\hrulefill\null}%

\verb|\getvalue{vala}|: \getvalue{vala}%

\verb|\getvalue{valc}|: \getvalue{valc}%

\verb|\getvalue{valb}|: \getvalue{valb}%

\hbox to\textwidth{\null\hrulefill\null}%

\begin{makeverbatimnice}
\begin{verbatim}
\setcounter{counterA}{0}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{vala}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{valb}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{valc}%
\end{verbatim}%
\end{makeverbatimnice}%
\setcounter{counterA}{0}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{vala}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{valb}%
\stepcounter{counterA}% You can also use \refstepcounter but you don't have to.
\storevalue{valc}%

\hbox to\textwidth{\null\hrulefill\null}%

\verb|\getvalue{vala}|: \getvalue{vala}%

\verb|\getvalue{valc}|: \getvalue{valc}%

\verb|\getvalue{valb}|: \getvalue{valb}%

\end{document}

在此处输入图片描述

在此处输入图片描述

相关内容