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 am using the Beamer class and would like to redefine \emph to use \bfseries instead of \itshape. I have tried the following command:

\renewcommand<>{\emph}[1]{{\only#2{\bfseries}#1}}

but I get the following error

! LaTeX Error: Command \beamerx@\emph already defined.
          Or name \end... illegal, see p.192 of the manual.

I cannot understand: Why is it a problem that \emph already is defined when I am using \renewcommand?

share|improve this question
    
The code has two problems: a) spurious <>; b) inconsistent parameter number (1 declared, 2 used). Perhaps you could comment on what is the new \emph supposed to do — this would make things clearer. –  Andrey Vihrov Mar 17 '11 at 13:15
5  
The <> is not spurious. According to the beamer manual (page 86 in version 3.10), you can redefine an existing command by \renewcomamnd<>\cmd[1]{...}. The second parameter stores the overlay specification. –  Michael Ummels Mar 17 '11 at 13:21
    
@Michael: My bad. Thanks for the explanation! –  Andrey Vihrov Mar 17 '11 at 13:24
add comment

2 Answers

up vote 11 down vote accepted

Looking at the code, I'd say that this was a bug. Beamer defines a wrapper around the \newcommand and \renewcommand environments which step in when they are called with a following <>. But the new \renewcommand seems to do the following:

  1. Save the original definition
  2. Call the modified \newcommand

Now the modified \newcommand calls internally calls the original \newcommand but what it ought to do here is now call the original \renewcommand. (The error message, by the way, is because the original \newcommand is not called on the command specified, in this case \emph, but again there's a level of wrapping on top to deal with the overlay stuff.)

So, to fix this:

  1. Email the beamer maintainers informing them that you think you've found a bug.
  2. You could use the following code to temporarily fix this problem. Basically, I've just copied out the code that handles \newcommand and replace "new" by "renew" at all instances, however
  3. Email the beamer maintainers to say that fixing this bug reveals one or two more! When I use the above code then I get a few errors about commands not being defined. My interpretation of this is that beamer does a few redefinitions (at the \begin{document} time) using \renewcommand. With the old version, if the command-to-be-redefined is not currently defined then this goes through just fine. However, with the new version then if the command-to-be-redefined is not currently defined then this produces errors! (The guilty commands are \includegraphics and \pgfuseimage.)

Anyway, here's the fix. Use at your own risk:

\makeatletter
\def\renewcommand{\@ifnextchar<{\beamer@renewcom}{\beamer@origrenewcommand}}
\def\beamer@renewcom<>{\@star@or@long\beamer@renew@command}
\def\beamer@renew@command#1{\@ifnextchar[{\beamer@@renewcom{#1}}{\beamer@renewcomnoopt
{#1}{0}}}
\def\beamer@@renewcom#1[#2]{\@ifnextchar[{\beamer@renewcomopt{#1}{#2}}{\beamer@renewcomnoopt{#1}{#2}}}
\long\def\beamer@renewcomnoopt#1#2#3{%
  \ifnum#2=0\relax%
    \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@sortzero\expandafter{\csname beamerx@\string#1\endcsname}}%
  \else
    \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@sort\expandafter{\csname beamerx@\string#1\endcsname}{#2}}%
  \fi%
  \beamer@argscount=#2\relax%
  \advance\beamer@argscount by 1\relax%
  \expandafter\renewcommand\csname beamerx@\string#1\endcsname[\beamer@argscount]{#3}%
}
\long\def\beamer@renewcomopt#1#2[#3]#4{%
  \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@presort\expandafter{\csname beamerx@\string#1\endcsname}{#2}{#3}}%
  \beamer@argscount=#2\relax%
  \advance\beamer@argscount by 1\relax%
  \expandafter\renewcommand\csname beamerx@\string#1\endcsname[\beamer@argscount]{#4}%
}
\makeatother

(Added in edit): I made a mistake in the above code: it doesn't save the original version of the command which the beamer version of \renewcommand does. Also, due to the conflicts, I thought that actually it would be better to define a command \myrenewcommand which does the command. So the code below may be better. It's probably still nowhere near perfect - for example, I don't know if the \@star@or@long is appropriate for \renewcommands.

Anyway, here's version 2 wrapped up in a MWE:

\documentclass{beamer}
% http://tex.stackexchange.com/q/13726/86

\makeatletter
\def\myrenewcommand{\@ifnextchar<{\beamer@myrenewcom}{\beamer@origrenewcommand}}
\def\beamer@myrenewcom<>{\@star@or@long\beamer@myrenew@command}
\def\beamer@myrenew@command#1{%
  \expandafter\def\expandafter\beamer@name\expandafter{\csname @orig\string#1\endcsname}%
  \expandafter\let\beamer@name=#1\relax%
\@ifnextchar[{\beamer@@myrenewcom{#1}}{\beamer@myrenewcomnoopt
{#1}{0}}}
\def\beamer@@myrenewcom#1[#2]{\@ifnextchar[{\beamer@myrenewcomopt{#1}{#2}}{\beamer@myrenewcomnoopt{#1}{#2}}}
\long\def\beamer@myrenewcomnoopt#1#2#3{%
  \ifnum#2=0\relax%
    \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@sortzero\expandafter{\csname beamerx@\string#1\endcsname}}%
  \else
    \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@sort\expandafter{\csname beamerx@\string#1\endcsname}{#2}}%
  \fi%
  \beamer@argscount=#2\relax%
  \advance\beamer@argscount by 1\relax%
  \expandafter\renewcommand\csname beamerx@\string#1\endcsname[\beamer@argscount]{#3}%
}
\long\def\beamer@myrenewcomopt#1#2[#3]#4{%
  \expandafter\def\expandafter#1\expandafter{\expandafter\beamer@presort\expandafter{\csname beamerx@\string#1\endcsname}{#2}{#3}}%
  \beamer@argscount=#2\relax%
  \advance\beamer@argscount by 1\relax%
  \expandafter\renewcommand\csname beamerx@\string#1\endcsname[\beamer@argscount]{#4}%
}
\makeatother

\myrenewcommand<>{\emph}[1]{{\only#2{\bfseries}#1}}

\newcommand<>{\test}[1]{{\only#2{\bfseries}#1}}

\begin{document}

\begin{frame}
Some \emph{emphasised} text
\end{frame}
\end{document}
share|improve this answer
    
Thanks! I have reported the bug: bitbucket.org/rivanvx/beamer/issue/119/… –  Ulrik Nielsen Mar 17 '11 at 13:52
    
@Ulrik: Good! Don't forget to report back if you get confirmation or anything else significant. –  Andrew Stacey Mar 17 '11 at 13:56
    
@Andrew: Amongst other things, I am one of the beamer maintainers. This does look wrong to me - expect the patch to be added later today. –  Joseph Wright Mar 17 '11 at 14:14
    
@Joseph: Yippee-do! I had a hazy recollection that you were somehow involved, but couldn't remember for sure. I'll be interested to see your patch and see what the most efficient way of doing this is (and why I was getting those weird things with \includegraphics as I couldn't see why they were being generated when I dug deeper). –  Andrew Stacey Mar 17 '11 at 14:37
    
@Andrew: One issue with beamer is that Till's code is rather awkward to follow/alter! So the major approach is 'do not alter too much'. –  Joseph Wright Mar 17 '11 at 14:39
show 3 more comments

If all you want to do is have \emph embolden its text, you could do:

\let\emph\textbf

Each macro is overlay-specification aware and has the same “signature.” So just alias one for the other.

share|improve this answer
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.