[Tex/LaTex] Best practice for fixing a clash between packages without altering the .sty files

best practicesincompatibilitypackages

Here is another casualty of TeX's flat namespace and another reason to start using LaTeX3…

I noticed today that the algorithm2e and keystroke packages clash. More specifically, they both define a command called \Return:

  • in algorithm2e, \Return is a command for typesetting the pseudocode Return keyword;
  • in keystroke, \Return is a command that typesets Return.

Both packages define their \Return command using \newcommand; therefore, if both packages are loaded, LaTeX returns an error when it encounters the second \newcommand\Return.

I solved the problem by giving keystroke's \Return a new, unique name that doesn't clash with anything I'm using so far, like so:

\documentclass{article}

\usepackage{keystroke}
\let\ksReturn\Return
\let\Return\relax
\usepackage{algorithm2e}

\begin{document}
\Return \quad \ksReturn
\end{document}

That worked, but I have a question:

As a user (not a package writer/maintainer), what is best practice for fixing a clash between two homonymous, yet different, commands defined in two different packages, without altering either of the .sty files?
Can my approach have any detrimental side-effect (aside from my new name possibly generating a different clash)?


Side note: keystroke is quite an old package. At the time of writing this post, the current version dates back to November 2000, whereas the current version of algorithm2e was released more recently, in January 2013.

Edit: a less problematic and more powerful package for typesetting menu sequences,
paths, and keyboard shortcuts is the excellent menukeys package.

Best Answer

First, save the clashing identifiers:

\usepackage{keystroke}
\let\keystroke@Return\Return
\let\Return\undefined
\usepackage{algorithm2e}
\let\algorithmtwoe@Return\Return
\let\Return\undefined

Then defined two macros to setup the correct bindings.

\def\keystroke@setupbindings{%
   \let\Return\keystroke@Return
}
\def\algorithmtwoe@setupbindings{%
   \let\Return\algorithmtwoe@Return
}

Last patch the entry points using \Return so that they start with the appropriate @setupbindings macro. You can do this programatically by loading the replacement text of that entry point in a token register and refefining the entrypoint with \edef:

% Some code that loads the expansion text of \entrypoint in toks0
\edef\entrypoint{\noexpand\keystroke@setupbindings\the\toks0}

It is impossible to attain the largest level of genericity because, to the best of my knowledge, it is not possible to recover the application template of a macro in TeX. But if you really need this, you can write \patch macro so that

\patch\entrypoint\keystroke@setupbindings

does the same thing as the pseudo-code above. Dealing with \long and \outer modificators and macros having arguments can be a bit tedious, though, so it might be suitable to semi-manually patch the relevant macros.

EDIT — Well, it is actually possible to recover the application template of a macro and I should know this pretty good since I included a macro doing this in my Bhrìd TeX format! :-) Here is an untested translation for plain TeX:

\begingroup
  \edef\next{%
  \gdef\noexpand\toksloadmeaning@A
  ##1\noexpand\and##2\expandafter
  \ignore\string\macro:##3->##4\noexpand\stop{%
     ##1{##3}##2{##4}%
  }}
  \next
\endgroup

\def\toksloadcsmeaning#1\to#2\and#3{%
  \begingroup
  \toks0={#2}%
  \toks2={#3}%
  \edef\next{\noexpand\toksloadmeaning@A\the\toks0 \noexpand\and\the\toks2 %
  \meaning#1\noexpand\stop
  }%
  \expandafter\endgroup\next
}

After \toksloadcsmeaning\controlsequence\to{\toks1}\and{\toks3} the token register \toks1 contains the application template and \toks3 the meaning of the macro. With this in hand, writing a \patch macro should be a piece of cake.