3

Inspired by this answer, I would like to have a customized solution environment which accepts an optional argument. This argument can be either numeric or alphabetic, and its value corresponds to the question level whose width is desired to be set to the solution environment.

For example, suppose the question levels have some indices to be: 1 for questions, 2 for parts, 3 for subparts, and 4 for subsubparts. Then the new solution environment might be something like \begin{solution}[2] if I want the solution to span the whole line width of the part environment regardless of where I print this solution.

Finally, if I don't type the optional argument, I would like the width to be set by the parent question level.

\documentclass[answers]{exam}
\usepackage{lipsum}
\usepackage{mdframed}

\renewenvironment{solution}
{\begingroup\par\parshape0%
\begin{mdframed}[skipabove=\baselineskip,
                 innertopmargin=\baselineskip,
                 innerbottommargin=\baselineskip,
                 userdefinedwidth=\textwidth]
\textbf{Solution:}\enspace\ignorespaces}
{\end{mdframed}\par\endgroup}

\begin{document}
    \begin{questions}
        \question A question.
        \begin{parts}
            \part part
            \begin{solution}
                The long solution continues onto another page: \lipsum[1-8]
            \end{solution}
        \end{parts}
    \end{questions}

    \lipsum[1]
\end{document}

1 Answer 1

4

What you want has been implemented as a package for clean reuse among several documents: the package is called examwsolns and can be found here. Documentation is there too.

Sample usage

Here is an example.tex file that shows how to use this package:

\documentclass[answers]{exam}
\usepackage[framemethod=tikz]{mdframed}
%\usepackage[replace-solution-env]{examwsolns}
\usepackage{examwsolns}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{tikz}

% Also possible in the preamble:
% \examwsolnsSetup{replace-solution-env}
% \examwsolnsSetup{replace-solution-env=true}

% Default additional arguments to pass to the 'mdframed' environment
\examwsolnsSetMdFramedDefaultArgs{
  skipabove = \baselineskip,
  innertopmargin = \baselineskip,
  innerbottommargin = \baselineskip,
  userdefinedwidth = \linewidth
}

\begin{document}
Here is a full line:
\par\noindent\hrulefill

\begin{wsolution}
  Autodetected outer level.
\end{wsolution}

\begin{questions}
  \question A question.

    \begin{wsolution}
      Autodetected question level.
    \end{wsolution}

    \begin{parts}
       \part A part
         \begin{wsolution}[][innertopmargin = 2\baselineskip,
                             innerbottommargin = 2\baselineskip,
                             backgroundcolor=gray!40,
                             roundcorner=8pt]
           Autodetected part level.
         \end{wsolution}

         \begin{subparts}
            \subpart A subpart
              \begin{wsolution}
                Autodetected subpart level.
              \end{wsolution}

             \subpart
               \begin{subsubparts}
                 \subsubpart A subsubpart
                   \begin{wsolution}
                     Autodetected subsubpart level.
                   \end{wsolution}

                 \subsubpart Another subsubpart
                   \begin{wsolution}
                     Autodetected subsubpart level.
                   \end{wsolution}
               \end{subsubparts}
          \end{subparts}

       \part Other part
         \begin{wsolution}
           Autodetected part level.
         \end{wsolution}
    \end{parts}

  \question Other question
    \begin{wsolution}
      Autodetected question level.
    \end{wsolution}

    \begin{parts}
      \part A part
        \begin{wsolution}[1]
          Forced at level 1.
        \end{wsolution}

        \begin{wsolution}[2]
          Forced at level 2.
        \end{wsolution}

        \begin{wsolution}[3]
          Forced at level 3. \lipsum[2-8]
        \end{wsolution}

        \begin{wsolution}[4]
          Forced at level 4.

          \lipsum[9]\lipsum[10][1-2]
        \end{wsolution}

        {% \examwsolnsSetMdFramedPreText and \examwsolnsSetMdFramedPostText
         % respect TeX's grouping rules.
          \examwsolnsSetMdFramedPreText{\emph{Sample pre-text} $\langle$}%
          \examwsolnsSetMdFramedPostText{$\rangle$ \emph{Sample post-text}}%
        \begin{wsolution}[3]
          Forced at level 3.
        \end{wsolution}
        }

        \begin{wsolution}[2]
          Forced at level 2.
        \end{wsolution}
    \end{parts}

  \question Last question
    \begin{wsolution}[1]
      Forced at level 1.
    \end{wsolution}

    \begin{wsolution}[0]
      Forced at level 0.
    \end{wsolution}
\end{questions}

Here is a full line for comparison:
\par\noindent\hrulefill
\end{document}

Output for the example.tex file given above

Page 1:

Screenshot for page 1


Page 2:

Screenshot for page 2


Page 3:

Screenshot for page 3

22
  • Many thanks. Your answer is really impressive and exhausting to just read. If you don't mind I would like one final tweak: could you please make the input of the optional argument of zero (i.e. \begin{solution}[0]) results in the width of \textwidth spanning all the space between the left and right margins as done by the MWE in my question?
    – Diaa
    Commented May 7, 2019 at 0:13
  • 1
    Glad that you liked it (sometimes, people here ask questions, obtain responses that required a lot of work but no one reads them, not even the person who asked...). I've added handling of level 0 (“outer”). If you're still here, I may turn this into a package for clean reuse when you have several documents (probably the environment should have a different name [proposal?], with possibly an option to replace the existing solution environment; also, the optional arguments to mdframed should be parametrizable).
    – frougon
    Commented May 7, 2019 at 8:15
  • I always have to appreciate the time and effort anyone put in answering my questions with nothing in return.
    – Diaa
    Commented May 7, 2019 at 8:26
  • 1
    I tried to reproduce it but got this: no problem. You could try doing {\centering ... \par}\vspace*{whatever}, possibly followed by \null in case this doesn't work. I'd also suggest doing the dots with \dotfill and replacing the custom loop macros with something standard like \pgffor. No need for \centering, BTW. The following is much simpler and looks good to me: \begin{wsolution}[1] \foreach \i in {1,...,3} {\noindent\dotfill\par} \end{wsolution}result. \foreach is defined in the pgffor package.
    – frougon
    Commented Sep 1, 2019 at 12:51
  • 1
    Hello. With examwsolns version 0.4, you can use the new default-level package option: default-level=current|outer|question|part|subpart|subsubpart (the initial value is current, which corresponds to the usual behavior).
    – frougon
    Commented Jul 31, 2020 at 13:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .