0

I am writing exercises along my book and I am using xsim for this.

For some of the exercise there will be a hint that should appear at the end of the chapter (under "Hints to exercises" section).

Just as well, for some of the exercises there will also be a corresponding solution. Same - I want them to appear at the end of the chapter under a section "Solutions To exercises".

How do I that?

I tried to follow the example in the repository for hints and for cross referencing, but I don't know how to fully implement it.

  1. First would be to declare a new template, called myTemplate, for which the first thing would be to create a label for the exercises and the solutions, but how do I also create a label for the hints?
\DeclareExerciseEnvironmentTemplate{myTemplate}
    {%
    \IfInsideSolutionTF
      {\label{sol:\ExerciseID}}
      {\label{ex:\ExerciseID}}
      % how to create a label for the hints??
  1. I also need help with creating a command that prints the hints at the end of the chapter. I want the hints to appear as

Hint for exercise 3

Use the fact that $x=1$.

Hint for exercise 5

Recall that $x=y$.

etc.

A MWE for the document as I have it now is this:

%!TEX TS-program = xelatex
\documentclass[openany,oneside]{book}
\usepackage{xsim,xcolor}

\newcommand{\marginRef}[1]{%
  \marginpar{\colorbox{lightgray}{\parbox{\dimexpr\marginparwidth-2\fboxsep}{#1}}}
}

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

\DeclareExerciseProperty{hint}
\newcommand\hint[1]{\SetExerciseProperty{hint}{#1}}

\DeclareExerciseHeadingTemplate{myTemplate}{%
    \chapter{Solutions to Problems in chapter \thechapter}%
  }
\DeclareExerciseEnvironmentTemplate{myTemplate}
    {%
    \IfInsideSolutionTF
      {\label{sol:\ExerciseID}}
      {\label{ex:\ExerciseID}}
     % how to create a label for the hints??
  \GetExerciseHeadingF{\subsection*}%
    {%
    \XSIMmixedcase{\arial% <- font changed
        \GetExerciseName}\nobreakspace
    \GetExerciseProperty{counter}%
    \IfInsideSolutionF
    {%
    \GetExercisePropertyT{subtitle}
    { {\large\itshape\PropertyValue}}%
    }%
    }\marginpar{% how to print the hint page ref here?
                         }%
    \marginRef{solution in page \pageref{ex:\ExerciseID} }
%    \marginpar{\colorbox{lightgray}{\parbox{\dimexpr\marginparwidth-2\fboxsep}{solution in page \pageref{ex:\ExerciseID}}}}
    }
{\par}

% lang package
\usepackage{polyglossia}
\setdefaultlanguage{english}
\newfontfamily\arial{Arial}[Script=Latin,Language=English]

\begin{document}
\chapter{Geometry}
\section{Introduction}
\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}

\printsolutions[headings=true,headings-template=myTemplate]
\end{document}

Output:

output

0

2 Answers 2

1
+100

The following uses the MWE and example 11 (“Give Hints”) from xsim's manual:

\documentclass[openany,oneside]{book}
\usepackage{xsim,xcolor}

\newcommand{\marginRef}[1]{%
  \marginpar{\colorbox{lightgray}{\parbox{\dimexpr\marginparwidth-2\fboxsep}{#1}}}
}

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

\DeclareExerciseProperty{hint}
\newcommand\hint[1]{\SetExerciseProperty{hint}{#1}}

\DeclareExerciseHeadingTemplate{myTemplate}{%
  \chapter{Solutions to Problems in chapter \thechapter}%
}
\DeclareExerciseEnvironmentTemplate{myTemplate}{%
  \IfInsideSolutionTF
    {\label{sol:\ExerciseID}}
    {\label{ex:\ExerciseID}}%
     % how to create a label for the hints??
  \GetExerciseHeadingF{\subsection*}{%
    \XSIMmixedcase{% \arial% <- font changed
        \GetExerciseName}\nobreakspace
    \GetExerciseProperty{counter}%
    \IfInsideSolutionF{%
      \GetExercisePropertyT{subtitle}{ {\large\itshape\PropertyValue}}%
      \marginRef{%
        solution in page \pageref{sol:\ExerciseID}%
        \IfExercisePropertySetT{hint}{, hint in page \pageref{hint:\ExerciseID}}%
      }%
    }%
  }%
}
{\par}

\newcommand\printhints{%
  \section{Hints}
  \begin{description}
    \ForEachUsedExerciseByType{%
      \GetExercisePropertyT{hint}
        {\item[Hint for \XSIMmixedcase{\GetExerciseName}\label{hint:##2}~##3]####1}%
    }%
  \end{description}
}

% lang package
% \usepackage{polyglossia}
% \setdefaultlanguage{english}
% \newfontfamily\arial{Arial}[Script=Latin,Language=English]

\usepackage{hyperref}

\begin{document}
\chapter{Geometry}
\section{Introduction}
\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}

\newpage
\printhints

\printsolutions[headings=true,headings-template=myTemplate]
\end{document}

enter image description here

enter image description here

You can extend the above to add a margin note per hint, count the hints per problem, ...

\documentclass[openany,oneside]{book}
\usepackage{xsim,xcolor}

\newcommand{\marginRef}[1]{%
  \marginpar{\colorbox{lightgray}{\parbox{\dimexpr\marginparwidth-2\fboxsep}{#1}}}
}

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

\DeclareExerciseProperty{hint}
\newcounter{hint}[exercise]
\newcommand\thishint{}
\newcommand\hint[1]{%
  \stepcounter{hint}%
  \eappto\thishint{Hint \thehint: \unexpanded{#1}\par}%
  \marginRef{hint \thehint\ in page \pageref{hint:\ExerciseID}}%
}

\DeclareExerciseHeadingTemplate{myTemplate}{%
  \chapter{Solutions to Problems in chapter \thechapter}%
}
\DeclareExerciseEnvironmentTemplate{myTemplate}{%
  \IfInsideSolutionTF
    {\label{sol:\ExerciseID}}
    {\label{ex:\ExerciseID}}%
  \GetExerciseHeadingF{\subsection*}{%
    \XSIMmixedcase{\GetExerciseName}\nobreakspace
    \GetExerciseProperty{counter}%
    \IfInsideSolutionF{%
      \GetExercisePropertyT{subtitle}{ {\large\itshape\PropertyValue}}%
      \marginRef{solution in page \pageref{sol:\ExerciseID}}%
    }%
  }%
}%
{%
  \par
  \IfInsideSolutionF{%
    \ifdefvoid\thishint{}
      {\SetExpandedExerciseProperty{hint}{\expandonce{\thishint}}}%
  }%
}

\newcommand\printhints{%
  \section{Hints}
  \begin{description}
    \ForEachUsedExerciseByType{%
      \GetExercisePropertyT{hint}
        {\item[Hints for \XSIMmixedcase{\GetExerciseName}\label{hint:##2}~##3]####1}%
    }%
  \end{description}
}

\usepackage{hyperref}

\begin{document}
\chapter{Geometry}
\section{Introduction}
\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.}
  \hint{Another hint.}
\end{exercise}
\begin{solution}
  The proof is easy.
\end{solution}

\newpage
\begin{exercise}
  No hints here.
\end{exercise}
\begin{solution}
  The solution.
\end{solution}
\begin{exercise}
  One hint here.\hint{see?}
\end{exercise}
\begin{solution}
  The solution.
\end{solution}

\newpage
\printhints

\printsolutions[headings=true,headings-template=myTemplate]
\end{document}

enter image description here

enter image description here

12
  • Brilliant! I didn't mention it in the original post. But can you make the hint and the solution reference separated? I mean, print two different margin paragraphs for each of them.
    – tush
    Commented Jun 18, 2022 at 7:55
  • @tush sure. You can use two marginpars instead of one if you want to.
    – cgnieder
    Commented Jun 18, 2022 at 7:57
  • What if I have two hints for one exercise? Can I print them separately?
    – tush
    Commented Jun 18, 2022 at 8:15
  • @tush what exactly do you mean by “separately”? Just as separate sentences in the list of hints?
    – cgnieder
    Commented Jun 18, 2022 at 13:32
  • I mean that I want the n hint references to be typed in n different marginpars.
    – tush
    Commented Jun 18, 2022 at 13:42
1

The design of xsim seems to only allow exercise+solution. It is difficult to add a third category. So I implemented the functions you asked with LaTeX3.

  • You may need to compile twice to get the margin notes right
  • When margin notes are weird, try clearing the aux file
  • You need to call \PrintSolHint at the end of each chapter
%!TEX TS-program = xelatex
\documentclass[openany,oneside]{book}
\usepackage{unicode-math}
\usepackage{xparse}
\usepackage{xcolor}
\usepackage{blindtext}
\usepackage{hyperref}


\makeatletter
\ExplSyntaxOn


\cs_new:Npn \myex_add_to_solutions:n #1 {
  \tl_if_exist:NTF \@@myex@solutions{
        \tl_gput_right:Nn \@@myex@solutions {,#1}
    } {
        \tl_gset:Nn \@@myex@solutions {#1}
    }
}

\cs_new:Npn \myex_add_to_hints:n #1 {
    \tl_if_exist:NTF \@@myex@hints{
        \tl_gput_right:Nn \@@myex@hints {,#1}
    } {
        \tl_gset:Nn \@@myex@hints {#1}
    }
}


% #1: type (solution/hint)
% #2: number
\cs_new:Npn \myex_if_problem_has:nnTF #1#2#3#4 {
  \cs_if_exist:cTF {@@myex@#1s@old} {
    \clist_if_in:cnTF {@@myex@#1s@old} {#2} {#3} {#4}
  } {#4}
}

\cs_generate_variant:Nn \myex_if_problem_has:nnTF {neTF}

\AtEndDocument{
    \tl_if_exist:NT \@@myex@solutions {
        \write\@auxout{\gdef\string\@@myex@solutions@old{\@@myex@solutions}}
    }
    \tl_if_exist:NT \@@myex@hints {
        \write\@auxout{\gdef\string\@@myex@hints@old{\@@myex@hints}}
    }
}

\seq_new:N \g_myex_solutions_seq
\seq_new:N \g_myex_hints_seq
\seq_new:N \l_myex_tmpa_seq
\tl_new:N \l_myex_tmpa_tl

% create counter
\newcounter{problem}
\numberwithin{problem}{chapter}

\newcommand{\marginRef}[1]{%
  \marginpar{\colorbox{lightgray}{\parbox{\dimexpr\marginparwidth-2\fboxsep}{\footnotesize #1}}}
}

% declare exercise environment
\DeclareDocumentEnvironment{exercise}{O{}}{
    \begin{trivlist}
    % increment the counter
    \refstepcounter{problem}
    % produce heading
    \item{\arial\bfseries\large Problem\ \theproblem\ {\itshape #1}}\label{prob:\theproblem}
    % cross referencing
    \seq_clear:N \l_myex_tmpa_seq
    \myex_if_problem_has:neTF {hint} {\theproblem} {
      \seq_put_right:Nx \l_myex_tmpa_seq {hint~on~page~\exp_not:N\pageref{hint:\theproblem}}
    } {}
    \myex_if_problem_has:neTF {solution} {\theproblem} {
      \seq_put_right:Nx \l_myex_tmpa_seq {solution~on~page~\exp_not:N\pageref{sol:\theproblem}}
    } {}
    \tl_set:Nx \l_myex_tmpa_tl {\seq_use:Nn \l_myex_tmpa_seq {;\ }}
    \tl_if_empty:NF \l_myex_tmpa_tl {
      \marginRef{\exp_args:NV \text_titlecase:n \l_myex_tmpa_tl}
    }
    % body text
    \item
}{\end{trivlist}}


% declare solution and hint environments
\DeclareDocumentEnvironment{solution}{+b}{
    \exp_args:Ne \myex_add_to_solutions:n {\theproblem}
}{\seq_gput_right:Nx \g_myex_solutions_seq {{\theproblem}{\exp_not:n {#1}}}}

\DeclareDocumentEnvironment{hint}{+b}{
    \exp_args:Ne \myex_add_to_hints:n {\theproblem}
}{\seq_gput_right:Nx \g_myex_hints_seq {{\theproblem}{\exp_not:n {#1}}}}

\newcommand{\PrintSolHint}{
  \seq_if_empty:NF \g_myex_hints_seq {
    \section{Hints~to~Problems~in~Chapter\ \thechapter}
    \begin{trivlist}
    \seq_map_inline:Nn \g_myex_hints_seq {
      \item {\arial\large\bfseries Hint~\tl_item:nn {##1} {1}} \label{hint:\tl_item:nn {##1} {1}}
      \item \tl_item:nn {##1} {2}
    }
    \end{trivlist}
  }
  \seq_if_empty:NF \g_myex_solutions_seq {
    \section{Solutions~to~Problems~in~Chapter\ \thechapter}
    \begin{trivlist}
    \seq_map_inline:Nn \g_myex_solutions_seq {
      \item {\arial\large\bfseries Solution~\tl_item:nn {##1} {1}} \label{sol:\tl_item:nn {##1} {1}}
      \item \tl_item:nn {##1} {2}
    }
    \end{trivlist}
  }
  % clear the solution/hint storage after each print
  \seq_gclear:N \g_myex_solutions_seq
  \seq_gclear:N \g_myex_hints_seq
}

\ExplSyntaxOff
\makeatother




% lang package
\usepackage{polyglossia}
\setdefaultlanguage{english}
\newfontfamily\arial{Arial}[Script=Latin,Language=English]

\begin{document}

\chapter{Geometry}
\section{Introduction}
\begin{exercise}[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{hint}
Draw the altitude from point $C$, and call $H$ its intersection with the side $AB$.
\end{hint}

\begin{exercise}[Some other theorem]
Please determine what gravity is.
\end{exercise}
\begin{solution}
The proof is easy.
\end{solution}
\begin{hint}
The solution to the equation is very easy:
\begin{align}
i\hbar\frac{\partial}{\partial t} \Psi(\mathbf{r},\,t) =
    -\frac{\hbar^2}{2m}\nabla^2 \Psi(\mathbf{r},\,t) + V(\mathbf{r})\Psi(\mathbf{r},\,t)
\end{align}
\end{hint}

\PrintSolHint

\chapter{Algebra}
\section{Introduction}
\begin{exercise}[Theorem 1]
\Blindtext[3]
\end{exercise}
\begin{solution}
\Blindtext[5]
\end{solution}
\begin{hint}
\Blindtext[5]
\end{hint}

\begin{exercise}[Theorem 2]
\Blindtext[3]
\end{exercise}
\begin{hint}
\Blindtext[5]
\end{hint}

\begin{exercise}[Theorem 3]
\Blindtext[3]
\end{exercise}
\begin{solution}
\Blindtext[5]
\end{solution}


\begin{exercise}[Theorem 4]
\Blindtext[8]
\end{exercise}



\PrintSolHint
\end{document}
5
  • Thanks very much indeed for your time you put into it. What do you mean when you say "to add a third category" with xsim? The hints I am talking about are the content of the third category?
    – tush
    Commented Jun 16, 2022 at 21:20
  • I am sorry, I don't feel comfortable with LaTeX3 functions (ExplSyntaxOn). I never worked with it before. I prefer a solution which is implemented with xsim.
    – tush
    Commented Jun 16, 2022 at 21:26
  • If you look into the source code of xsim (xsim.sty), on line 2930, they declared "exercise" and "solution" for a "problem". There is no space for "hint" here. To add a hint, you need to play with \xsim_declare_exercise_type:nn, which is essentially LaTeX3.
    – Alan Xiang
    Commented Jun 16, 2022 at 21:41
  • What about the example that I mentioned in the question that is available in the repo? Can't it be implemented here?
    – tush
    Commented Jun 16, 2022 at 21:46
  • 1
    Let me try something. The problem is you can indeed save hint using a property, but it is very difficult to print them out in a organized fashion. Also, you can't really use display math environments in them.
    – Alan Xiang
    Commented Jun 16, 2022 at 21:52

You must log in to answer this question.

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