使用 gdef 设置变量不起作用

使用 gdef 设置变量不起作用

请考虑以下 MWE:

\documentclass{report}
\usepackage{amsthm}

\makeatletter
%Define variable
\gdef\@depRe{chapter}
\def\depRe#1{\gdef\@depRe{#1}}

%Usie variable
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[\@depRe]
\makeatother

%Set variable
\depRe{section}

\begin{document}
\chapter{Network}
\section{Cellular}
\begin{theorem}
This is an example.
\end{theorem}
\end{document}

结果如下:

在此处输入图片描述

如您所见,我定义了“depRe”变量并将其用作定理计数器。但它对我不起作用,并且“depRe”(即部分)的值不适用!现在放在\depRe{section}前面\newtheorem ...,所以它起作用了。是否存在任何解决方案,我可以在\newtheorem命令之后设置“depRe”?

值得注意的是,我有 TexLive 2019。

答案1

问题在于,\newtheorem的编号参数(表示计数器的名称)在执行时会得到全面评估\newtheoremn

您可以使用伪计数器来实现\newtheorem参数内的编号,并使用前导宏\depRe来重新定义伪计数器指向哪个真实计数器:

\documentclass{report}

\makeatletter

% define fake-infrastructure of fake-counter:
\newcommand*\c@MyFakeCnt{}%
\newcommand*\cl@MyFakeCnt{}%
\newcommand*\p@MyFakeCnt{}%
\newcommand*\theMyFakeCnt{}%
\newcommand*\theHMyFakeCnt{}%
\newcommand*\MyFakeCntautorefname{}%
\newcommand*\MyFakeCntname{}%

% define \depRe to map MyFakeCnt to counter denoted by argument:
\newcommand\depRe[1]{%
  \expandafter\let\expandafter\c@MyFakeCnt\expandafter=\csname c@#1\endcsname
  \expandafter\let\expandafter\cl@MyFakeCnt\expandafter=\csname cl@#1\endcsname
  \expandafter\let\expandafter\p@MyFakeCnt\expandafter=\csname p@#1\endcsname
  \expandafter\let\expandafter\theMyFakeCnt\expandafter=\csname the#1\endcsname
  \expandafter\let\expandafter\theHMyFakeCnt\expandafter=\csname theH#1\endcsname
  \expandafter\let\expandafter\MyFakeCntautorefname\expandafter=\csname #1autorefname\endcsname
  \expandafter\let\expandafter\MyFakeCntname\expandafter=\csname #1name\endcsname
}%
\@onlypreamble\depRe
% some initialization:
\depRe{section}%
\makeatother


\usepackage{amsthm}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[MyFakeCnt]%

%\depRe{chapter}
\depRe{section}

\begin{document}
\chapter{Network}
\section{Cellular}
\begin{theorem}
This is an example.
\end{theorem}
\end{document}

答案2

\newtheorem处理时,尾随的可选参数应该扩展为计数器名称;该计数器永久附加到环境的定义。

从技术上讲,尾随参数是通过 处理的\csname...\endcsname,这意味着中间的标记的完全扩展。

如果您想制作一个包,我建议使用一个选项。

diyanat.sty

\RequirePackage{kvoptions}

\SetupKeyvalOptions{
  family=diyanat,
  prefix=diyanat@,
}

\DeclareStringOption[chapter]{theoremdepth}[chapter]
\define@key{diyanat}{theoremdepth}{\renewcommand{\diyanat@theoremdepth}{#1}}
\newcommand{\theoremdepth}{\diyanat@theoremdepth} % the user level interface

\ProcessKeyvalOptions*

test.tex

\documentclass{report}

%\usepackage{diyanat} % would use chapter
\usepackage[theoremdepth=section]{diyanat} % would use section

\usepackage{amsthm}

\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[\theoremdepth]

\begin{document}

\chapter{Network}

\section{Cellular}

\begin{theorem}
This is an example.
\end{theorem}

\end{document}

输出与\usepackage{diyanat}\usepackage[theoremdepth=chapter]{diyanat}

在此处输入图片描述

输出\usepackage[theoremdepth=section]{diyanat}

在此处输入图片描述

答案3

在阅读了您对问题的评论后,我想知道您是否有兴趣嵌套调用\@ifclassloaded

%\documentclass{book}
\documentclass{report}
%\documentclass{article}

\usepackage{amsthm}
\theoremstyle{plain}

\makeatletter
%%
%%\@ifclassloaded{<someclass>}{<true code>}{<false coode>}%
%%
\@ifclassloaded{book}{%
  \newtheorem{theorem}{Theorem}[chapter]%
}{%
  \@ifclassloaded{report}{%
    \newtheorem{theorem}{Theorem}[chapter]%
  }{%
    \@ifclassloaded{article}{%
      \newtheorem{theorem}{Theorem}[section]%
    }{%
      \newtheorem{theorem}{Theorem}%
    }%
  }%
}%
\makeatother

\begin{document}
\csname @ifundefined\endcsname{chapter}{\section}{\chapter}{Network}
\begin{theorem}
This is an example in a chapter.
\end{theorem}
\section{Cellular}
\begin{theorem}
This is an example in a section.
\end{theorem}
\end{document}

相关内容