Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
Do you load the package form_110? In the LaTeX companion book, page 880, there is a footnote saying "It is the responsibility of the package writer to actually load such packages. LaTEX does not check that packages receiving options via \PassOptionsToPackage are actually loaded later on." –  Guido May 4 at 5:59
    
@Guido, this package is loaded via \RequirePackage in russian_post. –  Eddy_Em May 4 at 6:02
    
This minimal example produces as output "test opt passed", as expected. It would be great if you could widdle down your current setup to something minimal and self-contained that you can post here. –  Werner May 4 at 6:14
    
@Werner, thanks! I found it: that was because of \RequirePackage{russian_post} in form_110.sty. It is become now more weird: latex should omit such multiple inclusion... –  Eddy_Em May 4 at 6:37
add comment

1 Answer 1

up vote 6 down vote accepted

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:

\usepackage[ngerman]{babel}
\usepackage[english]{babel}

LaTeX stops with an error:

! LaTeX Error: Option clash for package babel.

Pressing h at the prompt reveals:

The package babel has already been loaded with options:
  [ngerman]
There has now been an attempt to load it with options
  [english]
Adding the global options:
  ngerman,english
to your \documentclass declaration may fix this.

Or without global options:

\usepackage[ngerman,english]{babel}

or if the first package loading is hidden in a class or package:

\PassOptionsToPackage{ngerman,english}{babel}
\documentclass{...}

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.
  • Also it does not check, whether the package is already loaded. (Perhaps a warning could be given in this case. A package could later check for new options, but \@ifpackagewith is limited to the preamble.)

Specific problem

You have the following package loading order:

* \usepackage[smalltab]{russian_post}
  * \RequirePackage{form_110}
    * \RequirePackage{russian_post}

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 of russain_post is late enough to get LaTeX's option stuff of the first loading finished:

Package russian_post contains then:

\AtEndOfPackage{RequirePackage{form_110}}

The loading order/nesting of the test file is then:

* \usepackage[smalltab]{russian_post}
* \RequirePackage{form_110}
   * \usepackage{russian_post}

Thus the second \usepackage{russian_post} is not longer inside the scope of its first loading.

share|improve this answer
    
Thanks! \AtEndOfPackage fully solve my problem. –  Eddy_Em May 4 at 8:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.