我的计数器正在通过命令更新,我想在特定点保存该计数器的当前值 + 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}