4

I am a fairly experienced LaTeX user. Now, I am trying to get into learning the internals of LaTeX packages and classes. I do not know much about TeX coding. I thought a good beginning would be to try to make a small package that typesets problems and solutions. I have already looked at many such packages like examdesign, exams, answers etc. For a beginner, I understand the overall logic in some of these classes/packages, but not all the details. So, I wanted to do things a bit myself to gain more insight. Here is my attempt at a simple package which I call it qakeysoln:

%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'qakeysoln.sty', version 1.0, May 2015.                     %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or any later version. The latest      %
% version of this license is in http://www.latex-project.org/lppl.txt      %
% and version 1.3 or later is part of all distributions of LaTeX           %
% version 2005/12/01 or later.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% Copyright (c) 2015 Rav Bell.             %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\@ifpackageloaded{newenviron}{}{\RequirePackage{newenviron}}
\@ifpackageloaded{etoolbox}{}{\RequirePackage{etoolbox}}
\StyleFilePurpose{For formatting questions, optionally answer keys/hints, and solutions}
\ProvidesPackage{qakeysoln}[2015/05/11 Rav Bell]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]



% Initialize a global list to hold all the solutions 
\listxadd{\qaks@solutionlist}{}

% Provide a command to the user to list all the solutions 
\newcommand{\thesolutionlist}{%
\show\qaks@solutionlist
\begin{enumerate}%
\renewcommand*{\do}[1]{\item ##1}
\dolistloop{\qaks@solutionlist}
\end{enumerate}
}

% Define the question environment 
% to be used inside a bigger environment like essayq, shortanswer etc.
\newcommand{\qaks@DefineQuestion}{
\newenvironment{question}{\item 

%Use a temporary list \temp@solnlist to store solutions. This is useful if several
%solution environments are defined by a user within one question
%environment (perhaps as alternate solutions). Then all these are
%stored in a single temp list and then the list is appended to the
%global list

% Define solution environment inside question env so that it cannot be    
% used outside of the question environment 
\newenviron{solution}{}{\xappto{\temp@solnlist}{\solutionbody {\@@par}}} %



}{%

%Add the solutions collected to the global list of solutions
\listxadd{\qaks@solutionlist}{%
% noexpand so that I want it to expand later when typesetting the whole
%solution list. But note that \temp@solnlist is expanded right here.
\noexpand\begin{enumerate}
  \forlistloop{\noexpand\item\noexpand[\noexpand]}{\temp@solnlist}
\noexpand\end{enumerate}
}

%delete all the solutions in the temporary list for the current question
\gdef\temp@solnlist{}

}

}

% define a essay question environment:
\newenvironment{essayq}{%
\begin{enumerate}%
\qaks@DefineQuestion
}{\end{enumerate}}

Here is a sample LaTeX file that I used to test this.

\documentclass[a4paper]{article}
\usepackage{qakeysoln}



\begin{document}
\title{A sample file to demonstrate the Questions and Solns}
\maketitle


\section{Questions}
\label{sec:questions}


\begin{essayq}



\begin{question}

  What is $2\times3$?

 \begin{solution}
   $ 3 + 3 = 6$
 \end{solution}

\end{question}

\begin{question}
  What is $3\times2$?  


  \begin{solution}
    Here is the solution: $2 + 2 + 2 = 6$

    Note that this was such a trivial solution that it required no
    explanations.    
  \end{solution}

  \begin{solution}  
    This is an \textbf{alternative solution}:

    $((2+2)+2) = 6$
  \end{solution}



\end{question}

\end{essayq}





\clearpage
\section{Solutions}
\label{sec:solns}

\thesolutionlist


\end{document}

This throws an error when compiling. The problem, it turns out, is the \textbf{alternative solution}. If I remove \textbf. It works just fine. I tried so many different things including \noexpand and \protect. But nothing worked. I felt like I hit a hard wall here. I am pretty sure this must be something trivial for some of the experts here. I am looking forward to understanding and finding a solution to this here.

RavBell
  • 165

1 Answers1

3

You have too deep expansion in two places: add \expandonce.

First:

\newenviron{solution}{}{\xappto{\temp@solnlist}{\expandonce{\solutionbody} {\@@par}}} %

Second:

\listxadd{\qaks@solutionlist}{%
%noexpand so that I want it to expand later when typesetting the whole
%solution list. But note that \temp@solnlist is expanded right here.
\noexpand\begin{enumerate}
  \forlistloop{\noexpand\item[]}{\expandonce{\temp@solnlist}}
\noexpand\end{enumerate}       

(I removed a couple of useless \noexpand tokens).

Another error:

\renewcommand{\do}[1]{\item ##1}

You have \renewcommand* that doesn't allow \par tokens in the argument.


Do yourself a favor and indent your code. Avoid blank lines in the body of a definition, they become \par tokens that can be unwanted.

egreg
  • 1,121,712
  • Thanks so much! \renewcommand* was a nice catch. I had cut and paste this small part from the manual and overlooked it. Now everything works as I expect. Your suggestions on coding style is well taken. – RavBell May 19 '15 at 04:30