![使 \refstepcounter (\@currentlabel) 在其组之外可见](https://linux22.com/image/365839/%E4%BD%BF%20%5Crefstepcounter%20(%5C%40currentlabel)%20%E5%9C%A8%E5%85%B6%E7%BB%84%E4%B9%8B%E5%A4%96%E5%8F%AF%E8%A7%81.png)
我定义了自己的列表环境。请参阅以下 MWE:(如果您问我为什么不使用标准列表,实际定义要复杂得多)
\documentclass{article}
\makeatletter
\newcounter{mylist}
\renewcommand*{\themylist}{\Alph{mylist}}
\newcommand*{\labelmylist}{\themylist}
\newcommand*{\makemylabel}[1]{%
\refstepcounter{mylist}%
\@mklab{\labelmylist}%
}
\newenvironment{mylist}{
\list{\@empty}{
\let\makelabel\makemylabel
\setcounter{mylist}{0}
}
}{
\endlist
}
\makeatother
\begin{document}
\section{Section Title}
\begin{mylist}
\item\label{foo} List entry 1
\end{mylist}
The reference are wrong: \ref{foo}.
\end{document}
错误在于\ļabel{foo}
创建了对子部分计数器的引用,从而\ref{foo}
打印了错误的标签。
我理解,\refstepcounter
重新定义\@currentlabel
并\label
发送\@currentlabel
至辅助文件。
但\refstepcounter
使用\edef
(而非\xdef
),因此在命令结束\@currentlabel
后重置为旧定义\makemylabel
。因此\label{foo}
使用 的计数器\section
。
我如何\label{foo}
使用正确的计数器?
根据评论进行更新
由于 @david-carlisle 和 @alan-munn 提出的问题,MWE 不再那么小
\documentclass{article}
\makeatletter
\newcounter{mylist}
\renewcommand*{\themylist}{FA-\Alph{mylist}}
\newcommand*{\labelmylist}{\themylist}
\newcommand*{\makemylabel}[1]{%
\if#1\@empty\else\setcounter{mylist}{#1}\addtocounter{mylist}{-1}\fi%
\refstepcounter{mylist}%
\@mklab{\labelmylist}%
}
\newenvironment{mylist}{
\list{\@empty}{
\let\makelabel\makemylabel
\setcounter{mylist}{0}
}
}{
\endlist
}
\makeatother
\begin{document}
\section{Section Title}
\begin{mylist}
\item\label{foo} List entry A
\item[5] List entry E
\item\label{bar} List entry F
\end{mylist}
The reference are wrong: \ref{foo} and \ref{bar}.
\end{document}
答案1
我认为最好构造代码以使用第一个参数,\list
该参数专门用于控制用于引用的计数器,但是从您所在的位置开始,您可以使用以下方法将定义\@currentlabel
从组中提出\aftergroup
:
\documentclass{article}
\makeatletter
\newcounter{mylist}
\renewcommand*{\themylist}{FA-\Alph{mylist}}
\newcommand*{\labelmylist}{\themylist}
\newcommand*{\makemylabel}[1]{%
\if#1\@empty% you probably want \ifx\relax#1\relax
\else\setcounter{mylist}{#1}\addtocounter{mylist}{-1}\fi%
\refstepcounter{mylist}%
\protected@xdef\zzz{\def\noexpand\@currentlabel{\@currentlabel}}%
\aftergroup\zzz
\@mklab{\labelmylist}%
}
\newenvironment{mylist}{%%%%%
\list{}{%%%%%
\let\makelabel\makemylabel
\setcounter{mylist}{0}%%%%%
}
}{%%%%%%%%%%
\endlist
}
\makeatother
\begin{document}
\section{Section Title}
\begin{mylist}
\item\label{foo} List entry A
\item[5] List entry E
\item\label{bar} List entry F
\end{mylist}
The reference are wrong: \ref{foo} and \ref{bar}.
\end{document}