9

Within a package I'm making, I want ignore the default draft behavior and write my own. I have tried:

\DeclareOption{draft}{
MYCOMMANDS
...
\OptionNotUsed
}
\ProcessOptions

If draft is used, my commands are run, but all other features of the draft option (e.g. disabling images and hyperlinks) are still enabled.

I want to disable the draft option from the document class level from my package and prevent it from being passed to any packages. Is this possible to do from my package?

egreg
  • 1,121,712
  • So you want to patch the code of other packages? – Martin Schröder Oct 31 '11 at 18:26
  • I would like to disable the draft option at the document class level and prevent it from being passed to any other packages. – Scribblemacher Oct 31 '11 at 18:29
  • 4
    You can't: if the draft option is specified with \documentclass it will be passed to all packages that know such option. Conversely, if it's specified only to your package, it will not be passed to other packages. – egreg Oct 31 '11 at 18:34
  • 1
    @David: This would only be possible (if it's possible at all) at class level. But you probably need to patch the option handling of LaTeX to make it work. – Martin Schröder Oct 31 '11 at 21:54
  • 1
    Is there any reason why you want to specify the draft option at the class level and not for your package only? I think this would be the easiest option without any fiddling around with LaTeX internals. – Elmar Zander Nov 01 '11 at 22:19

1 Answers1

13

If the draft option is specified with \documentclass it will be passed to all packages that know such option. Conversely, if it's specified only along your package, it will not be passed to other packages.

\documentclass[<global options>]{<class>}
\usepackage[<local options>]{<package>}

The options in the <global options> list will be tried by the class and any package loaded in the preamble, but won't show errors or warnings if not known by a package.

The options in the <local options> list will be passed to <package> (which might pass them to other packages loaded after it, via \PassOptionsToPackage).

So with

\documentclass[draft,...]{article}

all packages will try to honor the draft option, and nothing can be done about this with code in some package.

However, if your package is loaded immediately after the class and you know how to modify the global options list, then it's possible to do what you wish. Here's the "secret" code:

\def\@clearglobaloption#1{%
  \def\@tempa{#1}%
  \let\@tempb\@gobble
  \@for\next:=\@classoptionslist\do
    {\ifx\next\@tempa
       \message{Cleared  option \next\space from global list}%
     \else
       \edef\@tempb{\@tempb,\next}%
     \fi}%
  \let\@classoptionslist\@tempb
  \ifx\@tempb\@gobble
    \let\@classoptionslist\@empty
  \fi}

@clearglobaloption{draft}

I've made it generic: any option can be cleared in this way. Beware that some classes such as beamer do different things with the option list and so the trick might not work with them.

Update

With expl3 in the LaTeX kernel (which has been for a couple of years), we can simplify the business quite a lot.

\ExplSyntaxOn
\cs_new_protected:cpn { @clearglobaloption } #1
 {
  \clist_remove_all:cn { @classoptionslist } { #1 }
 }
\ExplSyntaxOff
egreg
  • 1,121,712
  • 1
    Don't many packages also have a final package option that overrides a draft class option for the purposes of that specific package? – tparker Jun 07 '18 at 18:13
  • There seems to be a bug in the "secret" code, if the first kept option starts with twice the same letter the \ifx matches and we get text before \begin{document} ... – Vincent Beffara Mar 05 '21 at 23:38
  • @VincentBeffara \ifx the two macros \next and \@tempa, returning true if they have the same replacement text – egreg Mar 06 '21 at 08:39
  • No I mean the second \ifx to test for the empty case. If \@tempb ends up being aa,whatever then it tests the first a against the second one – Vincent Beffara Mar 06 '21 at 21:59
  • @VincentBeffara oh, I see. Needs a fix – egreg Mar 06 '21 at 22:02
  • Probably \clist_remove_all:Nn would make more sense these days anyway – Vincent Beffara Mar 06 '21 at 22:10
  • @VincentBeffara Sure! A good occasion for fixing the mistake and for showing a much simpler approach. – egreg Mar 06 '21 at 22:24