假设在我冗长的博士论文中,我使用了一个类似定理的环境(可能是定理,可能是引理等),并给它贴上标签。在另一个地方,我想要一个与之前相同的环境(但编号不同)。我可以用cleveref
's获取环境的名称\namecref
- 但我不能直接使用它:
\documentclass{article}
\usepackage{ntheorem}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\begin{document}
\begin{theorem}
\label{myfirst}
This is the first theorem.
\end{theorem}
\begin{\namecref{myfirst}}
This is another environment of the same kind as \ref{myfirst}!.
\end{\namecref{myfirst}}
\end{document}
尝试\def
或\edef
对某事进行\namecref
操作也不起作用。我该怎么办?当然,第一次运行时无法知道环境,因此我显然需要一个宏,该宏可以在第一次运行时扩展为某个“虚拟环境”,在第二次运行时扩展为真实环境(\namecref
应该给出??第一次运行是没有用的。)
笔记:这个问题是这个问题的引子需要一个“薄”的、灵活的定理重述环境。
答案1
以下是基于现有cleveref
实现的 hack,我对此并不熟悉。它似乎有效,但您可能需要增加一些鲁棒性。(该解决方案类似于 Axel 的解决方案之一。)
\documentclass{article}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\usepackage{cleveref}
\makeatletter
\newenvironment{reformulation}[1]
{\expandafter\ifx\csname r@cref@#1\endcsname\relax% label undefined
\def\my@env{theorem}% if label is undefined, assume it's a theorem
\else%
\cref@gettype{#1}{\my@env}%
\fi%
\begin{\my@env}}%
{\end{\my@env}}
\makeatother
\begin{document}
\begin{lemma}\label{hi}
Lemma.
\end{lemma}
\begin{reformulation}{hi}
Theorem or lemma.
\end{reformulation}
\end{document}
答案2
可以使用cleveref
或hyperref
从辅助文件中获取环境的“纯”名称。遗憾的是,没有关于如何执行此操作的文档方法,因此在这两种情况下都必须使用内部宏(将来的版本可能会更改)。
首先是 的解决方案cleveref
。它使用了cleveref
包中的两个内部组件:
- cleveref 存储一个以“cref@”开头的附加标签,用于保存环境名称
- cleveref 提供了一个内部宏,用于
\cref@gettype
获取“纯”环境名称
\documentclass{article}
\usepackage{ntheorem}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}
\makeatletter
\newenvironment{xxxref}[1]{%
\@ifundefined{r@cref@#1}%
{\def\@xxx@env{quote}}% use default environment
{\cref@gettype{#1}{\@xxx@env}}%
\begin{\@xxx@env}}%
{\end{\@xxx@env}}%
\makeatother
\begin{document}
\begin{theorem}
\label{myfirst}
This is the first theorem.
\end{theorem}
\begin{xxxref}{myfirst}
\label{xxxfirst}
This is another environment of the same kind as \ref{myfirst}!.
\end{xxxref}
\begin{xxxref}{myfirst}
This is another environment of the same kind as \ref{xxxfirst}!.
\end{xxxref}
\end{document}
其次,为 提供了一个解决方案hyperref
。它使用了hyperref
包中的两个内部组件:
- hyperref 将环境名称存储在标签的第四个参数中
- 环境名称受该参数内的句点限制。
另请参阅我的回答:获取标签目标类型
\documentclass{article}
\usepackage{ntheorem}
\usepackage{hyperref}
\newtheorem{theorem}{Theorem}
\makeatletter
\newcommand*\@myautoref[2]{% \HyPsd@@@autoref from hyperref, modified
\expandafter\expandafter\expandafter\@@myautoref
\csname r@#2\endcsname{}{}{}{}\@nil#1\@nil
}
\def\@@myautoref#1#2#3#4#5\@nil#6\@nil{% \HyPsd@autorefname, modified
#6#4.\@nil}% Argument #4 = type and number, e.g. "section.1" or "subsection.1.2"
\def\@myreftype#1.#2\@nil{#1}
\newcommand*\beginref{\xxx@ref{\begin}}
\def\endref{\xxx@ref{\end}}
\newcommand*\xxx@ref[2]{%
\@ifundefined{r@#2}%
{\def\@tempa{quote}}% use default environment
{\def\@tempa{\@myautoref\@myreftype{#2}}}%
\edef\@tempa{\noexpand#1{\@tempa}}%
\@tempa}
\makeatother
\begin{document}
\begin{theorem}
\label{myfirst}
This is the first theorem.
\end{theorem}
\beginref{myfirst}
This is another environment of the same kind as \ref{myfirst}!.
\endref{myfirst}
\beginref{xxxfirst}
This is another environment of the same kind as \ref{xxxfirst}!.
\endref{xxxfirst}
\makeatother
\end{document}