4

I am writing a math book. I have exercises that have questions AND subquestions (for example 1 then 1.a, 1.b, 2 then 2.a, 2.b, 2.c etc.). I also have exercises that have one questions, without subquestions (1, 2, 3,...).

I would like to make LaTeX check how many \begin{enumerate}s there are. If there is just 1 (which means that I only have questions, no subquestions), I want the label to be a letter. Otherwise, keep it as is.

Here is a MWE where I do that manually.

 \documentclass{article}

 \usepackage{enumitem}

 \usepackage{xsim} % I'm using this package for the exercise environment

\begin{document}

\section*{Exercise 2}
% This enumerate has only 1 level, so enumerate using a letter (\alph).
\begin{enumerate}[label=\textbf{\alph*.}]
    \item Question 1
    \item Question 2
    \item Question 3
\end{enumerate}


\section*{Exercise 2}
% This enumerate has only 1 level, so enumerate using using a number (\arabic).
\begin{enumerate}[label=\textbf{\arabic*.}]
    \item Question 1
    \begin{enumerate}[label=\textbf{\alph*.}]
        \item Subquestion a
        \item Subquestion b
    \end{enumerate}
    \item Question 2
        \begin{enumerate}[label=\textbf{\alph*.}]
            \item Subquestion a
            \item Subquestion b
            \item Subquestion c
    \end{enumerate}
\end{enumerate}    

\end{document}

N.B. The exercise environment already exists in xsim,and I'm using it.Thank you

1
  • 2
    I removed \usepackge{enumerate} from your preamble as it is best to stick to one package that provides a certain functionality (list management) - enumitem in this case - otherwise there may be conflicts.
    – Werner
    Commented Jul 15 at 18:19

2 Answers 2

5

If it's fine to use an environment for the individual exercises, the following can be used (it'll detect if you use either \begin{enumerate} or \begin {enumerate} inside it):

\documentclass{article}

\usepackage{enumitem}

