31

Is it possible to unload a LaTeX package?

I have a preamble file which I use for most documents. Now suppose I want to use a preamble file preamble.tex and explicitly don't want to use one of the packages loaded in it. For example in this file there is a line:

\usepackage{mypackage}

and then I want to have a file test.tex which contains something like this:

\input{preamble}
\unloadpackage{mypackage}
\usepackage{myotherpackage} %myotherpackage can only be loaded when mypackage is not present
Martin Scharrer
  • 262,582
student
  • 29,003

2 Answers2

29

You can fool LaTeX into believing that it has already loaded package foo with options bar and baz by defining a command with name "ver@foo.sty" and one with name "opt@foo.sty" in a suitable way; so

\makeatletter
\newcommand{\dontusepackage}[2][]{%
  \@namedef{ver@#2.sty}{9999/12/31}%
  \@namedef{opt@#2.sty}{#1}}
\makeatother

will prevent both loading the package and also keep LaTeX happy with the options possibly passed to it.

However, \dontusepackage[bar,baz]{foo} must be issued before \input{preamble}.

I'm in general contrary to "do-it-once-and-for-always" preambles, which raise problems such as this one. There's no such thing as a universal preamble and later developments make some packages obsolete or at least superseded by new ones.

Just copy preamble.tex into the working directory and change it for what's needed for the current document you're writing.

UPDATE 2023

The LaTeX kernel now has \disable@package@load so the incantation is

\makeatletter
\newcommand{\disablepackage}[2]{%
  \disable@package@load{#1}{#2}%
}
\newcommand{\reenablepackage}[1]{%
  \reenable@package@load{#1}%
}
\makeatother

to be called by

\disablepackage{foo}{}

In the second argument you can put code to be executed if there is an actual request to load the package, possibly a message to be printed on the console. There is also the possibility to reenable the loading later.

egreg
  • 1,121,712
  • @egreg I think it is useful to emphasize that, to avoid option clash later, bar and baz must be the only options for package foo. This will require knowing all the options of foo. This also assumes that foo wasn't loaded before \dontusepackage. – Ahmed Musa Dec 27 '11 at 19:25
  • I've chosen to pass also the options used in preamble.tex in order to raise an error if some other package tries to load it with different options. However it's not that important. – egreg Dec 27 '11 at 20:21
  • @egreg In https://tex.stackexchange.com/q/702524/33634 I learned about \disable@package@load{hyperref}{}. Might it be appropriate to update your answer? – Gabriele Nov 28 '23 at 19:47
  • 1
    @GabrieleNicolardi I added the code. – egreg Nov 28 '23 at 23:04
24

Tell your preamble that mypackage is already "loaded". Packages are not loaded twice:

\makeatletter
\@namedef{ver@mypackage.sty}{}% a fake for a "loaded" package
\makeatother
\input{preamble}
\usepackage{myotherpackage} %myotherpackage can only be loaded when mypackage is not present
  • \documentclass{article} \makeatletter \@namedef{ver@subfig.sty}{}% a fake for a "loaded" package \makeatother \usepackage{caption,subcaption} \begin{document} A \end{document} leads to : ! Package subcaption Error: This package can't be used in cooperation. Of course it works if I remove the "fake" loaded package, but in my preamble.tex something is loading subfig and I want to use subcaption. Any suggestions? – Huckleberry Febbo Nov 09 '18 at 04:48
  • turns out the svg package loads subfig – Huckleberry Febbo Nov 09 '18 at 05:16
  • \@namedef{ver@subfig.sty} fools the system that it is loaded, which leads package subcaption to the message. –  Nov 09 '18 at 19:55