我希望能够做如下的事情:
\incmycounter{abc} %% counter value initialized to 0; associated with label 'abc'
\incmycounter{def} %% counter value initialized to 0; associated with label 'def'
... various text (including some calls to \incmycounter) ...
\incmycounter{abc} %% counter value == 2; associated with label 'abc'
\incmycounter{def} %% counter value == 100; associated with label 'def'
... some text (possibly defining new sections, labels, etc.) ...
\myref{abc} %% generate '2'
... more text ...
\myref{abc} %% generate '2'
\incmycounter{abc} %% counter value == 3; associated with label 'abc'
... more text ...
\myref{abc} %% generate '3'
\myref{def} %% generate '100'
该\incmycounter
命令应该初始化一个新的计数器(与提供的标签名称相关联),或者增加当前定义的计数器。给定的\myref
命令应该始终引用/生成前一个\incmycounter
命令执行后相关计数器的值。这可能吗?如果可以,怎么做?
答案1
您可以定义一个宏来根据需要存储和更改值,而无需使用\label
- \ref
:
\documentclass{article}
\makeatletter
\newcommand{\mycounter}[2]{\global\@namedef{@cnt-#1}{#2}}
\newcommand{\myref}[1]{\@nameuse{@cnt-#1}}
\makeatother
\begin{document}
\mycounter{abc}{2} %% new counter value == 2
\mycounter{def}{100} %% new counter value == 100
\par \ldots some text (possibly defining new sections, labels, etc.) \ldots \par
\myref{abc} %% generate '2'
\par \ldots more text \ldots \par
\myref{abc} %% generate '2'
\mycounter{abc}{3} %% new counter value == 3
\par \ldots more text \ldots \par
\myref{abc} %% generate '3'
\myref{def} %% generate '100'
\end{document}
\@namedef{<name>}{<stuff>}
存储<stuff>
在 中\<name>
,而\@nameuse
检索它。我在名称前面加上了@cnt-
,因为\def
(如您的示例)是“已被使用”,而\@cnt-def
不是。\global
使更改成为全局的,否则它可能会被困在基于其范围的环境中。使用\@namedef
- \@nameuse
(来自 LaTeX 内核)还允许您(如我的示例)使用通常不允许的字符来定义名称。
上述示例未使用计数器,但可以对其进行修改以允许使用计数器。从代码片段来看,这似乎没有必要。
这是一个使用计数器的修改版本,如果计数器尚不存在则创建它们:
\documentclass{article}
\makeatletter
\newcommand{\incmycounter}[1]{%
\@ifundefined{c@#1}
{\newcounter{#1}}
{\stepcounter{#1}}}
\newcommand{\myref}[1]{\@nameuse{the#1}}
\makeatother
\begin{document}
\incmycounter{abc} %% counter value initialized to 0; associated with label 'abc'
\incmycounter{def} %% counter value initialized to 0; associated with label 'def'
\par \ldots various text (including some calls to macros\incmycounter{abc}\incmycounter{def}) \ldots \par
\myref{abc} %% generate '1'
\par \ldots more text \ldots \par
\incmycounter{def}\myref{def} %% generate '2'
\incmycounter{abc} %% counter value == 2
\par \ldots more text \ldots \par
\incmycounter{abc}\myref{abc} %% generate '3'
\myref{def} %% generate '100'
\end{document}
的第一步\incmycounter{<name>}
是检查计数器是否<name>
已经存在。这是使用 完成的\@ifundefined{c@#1}
,因为由 定义的所有计数器都\newcounter
引用以 开头的宏c@
。因此,计数器<name>
实际上存储在 中\c@<name>
。如果不存在,则发出\newcounter{<name>}
,否则\stepcounter{<name>}
。
另一个版本使用计数器,可用于设置/步进/任意增加您使用的计数器:
\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\makeatletter
\NewDocumentCommand{\mycounter}{s O{1} m}{%
\@ifundefined{c@#3}
{\newcounter{#3}}
{\IfBooleanTF{#1}
{\setcounter{#3}{#2}}
{\addtocounter{#3}{#2}}}}
\newcommand{\myref}[1]{\@nameuse{the#1}}
\makeatother
\begin{document}
\mycounter{abc} %% counter value initialized to 0; associated with label 'abc'
\mycounter{def} %% counter value initialized to 0; associated with label 'def'
\par \ldots various text (including some calls to macros\mycounter{abc}\mycounter{def}) \ldots \par
\myref{abc} %% generate '1'
\par \ldots more text \ldots \par
\mycounter{def}\myref{def} %% generate '2'
\mycounter{abc} %% counter value == 2
\par \ldots more text \ldots \par
\mycounter{abc}\myref{abc} %% generate '3'
\mycounter*[100]{def}%% counter value == 100
\myref{def} %% generate '100'
\end{document}
这使用xparse
提供命令接口。现在在可选的星号版本 ( ) 中\mycounter[<value>]{<cntr>}
增加或设置<cntr>
为。<value>
<cntr>
<value>
\mycounter*[<value>]{<cntr>}
答案2
据我了解,你可以写:
\newcounter{myabc}
\newcounter{mydef}
\setcounter{myabc}{2}
\setcounter{mydef}{100}
.... some text ....
\themyabc %% geenerate '2'
\stepcounter{myabc}
.... more text ....
\themyabc %% generates '3'
\themydef %% generate '100'
如果您可以提供更多背景信息,我可能会给您一个更能满足您需求的答案。
以下是如何运用\myref
我上面概述的方法:
\documentclass{article}
\newcounter{abc}
\makeatletter
\newcommand{\myref}[1]{\@nameuse{the#1}}
\makeatother
\begin{document}
\setcounter{abc}{3}
\theabc\ compared to \myref{abc}
\end{document}
这确实沃纳而不是我。
这就是为什么我认为@werner 的解决方案更好:
它非常方便用户使用:您不必记住如何设置。使用我的方法,您必须记住要定义一个计数器,计数器需要步进,等等。
六个月或一年后,你可能会想,“我做的那个很酷的把戏是什么?”正如我所写的那样,几乎没有什么可以提醒你全部您需要采取哪些步骤来重现效果。Werner 的解决方案非常紧凑,而且——只要您能轻松阅读 TeX 和 LaTeX 代码——相对来说很容易理解(带或不带注释)。
Werner 的方法非常灵活。也许一周后或一个月后,你会意识到你想要一些更动态的东西,或者你想让这些计数器与文档中的其他结构(如章节、定理等)相关联。(我知道你最初的帖子似乎表明这不是你想要的,但我们经常改变主意。)在这方面,我的方法非常笨拙,容易出错。