# Using string conditionals to determine document class

I am trying to set up a set of templates for most of the styles I have created or collected. Right now I am using a bunch of LaTeX files with the \input{} and setting variables with \def. What I am looking to accomplish is to have the template setup execute a series of steps depending on the variable sent. For example.

My main document will have something like this on the first couple of lines.

\def\doctype{letter} % this could also be a book, article, beamer presentation, etc.
\input{template-setup}


Based on the doctype I want to get my template setup to select the right document class. I know of the xstring or xifthen packages, but since I want to use the doctype variable to select the right document class, this is not possible (since you cannot use a package before \documentclass). Can somebody please help me?

-
Welcome to LaTeX! Welcome to TeX.sx! You can enclose words in backticks  to mark them as code, as can be seen in my edit. (You can also highlight the code and click the "code" button (with "{}" on it) or hit Ctrl + K.) –  Torbjørn T. Apr 18 '12 at 19:55
Why not just let \doctype be the document class itself? So then you can say \documentclass{\doctype}, and afterwards load the appropriate preamble. –  Peter Grill Apr 18 '12 at 19:56
You can use \ifx. See here for an example: What does \ifx\\#1\\ stand for? –  Marco Daniel Apr 18 '12 at 19:57
Thank you for the tip Torb. Peter, because I use the same documentclass for several styles and I also use that doctype variable to set the rest of the template. Marco Daniel, wow, what can I say? I am completely lost. Do you mean I can do something like this? \ifx\doctype\letter <code for #1 is empty> \else \ifx\doctype\book <code for #1 is _not_ empty> \else \fi \fi –  tuxtlequino Apr 18 '12 at 22:07
–  lockstep Apr 19 '12 at 15:20

I will use a general class file that can load the specific class as an option and create a boolean type test for all the different classes. The following is just a first try. It can be enhanced with keyvalues, etc.

Edit 1: Add command \ClassList to provide your own class list.

%%%% generalclass.cls %%%%

\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{generalclass}[2012/04/19 v0.1 General class (DNJ ELS)]

\RequirePackage{etoolbox}

\newcommand*\DeclareClassList[2]{%
\def\@clsopt@select{#1}%-------------------- default class
\edef\@clsopt@list{\zap@space#2 \@empty}%--- list of classes
\@for\@clsopt@item:=\@clsopt@list\do{%
\newbool{@clsopt@test@\@clsopt@item}%
\csedef{@clsopt@def@\@clsopt@item}{%
\def\noexpand\@clsopt@select{\@clsopt@item}}}
\edef\@currclass@opt{\@ptionlist{\@currname.\@currext}}%
\@for\CurrentOption:=\@currclass@opt\do{%--- Go through documents options
\ifcsdef{@clsopt@def@\CurrentOption}{%
\csuse{@clsopt@def@\CurrentOption}%
\csdef{ds@\CurrentOption}{}%
\@use@ption}{}}}

\newcommand*\ThisClass{}
\newcommand\SetClassOption{%
\edef\@clsopt@temp{%
\noexpand\booltrue{@clsopt@test@\@clsopt@select}%
\def\noexpand\ThisClass{\@clsopt@select}}%
\@clsopt@temp}

\newcommand\IfClass[3]{%
\ifbool{@clsopt@test@#1}{#2}{#3}}

%----------------------------------------------------------------------
\providecommand*\ClassDefault{article}                   % Edit 1
\providecommand*\ClassList{article,report,book,letter}   % Edit 1
\DeclareClassList{\ClassDefault}{\ClassList}             % Edit 1
\SetClassOption

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{\ThisClass}}
\ProcessOptions\relax
\endinput


It can then be used as follows:

\newcommand*\DocType{memoir}
\newcommand*\FontSize{10pt}
\newcommand*\PaperSize{a4paper}

%---- [ Put this in template for \input{} ] -------------
\newcommand*\ClassList{article,report,book,letter,memoir}
\documentclass[\DocType,\FontSize, \PaperSize]{generalclass}
%% Usage
%\IfClass{article}{..<true>..}{..<false..}
%\IfClass{report}{..<true>..}{..<false..}
%\IfClass{book}{..<true>..}{..<false..}
%\IfClass{letter}{..<true>..}{..<false..}
%\IfClass{memoir}{..<true>..}{..<false..}
%---- [ End template ] ----------------------------------

\begin{document}
This class is: \ThisClass \par
This is \IfClass{article}{an}{not an} article class document\par
This is \IfClass{report}{a}{not a} report class document\par
This is \IfClass{book}{a}{not a} book class document\par
This is \IfClass{letter}{a}{not a} letter class document\par
This is \IfClass{memoir}{a}{not a} memoir class document\par
\end{document}

-
Wow Daniel, this is perfect. Thank you very much for providing the code. This is WAY beyond my knowledge of LaTex. I read and re-read until I figured out what was going on. If I had any reputation I would give you points for this answer. I am know scratching my head thinking how to use something like memoir (so I can use the document class article and memoir and the article option. How would you go about accomplishing this? Should I create another question for that? –  tuxtlequino Apr 19 '12 at 20:02
@tuxtlequino: I have changed the code a little bit to make it more general –  Danie Els Apr 20 '12 at 5:37
Daniel, I spent hours trying to find documentation for some of the things that you used in the code you provided without any meaningful results. Could you please point me somewhere I can figure out your code, or even better, could you document every line explaining what is happening? –  tuxtlequino Apr 20 '12 at 6:02
I think I did not made myself clear on my second question. The improvements to the code are appreciated but I still cannot do something like this... \documentclass{10pt,oneside,article}{memoir} or this \documentclass{10pt,oneside,book}{memoir} –  tuxtlequino Apr 20 '12 at 15:46
@tuxtlequino: Regarding the code, it is mostly for the source of the LaTeX kernel (see source2e.pdf) taken from the \ProcessOptions commands. For the second part the class type is now alway an optional argument for generalclass e.g. \documentclass[<options>, article]{generalclass} or \documentclass[<options>, memoir]{generalclass}. Please look at the example! –  Danie Els Apr 21 '12 at 3:39

You can define macros which hold the different values (letter, book, etc.) and then compare it with \doctype using \ifx\firstmacro\secondmacro <equal> \else <not equal> \fi:

\def\doctype{letter} % this could also be a book, article, beamer presentation, etc.
% ..
\def\doctypeletter{letter}
\def\doctypebook{book}
% ...

\ifx\doctype\doctypeletter
% doctype is 'letter'
\else
\ifx\doctype\doctypebook
% doctype is 'book'
\fi
\fi


Note that it is also possible (but not always recommendable) to load a package before the class using \RequirePackage instead of \usepackage.

You could also make your own class files which load the real class using \LoadClassWithOptions{<real class>}` and then include your required settings for this class.

-
Arg, just seeing now that tuxtlequino posted basically the same as comment 11 hours ago! Well I keep it for now. –  Martin Scharrer Apr 19 '12 at 9:27
Thank you very much Martin. –  tuxtlequino Apr 19 '12 at 16:37