# Creating package options which are mutually exclusive and choosing a default

I want to automatize some of the code that I usually include to setup my theorem environment functionality into a package. So here is what I do to control within which counter my theorems are numbered:

\RequirePackage{filecontents}

\begin{filecontents}{mytheorems.sty}
\RequirePackage{xkeyval}
\RequirePackage{amsthm}

\DeclareOptionX{numberwithin}{%
\theoremstyle{plain}%
\newtheorem{theorem}{Theorem}[#1]%
}
\DeclareOptionX{nonumberwithin}{%
\theoremstyle{plain}%
\newtheorem{theorem}{Theorem}%
}
\ProcessOptionsX

\theoremstyle{plain}
\newtheorem{lemma}[theorem]{Lemma}
\end{filecontents}

\documentclass{article}

\usepackage[nonumberwithin]{mytheorems}%or use option [numberwithin=section] for example

\begin{document}
\begin{lemma}
content...
\end{lemma}
\end{document}


Now I would like that the package is loaded with [nonumberwithin] if no option is given. However adding \ExecuteOptionsX{nonumberwithin} to the package won't allow [numberwithin=section] any longer because the two options clash. So what should I do?

In my opinion, the numberwithin etc. options should set a \if... variable and postpone the definition of the theorem according to the state of the, say, \if@numberwithin boolean. The argument of numberwithin must be stored, however.

As far as I know this is the way how standard LaTeX classes process mutually exclausive states for options.

\RequirePackage{filecontents}

\begin{filecontents}{mytheorems.sty}
\RequirePackage{xkeyval}
\RequirePackage{amsthm}

\newif\if@numberwithin
\def\@numberwithin{section}% Defining a default if needed
\DeclareOptionX{numberwithin}{%
\@numberwithintrue
\gdef\@numberwithin{#1}%
}
\DeclareOptionX{nonumberwithin}{%
\@numberwithinfalse
}
\ExecuteOptionsX{nonumberwithin}
\ProcessOptionsX

\if@numberwithin
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[\@numberwithin]%
\else
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}%
\fi

\theoremstyle{plain}
\newtheorem{lemma}[theorem]{Lemma}
\end{filecontents}

\documentclass{article}

%\usepackage[numberwithin=section]{mytheorems}%or use option [numberwithin=section] for example

\usepackage{mytheorems}%or use option [numberwithin=section] for example

\begin{document}
\begin{lemma}
content...
\end{lemma}
\end{document}

• Thank you. Good to know that it is common practice to only set some booleans in a package option. – John Dorian Mar 27 '18 at 10:10
• Could you explain why you use \gdef here? In my primitive test samples, your code also works if I use \def. – John Dorian Mar 27 '18 at 10:11
• @JohnDorian: I was unsure whether there is a grouping involved during option processing, so I used \gdef (\global\def) for 'safety' reasons. If it works with \def as well, the better – user31729 Mar 27 '18 at 10:13

Add a default option to numberwithin, so that calling

\usepackage[numberwithin]{mytheorems}


or

\usepackage[numberwithin=section]{mytheorems}


will be equivalent as well as \usepackage{mytheorems}, because of \ExecuteOptionsX{numberwithin}. Then delay the association of the counter after processing the options.

\ProvidesPackage{mytheorems}
\RequirePackage{xkeyval}
\RequirePackage{amsmath}
\RequirePackage{amsthm}

\DeclareOptionX{numberwithin}[section]{%
\def\mthm@numberwithin{#1}%
}
\DeclareOptionX{nonumberwithin}{%
\def\mthm@numberwithin{}%
}
\ExecuteOptionsX{numberwithin}
\ProcessOptionsX

\theoremstyle{plain}
\newtheorem{theorem}{Theorem}

\ifx\mthm@numberwithin\@empty\else
\numberwithin{theorem}{\mthm@numberwithin}
\fi

\newtheorem{lemma}[theorem]{Lemma}