考虑输出
此 MWE:
\documentclass{book}
\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{suffix}
\declaretheorem[numberwithin=chapter, style=plain,name=Theorem,refname={theorem,theorems},Refname={Theorem,Theorems}]{theorem}
\begin{document}
\chapter{Test Chapter}
\begin{restatable}[Made-Up Theorem]{theorem}{MadeUpTheorem}
This is a made-up theorem.
\end{restatable}
Now, let's repeat the restatable theorem:
\MadeUpTheorem*
Next, let's try to define a new command if it has not yet been defined.
\WithSuffix\providecommand\MadeUpTheorem*{ABC}
Let's see what happens:
\MadeUpTheorem*
\textbf{Why does this output ABC? Why not the original theorem?}
I thought providecommand only defined a command if it had not already been defined.
\end{document}
- (可选)问:为什么会输出 ABC?为什么它不再次输出原来编造的定理?
- 问:
\MadeUpTheorem*
更重要的是,如果它以前没有被定义,我该如何“重新定义” ?
即使已经定义,它似乎\providecommand
也会覆盖原始定义。\MadeUpTheorem*
在我的用例中,原始文件restatable
与调用的文件位于不同的文件中\MadeUpTheorem*
。它是使用编译的\include
,但在中间编译期间不是包括在内,因此未定义。但在最终编译期间,它被包括在内,因此不应打印“ABC”。
答案1
(可选)问:为什么输出 ABC?为什么不再次输出原来编造的定理?
因为实际上执行的 if-defined-then-skip 条件作用\providecommand
于内部命令\WSF:\MadeUpTheorem the character *
(由 组成\csname\SuffixName\MadeUpTheorem*\endcsname
),而不是\MadeUpTheorem
其本身。
由于内部命令始终未定义,因此\MadeUpTheorem
后跟星号的行为始终会发生变化。这意味着\WithSuffix\providecommand...
和的净效应\WithSuffix\newcommand...
相同。
thmtools
查看不使用但使用手动定义的示例\mycmd*
\documentclass{article}
\usepackage{suffix}
\usepackage{fvextra} % for \EscVerb
\makeatletter
\def\mycmd{\@ifstar{\mycmd@{starred, original}}{\mycmd@{not starred}}}
\def\mycmd@#1{#1\par}
\makeatother
\parindent=0pt
\begin{document}
\subsection*{initially}
\mycmd
\mycmd*
\subsection*{after \EscVerb{\\WithSuffix\\providecommand\\mycmd*{...}}}
\WithSuffix\providecommand\mycmd*{starred, after \EscVerb{\\WithSuffix}}
\mycmd
\mycmd*
\end{document}
问
\MadeUpTheorem*
:更重要的是,如果以前没有定义过,我该如何“重新定义” ?
一般来说,没有简单的解决方案。关键在于它\MadeUpTheorem*
不是一个单一的命令,而是\MadeUpTheorem
后面跟着一个星号,并且\MadeUpTheorem
定义了它是否后面跟着可选的星号,其行为会有所不同。
一般条件检查“如果命令/宏接受可选星号”并不简单,但如果您知道该命令是由某些实用程序命令定义的,因此/或其替换文本遵循某种模式,则可以检查这些模式并提供部分解决方案。
例如,\MadeUpTheorem
定义的\begin{restatable}[Made-Up Theorem]{theorem}{MadeUpTheorem}
模式为
% see https://github.com/muzimuzhi/thmtools/blob/0.74/source/thm-restate.dtx#L201-L207
\gdef\MadeUpTheorem{%
\@ifstar{%
\thmt@thisistheonefalse\csname thmt@stored@MadeUpTheorem\endcsname
}{%
\thmt@thisistheonetrue\csname thmt@stored@MadeUpTheorem\endcsname
}%
}
\documentclass{article}
\usepackage{suffix}
\usepackage{amsthm, thmtools}
\usepackage{fvextra} % for \EscVerb
\declaretheorem[numberwithin=section, style=plain,name=Theorem,refname={theorem,theorems},Refname={Theorem,Theorems}]{theorem}
\makeatletter
\def\mycmd{\@ifstar{\mycmd@{starred, original}}{\mycmd@{not starred}}}
\def\mycmd@#1{#1\par}
\newcommand\starred@restatable[1]{%
\unexpanded{%
\@ifstar{%
\thmt@thisistheonefalse\csname thmt@stored@#1\endcsname
}{%
\thmt@thisistheonetrue\csname thmt@stored@#1\endcsname
}%
}%
}
\newcommand\IfRestatableTF[1]{%
\begingroup
\edef\starred@temp{\ExpandArgs{e}\starred@restatable{\scantokens\expandafter{\expanded{\expandafter\@gobble\string#1}\noexpand}}}%
\expandafter\endgroup
\ifx#1\starred@temp
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\parindent=0pt
\begin{document}
\section{title}
\begin{restatable}[Made-Up Theorem]{theorem}{MadeUpTheorem}
This is a made-up theorem.
\end{restatable}
\subsection*{initially}
\mycmd
\mycmd*
\MadeUpTheorem
\MadeUpTheorem*
\subsection*{after \EscVerb{\\WithSuffix\\providecommand\\mycmd*{...}}}
\WithSuffix\providecommand\mycmd*{starred, after \EscVerb{\\WithSuffix}}
\mycmd
\mycmd*
\IfRestatableTF\MadeUpTheorem
{}
{\WithSuffix\newcommand\MadeUpTheorem*{ABC}}
\MadeUpTheorem
\MadeUpTheorem*
\end{document}
注意@Ulrike Fischer 的建议(\ProvideDocumentCommand\MadeUpTheorem{s}{abc}
)检查\MadeUpTheorem
其本身是否已定义,而不是是否\MadeUpTheorem
已定义和接受可选的星星。