我使用 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}