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
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)
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
xkeyval provides \XKV@documentclass which contains the class
if loaded after the \documentclass command.
-Hendri.
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>
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.
> > 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>
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>
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.
\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.
> > 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>
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>
If used before \documentclass, it would indeed have been nice
if it would produce an error. Let's forget about this case then.
-Hendri.
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.