![枚举列表交叉引用的后缀](https://linux22.com/image/329555/%E6%9E%9A%E4%B8%BE%E5%88%97%E8%A1%A8%E4%BA%A4%E5%8F%89%E5%BC%95%E7%94%A8%E7%9A%84%E5%90%8E%E7%BC%80.png)
我有一个关于操作枚举列表交叉引用的问题。要更改列表的外观,我知道\theenumi
选择类型(罗马字母、阿拉伯字母、字母……)的命令,\labelenumi
用于列表中的标签和\p@enumi
交叉引用的前缀。但是是否也有用于后缀的宏?
举个例子,我想实现以下几点:
\begin{enumerate}
\item \label{item 1} Item
\begin{enumerate}
\item \label{subitem 1} Subitem
\item Second Subitem
\end{enumerate}
\item Another item
\end{enumerate}
其中引用\ref{item1}
给出(i)
并\ref{subitem 1}
给出(ia)
。我可以定义
\renewcommand*{\theenumi}{\roman{enumi}}
\renewcommand*{\theenumii}{\alph{enumii}}
\renewcommand*{\labelenumi}{(\theenumi)}
\renewcommand*{\labelenumii}{(\theenumii)}
这会给我列表本身的(i)
和。对于交叉引用,我可以尝试类似(a)
\renewcommand*{\p@enumi}{(}
\renewcommand*{\p@enumii}{\p@enumi\theenumi}
这给出了第一个括号,结果为(i
和(ia
。但是如何关闭括号呢?
从学术角度而非实际使用角度来说,我想知道三或四个嵌套列表的解决方案(尽管看起来很丑陋)。
我认为使用附加包可以很容易地解决问题。但我的问题实际上是关于后缀的可能宏,我不知何故希望它存在。因此还有一个问题:我(作为新手)如何找到已定义的宏列表?
答案1
对于您的基本示例,p
使用 TeX 的参数文本设置捕获前缀后面的内容就足够了:
\documentclass{article}
\makeatletter
\renewcommand*{\theenumi}{\roman{enumi}}
\renewcommand*{\theenumii}{\alph{enumii}}
\renewcommand*{\labelenumi}{(\theenumi)}
\renewcommand*{\labelenumii}{(\theenumii)}
\def\p@enumi\csname #1\endcsname{(\theenumi)}% First level
\def\p@enumii\csname #1\endcsname{(\theenumi\theenumii)}% Second level
% \def\p@enumiii\csname #1\endcsname{(\theenumi\theenumii\theenumiii)}% Third level
%...
\makeatother
\begin{document}
\section{First}\label{section1}
\begin{enumerate}
\item \label{item1} Item
\begin{enumerate}
\item \label{subitem1} Subitem
\item Second Subitem
\end{enumerate}
\item Another item~\ref{subitem1}
\end{enumerate}
Those are references to items:~\ref{item1} and~\ref{subitem1}, but this reference here~\ref{section1} does not have parentheses.
\end{document}
答案2
它实际上是\label
将 写入文件的命令\newlabel{foo}{\@currentlabel}{\thepage}
。.aux
由于\@currentlabel
已经是 等的扩展版本,因此\p@...
使用 之类的命令还为时过早(\p@...)
。
在我看来,该对必须由(...)
写入文件中,并且不能添加到自身中,因为涉及到链的扩展。.aux
\@currentlabel{...}
\p@....
\protected@edef
\@p...
我通过在启动后添加一些代码来应用这一策略enumerate
,\@currentlabel
只需稍微重新定义即可将这(...)
对作为的包装器\p@...\the...
。
重新定义以\refstepcounter
添加是(...)
不够的——这将应用于任何正在被引用的计数器。以下代码首先检查当前环境是否是enumerate
,然后应用相关设置。(但是,对于具有\refstepped
枚举但不在组中的其他计数器,它可能会失败。)
由于所有内容都在一个(环境)组中,因此的重新定义\refstepcounter
不会泄漏到外面。
\documentclass{article}
\makeatletter
\renewcommand*{\theenumi}{\roman{enumi}}
\renewcommand*{\theenumii}{\alph{enumii}}
\renewcommand*{\labelenumi}{(\theenumi)}
\renewcommand*{\labelenumii}{(\theenumii)}
\newcommand{\@@labelprefix}{%
(%
}
\newcommand{\@@labelpostfix}{%
)%
}
\let\@@latex@@refstepcounter\refstepcounter
\def\is@@enumerate{enumerate}
\def\refstepcounter#1{%
\ifx\@currenvir\is@@enumerate
\stepcounter{#1}%
\protected@edef\@currentlabel{\@@labelprefix\csname p@#1\endcsname\csname the#1\endcsname\@@labelpostfix}
\else
\@@latex@@refstepcounter{#1}%
\fi
}
\makeatother
\begin{document}
\section{First}\label{section1}
\begin{enumerate}
\item \label{item1} Item
\begin{enumerate}
\item \label{subitem1} Subitem
\item Second Subitem
\begin{figure}
\caption{foo}\label{firstfoo}
\end{figure}
\end{enumerate}
\item Another item \ref{subitem1}
\end{enumerate}
Those are references to items: \ref{item1} and \ref{subitem1}, but this reference here \ref{section1} does not have parentheses.
A reference for \ref{firstfoo}
\end{document}
enumitem
有了包裹就会更容易了;-)