如何在环境参数中包含标签?

如何在环境参数中包含标签?

我使用 environment 包为关键参数编写了自己的环境“定理”,最近遇到了两个问题:如何插入引用作为参数以及如何使用标签来实现?

情况如下:引用定理时,我不仅想获取数字,还想获取文本“定理 1.1”(其中 1.1 是定理的正确数字)。我不喜欢在其他环境中首先将标签写为 BODY,所以我想将其作为参数包含在内。当我使用标签名称作为参数()\mytheorem@label并将其作为环境代码写入时,这种方法可以正常工作\label{\mytheorem@label}。但这有一个缺点,即在编写文档时,我在提示时无法获得标签列表\ref{}。因此,我想通过给出[label=\label{randomStuff}]作为参数来替换环境中的代码片段。

问题是,这根本行不通。它返回错误,即标签中的某些内容从未定义。我最近在引用方面遇到了同样的问题(结果应该看起来像定理 1.1(参见 [1]),其中 [1] 是第一个引用),在尝试\expandafter和之后\protect(我总是尝试,因为它们看起来很重要),我发现一个简单的\begin{mytheorem}[{cite=\cite{firstBook}}]方法就可以解决问题。所以我尝试了类似的东西,但没有用。

你有什么想法吗?如果有办法去掉 `cite 周围的括号,我也很乐意听听。下面是我想要的一个例子。

\documentclass{scrartcl]
\usepackage{Environ}
\newcounter{\theoremcounter}
\define@key{mytheorem}{cite}{\def\mytheorem@cite{#1}}
\define@key{mytheorem}{label}{\def\mytheorem@label{#1}}
\NewEnviron{mytheorem}[1][]{
    theorem \thesection.\theoremcounter\ \protect\theorem@cite\\
    \def\@currentlabel{theorem~\thesection.\theoremcounter}{{\lemma@label}}
    \BODY
}
\section{first sec}
\begin{document}
    \begin{mytheorem}[label=\label{th1},cite=(see \cite{author1})]
        good idea
    \end{mytheorem}

    As stated in \ref{th1} it is ... 
\end{document}

输出结果如下

1. first sec

theorem 1.1 (see [1])
good idea
As stated in theorem 1.1

抱歉,如果有什么不清楚的地方。我会尽力解释你需要的一切。我不得不让我的代码变得更小,我希望你能明白我的意思。

提前致谢

答案1

我不会重新发明轮子:定义类似定理的环境时有几个微妙之处,恐怕您的代码没有解决这些问题。有了amsthm您,您就有了很好的方法来管理它们。您可以使用cleveref它来添加标签。

我使用expl3键值系统的语法,因为它功能强大并且可以与语言的其他功能相结合,例如检查键是否已设置。

我们还可以想象一个抽象层,允许\NewTheorem命令执行类似的工作\newtheorem并应用下面概述的想法。

\documentclass{article}
\usepackage{amsthm}
\usepackage{cleveref}

\newtheorem{generalthm}{Theorem}[section]
\crefname{generalthm}{theorem}{theorems}
\Crefname{generalthm}{Theorem}{Theorems}

\ExplSyntaxOn
\NewDocumentEnvironment{theorem}{O{}}
 {
  \keys_set:nn { hannes/theorem } { #1 }
  \tl_if_empty:VTF \l__hannes_theorem_cite_tl
   { \generalthm }
   { \generalthm[\l__hannes_theorem_cite_tl] }
   \tl_if_empty:VF \l__hannes_theorem_label_tl { \l__hannes_theorem_label_tl }
 }
 {
  \endgeneralthm
 }

\keys_define:nn { hannes/theorem }
 {
  cite  .tl_set:N = \l__hannes_theorem_cite_tl,
  label .tl_set:N = \l__hannes_theorem_label_tl,
 }

\ExplSyntaxOff

\begin{document}

\section{Main results}

\begin{theorem}[label=\label{th1},cite=see \cite{author1}]
good idea
\end{theorem}

\begin{theorem}[label=\label{th2},cite=see \cite[page~42]{author1}]
good idea
\end{theorem}

\begin{theorem}[label=\label{th3}]
good idea
\end{theorem}

We see that \cref{th1} is important. But \cref{th2} is more important.
Not to mention \cref{th3}.

\begin{thebibliography}{1}

\bibitem{author1} A. Uthor, \emph{Nice paper}, Journal (\textbf{1}), 2022

\end{thebibliography}

\end{document}

我不会使用这样的键值语法,因为标准\label很容易输入:

\begin{theorem}[see \cite{author1}]\label{th1}
good idea
\end{theorem}

甚至更容易输入。

在此处输入图片描述

顺便说一句,我认为没有理由使用\NewEnviron

这是抽象层。

\documentclass{article}
\usepackage{amsthm}
\usepackage{cleveref}

\ExplSyntaxOn

\NewDocumentCommand{\NewTheorem}{momo}
 {
  % define the inner theorem-like environment
  \IfNoValueTF { #4 }
   {% we possibly have the first optional argument
    \IfNoValueTF { #2 }
     {% no parent counter
      \newtheorem{#1@inner}{#3}
     }
     {
      \newtheorem{#1@inner}[#2@inner]{#3}
     }
   }
   {% second optional argument
    \newtheorem{#1@inner}{#3}[#4]
   }
  % take care of cleveref
  \use:e
   {
    \exp_not:N \crefname{#1@inner}{\text_lowercase:n { #3 }}{\text_lowercase:n { #3 }s}
    \exp_not:N \Crefname{#1@inner}{\text_titlecase:n { #3 }}{\text_titlecase:n { #3 }s}
   }
  % define the user level environment
  \NewDocumentEnvironment{#1}{O{}}
   {
    \keys_set:nn { hannes/theorem } { ##1 }
    \tl_if_empty:VTF \l__hannes_theorem_cite_tl
     { \begin{ #1@inner } }
     { \begin{ #1@inner } [\l__hannes_theorem_cite_tl] }
    \tl_if_empty:VF \l__hannes_theorem_label_tl { \l__hannes_theorem_label_tl }
   }
   {
    \end{#1@inner}
   }
 }
\keys_define:nn { hannes/theorem }
 {
  cite  .tl_set:N = \l__hannes_theorem_cite_tl,
  label .tl_set:N = \l__hannes_theorem_label_tl,
 }

\ExplSyntaxOff

\NewTheorem{theorem}{Theorem}[section]
\NewTheorem{definition}[theorem]{Definition}

\begin{document}

\section{Main results}

\begin{theorem}[label=\label{th1},cite=see \cite{author1}]
good idea
\end{theorem}

\begin{theorem}[label=\label{th2},cite=see \cite[page~42]{author1}]
good idea
\end{theorem}

\begin{definition}[label=\label{def1}]
A definition
\end{definition}

\begin{theorem}[label=\label{th3}]
good idea
\end{theorem}

We see that \cref{th1} is important. But \cref{th2} is more important.
Not to mention \cref{th3}. And we have \cref{th1,th2,th3}.
Also \cref{def1} is interesting.


\begin{thebibliography}{1}

\bibitem{author1} A. Uthor, \emph{Nice paper}, Journal (\textbf{1}), 2022

\end{thebibliography}

\end{document}

在此处输入图片描述

注意如何\cref呈现多个交叉引用。

答案2

稍微不同的方法:

\documentclass{article}

\usepackage{ntheorem}
\usepackage{cleveref}
\theoremstyle{break}
\newtheorem{thm}{theorem}[section]

\usepackage{keyval}
\makeatletter
\define@key{mytheorem}{cite}{\def\mytheorem@cite{#1}}
\define@key{mytheorem}{label}{\def\mytheorem@label{#1}}
\newenvironment{mytheorem}[1][]{%
    \setkeys{mytheorem}{#1}%
    \begin{thm}[see \mytheorem@cite] \mytheorem@label
}{%
    \end{thm}
}
\makeatother

\begin{document}
\section{first sec}
\begin{mytheorem}[label=\label{th1},cite=\cite{book}]
    good idea
\end{mytheorem}

As stated in \cref{th1} it is ... 

\begin{thebibliography}{9}
\bibitem{book} Donald E. Knuth (1986) \emph{The \TeX{} Book}, Addison-Wesley Professional.
\end{thebibliography}
\end{document}

在此处输入图片描述

相关内容