8

I am currently working on a document class for homework problems which should have a certain layout. To this aim I have created a new environment for the problems and it already works to some extend, however it still has some bugs.

The layout of the problems should be as follows: The problem number should appear on the left side of the page with an optional box containing the points for the problem underneath. Optionally it should also be possible to print an alternative text such as 'Bonus' instead of the number of the problem. The text of the problem should then appear on the right side with the first line starting on the baseline of the problem number.

My current implementation of the problem environment looks as follows (a full MWE can be found below):

\newcounter{Problem}
\NewDocumentEnvironment{Problem}{o D(){\theProblem)}}
{%
  \refstepcounter{Problem}%
  % Problem number as margin note
  \noindent\marginpar{%
    \begin{center}
      \textbf{\large #2}
      \IfNoValueF{#1}{% If arg1 given
        % Create box with points
        \vspace*{0.6\baselineskip}\par
        \framebox[1.1\width]{#1 Points}}
    \end{center}%
  }%
  \ignorespaces%
}{%
  \vspace{\baselineskip}
}

In order to obtain the desired layout I tweaked the page margins and reversed the marginpar such that it appears on the left side of the page.

I have the following problems with the current implementation of the problem environment (all problems are also documented in the MWE below):

  1. If the text of a problem has too few lines, the problem number of a following problem get shifted downwards in the margin in order to not overlap with the previous problem and points. This causes the base line of the following problem to be not aligned with the problem number.
  2. If I give the problem a label an unwanted whitespace appears at the beginning since \ignorespaces does not work as desired in this case. This could be avoided by using \begin{Problem}\label{prob}% but it is likely to be forgotten.
  3. If the problem starts with an enumerate or itemize environment an unwanted empty line ins inserted at the beginning. Of course this could be fixed by using \vspace but maybe there is a more elegant solution?

I think all these problems would be fixed if the text at the beginning of a problem would behave like the text at the beginning of a section, where the problem number is regarded as the section heading, but I dont know how to achieve this.

Here comes a full MWE which also demonstrates the three mentioned problems:

\documentclass[a4paper,12pt]{article}

\usepackage{geometry}
\usepackage{enumitem}
\usepackage{xparse}

% Page layout
\geometry{
  top=0.07\paperheight,
  bottom=0.1\paperheight,
  left=0.2\paperwidth,
  right=0.07\paperwidth,
  marginparwidth=0.1\paperwidth,
  marginparsep=0.03\paperwidth
}

% Put margin notes on left side
\reversemarginpar

% Problem environment
\newcounter{Problem}
\NewDocumentEnvironment{Problem}{o D(){\theProblem)}}
{%
  \refstepcounter{Problem}%
  % Problem number as margin note
  \noindent\marginpar{%
    \begin{center}
      \textbf{\large #2}
      \IfNoValueF{#1}{% If arg1 given
        % Create box with points
        \vspace*{0.6\baselineskip}\par
        \framebox[1.1\width]{#1 Points}}
    \end{center}%
  }%
  \ignorespaces%
}{%
  \vspace{\baselineskip}
}

\begin{document}

\begin{Problem}[10]
  A problem\\with many lines\\and no label\\works well.
\end{Problem}

\begin{Problem}[10](Bonus)
  Another problem with only one line.
\end{Problem}

\begin{Problem}\label{prob:3}
  A problem with a label suffers from an unwanted whitespace at the
  beginning. Furthermore it does not start at the baseline of the
  problem number since the previous problem was very short.
\end{Problem}

\begin{Problem}
  \begin{enumerate}[leftmargin=*]
  \item A problem that starts with an enumerate or itemize environment
  \item has a newline at the beginning such that the first line of
    text does not start at the baseline of the problem number.
  \end{enumerate}
\end{Problem}

\end{document}

I would be very thankful for any help or advises!

Edit: I had partial success by using \trivlist\item\relax instead of \ignorespaces in the definition of my environment. This solves at least problems 2. and 3. but introduces some additional vertical space at the beginning of the text which I have to correct for. My current implementation looks as follows:

\newcounter{Problem}
\NewDocumentEnvironment{Problem}{o D(){\theProblem)}}
{%
  \refstepcounter{Problem}%
  % Problem number as margin note
  \noindent\marginpar{%
    \parbox[t]{\marginparwidth}{%
      \centering
      \textbf{\large #2}%
      \IfNoValueF{#1}{% If arg1 given
        % Create box with points
        \vspace*{0.6\baselineskip}\par%
        \framebox[1.1\width]{#1 Points}}%
    }%
  }%
  % trivlist introduces some space which we have to correct
  \vspace*{-2.5\topsep}%
  \trivlist\item\relax%
}{%
  \endtrivlist%
  \vspace*{\baselineskip}
}

But still, if a problem just has a single line, then the number of the following problem is shifted downwards and consequently is not correctly aligned with the text. Therefore I would be thankful for suggestions on how to improve the implementation of my environment.

11
  • 2
    Please choose a better title for your problem. The word "homework" already frightens people away.
    – albert
    Commented Oct 29, 2018 at 13:53
  • 1
    I think the exam class could be of some help.
    – Abby
    Commented Oct 29, 2018 at 18:14
  • 1
    I think your first point is the opposite: It is not the text being shifted upward. Instead, it is the problem number (“3)” in your MWE) that is being shifted downward. If the bonus margin note takes many spaces, then the following margin note must be shifted downward to make room. Commented Oct 29, 2018 at 18:36
  • 1
    You could change the \vspace*{\baselineskip} in the second to last line of your edited MWE in something like \vspace{2cm} (or however much you'd like, 2cm might be a bit too much). It's not the most fancy solution, but then at least you have the same amount of space between the text of each question, and they won't be too close together when there is a question with just one line.
    – Abby
    Commented Oct 29, 2018 at 18:44
  • 1
    To solve your first problem, I can think of two possibilities (both avoiding the use of \marginpar. First is to use some sort of tabular environment, and put the question number in one column and the question text in the other. Second is to throw both the question number and the question text in the same line of text, each wrapped in individual minipages. Both have drawbacks. Commented Oct 29, 2018 at 21:04

1 Answer 1

2

Here is a suggestion based using package xsim. I do this because it provides a lot of bells and whistles for creating custom exercises and exams.

For the example at hand it uses \trivlist as you've already found yourself, and places number and points in the margin with the help of a tabular in an overlapping box.

In case points are given it measures the exercise body height and adds some vertical space if needed. You can do this without xsim in a similar way by using xparse's b type argument for environments and the measurement method I've used below.

In xsim the above is done by defining a template for the exercises and telling the package to use it. For the bonus question a boolean property bonus is defined.

enter image description here

The code

\documentclass{article}
\usepackage[showframe]{geometry}
\geometry{
  top=0.07\paperheight,
  bottom=0.1\paperheight,
  left=0.2\paperwidth,
  right=0.07\paperwidth,
  marginparwidth=0.1\paperwidth,
  marginparsep=0.03\paperwidth
}

\usepackage[no-files]{xsim}
\usepackage{enumitem,array,needspace}

\newbox\problembody

\DeclareExerciseProperty*{bonus}
\DeclareExerciseEnvironmentTemplate{problem}
  {%
    \trivlist
    \item[\llap{%
      \smash{%
        \tabular[t]{@{}p{\marginparwidth}@{}}
          \IfExercisePropertySetTF{bonus}
            {\addtocounter{\GetExerciseParameter{counter}}{-1}\textbf{\large Bonus}}
            {\textbf{\large\GetExerciseProperty{counter})}}%
          \IfExercisePropertySetT{points}{%
            \tabularnewline
            \framebox[1.1\width]{%
              \printgoal{\GetExerciseProperty{points}}%
              ~\XSIMtranslate{points}%
            }%
          }%
        \endtabular
      }%
    }]\relax
  }
  {%
    \endtrivlist
    \IfExercisePropertySetT{points}{%
      \setbox\problembody=\vbox{\GetExerciseProperty{exercise-body}}%
      \ifdim\ht\problembody>\baselineskip\else
        \vspace*{\baselineskip}
      \fi
    }%
  }

\xsimsetup{
  exercise/template = problem
}

\begin{document}

\begin{exercise}[points=10]
  A problem\\with many lines\\and no label\\works well.
\end{exercise}

\begin{exercise}[points=10,bonus]
  Another problem with only one line.
\end{exercise}

\begin{exercise}\label{prob:3}
  A problem with a label suffers from an unwanted whitespace at the
  beginning. Furthermore it does not start at the baseline of the
  problem number since the previous problem was very short.
\end{exercise}

\begin{exercise}
  \begin{enumerate}[leftmargin=*]
  \item A problem that starts with an enumerate or itemize environment
  \item has a newline at the beginning such that the first line of
    text does not start at the baseline of the problem number.
  \end{enumerate}
\end{exercise}

\end{document}

You must log in to answer this question.

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