From f357d5402f0a195a92c76d252e4ad5db974f8f9e Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 25 Sep 2018 20:25:41 +0000 Subject: exercisebank (25sep18) git-svn-id: svn://tug.org/texlive/trunk@48757 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/latex/exercisebank/exercisebank.sty | 449 +++++++++++++++------ 1 file changed, 321 insertions(+), 128 deletions(-) (limited to 'Master/texmf-dist/tex/latex/exercisebank') diff --git a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty index 3ad71d95aff..fec5d392ed3 100644 --- a/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty +++ b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty @@ -1,5 +1,5 @@ % Source (with comments) can be found at https://github.com/Strauman/exercisebank/ -%% The LaTeX package exercisebank - version v0.2.0 (2018/07/21) - build 75 +%% The LaTeX package exercisebank - version v0.2.1 (2018/09/24) - build 95 %% exercisebank.sty: Exercise bank %% ------------------------------------------------------------------------------------------- %% Copyright (c) 2018 by Andreas Storvik Strauman @@ -13,9 +13,10 @@ %% version 2008/05/04 or later. %% This work has the LPPL maintenance status `author-maintained'. %% This work consists of all files listed in README -\ProvidesPackage{exercisebank}[2018/07/21 v0.2.0 Creates a setup that gives freedom in making sets and exercises.] +\ProvidesPackage{exercisebank}[2018/09/24 v0.2.1 Creates a setup that gives freedom in making sets and exercises.] \xdef\exbank@quiet{1} -\PackageWarningNoLine{exercisebank-v0.2.0}{This package is in the beta stage, and if something unexpected happens please, oh pretty please, report it to https://github.com/Strauman/exercisebank. Thank you!} +\def\exercisebankversion{v0.2.1 - Build 95} +\PackageWarningNoLine{exercisebank-v0.2.1}{This package is in the beta stage, and if something unexpected happens please, oh pretty please, report it to https://github.com/Strauman/exercisebank. Thank you!} \@ifundefined{ownLineNoSpacesGotIt}{\@latex@warning{Compilation wont work unless \string\end{problem} and \string\end{solution} are on their own lines and without any spaces. This warning can be removed by doing \string\def\string\ownLineNoSpacesGotIt{} before \@backslashchar usepackage{exercisebank}} }{} \gdef\setExercisesDir#1{\@latex@error{\string\setExercisesDir is deprecated. Use \string\exercisebanksetup{exercise directory=#1} instead}{}\stop\bye @@ -35,28 +36,52 @@ \usepackage{needspace} \edef\@isTrue{1} \edef\@isFalse{0} -\gdef\isin#1#2#3#4{ \def\needle{#2} - \def\haystack{#1} - \def\isFalse{0} - \let\isInList = \isFalse - \IfInteger{\needle}{}{\@latex@error{ISIN: Can't look for part problem that is not numeric!}{}\bye\stop} - \IfInteger{\haystack}{ \ifnum\haystack=\needle\relax - #3 - \else - #4 - \fi -}{ \foreach\pp in #1{ \ifnum\pp=\needle\relax% - \gdef\isInList{1} - #3 - \fi -} - \if\isInList\isFalse - #4 - \fi -} +\gdef\exb@int@isin#1#2#3#4{% + \def\needle{#1} + \def\haystack{#2} + \ifx\haystack\empty\relax#4\else% + \def\isFalse{0}% + \let\isInList = \isFalse% + \IfInteger{\needle}{}{\@latex@error{ISIN: Can't look for part problem that is not numeric: `\needle' in `\haystack'!}{}\bye\stop}% + \IfInteger{\haystack}{ \ifnum\haystack=\needle\relax% + #3% + \else% + #4% + \fi% +}{ \foreach\pp in #2{% + \ifnum\pp=\needle\relax% + \gdef\isInList{1}% + #3% + \fi% +}% + \if\isInList\isFalse% + #4% + \fi% +}% + \fi} +\gdef\exb@warn{\PackageWarningNoLine{exercisebank-v0.2.1}} +\gdef\exb@err#1{\PackageError{exercisebank}{#1}{}} +\newif\ifexb@isInList +\newcounter{exb@isin@dots} +\gdef\exb@isin#1#2#3#4{\@dinfo{running isin} + \global\exb@isInListfalse + \xdef\needle{#1} + \xdef\haystack{#2} + \def\whenfalse{#4} + \def\whentrue{#3} + \ifx\haystack\empty\relax#4\else% + \readlist*\items\haystack% + \foreachitem\itm\in\items{% + \ifnum\pdfstrcmp{\needle}{\itm}=\z@\relax% + \global\exb@isInListtrue% + #3\fi% +}% + \ifexb@isInList\else% + #4 + \fi\fi% } \gdef\strif#1#2{% - \ifnum\pdfstrcmp{#1}{#2}=\z@\relax% + \ifnum\pdfstrcmp{#1}{#2}=\z@\relax% } \let\ea = \expandafter \begingroup\lccode`\|=`\\ @@ -64,36 +89,86 @@ \gdef\exbank@macroname#1{\expandafter\removebs\string#1} \gdef\@noneofone#1{} \gdef\@noneoftwo#1#2{} -\@ifundefined{exbank@quiet}{ \global\let\@dlog\@latex@warning -}{ \global\let\@dlog\@noneofone +{\globaldefs=1\newcommand\@opt@gobble[2][]{}} +\@ifundefined{exbank@verbose}{ \global\let\@dinfo\@gobble + \global\let\@dinfomode\@opt@gobble +}{ \bgroup + \globaldefs=1\newcommand\@dinfo[2][]{% + \@latex@warning{--INFO:#2}% +}% + \egroup% +} +\@ifundefined{exbank@quiet}{ \gdef\@dlog#1{\@latex@warning{::DEBUG:#1}}% +}{ \global\let\@dlog\@noneofone% } -\newcommand\ex@before[2]{\edef #1{\unexpanded{#2}\unexpanded\expandafter{#1}} +\gdef\shownextchar#1{\@latex@warning{NEXT:\string#1}#1} +\newcommand\ex@before[2]{ \edef #1{\unexpanded{#2}\unexpanded\expandafter{#1}} } \newcommand{\exb@lmargin}[2]{\strut\vadjust{\exb@domark{#1}{#2}}} \newcommand{\exb@domark}[2]{% - \hbox to #2{ \vbox to 0pt{ \kern-\dp\strutbox - \smash{\llap{#1}} - \vss + \hbox to #2{ \vbox to 0pt{ \kern-\dp\strutbox + \smash{\llap{#1}} + \vss }% } } +\newif\ifexb@isintersection +\def\exb@intersection@any#1#2#3#4{% + \global\exb@isintersectionfalse% + \edef\listarg{#1}% + \ifx\listarg\empty\@dlog{RELAX}#4\else% + \readlist*\needlelist{#1}% + \foreachitem\needle\in\needlelist{% + \exb@isin{\needle}{#2}{\global\exb@isintersectiontrue}{}% +}% + \ifexb@isintersection#3\else#4\fi% + \fi% +} +\gdef\@makespacesignored{% +\global\let\@oldtilde~% +\gdef~{}% +\global\catcode`\^^M=9\relax% +\global\catcode`\^^J=9\relax% +\global\catcode`\ =9\relax% +} +\gdef\@makespacesnormal{% +\global\let~\@oldtilde% +\global\catcode`\^^M=5\relax% +\global\catcode`\^^J=12\relax% +\global\catcode`\ =10\relax% +} +\let\nextPar\everypar +\newtoks\everypar +\nextPar{\the\everypar} +\def\AtNextPar#1{\nextPar\expandafter{\the\nextPar\nextPar{\the\everypar}#1}} \edef\@isTrue{1} \edef\@isFalse{0} \gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}} +\gdef\exb@showtags{\isFalse} +\gdef\ShowTags{\gdef\exb@showtags{\isTrue}} +\gdef\exb@printCurrentTags{Tags: \exb@currentTags~} +\gdef\ShowFilenames{\At\VeryBeginProblem{\exerciseFile\\}} \gdef\@DisplaySolutions{\@isFalse} \gdef\DisplaySolutions{\xdef\@DisplaySolutions{\isTrue}\@latex@warning{Showing solutions}} +\gdef\ifDisplaySolutions{\if\@DisplaySolutions\@isTrue} \gdef\@SolutionsOnly{\@isFalse} \gdef\SolutionsOnly{\xdef\@SolutionsOnly{\@isTrue}\DisplaySolutions} +\gdef\exb@currentPoints{0} +\newif\ifexbank@if@needspace +\global\exbank@if@needspacetrue \pgfkeys{/exbanksetup/.is family, /exbanksetup, default/.style = { part problems = On, tighten paragraphs = True, problem header={\normalsize\Large\bfseries\@tr{Problem}~\theproblemcounter}, part problem header={\large\textbf{(\theproblemcounter\alph{partproblemcounter})}}, + part problem header suffix={}, solution header={\large{\textbf{\@tr{Solution}:}}}, exercise directory=., figure root directory=\@exercisesDir, style margins=On, - problem needs space=0.2\paperheight + problem needs space=0.2\paperheight, + no needspace/.is if={exbank@if@needspace}, + no needspace/.default = false }, exercise directory/.estore in = \@exercisesDir, % figure root directory/.estore in = \@figrootDir, % @@ -103,6 +178,7 @@ problem header/.store in = \exbank@opt@problemHeader, part problem header/.store in = \exbank@opt@partProblemHeader, solution header/.store in = \exbank@opt@solutionHeader, problem needs space/.store in = \exbank@opt@problemneedspace, +part problem header suffix/.store in=\exb@partproblem@header@suffix, part problems/.style = {switches/#1/.get = \exbank@opt@partProblems}, tighten paragraphs/.style = {switches/#1/.get = \exbank@opt@tightenparagraphs}, style margins/.style={switches/#1/.get = \exbank@opt@doMargins}, @@ -155,18 +231,25 @@ switches/.cd, \let\ea = \expandafter \begingroup\lccode`\|=`\\ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} -\newcommand{\At}[2]{ \edef\mname{\exbank@macroname{#1}} - \ifcsname At@\mname\endcsname - \ea\g@addto@macro\csname At@\mname\endcsname{#2} - \else - \ea\gdef\csname At@\mname\endcsname{#2} - \AtEndDocument{ \expandafter\let\csname At@\mname\endcsname\relax +\ifcsname at@verbose\endcsname +\global\def\@triggerLog#1{\@latex@warning{--\string\TRIGGER: #1}}% +\else +\global\let\@triggerLog\@gobble% +\fi +\newcommand{\At}[2]{ \edef\mname{\exbank@macroname{#1}}% + \ifcsname At@\mname\endcsname% + \ea\g@addto@macro\csname At@\mname\endcsname{#2}% + \else% + \ea\gdef\csname At@\mname\endcsname{#2}% + \AtEndDocument{% + \expandafter\let\csname At@\mname\endcsname\relax% } - \fi + \fi% } -\newcommand{\Trigger}[1]{ \edef\mname{\exbank@macroname{#1}} +\newcommand{\Trigger}[1]{% + \edef\mname{\exbank@macroname{#1}}% \ea\@ifundefined{At@\mname}{}{% - \csname At@\mname\endcsname% + \@triggerLog{\mname}\csname At@\mname\endcsname% }% } \xdef\figuresPath{\@figrootDir/} @@ -180,7 +263,6 @@ switches/.cd, \xdef\fileInputPath{\figuresPath\filename@area} \xdef\fileInputBase{\figuresPath\filename@area\filename@base/} \graphicspath{{\fileInputBase}{\fileInputPath}} - \@dlog{\fileInputBase} \@ifundefined{input@path}{\gdef\input@path{{\fileInputBase}{\fileInputPath}}}{} } \newlength{\pMarginBelow} @@ -214,7 +296,7 @@ switches/.cd, \newcounter{partproblemcounter} \At\VeryBeginProblem{% \if\exbank@opt@tightenparagraphs\@isTrue\relax% - \needspace{\exbank@opt@problemneedspace}% + \ifexbank@if@needspace\needspace{\exbank@opt@problemneedspace}\fi% \vskip-2\baselineskip\relax% \fi% \stepcounter{problemcounter}% @@ -225,24 +307,42 @@ switches/.cd, } \At\EndProblem{% \tighten@paragraph% -} +}% \At\VeryBeginPartproblem{% +\@dinfo{Triggered Beginning Part Problem (\string\VeryBeginPartproblem)}% \stepcounter{partproblemcounter}% - \bgroup% + \@dinfo{Generating title for part problem}% + \gdef\exb@prePPHead{}% + \gdef\exb@postPPHead{}% \if\@displayMetaCounter\@isTrue\relax% - \ex@before\exbank@opt@partProblemHeader{{\Large\themetacounter}:}% + \gdef\exb@prePPHead{{\Large\themetacounter}:}% + \fi% + \if\exb@showtags\isTrue% + \gdef\exb@postPPHead{\exb@printCurrentTags}% \fi% -\if\exbank@opt@doMargins\@isTrue\relax% -\leavevmode\smash{\llap{{\exbank@opt@partProblemHeader}\hskip\ppMargin}}% -\else{\exbank@opt@partProblemHeader}\fi% +\ifnum\pdfstrcmp{\exbank@opt@doMargins}{\@isTrue}=\z@\relax% +\newbox\nobox% +\gdef\exb@pp@lefttag{\leavevmode{\smash{\llap{{\exb@prePPHead\exbank@opt@partProblemHeader\Trigger\PartProblemHeaderSuffix}\hskip\ppMargin}\exb@postPPHead}}}% +\else% +\gdef\exb@pp@lefttag{{\exbank@opt@partProblemHeader\Trigger\PartProblemHeaderSuffix}}% +\fi% +\AtNextPar{\exb@pp@lefttag}% \ignorespaces}% \At\EndPartproblem{% - \egroup% \vspace*{\pMarginBelow}% \tighten@paragraph\par% } \At\BeginSolution{\hfill\break\vspace*{\solutionMarginAbove}{\exbank@opt@solutionHeader}} \At\EndSolution{} +\newif\ifexb@opthides +\providecommand\exb@currentTags{} +\pgfkeys{/exbank/problems/.cd,% +default/.style={hide=false,tag=\relax},% +hide/.is if={exb@opthides},% +tags/.estore in=\exb@currentTags,% +tag/.code={\pgfkeysalso{tags={#1}}}% +} +\def\nextproblem{\pgfqkeys{/exbank/problems}} \At\EndProblem{% \if\exbank@opt@tightenparagraphs\@isTrue\relax% \if\@SolutionsOnly\@isFalse% @@ -265,40 +365,42 @@ switches/.cd, \fi } \global\let\do@ProcessCutFile = \ProcessCutFile +\newif\ifexb@isdisplaying +\newif\ifexb@hidenextsol +\global\exb@hidenextsolfalse +\gdef\exb@ifshowproblem#1#2{\exb@isdisplayingfalse\ifnum\pdfstrcmp{\DisplayProblem}{\@isTrue}=\z@\ifexb@opthides\else\exb@isdisplayingtrue\fi\fi% +\ifexb@isdisplaying#1\else#2\fi} \gdef\showhideproblem#1{% - \if\DisplayProblem\isFalse - \def\ProcessCutFile{} - \else - \if\@SolutionsOnly\@isTrue\relax% - \def\ProcessCutFile{}\fi% - #1 - \fi -} -\generalcomment{problem}{ \edef\DisplaySolution{\@DisplaySolutions} - \stepcounter{metacounter} - \Trigger\DecideProblemDisplay - \begingroup +\exb@ifshowproblem{\let\ProcessCutFile\do@ProcessCutFile#1\global\exb@hidenextsolfalse}{\def\ProcessCutFile{}\global\exb@hidenextsoltrue}% +} +\generalcomment{problem}{% + \edef\DisplaySolution{\@DisplaySolutions}% + \stepcounter{metacounter}% + \@dinfo{problem: Triggering \string\DecideProblemDisplay}% + \Trigger\DecideProblemDisplay% + \@dinfo{problem:Executing - \string\showhideproblem}% \showhideproblem{% \if\exbank@opt@partProblems\isTrue - \Trigger\BeginPartproblem - \Trigger\VeryBeginPartproblem - \else - \Trigger\BeginProblem - \Trigger\VeryBeginProblem - \fi -} -}{ \if\DisplayProblem\@isFalse\relax\else - \if\exbank@opt@partProblems\isTrue - \Trigger\EndPartproblem - \tighten@paragraph + \Trigger\BeginPartproblem% + \Trigger\VeryBeginPartproblem% + \else% + \Trigger\BeginProblem% + \Trigger\VeryBeginProblem% + \fi% +}% +}{\@dinfo{Ending problem env}% + \if\DisplayProblem\@isTrue\relax% + \if\exbank@opt@partProblems\@isTrue\relax% + \Trigger\EndPartproblem% + \tighten@paragraph\fi% \else - \Trigger\EndProblem - \fi - \fi - \endgroup + \Trigger\EndProblem% + \fi% +\@dinfo{Ended problem env}% } -\generalcomment{solution} -{\Trigger\AtBeginSolutionHard +\g@addto@macro\AfterproblemComment{\nextproblem{default}\ignorespaces}% +\generalcomment{solution}{\@dinfo{START solution ENV}% +\Trigger\AtBeginSolutionHard \begingroup \if\@DisplaySolutions\isTrue \if\DisplayProblem\isFalse @@ -306,18 +408,20 @@ switches/.cd, \fi \fi \if\DisplaySolution\isTrue - \Trigger\BeginSolution + \ifexb@hidenextsol\else\Trigger\BeginSolution\fi \else \def\ProcessCutFile{} \fi -}{\if\DisplaySolution\isTrue +}{% +\if\DisplaySolution\isTrue \Trigger\EndSolution \tighten@paragraph@solutions \vspace*{0.5em} \fi \endgroup -\Trigger\EndSolutionHard% +\Trigger\EndSolutionHard\@dinfo{END solution ENV}% } +\g@addto@macro\AftersolutionComment{\ignorespaces} \def\intromargin#1{% \if\exbank@opt@doMargins\@isTrue% \gdef\endintromargin{\endlist\endgroup}% @@ -325,29 +429,42 @@ switches/.cd, \else% \relax\global\let\endintromargin=\relax\fi% } -\generalcomment{intro}{ \if\@countIntros\isTrue - \stepcounter{metacounter} - \Trigger\DecideProblemDisplay - \begingroup +\generalcomment{intro}{\@dinfo{START intro ENV}% + \if\@countIntros\isTrue% + \stepcounter{metacounter}% + \Trigger\DecideProblemDisplay% + \gdef\exb@pre@intro{}% + \gdef\exb@post@intro{}% \if\@displayMetaCounter\isTrue\relax% - {\exb@lmargin{{\Large\themetacounter}}{\pMarginLeft}} - \fi - \if\@spriteMode\@isTrue - \if\introarg\@isTrue - \stepcounter{partproblemcounter} - \fi - \fi + \gdef\exb@pre@intro{{\leavevmode{\llap{{\Large\themetacounter}:\hspace*{-\pMarginLeft}}}}\ignorespaces}% + \fi% + \if\exb@showtags\isTrue% + \xdef\exb@post@intro{\exb@printCurrentTags}% + \fi% + \if\@spriteMode\@isTrue% + \if\introarg\@isTrue% + \stepcounter{partproblemcounter}% + \fi% + \fi% + \gdef\@displayIntro{\@isFalse} \showhideproblem{% \tighten@paragraph% - \Trigger\BeginIntro% -} - \fi% + \Trigger\BeginIntro\exb@pre@intro\exb@post@intro% + \gdef\@displayIntro{\@isTrue} +}% + \exb@ifshowproblem{\intromargin{-1em}}{} + \else% \intromargin{-1em} -}{ \if\@countIntros\isTrue - \Trigger\EndIntro - \endgroup - \fi\par\endintromargin + \fi% +}{ \if\@countIntros\isTrue% + \Trigger\EndIntro% + \exb@ifshowproblem{\endintromargin}{} + \else + \endintromargin + \fi% + \@dinfo{END intro ENV}\ignorespaces% } +\g@addto@macro\AfterintroComment{\nextproblem{default}\ignorespaces} \def\squeeze{ \newlength{\marginw} \setlength{\marginw}{1.5cm} \newgeometry{margin=\marginw} @@ -381,7 +498,11 @@ switches/.cd, \let\ea = \expandafter \newcounter{metacounter} \setcounter{metacounter}{0} -\gdef\emptyList{0} +\gdef\exb@emptyList{0} +\newif\ifexb@tagbuildmode +\global\exb@tagbuildmodefalse +\global\let\emptyList\exb@emptyList +\global\let\exb@tagList\exb@emptyList \gdef\ifppMode#1{ \def\mname{\exbank@macroname{#1}} \strif\mname\ppMode } @@ -404,19 +525,36 @@ switches/.cd, \At\DecideProblemDisplay{% \ifnum\pdfstrcmp{\ppList}{\emptyList}=\z@\relax% \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@} - \else - \isin{\ppList}{\themetacounter}{ \xdef\DisplayProblem{\ipm\exclude\F@\ipm\select\T@\ipm\normal\T@} -}{ \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@\ipm\normal\T@} -} \fi + \exb@int@isin{\themetacounter}{\ppList}{ \xdef\DisplayProblem{\ipm\exclude\F@\ipm\select\T@\ipm\normal\T@} +}{ \xdef\DisplayProblem{\ipm\exclude\T@\ipm\select\F@\ipm\normal\T@} } +\ifexb@tagbuildmode +\ifnum\pdfstrcmp{\DisplayProblem}{\T@}=\z@\relax% +\exb@intersection@any{\exb@currentTags}{\exb@tagList}{\global\exb@opthidesfalse}{\global\exb@opthidestrue}% +\fi +\fi +} +\gdef\introarg{\@isFalse} +\gdef\noheadarg{\@isFalse} \pgfkeys{ /makeset/.is family, /makeset, - default/.style = {noheadarg=\isFalse, introarg=\isFalse}, - intro/.style = {introarg=\isTrue}, - nohead/.style = {noheadarg=\isTrue}, + default/.style = {}, + intro/.style = {introarg=\@isTrue}, + nointro/.style = {introarg=\@isFalse}, + nohead/.style = {noheadarg=\@isTrue}, + head/.style = {noheadarg=\@isFalse}, introarg/.estore in = \introarg, noheadarg/.estore in = \noheadarg } +\gdef\makesetdefaults#1{% +\edef\exb@setpgfkeys{{\unexpanded\expandafter{/makeset/default/.style = {#1}}}}% +\expandafter\pgfkeys\exb@setpgfkeys% +} +\pgfkeys{/makeset/override/.cd, +intro/.code = {\gdef\introarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSetID @intro\endcsname{\@isTrue}}, +nointro/.code = {\gdef\introarg{\@isFalse}\ea\gdef\csname setlist@\exb@currentSetID @intro\endcsname{\@isFalse}}, +nohead/.code = {\gdef\noheadarg{\@isTrue}\ea\gdef\csname setlist@\exb@currentSetID @nohead\endcsname{\@isTrue}} +} \gdef\@listOfSets{} \gdef\@spriteMode{\isFalse} \gdef\exbank@spriteSets{\emptyList} @@ -472,18 +610,22 @@ switches/.cd, \gdef\ppMode{\pm@Normal} \fi } +\global\let\ex@protect\noexpand +\long\gdef\exec#1{:\ex@protect{#1}} +\gdef\exb@def@makeset@cmd#1{\@ifnextchar[{\@exb@def@makeset@cmd{#1}}{\@exb@def@makeset@cmd{#1}[0]}} +\gdef\@exb@def@makeset@cmd#1[#2]#3{\def\ncArgs{#1[#2]}% +\bgroup\globaldefs=1\ea\newcommand\ncArgs{\exec{#3}}\egroup% +} +\def\exbank@def@makeset@command{\exb@warn{\string\exbank@def@makeset@command\space is deprecated and will be removed in versions >= 0.3.0. Use \string\exb@def@makeset@cmd}\exb@def@makeset@cmd} +\let\DeclareExerciseCommand\exb@def@makeset@cmd \newcommand{\exclude}[2]{[{#2}]{#1}{exclude}} \newcommand{\select}[2]{[{#2}]{#1}{select}} -\gdef\buildex#1{ \makeset{#1}{#1} - \buildset{#1} -} -\gdef\exbank@def@makeset@command#1#2{% - \edef\macroname{\exbank@macroname{#1}}% - \xdef#1{?{@\macroname}}% - \ea\gdef\csname @\macroname\endcsname{#2}% +\newcommand{\orderedselect}[2]{% +\readlist*\thelist\csv@list% +\foreachitem\items\in\thelist{[{\item}]{#1},}% } \let\exbank@isFirstProblem\isTrue -\exbank@def@makeset@command{\phead}{ \if\exbank@isFirstProblem\isTrue% +\exb@def@makeset@cmd{\phead}{ \if\exbank@isFirstProblem\isTrue% \let\exbank@isFirstProblem\isFalse% \else% \Trigger\EndProblem% @@ -491,19 +633,29 @@ switches/.cd, \Trigger\BeginProblem% \Trigger\VeryBeginProblem% } -\exbank@def@makeset@command{\pbreak}{\clearpage} -\let\DeclareExerciseCommand\exbank@def@makeset@command -\global\let\ex@protect\noexpand -\gdef\exec#1{:\ex@protect{#1}} +\exb@def@makeset@cmd{\pheadarg}[1]{ \if\exbank@isFirstProblem\isTrue% + \let\exbank@isFirstProblem\isFalse% + \else% + \Trigger\EndProblem% + \fi% + \Trigger\BeginProblem% + \bgroup\def\theproblemcounter{#1}\Trigger\VeryBeginProblem\egroup% +} +\exb@def@makeset@cmd{\pbreak}{\clearpage} +\gdef\buildex#1{ \makeset{#1}{#1} + \buildset{#1} +} \gdef\@countIntros{\isFalse} \gdef\exb@setpgf#1{% \edef\keystring{{/makeset,default,#1}}% \ea\pgfkeys\keystring} \newcommand\buildset[2][]{% - \def\oarg{#1}% - \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}\@dlog{Counting intros}}% + \xdef\exb@currentSetID{#2}% + \pgfkeys{/makeset/override/.cd, #1} + \global\let\setName\exb@currentSetID% + \gdef\exb@buildset@oarg{#1} + \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}}% \@ifundefined{setlist@#2@nohead}{\gdef\nohead{\isFalse}}{\gdef\nohead{\isTrue}}% - \xdef\setName{#2}% \ifcsname setkeys@\setName\endcsname% \xdef\skeys{\csname setkeys@#2\endcsname}% \exb@setpgf\skeys% @@ -524,7 +676,7 @@ switches/.cd, \gdef\@is@file{\@ifnextchar[\exb@setEnv@withOptargs\X@exb@setEnv}% \gdef\X@exb@setEnv##1{% \def\continueLoop{\isTrue}% - \@dlog{Processing normal file "\exerciseFileInfo.tex"}% + \@dinfo{Processing normal file "\exerciseFileInfo.tex"}% \exbank@setEnv@normal{\exerciseFileInfo}\bgroup\nullfont% } \gdef\exb@setEnv@withOptargs{% @@ -532,12 +684,12 @@ switches/.cd, } \gdef\@execute@makeset@command ?##1{% \edef\inner{\@firstofone##1}% - \@dlog{Executing macro \@backslashchar\@gobble##1}% + \@dinfo{Executing macro \@backslashchar\@gobble##1}% \csname\inner\endcsname% #1\def\continueLoop{\isFalse}\ea\bgroup% } \def\@execute@exec:{% - \def\continueLoop{\isFalse}\@dlog{Executing custom command}\bgroup% + \def\continueLoop{\isFalse}\@dinfo{Executing custom command}\bgroup% } \readlist*\setlist\exbank@setlist% \foreachitem\exerciseFileInfo\in\setlist{% @@ -562,7 +714,7 @@ switches/.cd, \incl{\@exercisesDir/\exerciseFile}% \if\@spriteMode\isTrue% \setcounter{partproblemcounter}{0}% - \fi + \fi% }{ \@latex@error{Could not find \@exercisesDir/\exerciseFile. Maybe it is because the default exercise directory is now changed to the same directory that your main file is in. To set default exercise directory to exercises, do \string\exercisebanksetup{exercise directory=exercises}}{} \stop\bye } @@ -571,17 +723,30 @@ switches/.cd, } \if\@spriteMode\isFalse% \Trigger\EndBuildset% - \fi + \fi% \setcounter{problemcounter}{0}% \setcounter{partproblemcounter}{0}% \clearpage% } -\newcommand\buildsets[1]{% - \xdef\csvlist{#1}% +\newcommand\buildsets[2][]{% + \xdef\csvlist{#2}% \readlist*\items\csvlist% \foreachitem\set\in\items{% + \buildset[#1]{\set}% +} +} +\newcommand\buildtags[2]{% + \global\exb@tagbuildmodetrue + \xdef\csvtags{#1}% + \xdef\csvlist{#2} + \xdef\csvsets{#2}% + \readlist*\tagsItems\csvtags% + \readlist*\setsItems\csvsets% + \foreachitem\set\in\setsItems{% + \xdef\exb@tagList{\csvtags} \buildset{\set}% } + \global\exb@tagbuildmodefalse } \newcommand\refcounter[1]{\edef\@currentlabel{#1}% } @@ -598,3 +763,31 @@ switches/.cd, \newcommand\pref[1]{% \ref{pr:\exerciseFile:#1}\relax% } +\gdef\exb@currentPoints{0} +\gdef\exb@currentPointsStyle{} +\newif\ifexb@enablepoints\global\exb@enablepointstrue +\exercisebanksetup{% +current points style/.store in=\exb@currentPointsStyle, +current points style={\ifnum\exb@currentPoints=\z@\ifnum\totalpoints=\z@\else\phantom{0p}\fi\else\exb@currentPoints p\fi\ignorespaces}, +disable points/.is if={exb@enablepoints} +} +\ifexb@enablepoints +\AtEndDocument{% +\immediate\write\@auxout{\string\gdef\string\totalpoints{\the\c@exb@points}}% +} +\At\PartProblemHeaderSuffix{\exb@currentPointsStyle} +\fi +\newcounter{exb@points} +\setcounter{exb@points}{0} +\providecommand\totalpoints{} +\nextproblem{points/.store in=\exb@currentPoints} +\At\BeginPartproblem{\addtocounter{exb@points}\exb@currentPoints} +\At\EndPartproblem{\gdef\exb@currentPoints{0}} +\def\exb@hidetaglist{} +\At\DecideProblemDisplay{\ifnum\pdfstrcmp{\DisplayProblem}{\T@}=\z@\relax% +\ifx\exb@hidetaglist\relax\else +\exb@intersection@any{\exb@currentTags}{\exb@hidetaglist}{\global\exb@opthidestrue}{\global\exb@opthidesfalse}% +\fi +\fi +} +\gdef\HideTags#1{\xdef\exb@hidetaglist{#1}} -- cgit v1.2.3