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 came across an odd problem compiling LaTeX exam.cls document producing with knitr. Pasted below is minimal reproducible code.

knitr compiles fine, but pdflatex terminated with:

  • Command \framed already defined.
  • Command \shaded already defined.
  • Command \leftbox already defined.

It seems the author of exam.cls pasted most of the framed.sty into the class file, which is generating conflicts with anyone who actually wants to load the original framed.sty package, including knitr.

My ugly solution to an ugly problem was to modify exam.cls file:

% Original
\newenvironment{framed}% using default \FrameCommand
  {\MakeFramed {\advance\hsize-\width \FrameRestore}}%
  {\endMakeFramed}

% Modified
\newenvironment{exam-framed}% using default \FrameCommand
  {\MakeFramed {\advance\hsize-\width \FrameRestore}}%
  {\endMakeFramed}

% Same for "\newenvironment{shaded}" and "\newenvironment{leftbar}"

I would like to find more elegant solution, not rewriting original exam.cls file.

Thanks in advance for any pointers.

share|improve this question
    
You could add a \let\<name>\relax for each previously defined <name>. This should eliminate the need to change the .cls file. –  Peter Grill Sep 11 '12 at 18:42
    
Please make sure all codes in your question are enclosed by code mark downs. There are some unformatted codes in the second paragraph in your question that needs your attention. –  stalking is prohibited Sep 11 '12 at 18:50
    
I think @Werner reformat code in 2nd paragraph for me? –  Andrej Sep 11 '12 at 19:04
    
@PeterGrill \let\framed\relax, \let\shaded\relax and \let\leftbox\relax doesn't work. Still same error. –  Andrej Sep 11 '12 at 19:13
    
@Andrej: Note that for environments you have two macros defined - a start and an end. See Heiko's answer for some reference to that. So, for \framed, there's also \endframed; \shaded and \endshaded; \leftbox and \endleftbox. –  Werner Sep 11 '12 at 19:36

1 Answer 1

up vote 12 down vote accepted

Renaming using \let

Name clashes can be resolved by renaming. In this case these are simple environments. An environment name defines two macros \name and \endname (the latter can also left undefined, because it is called via \csname).

\documentclass{exam}
\newcommand*{\renameenviron}[1]{%
  \expandafter\let\csname exam-#1\expandafter\endcsname
      \csname #1\endcsname
  \expandafter\let\csname endexam-#1\expandafter\endcsname
      \csname end#1\endcsname
  \expandafter\let\csname #1\endcsname\relax
  \expandafter\let\csname end#1\endcsname\relax
}
\renameenviron{framed}
\renameenviron{shaded}
\renameenviron{leftbar}
\usepackage{framed}
\begin{document}
\end{document}

However this method overwrites the internal stuff of framed in exam by the original code of package framed, see below for further discussion.

Simulate package loading

The class exam says:

% Donald Arseneau <...>, who created the excellent
% ``framed.sty'' and generously allowed me to include basically the
% whole thing in exam.cls, making the few changes needed for it to
% work well with question environments:
% framed.sty   v 0.8a   21-Jul-2003
% Copyright (C) 1992-2003 by Donald Arseneau
% These macros may be freely transmitted, reproduced, or modified
% provided that this notice is left intact.

That could mean, framed is already loaded. It might not make sense to load it twice. Then LaTeX can be tricked to think that the package is already loaded:

\documentclass{exam}
\makeatletter
\expandafter\providecommand\expandafter*\csname ver@framed.sty\endcsname
{2003/07/21 v0.8a Simulated by exam}
\makeatother
\usepackage{framed}
\begin{document}
\end{document}

The long story

Both methods above do not address the question, what has changed in the implementation of framed in class exam to the original framed. The environments are one side, the internal stuff the other side. For example, internal macros are defined using \def that does not generate an error, if the macro is already defined. In the first method, the later loaded package framed overwrites the internal stuff of class exam. In the second method the version of framed in class exam is used.

Advantage of the first method: The latest framed is used including bug fixes and new features (if there are any). On the downside, the changes of exam are lost (A quick look reveals some margin and positioning stuff). Therefore the second method might be better here.

If you are lucky, the second method already works for your document.

Otherwise it can be that this knitr requires a later version of framed or expects an unmodified framed. These cases cause lots of work, because the different macro versions need to be analyzed for differences and merging or providing different environments.

share|improve this answer

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.