\ExplSyntaxOn
\NewDocumentEnvironment {exercise} {m b}
  {
    \section*{#1}
    \str_if_in:nnTF {#2} { \begin{enumerate} }
      { \begin{enumerate}[label=\textbf{\arabic*.}] }
      { \begin{enumerate}[label=\textbf{\alph*.}] }
    \setlist[enumerate,2]{label=\textbf{\alph*.}}
    #2
  }
  { \end{enumerate} }
\ExplSyntaxOff

\begin{document}

\begin{exercise}{Exercise 2}
  \item Question 1
  \item Question 2
  \item Question 3
\end{exercise}


\begin{exercise}{Exercise 2}
% This enumerate has only 1 level, so enumerate using using a number (\arabic).
  \item Question 1
    \begin{enumerate}
      \item Subquestion a
      \item Subquestion b
    \end{enumerate}
  \item Question 2
    \begin{enumerate}
      \item Subquestion a
      \item Subquestion b
      \item Subquestion c
    \end{enumerate}
\end{exercise}    

\end{document}

If the exercise environment is already defined, just change the name of the new environment, the following uses questions instead:

\documentclass{article}

\usepackage{enumitem}

\usepackage{xsim} % I'm using this package for the exercise environment

\ExplSyntaxOn
\NewDocumentEnvironment {questions} {m b}
  {
    \section*{#1}
    \str_if_in:nnTF {#2} { \begin{enumerate} }
      { \begin{enumerate}[label=\textbf{\arabic*.}] }
      { \begin{enumerate}[label=\textbf{\alph*.}] }
    \setlist[enumerate,2]{label=\textbf{\alph*.}}
    #2
  }
  { \end{enumerate} }
\ExplSyntaxOff

\begin{document}
\begin{questions}{Exercise 2}
  \item Question 1
  \item Question 2
  \item Question 3
\end{questions}


\begin{questions}{Exercise 2}
% This enumerate has only 1 level, so enumerate using using a number (\arabic).
  \item Question 1
    \begin{enumerate}
      \item Subquestion a
      \item Subquestion b
    \end{enumerate}
  \item Question 2
    \begin{enumerate}
      \item Subquestion a
      \item Subquestion b
      \item Subquestion c
    \end{enumerate}
\end{questions}    
\end{document}

Output of both documents above:

enter image description here

You can also omit the mandatory argument and the section from the definition if you want that to be separate:

\ExplSyntaxOn
\NewDocumentEnvironment {exercise} {b}
  {
    \str_if_in:nnTF {#1} { \begin{enumerate} }
      { \begin{enumerate}[label=\textbf{\arabic*.}] }
      { \begin{enumerate}[label=\textbf{\alph*.}] }
    \setlist[enumerate,2]{label=\textbf{\alph*.}}
    #1
  }
  { \end{enumerate} }
\ExplSyntaxOff
5
  • sorry I forgot to mention that I am using the xsim package, so the exercise environment is already defined and set up (and I am using it) Commented Jul 16 at 13:09
  • @stargazer45 simply change the name of the new environment, see my edit.
    – Skillmon
    Commented Jul 16 at 19:12
  • I need to use the xsim environments to be able to use other features later. Is it possible to do it? Commented Jul 16 at 20:15
  • @stargazer45 if you rename the environment defined in my answer not to collide with xsim there is no reason why you shouldn't be able to use the xsim environments just as you're used to otherwise.
    – Skillmon
    Commented Jul 16 at 20:34
  • @stargazer45 of course you could just try. Put my code in your document using xsim and see whether it breaks.
    – Skillmon
    Commented Jul 16 at 20:35
5

You can use “properties” and properly named environments, rather than the generic enumerate.

I define a new property that records the value of the counter subquestion at the end of an exercise environment. The label is autogenerated based on a counter that's stepped at each exercise environment.

The exercise environment checks the recorded value based on the autogenerated label. If the value is positive, then \arabic* is used, otherwise \alph*.

This requires two LaTeX runs when an exercise is added or removed, which should not be a problem, because the warning about “Labels may have changed” is issued in this case, so also automated systems such as latexmk will do the right thing.

\documentclass{article}
\usepackage{enumitem}

\NewProperty{question}{now}{0}{\thesubquestion}
\newcounter{question}
\newcounter{subquestion}

\newenvironment{question}{%
  \stepcounter{question}
  \ifnum\RefProperty{exe\thequestion}{exercise}>0
    \begin{enumerate}[label=\textbf{\arabic*.}]
  \else
    \begin{enumerate}[label=\textbf{\alph*.}]
  \fi
}{%
  \RecordProperties{exe\thequestion}{question}%
  \setcounter{subquestion}{0}%
  \end{enumerate}
}
\newenvironment{subquestion}{%
  \stepcounter{subquestion}%
  \begin{enumerate}[label=\textbf{\alph*.}]
}{%
  \end{enumerate}
}

\begin{document}

\section*{Exercise 1}

\begin{question}
  \item Question 1
  \item Question 2
  \item Question 3
\end{question}

\section*{Exercise 2}

\begin{question}
  \item Question 1
    \begin{subquestion}
      \item Subquestion a
      \item Subquestion b
    \end{subquestion}
  \item Question 2
    \begin{subquestion}
      \item Subquestion a
      \item Subquestion b
      \item Subquestion c
    \end{subquestion}
\end{question}

\end{document}

output

7
  • I forgot to mention that I am using the xsim package, so the exercise environment is already defined and set up. Commented Jul 16 at 13:01
  • @stargazer45 Use a different name…
    – egreg
    Commented Jul 16 at 13:04
  • I mean I am using the exercise environment, sorry it wasn't clear Commented Jul 16 at 13:06
  • @stargazer45 Sorry, but if you present incomplete examples it's impossible to help.
    – egreg
    Commented Jul 16 at 13:18
  • I didn't think you would create an environment of the exercises.I will edit my post Commented Jul 16 at 13:57

You must log in to answer this question.

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