diff options
author | Karl Berry <karl@freefriends.org> | 2019-01-03 21:59:46 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-01-03 21:59:46 +0000 |
commit | 7abdb429e2ffcd91585c294fb8f11f95fadfabe2 (patch) | |
tree | 43678483b3267c5f37cdd32a2bc3dacfabc9fabb /Master/texmf-dist/tex/latex/exercisepoints | |
parent | 3250173a826bc8ce3049aa267af8878fb93a1314 (diff) |
exercisepoints (3jan19)
git-svn-id: svn://tug.org/texlive/trunk@49590 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/exercisepoints')
-rw-r--r-- | Master/texmf-dist/tex/latex/exercisepoints/exercisepoints.sty | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/exercisepoints/exercisepoints.sty b/Master/texmf-dist/tex/latex/exercisepoints/exercisepoints.sty new file mode 100644 index 00000000000..42a37546727 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exercisepoints/exercisepoints.sty @@ -0,0 +1,330 @@ +% !TEX encoding = UTF-8 Unicode +% +%% exercisepoints.sty +%% A LaTeX package to count exercises and points. +%% +%% Copyright (c) 2017-2019 Henning Kerstan. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% 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.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Henning Kerstan. +% +% This work consists of the files `exercisepoints.sty' and `exercisepoints.tex'. +% + + +% package identification +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{exercisepoints}[% + 2019/01/03 v1.2.3 % + count exercises and points% +] + + +% switches for custom exercise layout +\newif\if@exercisepoints@usecustomlayout% +\newif\if@exercisepoints@exercise@layoutdefined% +\newif\if@exercisepoints@subexercise@layoutdefined% + +\DeclareOption{customlayout}{% + \@exercisepoints@usecustomlayouttrue% +} + +% this package does not have any other options +\DeclareOption*{ + \PackageWarning{exercisepoints}{Unknown option '\CurrentOption'} +} +\ProcessOptions\relax% + + +% avoid nesting (i.e. putting exercises in exercises) +\newif\if@exercisepoints@inexercise% +\global\@exercisepoints@inexercisefalse% +\newif\if@exercisepoints@insubexercise% +\global\@exercisepoints@insubexercisefalse% + + +% counters to store number of exercises +\newcounter{exercisepoints@exercisecount} +\newcounter{exercisepoints@subexercisecount}[exercisepoints@exercisecount] + + +% lengths to store points +\newlength{\exercisepoints@currentexercisepoints} +\newlength{\exercisepoints@currentsubexercisepoints} +\newlength{\exercisepoints@totalpoints} +\newlength{\exercisepoints@bonuspoints} + + +% macros to get total points and total number of exercises (whole document) +\providecommand{\totalpoints}{0} +\providecommand{\numberofexercises}{0} + + +% macros to get info about current exercise(-part) +% (to be used in AtBeginExercise or AtEndExercise hooks) +\providecommand{\currentexercisetitle}{} +\providecommand{\currentsubexercisetitle}{} + +\providecommand{\currentexercisepoints}{% + \if@exercisepoints@inexercise\else% + \PackageError{exercisepoints}{'\string\currentexercisepoints' can only be used in exercise or subexercise environment}% + \fi% + % + \ifcsname exercisepoints@points@\currentexercisenumber\endcsname% + \@nameuse{exercisepoints@points@\currentexercisenumber}% + \else% + \textbf{??}% TODO:issue package warning in such a way that it can be used also in section commands + \fi% +} + +\providecommand{\currentsubexercisepoints}{% + \if@exercisepoints@insubexercise\else% + \PackageError{exercisepoints}{'\string\currentsubexercisepoints' can only be used in subexercise environment}% + \fi% + % + \ifcsname exercisepoints@points@\currentexercisenumber.\currentsubexercisenumber\endcsname% + \@nameuse{exercisepoints@points@\currentexercisenumber.\currentsubexercisenumber}% + \else% + \textbf{??}% TODO:issue package warning in such a way that it can be used also in section commands + \fi% +} + +\providecommand{\currentexercisenumber}{% + \theexercisepoints@exercisecount% +} + +\providecommand{\currentsubexercisenumber}{% + \theexercisepoints@subexercisecount% +} + + +% hooks to modify the exercise typesetting +\providecommand{\AtBeginExercise}[1]{ + \renewcommand{\exercisepoints@begin}{#1}% + \@exercisepoints@exercise@layoutdefinedtrue% +} + +\providecommand{\AtEndExercise}[1]{ + \renewcommand{\exercisepoints@end}{#1} +} + +% the same for subexercises +\providecommand{\AtBeginSubexercise}[1]{ + \renewcommand{\exercisepoints@sub@begin}{#1} + \@exercisepoints@subexercise@layoutdefinedtrue% +} + +\providecommand{\AtEndSubexercise}[1]{ + \renewcommand{\exercisepoints@sub@end}{#1} +} + + +% storage for the hooks +\newcommand{\exercisepoints@begin}{} +\newcommand{\exercisepoints@end}{} +\newcommand{\exercisepoints@sub@begin}{} +\newcommand{\exercisepoints@sub@end}{} + + +% a very simple default exercise style +\if@exercisepoints@usecustomlayout\else% + \RequirePackage{ifthen}% + \AtBeginExercise{% + ~\smallskip\\\sffamily% + \ifthenelse{\equal{\currentexercisetitle}{}}% + {\textbf{Exercise~\currentexercisenumber}} % empty title + {% + \textbf{Exercise~\currentexercisenumber:} % + \currentexercisetitle% + }% non-empty title + \,~\hfill\textbf{(\currentexercisepoints~Points)}% + \smallskip\\\noindent\normalfont% + } + \AtEndExercise{~\smallskip\\} + % + \AtBeginSubexercise{% + ~\smallskip\\\sffamily% + \ifthenelse{\equal{\currentsubexercisetitle}{}}% + {\emph{Exercise~\currentexercisenumber.\currentsubexercisenumber}} % empty title + {% + \emph{Exercise~\currentexercisenumber.\currentsubexercisenumber:} % + \emph{\currentsubexercisetitle}% + }% non-empty title + \,~\hfill\emph{(\currentsubexercisepoints~Points)}% + \smallskip\\\noindent\normalfont% + } + \AtEndSubexercise{~\\} +\fi + + +% points commands sets points (additive within an exercise environment) +\newcommand{\points}[1]{% + \if@exercisepoints@inexercise% + \addtolength{\exercisepoints@currentexercisepoints}{#1 pt}% + \global\exercisepoints@currentexercisepoints=\exercisepoints@currentexercisepoints% + \addtolength{\exercisepoints@totalpoints}{#1 pt}% + \global\exercisepoints@totalpoints=\exercisepoints@totalpoints% + \if@exercisepoints@insubexercise% + \addtolength{\exercisepoints@currentsubexercisepoints}{#1 pt}% + \global\exercisepoints@currentsubexercisepoints=\exercisepoints@currentsubexercisepoints% + \fi% + \else% + \PackageError{exercisepoints}{\string\points{...} can only be used within exercise or subexercise environment.}% + \fi% +} + +% itempoints units +\newcommand{\exercisepoints@itempointsunit@singular}{} +\newcommand{\exercisepoints@itempointsunit@plural}{} +\newcommand{\setitempointsunit}[2]{% singular, plural + \renewcommand{\exercisepoints@itempointsunit@singular}{#1}% + \renewcommand{\exercisepoints@itempointsunit@plural}{#2}% +} + +% itempoints calls points and displays points flush right for use in +% enumerate environments +\RequirePackage{ifthen} +\newcommand{\itempoints}[1]{% + \points{#1}% + % check if exactly 1 points + \ifthenelse{\equal{#1}{1}}{% not robust, so issuing 1.0 will not result in correct (singular) form! + \ifthenelse{\equal{\exercisepoints@itempointsunit@singular}{}}{% + \,~\hfill(#1)% + }{% + \,~\hfill(#1~\exercisepoints@itempointsunit@singular)% + }% + }{% + \ifthenelse{\equal{\exercisepoints@itempointsunit@plural}{}}{% + \,~\hfill(#1)% + }{% + \,~\hfill(#1~\exercisepoints@itempointsunit@plural)% + }% + }% +} + + + + +% getpoints retrieves points for a specific exercise number (starting at 0) +\newcommand{\getpoints}[1]{% + \ifthenelse{#1 < \numberofexercises}% + {\exercisepoints@readfromaux{points@#1}}% + {\textbf{??}}% +} + + +% aux storage function (key-value store using #1 as key and #2 as value) +\newcommand{\exercisepoints@storetoaux}[2]{% + \immediate\write\@auxout{% + \string\global\string\long\string\@namedef{exercisepoints@#1}{#2}% + }% +} + + +% aux retrieval +\newcommand{\exercisepoints@readfromaux}[1]{% + \ifcsname exercisepoints@#1\endcsname% + \@nameuse{exercisepoints@#1}% + \else% + \textbf{??}% + \PackageWarning{exercisepoints}{% + Key 'exercisepoints@#1' not found in aux file. Maybe you need to recompile?% + }% + \fi% +} + + +% exercise environment; optional parameter is title of the respective exercise +\newenvironment{exercise}[1][]{% + \if@exercisepoints@inexercise% + \PackageError{exercisepoints}{You cannot nest exercise environments}% + \fi + % + \if@exercisepoints@exercise@layoutdefined\else% + \PackageError{exercisepoints}{Option `customlayout' requires you to define an exercise layout using at least `\string\AtBeginExercise{...}'} + \fi + % + \global\@exercisepoints@inexercisetrue% + \setlength{\exercisepoints@currentexercisepoints}{0pt}% + \global\exercisepoints@currentexercisepoints=\exercisepoints@currentexercisepoints% + \renewcommand{\currentexercisetitle}{#1}% + \exercisepoints@begin% +}{% + \exercisepoints@end% + \exercisepoints@storetoaux{points@\theexercisepoints@exercisecount}{\strip@pt\exercisepoints@currentexercisepoints}% + \stepcounter{exercisepoints@exercisecount}% + \global\@exercisepoints@inexercisefalse% +} + + +% exercise environment; optional parameter is title of the respective exercise +\newenvironment{subexercise}[1][]{% + \if@exercisepoints@insubexercise% + \PackageError{exercisepoints}{You cannot nest subexercise environments}% + \fi% + % + \if@exercisepoints@subexercise@layoutdefined\else% + \PackageError{exercisepoints}{Option `customlayout' requires you to define a subexercise layout using at least `\string\AtBeginSubexercise{...}'} + \fi% + \global\@exercisepoints@insubexercisetrue% + \setlength{\exercisepoints@currentsubexercisepoints}{0pt}% + \global\exercisepoints@currentsubexercisepoints=\exercisepoints@currentsubexercisepoints% + \renewcommand{\currentsubexercisetitle}{#1}% + \exercisepoints@sub@begin% +}{% + \exercisepoints@sub@end% + \exercisepoints@storetoaux{points@\theexercisepoints@exercisecount.\theexercisepoints@subexercisecount}{\strip@pt\exercisepoints@currentsubexercisepoints}% + \stepcounter{exercisepoints@subexercisecount}% + \global\@exercisepoints@insubexercisefalse% +} + + +\newcommand{\bonuspoints}[1]{% + \setlength{\exercisepoints@bonuspoints}{#1 pt}% + \global\exercisepoints@bonuspoints=\exercisepoints@bonuspoints% +} + +\newcommand{\getbonuspoints}{% + \exercisepoints@readfromaux{points@bonus}% +} + +\newcommand{\totalpointswithbonus}{% + \readfromaux{totalpointswithbonus}% +} + + +% read values from aux file at begin +\AtBeginDocument{ + \setlength{\exercisepoints@totalpoints}{0pt}% reset total points length + % + % set numberofexercises to 0 if not found in aux + \ifcsname exercisepoints@numberofexercises\endcsname% + \renewcommand{\numberofexercises}{% + \exercisepoints@readfromaux{numberofexercises}% + }% + \fi% + % + \renewcommand{\totalpoints}{\exercisepoints@readfromaux{points@total}}% + \renewcommand{\totalpointswithbonus}{\exercisepoints@readfromaux{points@totalwithbonus}}% +} + + +% store values in aux file at end +\AtEndDocument{ + \exercisepoints@storetoaux{numberofexercises}{\theexercisepoints@exercisecount}% + \exercisepoints@storetoaux{points@total}{\strip@pt\exercisepoints@totalpoints}% + \exercisepoints@storetoaux{points@bonus}{\strip@pt\exercisepoints@bonuspoints}% + \newlength{\exercisepoints@totalpointswithbonus}% + \setlength{\exercisepoints@totalpointswithbonus}{\exercisepoints@totalpoints}% + \addtolength{\exercisepoints@totalpointswithbonus}{\exercisepoints@bonuspoints}% + \exercisepoints@storetoaux{points@totalwithbonus}{\strip@pt\exercisepoints@totalpointswithbonus}% +} |