[Tex/LaTex] Changing the default options of a document class

class-optionsdocumentclass-writing

I would like to define some base-class.cls, with some options and their defaults, and then provide some mechanism so that other derived classes can reuse the existing options and change the defaults. Furthermore, I would like that options added to the base-class in the future also propagate to the derived classes without any further change.

This question is somewhat related to an existing question about new and existing class options. In essence, How to replace the default set of options when defining a new class?.

As an example, assume that there is some base article.cls with three mutually exclusive options: 10pt, 11pt and 12pt. Where 10pt is the default option. Now one wants to define a new document class, say nice-article which has the same three options, but 11pt is the default.

From the answer to the linked question, the solution would be to declare the three options within nice-article.cls using \DeclareOption which store the selected action in some if's or macros, then call \ExecuteOptions{11pt} to set the new default, and finally call \PassOptionsToClass{...}{article} with the appropriate saved option.

But all this seems too cumbersome and is not very modular. Say for example that later article adds a new 13pt option. Ideally I would also like nice-article to also benefit from this new option; in particular if I explicitly said

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

However using that solution I would also have to go and modify nice-article.cls to make it aware of the new existing 13pt.

So the question is (a) hasn't this problem been already solved? i.e. is there some package or extension or command which I'm missing and allows to do this? and, if not, (b) how should I go about implementing such feature?

Assume that I'm implementing a class base-class.cls which can have any kind of code and macros needed; but then I want to be able to define new classes on top of that (say nice-class.cls, bright-class.cls, funny-class.cls) which can use options from base-class, defining their own defaults and being automagically upgraded with more options if I happen to change the base-class.

Hope that the question makes sense.

Best Answer

You could declare a string option that accepts the font size and defaults to 11pt. However, this will come at the expense of the top class no longer being aware of what exactly it is doing. But that's a principal problem of upwards compatibility. E.g.

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{atop}[16/07/2011]

\RequirePackage{kvoptions}
% Declare a string option `fntsize' that is unique to the derived
% class `atop'. It will accept anything assuming `11pt' if
% unspecified.
\DeclareStringOption[11pt]{fntsize}
% probably more options...
\ProcessKeyvalOptions{atop}\relax
\PassOptionsToClass{\atop@fntsize}{article}

% Assume that any unknown option will be understood by the base class:
\DeclareOption*{%
  \PassOptionsToClass{\CurrentOption}{article}%
}
\ProcessOptions\relax

% Now load the base class with the `fntsize' option and any unknown
% option:
\LoadClass{article}

If you happen to be the author of the base class and hence have the freedom to make it "a good base class", you might do some fancier things. For example, you could add a macro that allows executing options after the class has been loaded. (Like hyperref's \hypersetup or geometry's \geometry.) Then you could further add a macro, say \getOptionList, that returns a comma separated list of all options. You may then retrieve the list of options accepted by the base class in the derived class and use it to make further decisions without hardcoding the status quo of base options.

Best