From f02c0d33eefe844fb67c5e438cfdcc26085c2223 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 1 Apr 2018 22:20:15 +0000 Subject: exercisebank (2apr18) git-svn-id: svn://tug.org/texlive/trunk@47223 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/latex/exercisebank/exercisebank.sty | 336 +++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty (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 new file mode 100644 index 00000000000..f4731b6893b --- /dev/null +++ b/Master/texmf-dist/tex/latex/exercisebank/exercisebank.sty @@ -0,0 +1,336 @@ +% Source (with comments) can be found at https://github.com/Strauman/exerciseBank +%% The LaTeX package exercisebank - version 0.0.2-1 (2018/04/01) +%% exercisebank.sty: Exercise bank +%% ------------------------------------------------------------------------------------------- +%% Copyright (c) 2018 by Andreas Storvik Strauman +%% ------------------------------------------------------------------------------------------- +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3c +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% 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/04/01 v0.0.2-1 Creates a setup that gives freedom in making sets and exercises.] +\@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 \string\usepackage{exbank}} +}{} +\gdef\setExercisesDir#1{\gdef\exercisesDir{#1}} +\@ifundefined{exercisesDir}{\gdef\exercisesDir{exercises} +}{} +\global\let\incl = \input +\usepackage{xstring} +\usepackage{pgffor} +\usepackage{scrextend} +\usepackage{comment} +\usepackage{calc} +\usepackage{pgfpages} +\usepackage{geometry} +\pgfkeys{ /exbanki18n/.is family, /exbanki18n, + default/.style = {Problem = Problem, Solution = Solution}, + Problem/.estore in = \@tr@Problem, + Solution/.estore in = \@tr@Solution +} +\newcommand{\translateExBank}[1]{ \pgfkeys{/exbanki18n, default, #1}% +} +\translateExBank{} +\gdef\@tr#1{\@ifundefined{@tr@#1}{#1}{ \csname @tr@#1\endcsname +} +} +\let\ea = \expandafter +\def\removebs#1{\if#1\@backslashchar\else#1\fi} +\newcommand{\At}[2]{ \def\macname{\expandafter\removebs\detokenize{#1}} + \let\mname = \macname + \ifcsname At@\mname\endcsname + \ea\g@addto@macro\csname At@\mname\endcsname{#2} + \else + \ea\gdef\csname At@\mname\endcsname{#2} + \fi +} +\newcommand{\Trigger}[1]{ \def\macname{\expandafter\removebs\detokenize{#1}} + \let\mname = \macname + \@ifundefined{At@\mname}{}{\csname At@\mname\endcsname} +} +\def\ppLeading{4em} +\def\pMarginBelow{1em} +\def\pMarginAbove{1em} +\def\pMarginLeft{-1.5em} +\def\ppMargin{1em} +\def\solMargin{\dimexpr\ppMargin+\ppMargin\relax} +\def\vsSize{1em} +\def\vs{\vspace{\vsSize}} +\newcounter{problemcounter} +\setcounter{problemcounter}{0} +\newcounter{partproblemcounter} +\At\VeryBeginProblem{ \stepcounter{problemcounter} + \setcounter{partproblemcounter}{1} + \vspace*{\pMarginAbove} + \begin{addmargin}{\pMarginLeft} + {\normalfont\Large\bfseries\@tr{Problem}~\theproblemcounter} + \end{addmargin} + \vspace*{\pMarginBelow} +} +\At\BeginPartproblem{ \vspace{\ppMargin}% + \begin{addmargin}{\ppMargin}% +\large\hspace*{-\ppMargin}\textbf{(\theproblemcounter\alph{partproblemcounter})}\normalsize + \stepcounter{partproblemcounter} +} +\At\EndPartproblem{\hfill +\end{addmargin}\vspace*{0.5em} +} +\At\BeginSolution{ \vspace*{1em} + \begin{addmargin}{\solMargin}% +\hspace*{-\solMargin}\large{\textbf{\@tr{Solution}:}}\normalsize +} +\At\EndSolution{ \end{addmargin}\vspace*{1em} +} +\gdef\isFalse{0} +\gdef\isTrue{1} +\gdef\DisplayProblem{\isTrue} +\gdef\@displayMetaCounter{\isFalse} +\gdef\ShowNumbers{\gdef\@displayMetaCounter{\isTrue}} +\gdef\@DisplaySolutions{\isFalse} +\gdef\DisplaySolutions{\xdef\@DisplaySolutions{\isTrue}\@latex@warning{Showing solutions}} +\AtBeginDocument{ \if\@DisplaySolutions\isFalse + \@latex@warning{Hiding solutions. Show them with \string\DisplaySolutions} + \fi +} +\global\let\do@ProcessCutFile = \ProcessCutFile +\gdef\showhideproblem#1{% + \if\@displayMetaCounter\isTrue% + {P:\Large\themetacounter} + \Trigger\BeginPartproblem + \gdef\DisplayProblem{\isTrue} + \else + \if\DisplayProblem\isFalse + \def\ProcessCutFile{} + \else + #1 + \fi + \fi +} +\generalcomment{problem}{ \edef\DisplaySolution{\@DisplaySolutions} + \Trigger\DecideProblemDisplay + \begingroup + \showhideproblem{\Trigger\BeginPartproblem} +}{ \if\DisplayProblem\isFalse\else + \Trigger\EndPartproblem + \fi + \endgroup +} +\generalcomment{solution} +{\Trigger\AtBeginSolutionHard +\begingroup + \if\@DisplaySolutions\isTrue + \if\DisplayProblem\isFalse + \xdef\DisplaySolution{\isFalse} + \fi + \fi + \if\DisplaySolution\isTrue + \Trigger\BeginSolution + \else + \def\ProcessCutFile{} + \fi +}{\if\DisplaySolution\isTrue +\Trigger\EndSolution +\fi +\Trigger\EndSolutionHard +\endgroup +} +\generalcomment{intro}{ \if\@countIntros\isTrue + \Trigger\DecideProblemDisplay + \begingroup + \showhideproblem{\Trigger\BeginIntro} + \fi +}{ \if\@countIntros\isTrue + \Trigger\EndIntro + \endgroup + \fi +} +\gdef\isin#1#2#3#4{ \def\needle{#2} + \def\haystack{#1} + \def\isFalse{0} + \let\isInList = \isFalse + \IfInteger{\haystack}{ \if\haystack\needle + #3 + \else + #4 + \fi +}{ \foreach\pp in #1{ \if\pp\needle + \gdef\isInList{1} + #3 + \fi +} + \if\isInList\isFalse + #4 + \fi +} +} +\def\squeeze{ \newlength{\marginw} + \setlength{\marginw}{1.5cm} + \newgeometry{margin=\marginw} + \renewcommand{\topfraction}{0.85} + \renewcommand{\bottomfraction}{0.85} + \renewcommand{\textfraction}{0.1} + \renewcommand{\floatpagefraction}{0.85} + \renewcommand{\dbltopfraction}{0.85} + \renewcommand{\dblfloatpagefraction}{.85} + \setcounter{topnumber}{25} + \setcounter{bottomnumber}{25} + \setcounter{totalnumber}{25} + \setcounter{dbltopnumber}{25} + \renewcommand{\baselinestretch}{0.9} + \let\markeverypar\everypar + \newtoks\everypar + \everypar\markeverypar + \markeverypar{\the\everypar\looseness=-1\relax} + \g@addto@macro\define@newfont{% + \fontdimen2\font@name=0.8\fontdimen2\font@name +}% + \fontdimen2\font@name=0.8\fontdimen2\font@name + \thinmuskip=0mu plus 3mu + \medmuskip=1mu plus 4mu + \thickmuskip=2mu plus 5mu + \abovedisplayskip=0pt plus 3pt + \belowdisplayskip=0pt plus 3pt + \abovedisplayshortskip=0pt plus 3pt + \belowdisplayshortskip=0pt plus 3pt +} +\let\ea = \expandafter +\newcounter{metacounter} +\def\emptyList{-1} +\begingroup\lccode`\|=`\\ +\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} +\newcommand{\macroname}[1]{\expandafter\removebs\string#1} +\gdef\ifppMode#1{ \def\mname{\macroname{#1}} + \if\mname\ppMode +} +\gdef\isppMode#1#2{ \edef\mname{\macroname{#1}} + \if{\macroname{#1}}\ppMode#2\fi +} +\gdef\@noneofone#1{} +\gdef\@noneOfTwo#1#2{} +\gdef\@ifppMode#1{% +\ifnum\pdfstrcmp{\macroname{#1}}{\ppMode}=\z@% +\expandafter\@firstofone% +\else% +\expandafter\@noneofone% +\fi% +}% +\def\pm@Exclude{exclude} +\def\pm@Select{select} +\let\ipm\@ifppMode +\let\T@\isTrue +\let\F@\isFalse +\At\DecideProblemDisplay{ \if\ppList\emptyList + \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 + \stepcounter{metacounter} +} +\pgfkeys{ /makeset/.is family, /makeset, + default/.style = {noheadarg=\isFalse, introarg=\isFalse}, + intro/.style = {introarg=\isTrue}, + nohead/.style = {noheadarg=\isTrue}, + introarg/.estore in = \introarg, + noheadarg/.estore in = \noheadarg +} +\gdef\@listOfSets{} +\gdef\@spriteMode{\isFalse} +\newcommand\makeset[3][]{ \pgfkeys{/makeset, default, #1}% + \if\introarg\isTrue% + \ea\gdef\csname setlist@#2@intro\endcsname{\isTrue} + \fi + \if\noheadarg\isTrue% + \ea\gdef\csname setlist@#2@nohead\endcsname{\isTrue} + \fi + \ea\gdef\csname setlist@#2\endcsname{#3} + \def\setmacro{\unexpanded\expandafter{\csname setlist@#2\endcsname}} + \g@addto@macro\@listOfSets{#2} +} +\long\gdef\about#1{} +\newcommand\sprite[1][4]{\squeeze +\gdef\@spriteMode{\isTrue} +\long\def\about##1{{\Large\textbf{About}:\\[1.1em]##1\\[1.5em]}} +\pgfpagesuselayout{#1 on 1}[a4paper,border shrink=5mm] + \foreach\set in \@listOfSets{ \buildset{\set} +} +} +\newcommand{\redef}[3][{-1}]{ \if\@spriteMode\isFalse% + \gdef\ppList{#1} + \gdef\exerciseFile{#2} + \gdef\ppMode{#3} + \else + \gdef\ppList{} + \gdef\exerciseFile{#2} + \gdef\ppMode{exclude} +\fi +} +\newcommand{\exclude}[2]{[{#2}]{#1}{exclude}} +\newcommand{\select}[2]{[{#2}]{#1}{select}} +\gdef\buildex#1{ \makeset{#1}{#1} + \buildset{#1} +} +\gdef\@countIntros{\isFalse} +\gdef\phead{?\noexpand\Trigger\noexpand\VeryBeginProblem} +\newcommand\buildset[2][]{ \def\oarg{#1} + \@ifundefined{setlist@#2@intro}{\gdef\@countIntros{\isFalse}}{\gdef\@countIntros{\isTrue}\@latex@warning{Counting intros}} + \@ifundefined{setlist@#2@nohead}{\gdef\nohead{\isFalse}}{\gdef\nohead{\isTrue}} + \xdef\setName{#2} + \@ifundefined{setlist@#2}{ \@latex@error{Couldn't find set #2. Did you remember to do \string\makeset{#2}{}?} + \stop +}{} + \edef\setlist{\csname setlist@#2\endcsname} + \if\@spriteMode\isFalse + \Trigger\StartBuildset + \fi + \foreach\exerciseFileInfo in \setlist{ \def\continueLoop{\isTrue} + \gdef\ppList{-1} + \setcounter{metacounter}{1} + \StrLeft{\exerciseFileInfo}{1}[\firstchar]% + \if[\firstchar + \ea\redef\exerciseFileInfo\relax + \def\continueLoop{\isTrue} + \else\if?\firstchar + \expandafter\@secondoftwo\exerciseFileInfo + \def\continueLoop{\isFalse} + \else + \redef{\exerciseFileInfo}{normal} + \def\continueLoop{\isTrue} + \fi\fi + \if\continueLoop\isTrue + \Trigger\InputExercise + \if\nohead\isFalse + \if\@spriteMode\isFalse + \Trigger\BeginProblem + \fi + \fi + \if\nohead\isFalse\Trigger\VeryBeginProblem\fi + \if\@spriteMode\isTrue\textbf{\exerciseFile.tex\\}\fi + \incl{\exercisesDir/\exerciseFile} + \if\nohead\isFalse\Trigger\EndProblem\fi + \fi +} + \if\@spriteMode\isFalse + \Trigger\EndBuildset + \fi +} +\newcommand\refcounter[1]{\edef\@currentlabel{#1}% +} +\DeclareRobustCommand{\pplabel}[1]{ \refcounter{\theproblemcounter}\label{pr:\exerciseFile:#1} + \refcounter{\thepartproblemcounter}\label{pp:\exerciseFile:#1} +} +\let\pptag = \pplabel +\newcommand\pppref[1]{% +(\ref{pp:\exerciseFile:#1})\relax% +} +\newcommand\ppref[1]{% +\ref{pr:\exerciseFile:#1}\ref{pp:\exerciseFile:#1}\relax% +} +\newcommand\pref[1]{% +\ref{pr:\exerciseFile:#1}\relax% +} -- cgit v1.2.3