Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Finding the Document Class

43 views
Skip to first unread message

Herbert Schulz

unread,
Jun 18, 2005, 2:17:04 PM6/18/05
to
Howdy,

Is there a (possibly low level) LaTeX command that allows a package
writer to find out the name of the document class (without the .cls
would be nice) for a given document? I was looking at latex.ltx but it
certainly wasn't clear to me.

Good Luck,
Herb Schulz

Ulrich M. Schwarz

unread,
Jun 18, 2005, 3:11:29 PM6/18/05
to
Herbert Schulz <he...@wideopenwest.com> writes:

You could try \@ifclasswith{article}{}{Yes}{No}, if I read correctly
(it's section 69.3 of the kernel).

Ulrich
--
∀x∈ℕ or \forall x\in \mathbb{N}?
http://talcum.sarovar.org/ (Current release: 0.5.0 20050306)

Morten Høgholm

unread,
Jun 18, 2005, 6:02:15 PM6/18/05
to

Not really. There's the command \@ifclassloaded{<class>} but that's not
quite what you want. So either you have to do something like

\let\LaTeXdocumentclass\documentclass
\renewcommand*\documentclass[2][]{%
\newcommand*\ClassName{#2}% for later use
\LaTeXdocumentclass[#1]{#2}}
\documentclass[<options>]{<class>}
...

or possibly something even more horrific...
--
Morten

Hendri Adriaens

unread,
Jun 19, 2005, 4:11:06 AM6/19/05
to
> Is there a (possibly low level) LaTeX command that allows a package
> writer to find out the name of the document class (without the .cls
> would be nice) for a given document? I was looking at latex.ltx but it
> certainly wasn't clear to me.

xkeyval provides \XKV@documentclass which contains the class
if loaded after the \documentclass command.

-Hendri.


Heiko Oberdiek

unread,
Jun 19, 2005, 9:52:57 AM6/19/05
to
Morten Høgholm <morten....@gmail.com> wrote:

Yes. :-(

A class can load another class.
Thus some kind of list datastructure is necessary
to get informed about the loaded classes.

%%% cut %%% classlist.sty %%% cut %%%
% File: classlist.sty
% Version: 2005/06/19 v1.0
% Author: Heiko Oberdiek
% Email: <ober...@uni-freiburg.de>
%
% Copyright: Copyright (C) 2005 Heiko Oberdiek.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3 of this license or (at your option) any
later
% version. The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions
of
% LaTeX version 2003/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% This Current Maintainer of this work is Heiko Oberdiek.
%
% Function: This package records the loaded classes and stores
% them in a list.
%
% Background: This packages is an answer of a newsgroup question:
% Newsgroup: comp.text.tex
% Subject: Finding the Document Class
% From: Herber Schulz <>
% Date: 18 Jun 2005 13:16:49 -0500
% Message-ID:
% <herbs-D55DB9....@news.isp.giganews.com>
%
% Use: Load this package before \documentclass:
% \RequirePackage{classlist}
% \documentclass[some,options]{whatever}
%
% \MainClass contains the first loaded class.
% \ClassList stores the class entries, eg.
% \ClassList -> \ClassListEntry{myarticle}{a4paper}{}
% \ClassListEntry{article}{}{}
% \ClassListEntry has three arguments:
% #1: class name
% #2: options given in \documentclass/\LoadClass
% #3: requested version, not the version of class
% \PrintClassList prints the list on screen it can be
% configured by
% \PrintClassListTitle for the title and
% \PrintClassListEntry for formatting the entries.
%
% History:
% 2005/06/19 v1.0:
% first published version
% (comp.text.tex, CTAN).
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{classlist}%
[2005/06/19 v1.0 Record loaded classes (HO)]

% This package must be loaded before the first \documentclass
\ifx\documentclass\@twoclasseserror
\PackageError{classlist}{%
Package loaded after \string\documentclass
}{%
Use:\MessageBreak
\string\RequirePackage{classlist}\MessageBreak
\string\documentclass...%
}%
\expandafter\endinput
\fi

\let\ClassList\@empty
\let\MainClassName\relax

\let\CL@org@fileswith@pti@ns\@fileswith@pti@ns
\def\@fileswith@pti@ns#1[#2]#3[#4]{%
% #1: \@clsextension
% #2: options of \documentclass/\LoadClass
% #3: class name
% #4: requested version
\ifx#1\@clsextension
\@ifl@aded#1{#3}{%
\PackageInfo{classlist}{%
Skipping class `#3', because\MessageBreak
this class is already loaded%
}%
}{%
\@ifundefined{MainClassName}{%
\def\MainClassName{#3}%
}{}%
\@temptokena\expandafter{%
\ClassList
\ClassListEntry{#3}{#2}{#4}%
}%
\edef\ClassList{\the\@temptokena}%
}%
\fi
\CL@org@fileswith@pti@ns{#1}[{#2}]{#3}[{#4}]%
}

\providecommand*{\PrintClassListEntry}[3]{%
\toks@{* #1}%
\typeout{\the\toks@}%
}
\providecommand*{\PrintClassListTitle}{%
\typeout{Class list:}%
}
\providecommand*{\PrintClassList}{%
\begingroup
\let\ClassListEntry\PrintClassListEntry
\PrintClassListTitle
\ClassList
\endgroup
}

\def\CL@InfoEntry#1#2#3{%
\advance\count@ by \@ne
\def\x{#2}%
\@onelevel@sanitize\x
\edef\CL@Info{%
\CL@Info
\noexpand\MessageBreak
(\the\count@) %
#1 [\x]%
\ifx\\#3\\%
\else
\space[#3]%
\fi
}%
}
\AtBeginDocument{%
\begingroup
\count@=\z@
\def\CL@Info{Class List with specified options:}%
\let\ClassListEntry\CL@InfoEntry
\ClassList
\let\on@line\@empty
\PackageInfo{classlist}{\CL@Info}
\endgroup
}
\endinput
%%% cut %%% classlist.sty %%% cut %%%

%%% cut %%% test.tex %%% cut %%%
\RequirePackage{classlist}
\documentclass[a4paper]{myarticle}

\typeout{Main class: \MainClassName}
\PrintClassList

\begin{document}
\section{Hello World}
\end{document}
%%% cut %%% test.tex %%% cut %%%

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Hendri Adriaens

unread,
Jun 19, 2005, 10:13:41 AM6/19/05
to
> Thus some kind of list datastructure is necessary
> to get informed about the loaded classes.

As far as I know, the first class in \@filelist is the
document class. That's what xkeyval uses when
parsing this list to define \XKV@documentclass.

-Hendri.


Heiko Oberdiek

unread,
Jun 19, 2005, 10:59:38 AM6/19/05
to
"Hendri Adriaens" <spotjeRE...@gmail.com> wrote:

> > Thus some kind of list datastructure is necessary
> > to get informed about the loaded classes.
>
> As far as I know, the first class in \@filelist is the
> document class.

You can load a lot of packages and even files with
extension ".cls" before \documentclass. Thus the
first "class" entry in \@filelist is a guess.

\input{foo.cls}
\RequirePackage{keyval}
\documentclass{article}

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Heiko Oberdiek

unread,
Jun 19, 2005, 11:19:38 AM6/19/05
to
Heiko Oberdiek <ober...@uni-freiburg.de> wrote:

But the options can be checked:

\@ifundefined{o...@foo.cls}{%
\typeout{foo.cls is not loaded as class}%
}{}

The probability is high, if the first entry
is selected that does have file extension
\@clsextension and passes the options
test above.

However the \@filelist can be fooled by
filenames that contain "," ...
\documentclass{abc,def}
\makeatletter
\show\@filelist
\@@end

Result: abc,def.cls

"def.cls" is the first entry with extension .cls.

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Hendri Adriaens

unread,
Jun 19, 2005, 11:17:04 AM6/19/05
to
> You can load a lot of packages and even files with
> extension ".cls" before \documentclass. Thus the
> first "class" entry in \@filelist is a guess.

Certainly, but it's a guess that will work in most common
cases. Of course redefining \documentclass so that it records
the class itself is the only solution that works guaranteed, but
I didn't want to do that in xkeyval as it would require any user
to load an additional file before \documentclass, even if a
package used by another package, used by etc. would need
the information. That's not workable.

Maybe I should note in the xkeyval docs that .cls files should
not be loaded with \input{foo.cls} but with \input foo.cls if
you really want to load a class before \documentclass. That
will solve the issue already:

\input foo.cls
\RequirePackage{xkeyval}
\documentclass{article}
\begin{document}
\makeatletter\XKV@documentclass
\end{document}

will make xkeyval complain that it is loaded before
\documentclass and hence it cannot determine the documentclass.
\LoadClass before \documentclass could still trick xkeyval though...

-Hendri.


Hendri Adriaens

unread,
Jun 19, 2005, 11:24:58 AM6/19/05
to
> \@ifundefined{o...@foo.cls}{%
> \typeout{foo.cls is not loaded as class}%
> }{}

\LoadClass before \documentclass can fool this test.

\LoadClass{foo}
\RequirePackage{xkeyval}
\documentclass{article}
\makeatletter
\@ifundefined{o...@foo.cls}{\show\undefined}{\show\empty}
\begin{document}
\XKV@documentclass
\end{document}

-Hendri.


Heiko Oberdiek

unread,
Jun 19, 2005, 12:18:31 PM6/19/05
to
"Hendri Adriaens" <spotjeRE...@gmail.com> wrote:

> > You can load a lot of packages and even files with
> > extension ".cls" before \documentclass. Thus the
> > first "class" entry in \@filelist is a guess.
>
> Certainly, but it's a guess that will work in most common
> cases. Of course redefining \documentclass so that it records
> the class itself is the only solution that works guaranteed, but
> I didn't want to do that in xkeyval as it would require any user
> to load an additional file before \documentclass, even if a
> package used by another package, used by etc. would need
> the information. That's not workable.
>
> Maybe I should note in the xkeyval docs that .cls files should
> not be loaded with \input{foo.cls} but with \input foo.cls if
> you really want to load a class before \documentclass. That
> will solve the issue already:
>
> \input foo.cls

This is worst plain input,
\input{foo.cls} must be the preferred way.

For your application, just add a check for
options: \csname o...@foo.cls\endcsname

See classlist.sty v1.1 (on its way to CTAN).

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Heiko Oberdiek

unread,
Jun 19, 2005, 12:47:39 PM6/19/05
to
"Hendri Adriaens" <spotjeRE...@gmail.com> wrote:

It is a test that excludes files, that are not loaded as
class or packages files. The option test improves the
\@filelist method by excluding false entries.
Looking at the file extension and the options,
the result is a list of classes.
The first class is the main class. This is the class that
defines the list of global options. And that class is "foo"
here.

If I look at \@twoloadclasserror I assume that the intension
was to forbid the parallel loading of classes. Only the loading
as single child of a parent class is usually allowed. Thus the
missing error message is probably a LaTeX bug, if \LoadClass is
loaded before \documentclass.

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Hendri Adriaens

unread,
Jun 20, 2005, 12:18:41 AM6/20/05
to
> If I look at \@twoloadclasserror I assume that the intension
> was to forbid the parallel loading of classes. Only the loading
> as single child of a parent class is usually allowed. Thus the
> missing error message is probably a LaTeX bug, if \LoadClass is
> loaded before \documentclass.

If used before \documentclass, it would indeed have been nice
if it would produce an error. Let's forget about this case then.

-Hendri.


Hendri Adriaens

unread,
Jun 20, 2005, 12:21:46 AM6/20/05
to
> > \input foo.cls
>
> This is worst plain input,
> \input{foo.cls} must be the preferred way.

Sure, but the one above would prevent error ;-)

> For your application, just add a check for
> options: \csname o...@foo.cls\endcsname

Yeah, I was thinking of that too anyway. It'll
make it a little more robust.

-Hendri.


0 new messages