交叉引用任何计数器

交叉引用任何计数器

我猜\ref{Label}返回的是最后出现的计数器\label{Label}

此时有可能获取另一个计数器的任意值吗?\pageref返回页码,如何获取我已经制作的一个计数器?

答案1

并非真正的最后一个计数器:\label{foo}将引用使用\refstepcounter 在同一范围内 \label

我见过几次的一个错误是

\begin{figure}
\begin{center}
\includegraphics{whatever}
\caption{The caption text}
\end{center}
\label{foo}
\end{figure}

由于多种原因,这种做法是错误的,但在这种情况下,它有助于说明上面的观点:环境center是计数器步进的范围figure(作为的副作用\caption),但\label超出了这个范围,因此它不会引用图号。

该机制的工作方式如下:\refstepcounter{figure}做两件事

  1. \stepcounter{figure}(全局操作figure
  2. \edef\@currentlabel{\thefigure}

请注意,第二部分是局部重新定义;\@currentlabel是保存最后一个“refstepped”计数器的内部宏。

如果您想要\label引用fredcounter,您必须\refstepcounter{fredcounter}在某处发出并确保\label{foo}出现在任何其他计数器“refstepped”之前(通过诸如\section\caption或 之类的命令\item),并且在同一范围内

答案2

我完全不知道为什么在放置标签时需要访问所有计数器的值。

我想了解LaTeX 中\label..机制的工作原理可能会帮助您重新考虑您的愿望。\ref

就在几周前,TeX - LaTeX StackExchange 上出现了一个问题“如何防止在新环境中引用枚举?”,我看到了详细阐述与\label..\ref机制相关的事物在 LaTeX 2ε 中相互作用的方式的机会。我当时的回答可以在这里找到:https://tex.stackexchange.com/a/442118/118714


如果你已经了解\label..\ref机制的细节,并且有充分的理由坚持你的愿望,我在下面提供了一个示例,概述了可能处理此问题的方式。

这个想法的要点是:

\cl@@ckpt用于\include..功能的LaTeX2e-kernel-macro\includeonly确实包含一个\@elt{⟨countername⟩}列表,其中包含通过 创建的所有计数器的名称\newcounter

使用时Heiko Oberdiek 的zref 包,您可以轻松地使用该列表为每个计数器定义一个可引用的属性。

您需要区分立即设置值的计数器和在输出例​​程发出相关页面时设置/调整值的计数器。

您没有要求任何超链接/hyperref-package-functionity。
因此,对于下面的示例,我没有实现该功能,因为我没有理由猜测需要什么样的工作流程。

\documentclass{article}
\usepackage{zref}
\makeatletter
%%-------------------------------------------------------------------------
%% Paraphernalia:
%%.........................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@temp{}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-------------------------------------------------------------------------
%% Check whether argument contains no \relax-token on top-brace-level:
%%.........................................................................
%% \UD@CheckWhetherNoRelax{<Argument which is to be checked>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does not contain \relax>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does contain \relax>}%
\newcommand*\UD@RemoveToRelax{}\long\def\UD@RemoveToRelax#1\relax{}%
\newcommand\UD@CheckWhetherNoRelax[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@RemoveToRelax#1\relax}%
}%
%%-------------------------------------------------------------------------
%% Fork depending on strings being "page", "abspage", i.e., the names
%% of counters whose values are not set immediately but at 
%% page-shipout-time:
%%.........................................................................
\newcommand*\UD@@ForkDelayedCounter{}%
% Manually add the names of more counters whose values are not set immediately
% but at page-shipout-time.
\long\def\UD@@ForkDelayedCounter%
  #1\relax page\relax abspage\relax#2#3\relax\relax\relax{#2}%
\newcommand\UD@ForkDelayedCounter[1]{%
  \UD@CheckWhetherNoRelax{#1}{%
    \UD@@ForkDelayedCounter
    \relax#1\relax abspage\relax{\UD@firstoftwo}%<-page-counter
    \relax page\relax#1\relax{\UD@firstoftwo}%<-abspage-counter
    \relax page\relax abspage\relax{\UD@secondoftwo}%<-counter other than both page and abspage
    \relax\relax\relax
  }{\UD@secondoftwo}%<-\relax-token in counter name. This should not happen.
}%
%%-------------------------------------------------------------------------
%% At the beginning of the document-environment, when all counter-defining
%% should be done, create a new property list holding all counter values:
%%  (The LaTeX2e-kernel-macro \cl@@ckpt which is used for the 
%%   \include/\includeonly-feature does hold an \@elt{<countername>}-list 
%%   with the names of all counters created via \newcounter.)
%%.........................................................................
\zref@newlist{UD@AllCounterValues}%
\newcommand\UD@CounterValueAsProperty[1]{%
  \UD@ForkDelayedCounter{#1}{%
    \zref@newprop*{Ref#1}{\csname the#1\endcsname}%
  }{%
    \zref@newprop{Ref#1}{\csname p@#1\endcsname\csname the#1\endcsname}%
  }%
  \zref@addprop{UD@AllCounterValues}{Ref#1}%
}%
\newcommand*\UD@AllCounterValuesAsProperties{%
  \let\UD@temp=\@elt
  \let\@elt=\UD@CounterValueAsProperty
  \cl@@ckpt
  \let\@elt=\UD@temp
}%
\AtBeginDocument{\UD@AllCounterValuesAsProperties}%
%%-------------------------------------------------------------------------
%% Create referencing and label commands:
%%.........................................................................
\newcommand*\AllCounterValuesLabel[1]{%
  \@bsphack
  \zref@labelbylist{#1}{UD@AllCounterValues}%
  \@esphack
}%
\newcommand*\CounterValueRef[2]{%
  \zifrefundefined{#1}{%
    \zref@refused{#1}\nfss@text{\reset@font\bfseries??}%
  }{%
    \zref@extractdefault{#1}{Ref#2}{%
      \@latex@warning{%
        Reference `#1' on page \thepage\space does not hold a value of counter #2%
      }%
      \nfss@text{\reset@font\bfseries??}%
    }%                
  }%
}%
\makeatother

\newcounter{mycounter}

\newcommand\DoSomethingWithMycounter{%
  \stepcounter{mycounter}%
  \texttt{mycounter} has the value \number\value{mycounter}.
}%


\begin{document}
\section{A section}
Some text
\subsection{A subsection}
Some text
\subsection{Another subsection}
\subsubsection{A subsubsection}
\subsubsection{Another subsubsection}
\subsubsection{Yet another subsubsection}
\begin{enumerate}
\item Item 1
\item Item 2
\item Item 3
\item Item 4\par
\DoSomethingWithMycounter\par
\DoSomethingWithMycounter\par
\AllCounterValuesLabel{MyNiceLabel}%
\end{enumerate}

\newpage

\section*{Referencing:}

\hskip\parindent
At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@section\thesection! expanded to:
\CounterValueRef{MyNiceLabel}{section}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@subsection\thesubsection! expanded to:
\CounterValueRef{MyNiceLabel}{subsection}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@subsubsection\thesubsubsection! expanded to:
\CounterValueRef{MyNiceLabel}{subsubsection}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@enumi\theenumi! expanded to:
\CounterValueRef{MyNiceLabel}{enumi}
\bigskip

At the time of placing the label \verb!MyNiceLabel!,\\
\verb!\p@mycounter\themycounter! expanded to:
\CounterValueRef{MyNiceLabel}{mycounter}
\bigskip

\end{document}

在此处输入图片描述 在此处输入图片描述

相关内容