\def\fileversion{0.5g} \def\filedate{2009/02/09} % TODO: allow \and in author and solutionsby % TODO: fix "above hint skip" %\NeedsTeXFormat{LaTeX2e}[1994/12/01] \ProvidesPackage{exercisesheets}[\filedate\space\fileversion\space Typesetting of exercise sheets] \message{`Typesetting of exercise sheets' \fileversion\space <\filedate>} \RequirePackage{etoolbox}[2008/06/28] \RequirePackage{scrlfile} \RequirePackage{pgfkeys} \RequirePackage{keyval} \RequirePackage{kvoptions} \RequirePackage{ifthen} \RequirePackage{amsmath} % configuration keys \newif\ifexsh@solutions \newif\ifexsh@oralsolutions \newif\ifexsh@nonoralsolutions \pgfkeys{/exsh/.is family,/exsh, solutions/.is choice, solutions/true/.code=\exsh@solutionstrue\exsh@oralsolutionstrue\exsh@nonoralsolutionstrue, solutions/oral/.code=\exsh@solutionstrue\exsh@oralsolutionstrue\exsh@nonoralsolutionsfalse, solutions/nonoral/.code=\exsh@solutionstrue\exsh@oralsolutionsfalse\exsh@nonoralsolutionstrue, solutions/false/.code=\exsh@solutionsfalse\exsh@oralsolutionsfalse\exsh@nonoralsolutionsfalse, solutions/.default=true, only/.initial={-}, all/.style={/exsh/only={-}},all/.value forbidden, solutionsby/.code={\def\exsh@solutionsby{#1}},solutionsby/.value required, } % store title data for sheet headers \ifundef\subject{% \subject is only provided by KOMA classes \newcommand{\subject}[1]{}% \def\@subject{}% }{} \apptocmd{\subject}{\pgfkeys{/exsh/subject={#1}}}{}{}% \ifdefempty{\@subject}{ \pgfkeys{exsh,subject/.initial={\PackageWarning{exercisesheets}{No \string\subject\space given}}} }{ \pgfkeys{/exsh/subject/.initial/.expand once=\@subject} } \ifdefstring{\@date}{\today}{ \pgfkeys{/exsh/semester/.initial={\PackageWarning{exercisesheets}{No semester given in \string\date}}} }{ \pgfkeys{/exsh/semester/.initial/.expand once=\@date} } \apptocmd{\date}{\pgfkeys{/exsh/semester={#1}}}{}{} \def\exsh@patchauthor{% \patchcmd{\exsh@author}{\and}{, }{\exsh@patchauthor}{}% } \pgfkeys{/exsh/author/.code={% \def\exsh@author{#1}% \exsh@patchauthor }, /exsh/author/.expand once=\@author} \let\exsh@oldauthor\author \def\author#1{\exsh@oldauthor{#1}\pgfkeys{/exsh/author={#1}}} % helper macro for automatic language selection \newif\ifexsh@provideonly \def\exsh@deforprovide#1#2{% \ifthenelse{\(\NOT\boolean{exsh@provideonly}\) \OR \equal{}{\pgfkeysvalueof{#1}}}{% \pgfkeys{#1=#2}% }{}% } \pgfkeys{exsh, % additional sheet info title/.initial={}, date/.initial={}, note/.initial={}, % % additional exercise info name/.initial={}, firstline/.initial={}, points/.initial={}, oral/.style={/exsh/points=oral},oral/.value forbidden, bonus/.style={/exsh/strings/points=\pgfkeysvalueof{/exsh/strings/bonus points}, /exsh/strings/point=\pgfkeysvalueof{/exsh/strings/bonus point}}, pointsinfo/.initial={}, optional/.style={/exsh/pointsinfo=\pgfkeysvalueof{/exsh/strings/optional}},optional/.value forbidden, % % translatable strings strings/sheet/.initial={}, strings/sheets/.initial={}, strings/solutions/.initial={}, strings/solutionsby/.initial={}, strings/exercise/.initial={}, strings/solution/.initial={}, strings/idea/.initial={}, strings/hint/.initial={}, strings/remark/.initial={}, strings/oral/.initial={}, strings/point/.initial={}, strings/points/.initial={}, strings/bonus point/.initial={}, strings/bonus points/.initial={}, strings/optional/.initial={}, % % languages: predifined string sets language/.is choice, language/german/.code={% \exsh@deforprovide{/exsh/strings/sheet} {\"Ubungsblatt}% \exsh@deforprovide{/exsh/strings/sheets} {\"Ubungsbl\"atter}% \exsh@deforprovide{/exsh/strings/solutions} {L\"osungsvorschl\"age}% \exsh@deforprovide{/exsh/strings/solutionsby} {L\"osungen von}% \exsh@deforprovide{/exsh/strings/exercise} {Aufgabe}% \exsh@deforprovide{/exsh/strings/solution} {L\"osung}% \exsh@deforprovide{/exsh/strings/idea} {L\"osungsidee}% \exsh@deforprovide{/exsh/strings/hint} {Hinweis}% \exsh@deforprovide{/exsh/strings/remark} {Bemerkung}% \exsh@deforprovide{/exsh/strings/oral} {m\"undlich}% \exsh@deforprovide{/exsh/strings/point} {Punkt}% \exsh@deforprovide{/exsh/strings/points} {Punkte}% \exsh@deforprovide{/exsh/strings/bonus point} {Zusatzpunkt}% \exsh@deforprovide{/exsh/strings/bonus points}{Zusatzpunkte}% \exsh@deforprovide{/exsh/strings/optional} {optional}% },language/german/.value forbidden, language/ngerman/.style={/exsh/language/german=#1}, language/english/.code={% \exsh@deforprovide{/exsh/strings/sheet} {Exercise Sheet}% \exsh@deforprovide{/exsh/strings/sheets} {Exercise Sheets}% \exsh@deforprovide{/exsh/strings/solutions} {Suggested Solutions}% \exsh@deforprovide{/exsh/strings/solutionsby} {Solutions by}% \exsh@deforprovide{/exsh/strings/exercise} {Exercise}% \exsh@deforprovide{/exsh/strings/solution} {Solution}% \exsh@deforprovide{/exsh/strings/idea} {Idea for solution}% \exsh@deforprovide{/exsh/strings/hint} {Hint}% \exsh@deforprovide{/exsh/strings/remark} {Remark}% \exsh@deforprovide{/exsh/strings/oral} {oral}% \exsh@deforprovide{/exsh/strings/point} {point}% \exsh@deforprovide{/exsh/strings/points} {points}% \exsh@deforprovide{/exsh/strings/bonus point} {bonus point}% \exsh@deforprovide{/exsh/strings/bonus points}{bonus points}% \exsh@deforprovide{/exsh/strings/optional} {optional}% },language/english/.value forbidden, language/.unknown/.code={% \PackageWarning{exercisesheets}{Unknown language \pgfkeyscurrentname. Defaulting to English.}{}% \pgfkeys{/exsh/language=english}% }, % % alternate strings idea/.style={/exsh/strings/solution=\pgfkeysvalueof{/exsh/strings/idea}}, remark/.style={/exsh/strings/hint=\pgfkeysvalueof{/exsh/strings/remark}}, % % hooks every sheet/.code={}, every exercise/.code={}, every solution/.code={}, every hint/.code={}, % % font specifications sheet header font/.initial=\normalfont\normalsize, subject font/.initial=\scshape, author font/.initial=\scshape, semester font/.initial={}, date font/.initial={}, solutionsby font/.initial=\itshape, sheet note font/.initial=\itshape\bfseries, sheet title font/.initial=\Large\bfseries, exercise title font/.initial=\bfseries, points font/.initial=\itshape, hint font/.initial={}, hint title font/.initial=\itshape, solution font/.initial={}, solution title font/.initial=\bfseries, todo marker font/.initial=\ifdef{\color}{\color{red}}{}\bfseries, % % skip values above sheet title skip/.initial={4ex}, above sheet note skip/.initial={.7ex}, above solutionsby skip/.initial={1ex}, below sheet header skip/.initial={4ex plus 1ex minus .5ex}, above exercise skip/.initial={3ex plus 1ex minus .5em}, below exercise title skip/.initial={\parskip}, above solution skip/.initial={1ex}, above hint skip/.initial={1ex}, } % default values \pgfkeys{exsh,solutions=false,all} % process package options \@expandtwoargs\pgfqkeys{/exsh}{\csname opt@exercisesheets.sty\endcsname} % mark options as processed \expandafter\undef\csname opt@exercisesheets.sty\endcsname % allow further keys to be set \def\exshset#1{\pgfkeys{exsh,#1}} % automatic language selection \AfterEndPreamble{% \exsh@provideonlytrue \ifdef{\bbl@main@language}{% \pgfkeys{/exsh/language=\bbl@main@language}% }{% \pgfkeys{/exsh/language=english}% }% \exsh@provideonlyfalse }% % range checks \newif\ifexsh@isinrange \newif\ifexsh@singularrange \def\exsh@checkrange#1{% \edef\exsh@range@entry{#1}% \def\exsh@range@curstart{}% \exsh@isinrangefalse \exsh@singularrangetrue \pgfkeysgetvalue{/exsh/only}{\exsh@temp}% \expandafter\exsh@range@parsestart\exsh@temp\exsh@range@end } \def\exsh@range@parsestart#1{% \ifstrequal{#1}{,}{% \exsh@singularrangefalse \ifdefstring{\exsh@range@curstart}{last}{% \let\exsh@range@curstart\exsh@lastsheet }{}% \ifdefequal{\exsh@range@entry}{\exsh@range@curstart}{% \exsh@isinrangetrue }{}% \def\exsh@range@curstart{}% \exsh@range@parsestart }{% \ifstrequal{#1}{\exsh@range@end}{% \ifdefstring{\exsh@range@curstart}{last}{% \let\exsh@range@curstart\exsh@lastsheet }{}% \ifdefequal{\exsh@range@entry}{\exsh@range@curstart}{% \exsh@isinrangetrue }{}% }{% \ifdefequal{#1}{-}{% \exsh@singularrangefalse \ifdefstring{\exsh@range@curstart}{}{% \def\exsh@range@curstart{0}% }{}% \ifdefstring{\exsh@range@curstart}{last}{% \let\exsh@range@curstart\exsh@lastsheet }{}% \def\exsh@range@curend{}% \exsh@range@parseend }{% \appto{\exsh@range@curstart}{#1}% \exsh@range@parsestart }% }% }% } \def\exsh@range@parseend#1{% \ifstrequal{#1}{,}{% \ifdefstring{\exsh@range@curend}{last}{% \def\exsh@range@curend{10000}% }{}% \ifdefstring{\exsh@range@curend}{}{ \def\exsh@range@curend{10000}% }{}% \ifthenelse{\NOT \(\exsh@range@curstart > \exsh@range@entry \OR \exsh@range@entry > \exsh@range@curend\)}{% \exsh@isinrangetrue }{}% \def\exsh@range@curstart{}% \exsh@range@parsestart }{% \ifstrequal{#1}{\exsh@range@end}{% \ifdefstring{\exsh@range@curend}{last}{% \def\exsh@range@curend{10000}% }{}% \ifdefstring{\exsh@range@curend}{}{ \def\exsh@range@curend{10000}% }{}% \ifthenelse{\NOT \(\exsh@range@curstart > \exsh@range@entry \OR \exsh@range@entry > \exsh@range@curend\)}{% \exsh@isinrangetrue }{% }% }{% \appto{\exsh@range@curend}{#1}% \exsh@range@parseend }% }% } % remember last sheet (for range checks) \def\exsh@lastsheet{0}% to be overridden in aux file \AtEndDocument{% \immediate\write\@auxout{\string\gdef\string\exsh@lastsheet{\arabic{part}}}% } \numberwithin{page}{part} \renewcommand{\thepage}{\arabic{page}}%changed for every sheet \setcounter{secnumdepth}{-1} % make PDF destinations unique: \AfterPackage*{hyperref}{% \def\theHsection{\arabic{part}.\arabic{section}}% \def\theHpage{\arabic{part}-\arabic{page}}% } % automatic title selection \let\exsh@title\relax \let\exsh@title@new\relax \def\exsh@write@title#1{% \xdef\exsh@title@new{\expandonce #1}% \protected@write\@auxout{}{\string\gdef\string\exsh@title{\expandonce\exsh@title@new}}% } \AfterEndDocument{% \ifthenelse{\equal{\exsh@title}{\exsh@title@new}}{}{% \@latex@warning@no@line{Label(s) may have changed. Rerun to get cross-references right}% }% } \AfterEndPreamble{% \exsh@checkrange{0}% \ifexsh@singularrange\else \pgfkeysgetvalue{/exsh/strings/sheets}{\exsh@tmp}% \exsh@write@title{\exsh@tmp}% \fi } \AtBeginDocument{% \ifexsh@solutions \title{\exsh@title: \pgfkeysvalueof{/exsh/strings/solutions}}% \else \title{\exsh@title} \fi } \newenvironment{sheet}[1][]{% \clearpage \pgfkeys{exsh,every sheet,#1}% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/title}}}{% \numdef\exsh@tmp{\value{part}+1}% \edef\exsh@temp{\expandonce{\pgfkeysvalueof{/exsh/strings/sheet}}\noexpand~\exsh@tmp}% \pgfkeys{/exsh/title/.expand once={\exsh@temp}}% \def\thepage{\arabic{part}-\arabic{page}}% }{% \def\thepage{\arabic{page}}% \setcounter{section}{0}% }% \numdef\exsh@tmp{\value{part}+1}% \exsh@checkrange{\exsh@tmp}% \ifexsh@isinrange \ifexsh@singularrange \pgfkeysgetvalue{/exsh/title}{\exsh@temp}% \exsh@write@title{\exsh@temp}% \fi \exsh@sheethead \else \refstepcounter{part}% \expandafter\exsh@skipsheet \fi }{% \par \begingroup \ifnum\value{page}=1\thispagestyle{empty}\fi \clearpage \endgroup } \listadd{\exsh@enums}{enumerate} \listadd{\exsh@enums}{compactenum} \listadd{\exsh@enums}{asparaenum} \listadd{\exsh@enums}{inparaenum} \listadd{\exsh@nonenums}{itemize} \listadd{\exsh@nonenums}{compactitem} \listadd{\exsh@nonenums}{asparaitem} \listadd{\exsh@nonenums}{inparaitem} \listadd{\exsh@nonenums}{description} \listadd{\exsh@nonenums}{compactdesc} \listadd{\exsh@nonenums}{asparadesc} \listadd{\exsh@nonenums}{inparadesc} \listadd{\exsh@nonenums}{asparablank} \listadd{\exsh@nonenums}{inparablank} \listadd{\exsh@nonenums}{list} \long\def\exsh@skipsheet#1{% \ifstrequal{#1}{\begin}{\exsh@skipsheet@begin}{% \ifstrequal{#1}{\end}{\exsh@skipsheet@end}{% \ifstrequal{#1}{\label}{\exsh@skipsheet@label}{% \ifstrequal{#1}{\setcounter}{\expandafter\exsh@skipsheet\setcounter}{% \ifstrequal{#1}{\item}{\ifdef{\@enumctr}{\@hyper@itemtrue\refstepcounter{\@enumctr}}{}}{}% \exsh@skipsheet}}}}% } \def\exsh@skipsheet@end#1{% \ifstrequal{#1}{sheet}{\end{sheet}}{\endgroup\exsh@skipsheet}% } \def\exsh@skipsheet@begin#1{% \begingroup \ifstrequal{#1}{exercise}{\refstepcounter{section}}{}% \ifinlist{#1}{\exsh@enums}{% \exsh@skipsheet@beginenum }{% \ifinlist{#1}{\exsh@nonenums}{% \undef\@enumctr }{}% \exsh@skipsheet }% } \def\exsh@skipsheet@beginenum{% \ifnum\@enumdepth>\thr@@ \@toodeep \else \advance\@enumdepth\@ne \edef\@enumctr{enum\romannumeral\the\@enumdepth}% \setcounter{\@enumctr}{0}% \fi \@ifnextchar[{\@enumlabel@{\exsh@skipsheet}[}{\exsh@skipsheet}% } \def\exsh@skipsheet@label#1{% \label{#1}\exsh@skipsheet } \def\exsh@sheethead{% \pgfkeysgetvalue{/exsh/title}{\exsh@tmp}% \ifexsh@solutions \expandafter\edef\expandafter\exsh@tmp{\expandonce\exsh@tmp:\noexpand~\pgfkeysvalueof{/exsh/strings/solutions}}% \fi \refstepcounter{part}% \stepcounter{page}% \part[\pgfkeysvalueof{/exsh/title}]{\normalsize \pgfkeysvalueof{/exsh/sheet header font}\centering% \begingroup\raggedright% {\pgfkeysvalueof{/exsh/subject font}\pgfkeysvalueof{/exsh/subject}}\hfill {\pgfkeysvalueof{/exsh/semester font}\pgfkeysvalueof{/exsh/semester}}\\ {\pgfkeysvalueof{/exsh/author font}\exsh@author}\hfill {\pgfkeysvalueof{/exsh/date font}\pgfkeysvalueof{/exsh/date}}\\ \vskip\pgfkeysvalueof{/exsh/above sheet title skip}\relax% \endgroup \begingroup \pgfkeysvalueof{/exsh/sheet title font}\exsh@tmp\\\unskip \endgroup \begingroup \pgfkeysvalueof{/exsh/sheet header font}% \ifexsh@solutions% \ifdefvoid{\exsh@solutionsby}{}{% \begingroup \pgfkeysvalueof{/exsh/solutionsby font}% \vskip\pgfkeysvalueof{/exsh/above solutionsby skip}\relax \pgfkeysvalueof{/exsh/strings/solutionsby}~\exsh@solutionsby\\\unskip% \endgroup }% \else \fi \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/note}}}{% }{% \begingroup \pgfkeysvalueof{/exsh/sheet note font}% \vskip\pgfkeysvalueof{/exsh/above sheet note skip}\relax \pgfkeysvalueof{/exsh/note}\\\unskip% \endgroup }% \endgroup }% \unskip \vskip\pgfkeysvalueof{/exsh/below sheet header skip}\relax } \ifdef{\othersectionslevelsformat}{% \renewcommand{\othersectionlevelsformat}[1]{% \ifstrequal{#1}{section}% {}% {\csname the#1\endcsname\autodot\enskip}}% }{} \newenvironment*{exercise}[1][]{% \pgfkeys{exsh,every exercise,#1}% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/points}}}{% \def\exsh@points{}% \def\exsh@shortpoints{}% }{% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/points}}}{% \edef\exsh@points{\pgfkeysvalueof{/exsh/pointsinfo}}% }{% \ifthenelse{\equal{oral}{\pgfkeysvalueof{/exsh/points}}}{% \edef\exsh@points{\pgfkeysvalueof{/exsh/strings/oral}}% }{% \ifthenelse{\equal{1}{\pgfkeysvalueof{/exsh/points}}}{% \edef\exsh@points{1 \pgfkeysvalueof{/exsh/strings/point}}% }{% \edef\exsh@points{\pgfkeysvalueof{/exsh/points} \pgfkeysvalueof{/exsh/strings/points}}% }% }% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/pointsinfo}}}{}{% \edef\exsh@points{\expandonce\exsh@points, \pgfkeysvalueof{/exsh/pointsinfo}}% }% }% \ifthenelse{\equal{}{\exsh@points}}{% \def\exsh@shortpoints{}% }{% \edef\exsh@shortpoints{ (\expandonce\exsh@points)}% }% \preto\exsh@points{\enskip\hfill\bgroup% \pgfkeysvalueof{/exsh/points font}}% \appto\exsh@points{\egroup}% }% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/firstline}}}{% \def\exsh@firstline{}% }{% \edef\exsh@firstline{\pgfkeysvalueof{/exsh/firstline}}% \preto\exsh@firstline{\quad\bgroup\normalfont\normalsize}% \appto\exsh@firstline{\egroup}% }% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/name}}}{% \def\exsh@exname{}% \def\exsh@shortexname{}% }{% \edef\exsh@exname{\space(\pgfkeysvalueof{/exsh/name})}% \edef\exsh@shortexname{:\space\pgfkeysvalueof{/exsh/name}}% }% \refstepcounter{section}% \edef\exsh@tmp{[\pgfkeysvalueof{/exsh/strings/exercise} \arabic{section}\exsh@shortexname\exsh@shortpoints]}% \expandafter\exsh@startsection\exsh@tmp{\noindent% \pgfkeysvalueof{/exsh/strings/exercise}~\arabic{section}\exsh@exname\exsh@firstline\exsh@points}% \unskip\vskip\pgfkeysvalueof{/exsh/below exercise title skip}\relax \vskip-\parskip\relax \@afterindentfalse \ignorespaces }{} \providecommand{\exsh@startsection}[2][]{% \@startsection{section}{1}{\z@}% {\pgfkeysvalueof{/exsh/above exercise skip}}% {1em}% afterskip corrected below {\pgfkeysvalueof{/exsh/exercise title font}}% [#1]{#2}% }% \AfterPackage*{varioref}{ \labelformat{section}{\pgfkeysvalueof{/exsh/strings/exercise}~\arabic{section}} \labelformat{enumi}{\arabic{section}.#1} } \AfterPackage*{paralist}{ \setdefaultenum{(a)}{(1)}{i.}{A.} } \newenvironment{hint}[1][]{% \pgfkeys{exsh,every hint,#1,hint font}% \par\vskip\pgfkeysvalueof{/exsh/above hint skip}\relax\noindent {\pgfkeysvalueof{/exsh/hint title font}\pgfkeysvalueof{/exsh/strings/hint}:}~\ignorespaces }{% \par } \newenvironment{hint*}[1][]{% \pgfkeys{exsh,every hint,#1,hint font}% ({\pgfkeysvalueof{/exsh/hint title font}\pgfkeysvalueof{/exsh/strings/hint}:}\space% }{% \unskip)% } \newenvironment{solution}[1][]{% \pgfkeys{exsh,every solution,#1,solution font}% \ifthenelse{\equal{oral}{\pgfkeysvalueof{/exsh/points}}}{% \ifbool{exsh@oralsolutions}{% \let\next\exsh@startsolution }{% \let\next\exsh@skipsolution }% }{% \ifbool{exsh@nonoralsolutions}{% \let\next\exsh@startsolution }{% \let\next\exsh@skipsolution }% }% \next }{% \ifthenelse{\equal{oral}{\pgfkeysvalueof{/exsh/points}}}{% \ifbool{exsh@oralsolutions}{\par}{}% }{% \ifbool{exsh@nonoralsolutions}{\par}{}% }% } \def\exsh@startsolution{\@afterindentfalse \vskip\pgfkeysvalueof{/exsh/above solution skip}\relax% {\parindent \z@ \pgfkeysvalueof{/exsh/solution title font}\nobreak \pgfkeysvalueof{/exsh/strings/solution}:\par\nobreak}\nobreak% \@afterheading }% \long\def\exsh@skipsolution#1{% \ifstrequal{#1}{\end}{\exsh@endsolution}{\exsh@skipsolution}% } \def\exsh@endsolution#1{% \ifstrequal{#1}{solution}{\end{solution}}{\exsh@skipsolution}% } \newcommand{\pun}[1][]{% \PackageWarning{exercisesheets}{Obsolete \string\pun[] macro used. Please use something\MessageBreak like \string\points{10} or \string\points{oral} instead.}{}% \exsh@subexpoints{#1}% } \newcommand{\points}[2][]{% \exshset{points=#2}% \bgroup \exshset{#1}% \ifthenelse{\equal{}{\pgfkeysvalueof{/exsh/pointsinfo}}}{% \def\exsh@tmp{}% }{% \def\exsh@tmp{, \pgfkeysvalueof{/exsh/pointsinfo}}% }% \ifthenelse{\equal{#2}{oral}}{% \exsh@subexpoints{\pgfkeysvalueof{/exsh/strings/oral}\exsh@tmp}% }{% \ifthenelse{\equal{#2}{}}{% \exsh@subexpoints{\pgfkeysvalueof{/exsh/pointsinfo}}% }{% \ifthenelse{\equal{#2}{1}}{% \exsh@subexpoints{1~\pgfkeysvalueof{/exsh/strings/point}\exsh@tmp}% }{% \exsh@subexpoints{#2~\pgfkeysvalueof{/exsh/strings/points}\exsh@tmp}% }% }% }% \egroup } \newcommand{\exsh@subexpoints}[1]{% \unskip\nobreak\space\nobreak\hspace*{\fill}\allowbreak\hspace*{\fill}% {\pgfkeysvalueof{/exsh/points font}\mbox{(#1)}}% } \newcommand{\TODO}{% \ifmmode ${\pgfkeysvalueof{/exsh/todo marker font}TODO}$% \else {\pgfkeysvalueof{/exsh/todo marker font}TODO}% \fi \PackageWarning{exercisesheets}{TODO marker found}% } \newcommand{\ifsolutions}[2]{% \ifbool{exsh@solutions}{#1}{#2}% } \newcommand{\iforalsolutions}[2]{% \ifbool{exsh@oralsolutions}{#1}{#2}% } \newcommand{\ifnonoralsolutions}[2]{% \ifbool{exsh@nonoralsolutions}{#1}{#2}% }