I am writing a simple class based on article that loads some commonly used packages and sets some defaults. The document font should be a key=value option \documentclass{myarticle}. For example, font=charter, font=utopia and font=libertine set the font to Charter, Utopia and Linux Libertine, respectively. Charter should be the default (just passing font should not be possible). I am having trouble setting this up using the kvoptions package. If I understand correctly I should use \DeclareStringOption[charter]{font}[] to set charter as the default of no font= is specified, but I am not sure where to declare the other options. In the documentation I see the function \SetupKeyvalOptions{}, but I don't understand what familiy, prefix and setkeys mean. The documentation is not clear on this (at least not to someone who's never done this kind of thing before).
I figured I would put the lines required to set the font in some kind of if else statement. I have looked at the ifthen package but I don't understand how to combine that with kvoptions. Also, it seems ifthen requires nesting of the different statements (correct?), which quickly becomes messy since I have more font options.
Here is what I have now for myarticle.cls:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myarticle}[2020/07/28 Custom article class]
\LoadClass{article}
\RequirePackage{kvoptions}
\SetupKeyvalOptions{
family = font,
prefix = font@
}
\DeclareStringOption[charter]{font}
\ProcessKeyvalOptions*
\iffont@charter
\RequirePackage[charter]{mathdesign}
\else\iffont@utopia
\RequirePackage[adobe-utopia]{mathdesign}
\else
\RequirePackage{libertine,libertinust1math}
\fi
and main.tex:
\documentclass[font=utopia]{myarticle}
\usepackage[utf8]{inputenc}
\begin{document}
Content...
\end{document}
The problem is that I don't know how to evaluate the option in the if statement. Can you only evaluate true/false statements?
PS. I am also a little confused by the \iffam command I see here (page 112). How does the combination between \if and fam work?
EDIT:
I have changed myarticle.cls to:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myarticle}[2020/07/28 Custom article class]
\LoadClass{article}
\RequirePackage{kvoptions}
\RequirePackage{etoolbox}
\SetupKeyvalOptions{family = opt, prefix = opt@}
\DeclareStringOption[charter]{font}
\ifdefstring{\opt@font}{charter}{\RequirePackage[charter]{mathdesign}}{}
\ifdefstring{\opt@font}{utopia}{\RequirePackage[utopia]{mathdesign}}{}
\ifdefstring{\opt@font}{libertine}{\RequirePackage{libertine,libertinust1math}}{}
\ifdefstring{\opt@font}{lmodern}{\RequirePackage{lmodern}}{}
\ProcessKeyvalOptions{opt}
Changing the default in \DeclareStringOption now changes the document font, but setting another option in \documentclass has no effect.
EDIT2:
Moving \ProcessKeyvalOptions{opt} to directly below \DeclareStringOption[charter]{font} solves my problem. Still, I'd like to know if this is a "good" approach to doing this.
\DeclareStringOptionet al. are only processed at the point you call\ProcessKeyvalOptions. Before that you can not rely on any code these options execute or any macros/strings they define. Since\DeclareStringOption[charter]{font}just sets\opt@font, you can only use\opt@fontafter\ProcessKeyvalOptionsif you want to actually grab the class options. In your case that means moving\ProcessKeyvalOptions{opt}to before the\ifdefstring{\opt@font}block. – moewe Jul 29 '20 at 06:53family = opt, prefix = opt@are fairly generic and may thus clash with other packages/classes. Maybe choose a more unique name likefamily = avsopt, prefix = avsopt@– moewe Jul 29 '20 at 06:56\iffam:\iffam@activeis a single command, with@in its command name. The same holds for\iffam@final. Related: \makeatletter explained. – muzimuzhi Z Aug 07 '20 at 16:36