I create a package: one common file that includes others. In common package file (russian_post.sty
) I define options:
\DeclareOption{times}{\@seriffalse}
\DeclareOption{landscape}{\@lscapetrue}
\DeclareOption{portrait}{\@lscapefalse}
\DeclareOption{smalltab}{\PassOptionsToPackage{smalltab}{form_110}}
\DeclareOption{tinytab}{\PassOptionsToPackage{tinytab}{form_110}}
\DeclareOption*{\PackageWarning{russian_post}{Unknown option `\CurrentOption'}}
\ProcessOptions\relax
after that I include packages, the interesting is
\RequirePackage{form_110}
In file form_110.sty
I define them again:
\DeclareOption{smalltab}{\@smallt@btrue}
\DeclareOption{tinytab}{\@tinyt@btrue}
\ProcessOptions\relax
And in my file.tex
I try to use my package with this options:
\usepackage[times,tinytab]{russian_post}
This cause latex errors:
! LaTeX Error: Unknown option `times' for package `russian_post'.
! LaTeX Error: Unknown option `tinytab' for package `russian_post'.
in spite of that I've already defined default action for unknown options (just show warning).
The weird things come later: after ignoring these errors I get a right pdf-file.
If I move all \RequirePackage
before options declaration block, latex works without errors but options don't pass to package. I know, that I can use global variables from russian_post.sty
in other packages, but what if I would like to use that package alone?
How can this be so? And how can I omit such errors?
UPD:*
Thanks to @Werner. I add minimal example:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{russian_post.sty}
\DeclareOption{smalltab}{\PassOptionsToPackage{smalltab}{form_110}}
\DeclareOption{tinytab}{\PassOptionsToPackage{tinytab}{form_110}}
\DeclareOption*{\PackageWarning{russian_post}{Unknown option `\CurrentOption'}}
\ProcessOptions\relax
\RequirePackage{form_110}
\end{filecontents*}
\begin{filecontents*}{form_110.sty}
\newif\if@smallt@b\newif\if@tinyt@b
\@smallt@bfalse\@tinyt@bfalse
\DeclareOption{smalltab}{\@smallt@btrue}
\DeclareOption{tinytab}{\@tinyt@btrue}
\ProcessOptions\relax
\RequirePackage{russian_post}
\def\testsmall{\if@smallt@b TRUE\else FALSE\fi}
\def\testtiny{\if@tinyt@b TRUE\else FALSE\fi}
\end{filecontents*}
\usepackage[smalltab]{russian_post}
\begin{document}
small: \testsmall
tiny: \testtiny
\end{document}
It seems that the problem is in multiple inclusion of russian_post.sty
. But latex should prevent such things when you're using \RequirePackage
or \usepackage
. I don't understand anything!!!
UPD2: it's more and more weird!
If I move this options to \documentclass
, all works fine! What is it?
Best Answer
General part
This comment indicates, that a more general answer might be useful.
If LaTeX loads a package
foo
, then it defines macro\ver@foo.sty
(containing version date and information). At the next loading request (\RequirePackage{foo}
,\usepackage{foo}
) it sees that\ver@foo.sty
is defined and does not load the package again. That would be quite fatal, if the package uses\newcommand
(which a good package should do ...).But it checks the options. LaTeX's understanding of an option is that an option adds/enables an additional feature. Therefore, if subsequent
\RequirePackage
and\usepackage
calls of the same package do not contain new options, LaTeX is happy and continues. Otherwise, if LaTeX sees a new option, it cannot load the package again to enable the new option. And LaTeX complains. Example:LaTeX stops with an error:
Pressing
h
at the prompt reveals:Or without global options:
or if the first package loading is hidden in a class or package:
Now, we reached
\PassOptionsToPackage
. It is useful before the package is loaded the first time, otherwise LaTeX options code does not see the subsequent option additions. And it should be noted:\PassOptionsToPackage
does not check, if the package will be loaded at all.\@ifpackagewith
is limited to the preamble.)Specific problem
You have the following package loading order:
The problem is that
russian_post
is again requested for loading before the first loading is completed. The package file is not loaded, but LaTeX has still to deal with the options.Workaround: Delay the loading of package
form_110
with\AtEndOfPackage
, then the nested loading ofrussain_post
is late enough to get LaTeX's option stuff of the first loading finished:Package
russian_post
contains then:The loading order/nesting of the test file is then:
Thus the second
\usepackage{russian_post}
is not longer inside the scope of its first loading.