1

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.

avs
  • 282
  • The options you define with \DeclareStringOption et 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@font after \ProcessKeyvalOptions if 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:53
  • 1
    Note that family = opt, prefix = opt@ are fairly generic and may thus clash with other packages/classes. Maybe choose a more unique name like family = avsopt, prefix = avsopt@ – moewe Jul 29 '20 at 06:56
  • About \iffam: \iffam@active is 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

0 Answers0