1

I am using xsim to print hints and solutions to exercises.

All of the exercises have corresponding solutions, but not all exercises have hints, as shown below.

When there is no hint to an exercise, LaTeX still prints a hint reference but with an unknown reference (drawn in red below).

How can I fix this so that in case that there is no hint, no reference on the margin paragraph would be printed?

\documentclass[]{book}
\setlength{\parskip}{10pt}
\usepackage{xsim}

\xsimsetup{
  exercise/name={Question},
  exercises/name={Questions},
  solution/name={Solution},
  solutions/name={Solutions},
  exercise/within = chapter,
  exercise/template=myTemplate,
  solution/template =myTemplate ,
  print-solutions/headings-template = myTemplate
}

\DeclareExerciseEnvironmentTemplate{myTemplate}
{%
\IfInsideSolutionTF
    {\label{sol:\ExerciseID}}
    {\label{ex:\ExerciseID}}
{\par\normalfont\bfseries\GetExerciseName~\GetExerciseProperty{counter}~\GetExercisePropertyT{subtitle}{{(\PropertyValue)}}\newline}
\IfInsideSolutionTF
{\marginpar{Question in page \pageref{ex:\ExerciseID}}}%
{%
\marginpar{Hint in page \pageref{hint:\ExerciseID}}
\marginpar{Solution in page \pageref{sol:\ExerciseID}}}%
}
{\par
}

% Add hints for the exercises
\DeclareExerciseProperty{hint}
\newcommand\hint[1]{\SetExerciseProperty{hint}{#1}}
\newcommand\printhints{%
  \begin{description}
    \ForEachUsedExerciseByType{%
      \GetExercisePropertyT{hint}
        {\item[Hint to question\label{hint:##2}~##3]~\marginpar{Question in page \pageref{ex:\ExerciseID}}\marginpar{Solution in page \pageref{sol:\ExerciseID}}####1}%
    }%
  \end{description}
}

\begin{document}
\chapter{Geometry}
\section{Introduction}
In mathematics, the Euclidean plane is a Euclidean space of dimension two.

\begin{exercise}[subtitle={Pythagoras' theorem}]
  Prove that the area of the square whose side is the hypotenuse is equal to the sum of the areas of the squares on the other two sides.
  \hint{Draw the altitude from point C, and call H its intersection with the side AB.}
\end{exercise}
\begin{solution}
  The proof is easy.
\end{solution}

\begin{exercise}[subtitle={Thales's theorem}]
If A, B, and C are distinct points on a circle where the line AC is a diameter, the angle ABC is a right angle.
\end{exercise}
\begin{solution}
Since the sum of the angles in a triangle is equal to $180°$\ldots
\end{solution}
\newpage
\section*{Hints}
\printhints

\printsolutions[headings=true]
\end{document}

enter image description here

2 Answers 2

2

Replace

\marginpar{Hint in page \pageref{hint:\ExerciseID}}

by

\expandafter\ifx \csname r@hint:\ExerciseID \endcsname \relax \else
   \marginpar{Hint in page \pageref{hint:\ExerciseID}}\fi

This code checks if the \r@hint:number is defined. If it is undefined then does nothing else prints \marginpar. The \r@hint:number is defined if and only if the relevant pagenumber is known.

1

To solve your problem I modified the exercise environment so that it will refer to the hint only if the conditional \ifhint is true, then I defined a new environment, myex, which checks if the token \hint appears in the body of the environment, if so, the conditional \ifhint is set to true, otherwise nothing happens, then it passes the body to the exercise environment.

\documentclass[]{book}
\setlength{\parskip}{10pt}
\usepackage{xsim}

\xsimsetup{
    exercise/name={Question},
    exercises/name={Questions},
    solution/name={Solution},
    solutions/name={Solutions},
    exercise/within = chapter,
    exercise/template=myTemplate,
    solution/template =myTemplate ,
    print-solutions/headings-template = myTemplate
}

\DeclareExerciseEnvironmentTemplate{myTemplate}
{%
    \IfInsideSolutionTF
    {\label{sol:\ExerciseID}}
    {\label{ex:\ExerciseID}}
    {\par\normalfont\bfseries\GetExerciseName~\GetExerciseProperty{counter}~\GetExercisePropertyT{subtitle}{{(\PropertyValue)}}\newline}
    \IfInsideSolutionTF
    {\marginpar{Question in page \pageref{ex:\ExerciseID}}}%
    {%
        \ifhint\marginpar{Hint in page \pageref{hint:\ExerciseID}}\fi
        \marginpar{Solution in page \pageref{sol:\ExerciseID}}}%
}
{\par
}

% Add hints for the exercises
\DeclareExerciseProperty{hint}
\newcommand\hint[1]{\SetExerciseProperty{hint}{#1}}
\newcommand\printhints{%
    \begin{description}
        \ForEachUsedExerciseByType{%
            \GetExercisePropertyT{hint}
            {\item[Hint to question\label{hint:##2}~##3]~\marginpar{Question in page \pageref{ex:\ExerciseID}}\marginpar{Solution in page \pageref{sol:\ExerciseID}}####1}%
        }%
    \end{description}
}
\newif\ifhint
\ExplSyntaxOn
\NewDocumentEnvironment {myex} { O{} +b }
    {
    \tl_if_in:nnTF {\hint} {#2} {\hinttrue} {}
    \begin{exercise}[#1]
        #2
    \end{exercise}
    \hintfalse
    }
    {}
\ExplSyntaxOff

\begin{document}
    \chapter{Geometry}
    \section{Introduction}
    In mathematics, the Euclidean plane is a Euclidean space of dimension two.
    
    \begin{myex}[subtitle={Pythagoras' theorem}]
        Prove that the area of the square whose side is the hypotenuse is equal to the sum of the areas of the squares on the other two sides.
        {\hint{Draw the altitude from point C, and call H its intersection with the side AB.}}
    \end{myex}
    \begin{solution}
        The proof is easy.
    \end{solution}
    
    \begin{myex}[subtitle={Thales's theorem}]
        If A, B, and C are distinct points on a circle where the line AC is a diameter, the angle ABC is a right angle.
    \end{myex}
    \begin{solution}
        Since the sum of the angles in a triangle is equal to $180°$\ldots
    \end{solution}
    \newpage
    \section*{Hints}
    \printhints
    
    \printsolutions[headings=true]
\end{document}

You must log in to answer this question.

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