diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls')
-rw-r--r-- | Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls | 246 |
1 files changed, 216 insertions, 30 deletions
diff --git a/Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls b/Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls index 659ccdb3514..2f7af0470fe 100644 --- a/Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls +++ b/Master/texmf-dist/tex/latex/tuda-ci/tudaexercise.cls @@ -1,4 +1,4 @@ -%% This is file `tudaexercise.cls' version 3.12 (2021/03/06), +%% This is file `tudaexercise.cls' version 3.13 (2021/03/16), %% it is part of %% TUDa-CI -- Corporate Design for TU Darmstadt %% ---------------------------------------------------------------------------- @@ -26,8 +26,8 @@ %% %% ============================================================================ %% -\def\fileversion{3.12} -\def\filedate{2021/03/06} +\def\fileversion{3.13} +\def\filedate{2021/03/16} \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \ProvidesExplClass{tudaexercise} @@ -41,7 +41,12 @@ \prop_gput:Nnn \g_ptxcd_clsopts_prop {captions} {nooneline} \prop_gput:Nnn \g_ptxcd_clsopts_prop {parskip} {half-} -\int_new:N \g_ptxcd_ruledheaders_int +\prop_new:N \g__ptxcd_points_collector_prop +\bool_new:N \l__ptxcd_points_auto_bool +\bool_new:N \g__ptxcd_points_bool +\prop_new:N \g__ptxcd_loaded_points_prop +\fp_new:N \g__ptxcd_points_total_fp + \int_new:N \g_ptxcd_paper_int \bool_new:N \g_ptxcd_geometry_bool @@ -51,6 +56,17 @@ \bool_new:N \g_ptxcd_smalltitle_bool \str_new:N \g_ptxcd_department_str +\tl_new:N \g_ptxcd_tmp_tl +\int_new:N \g_ptxcd_tmp_int +\tl_new:N \l_ptxcd_tmp_tl + +\clist_map_inline:nn {section,subsection,subsubsection,task,subtask,@solution} { + \bool_new:c {g__ptxcd_ruled_#1_bool} + \bool_gset_true:c {g__ptxcd_ruled_#1_bool} +} + +\bool_new:N \g__ptxcd_runin_subtask_bool + \RequirePackage{environ} \newenvironment{solution}{}{} @@ -171,6 +187,21 @@ }, solution .default:n = true, unknown .code:n = {\prop_gput:NVn \g_ptxcd_unknown_clsopts_prop \l_keys_key_tl {#1}}, + points .choice:, + points / true .code:n = \bool_set_false:N \l__ptxcd_points_auto_bool\bool_gset_true:N \g__ptxcd_points_bool, + points /false .code:n = \bool_set_false:N \l__ptxcd_points_auto_bool\bool_gset_false:N \g__ptxcd_points_bool, + points / auto .code:n = \bool_set_true:N \l__ptxcd_points_auto_bool\bool_gset_true:N \g__ptxcd_points_bool, + points .initial:n = false, + subtask .choice:, + subtask / ruled .code:n = + \bool_gset_true:N \g__ptxcd_ruled_subtask_bool + \bool_gset_false:N \g__ptxcd_runin_subtask_bool, + subtask / runin .code:n = + \bool_gset_false:N \g__ptxcd_ruled_subtask_bool + \bool_gset_true:N \g__ptxcd_runin_subtask_bool, + subtask / plain .code:n = + \bool_gset_false:N \g__ptxcd_ruled_subtask_bool + \bool_gset_false:N \g__ptxcd_runin_subtask_bool, } \ProcessKeysOptions{ptxcd/exercise} @@ -186,23 +217,33 @@ \RequirePackage{environ} \bool_new:N \l_ptxcd_ex_subtask_fallback_bool +\fp_new:N \l_ptxcd_ex_task_points_fp +\fp_new:N \g__ptxcd_ex_collected_points_fp +\tl_new:N \l_ptxcd_ex_task_credit_tl \keys_define:nn {ptxcd/task}{ - points .int_set:N = \l_ptxcd_ex_task_points_int, + points .choice:, + points / auto .code:n = + \bool_set_true:N \l__ptxcd_points_auto_bool, + points / unknown .code:n = \fp_set:Nn \l_ptxcd_ex_task_points_fp {#1} + \bool_set_false:N \l__ptxcd_points_auto_bool, points .initial:n = 0, - credit .tl_set:N = \l_ptxcd_ex_task_credit_tl, + credit .code:n = \tl_set:Nn \l_ptxcd_ex_task_credit_tl {#1} + \bool_set_false:N \l__ptxcd_points_auto_bool, credit .initial:n =, solution .meta:nn ={ptxcd/exercise}{solution=#1}, } +\fp_new:N \l_ptxcd_ex_subtask_points_fp \keys_define:nn {ptxcd/subtask} { credit .tl_set:N = \l_ptxcd_ex_subtask_credit_tl, credit .initial:n =, - points .int_set:N = \l_ptxcd_ex_subtask_points_int, + points .code:n = \fp_set:Nn \l_ptxcd_ex_subtask_points_fp {#1} + \bool_set_false:N \l__ptxcd_points_auto_bool, points .initial:n = 0, title .tl_set:N = \l_ptxcd_ex_title_tl, title .initial:n =, - unknown .code:n = \bool_set_true:N \l_ptxcd_ex_subtask_fallback_bool \tl_clear:N \l_ptxcd_ex_subtask_credit_tl \int_zero:N \l_ptxcd_ex_subtask_points_int, + unknown .code:n = \bool_set_true:N \l_ptxcd_ex_subtask_fallback_bool \tl_clear:N \l_ptxcd_ex_subtask_credit_tl \fp_zero:N \l_ptxcd_ex_subtask_points_fp, } \keys_define:nn {ptxcd/exercise/headline} { @@ -257,22 +298,30 @@ \renewcommand*\sectionlinesformat[4]{% \parbox{\linewidth}{ + \bool_if:cT {g__ptxcd_ruled_#1_bool} { \rule[5\g_ptxcd_titlerule_dim]{\linewidth}{\g_ptxcd_titlerule_dim}\par\nointerlineskip + } \@hangfrom{% \hskip #2#3}{ \tl_if_eq:nnT {#1} {task} { \exp_args:No \tl_if_empty:nF {#4} - {:~} + {:~} + \bool_if:NT \l__ptxcd_points_auto_bool { + \exp_args:NNx \prop_get:NnN \g__ptxcd_loaded_points_prop {\thetask} \l_ptxcd_tmp_tl + \quark_if_no_value:NF \l_ptxcd_tmp_tl { + \fp_set:Nn \l_ptxcd_ex_task_points_fp {\l_ptxcd_tmp_tl} + } + } } #4 \tl_if_in:nnT {#1} {task} { \tl_if_empty:cTF{l_ptxcd_ex_#1_credit_tl} - {\pointformat{\tl_use:c {l_ptxcd_ex_#1_points_int}}} + {\pointformat{\fp_to_decimal:c {l_ptxcd_ex_#1_points_fp}}} {\creditformat{\tl_use:c {l_ptxcd_ex_#1_credit_tl}}} } \rule[-\dp\strutbox]{0pt}{\dp\strutbox}\par}\nointerlineskip \skip_vertical:n {\ptxcd_titlerule_sep: -\dp\strutbox} - \smash{\rule{\linewidth}{\g_ptxcd_titlerule_dim}} + \bool_if:cT {g__ptxcd_ruled_#1_bool} {\smash{\rule{\linewidth}{\g_ptxcd_titlerule_dim}}} }} @@ -676,21 +725,26 @@ \newcommand*{\StudentIDsep}{:~} \providecommand{\creditformat}[1]{\space(#1)} +\providecommand{\creditformatsum}[1]{\creditformat{#1}} \newcommand*{\pointformat}[1]{ - \int_case:nnF {#1} + \fp_compare:nF {#1 = 0} { + \bool_if:NTF \l__ptxcd_points_auto_bool + \creditformatsum + \creditformat { - {0} {} - {1} {\creditformat{\int_to_arabic:n {#1}\space\PointName}} + \fp_to_decimal:n {#1}\space + \fp_compare:nTF {#1=1} + \PointName + \PointsName } - {\creditformat{\int_to_arabic:n {#1}\space\PointsName}} } +} \providecaptionname{ngerman, german}{\PointName}{Punkt} \providecaptionname{english, american, british}{\PointName}{Point} \providecommand{\PointsName}{Punkte} \providecaptionname{ngerman, german}{\PointsName}{Punkte} \providecaptionname{english, american, british}{\PointsName}{Points} - %Has to be initialized after captionnames have been defined \AtBeginDocument{ \ptxcd_update_headline_boxes: @@ -698,12 +752,10 @@ \global\let\ConfigureHeadline\ptxcd_ConfigureHeadline:n } - - %task environment \DeclareSectionCommand[% style=section,% - level=1,% + level=2,% indent=\z@,% beforeskip=\cs_if_exist_use:NF \scr@subsection@beforeskip {-3.25ex\@plus -1ex \@minus -.2ex},% afterskip=\cs_if_exist_use:NF \scr@subsection@afterskip {1.5ex \@plus .2ex},% @@ -712,7 +764,10 @@ tocnumwidth=\cs_if_exist_use:NF \scr@tso@subsection@numwidth {2.3em},% ]{task} -\renewcommand*{\thetask}{\g_ptxcd_ex_sheetnum_tl\tl_if_empty:NF \g_ptxcd_ex_sheetnum_tl{.}\arabic{task}} +\renewcommand*{\thetask}{ + \g_ptxcd_ex_sheetnum_tl\tl_if_empty:NF \g_ptxcd_ex_sheetnum_tl{.} + \arabic{task} +} \renewcommand*{\taskformat}{\taskname\tasksep\thetask{}} \let\@task\task @@ -721,7 +776,17 @@ \NewDocumentEnvironment{task}{om}{ \IfNoValueF{#1}{\keys_set:nn {ptxcd/task}{#1}} \@task{#2} -}{} + \bool_if:NF \l__ptxcd_points_auto_bool { + \prop_gput:Nxx \g__ptxcd_points_collector_prop + {\thetask} {\fp_to_decimal:N \l_ptxcd_ex_task_points_fp} + } +}{ + \bool_if:NT \l__ptxcd_points_auto_bool { + \prop_gput:Nxx \g__ptxcd_points_collector_prop + {\thetask} {\fp_to_decimal:N \g__ptxcd_ex_collected_points_fp} + \fp_gzero:N \g__ptxcd_ex_collected_points_fp + } +} \cs_set_eq:cN {task*} \task \cs_set_eq:cN {endtask*} \endtask @@ -729,7 +794,7 @@ % subtasks \DeclareSectionCommand[% style=section,% - level=2,% + level=3,% indent=\z@,% beforeskip=\cs_if_exist_use:NF \scr@subsubsection@beforeskip {-3.25ex\@plus -1ex \@minus -.2ex},% afterskip=\cs_if_exist_use:NF \scr@subsubsection@afterskip {1.5ex \@plus .2ex},% @@ -739,6 +804,10 @@ counterwithin=task,% ]{subtask} +\bool_if:NT \g__ptxcd_runin_subtask_bool { + \RedeclareSectionCommand[runin=true]{subtask} +} + \renewcommand*{\thesubtask}{\alph{subtask})} \renewcommand*{\subtaskformat}{\thetask{}\thesubtask\enskip} \setkomafont{subtask}{\mdseries\normalsize} @@ -767,14 +836,14 @@ %Solution mechanism \DeclareSectionCommand[% -style=section,% -level=2,% -indent=\z@,% -beforeskip=\cs_if_exist_use:NF \scr@subsubsection@beforeskip {-3.25ex\@plus -1ex \@minus -.2ex},% -afterskip=\cs_if_exist_use:NF \scr@subsubsection@afterskip {1.5ex \@plus .2ex},% -tocstyle=subsection,% -tocindent=\cs_if_exist_use:NF \scr@tso@subsubsection@indent {1.5em},% -tocnumwidth=\cs_if_exist_use:NF \scr@tso@subsubsection@numwidth {2.3em},% + style=section,% + level=3,% + indent=\z@,% + beforeskip=\cs_if_exist_use:NF \scr@subsubsection@beforeskip {-3.25ex\@plus -1ex \@minus -.2ex},% + afterskip=\cs_if_exist_use:NF \scr@subsubsection@afterskip {1.5ex \@plus .2ex},% + tocstyle=subsection,% + tocindent=\cs_if_exist_use:NF \scr@tso@subsubsection@indent {1.5em},% + tocnumwidth=\cs_if_exist_use:NF \scr@tso@subsubsection@numwidth {2.3em},% ]{@solution} @@ -819,5 +888,122 @@ tocnumwidth=\cs_if_exist_use:NF \scr@tso@subsubsection@numwidth {2.3em},% \ptxcd_makeheadrule[color=identbarcolor, width=\textwidth]{ptxcd_headrule} +% Point referencing +\AddtoDoHook{heading/preinit/subtask}{ + \bool_if:NT \g__ptxcd_points_bool { + \fp_gadd:Nn \g__ptxcd_ex_collected_points_fp {\l_ptxcd_ex_subtask_points_fp} + } +} + +\AddtoDoHook{heading/preinit/task}{ + \fp_gzero:N \g__ptxcd_ex_collected_points_fp +} + + +\msg_new:nnn {tudaexercise} {points-differ} { + Value~of~points~changed~for~at~least~one~task.\\ + Please~rerun~LaTeX~to~get~correct~references~and~calculations. +} + +\msg_new:nnn {tudaexercise} {empty-point-mapping} { + I~could~not~find~references~for~points~in~the~aux~file.\\ + Please~rerun~LaTeX~to~get~correct~references~and~calculations. +} + +\msg_new:nnn {tudaexercise} {point-referencing-disabled} { + You~try~to~use~#1.\\ + This~function~is~only~available~with~points=true~or~points=auto.\\ + Please~activate~referencing~to~use~it. +} + +\bool_if:NTF \g__ptxcd_points_bool { + \BeforeClosingMainAux{ + \tl_clear:N \l_tmpa_tl + \tl_clear:N \l_tmpb_tl + \prop_map_inline:Nn \g__ptxcd_points_collector_prop { + \tl_put_right:Nn \l_tmpa_tl {#1=#2,} + } + \prop_map_inline:Nn \g__ptxcd_loaded_points_prop { + \tl_put_right:Nn \l_tmpb_tl {#1=#2,} + } + \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl { + \msg_warning:nn {tudaexercise} {points-differ} + } + \iow_now:Nx \@auxout{ + \exp_not:N \ptxcd@LoadPoints[\thetask]{\l_tmpa_tl} + } + } + + \newcommand{\getPoints}[1]{ + \exp_args:NNf \prop_get:NnNTF \g__ptxcd_loaded_points_prop {#1} \l_tmpa_tl + {\l_tmpa_tl} + {\nfss@text{\reset@font\bfseries??}} + } + + \newcommand{\refPoints}[1]{ + \edef\x{#1} + \cs_if_exist:cTF {r@\x} { + \getPoints{\tl_head:v {r@\x}} + }{ + \nfss@text{\reset@font\bfseries??} + } + } + + \newcommand{\getPointsTotal}{ + \fp_use:N \g__ptxcd_points_total_fp + } +} { + \newcommand{\getPoints}[1]{ + \msg_error:nnn {tudaexercise} {point-referencing-disabled} {\getPoints} + } + \newcommand{\refPoints}[1]{ + \msg_error:nnn {tudaexercise} {point-referencing-disabled} {\refPoints} + } + \newcommand{\getPointsTotal}[1]{ + \msg_error:nnn {tudaexercise} {point-referencing-disabled} {\getPointsTotal} + } +} + +\cs_new:Nn \__ptxcd_map_points_helper:nn {#1-#2} +\NewDocumentCommand{\mapPoints}{sO{1}m}{ + \cs_gset_nopar:Nn \__ptxcd_map_points_helper:nn {#3} + \prop_if_empty:NTF \g__ptxcd_loaded_points_prop { + \msg_warning:nn {tudaexercise} {empty-point-mapping} + \__ptxcd_map_points_helper:nn {?task?} {?points?} + }{ + \int_gset:Nn \g_ptxcd_tmp_int {\value{task}} + \setcounter{task}{#2} + \tl_gclear:N \g_ptxcd_tmp_tl + \bool_gset_true:N \g_tmpa_bool + \bool_while_do:Nn \g_tmpa_bool + { + \exp_args:NNx \prop_get:NnNTF \g__ptxcd_loaded_points_prop {\thetask} \l_tmpa_tl + { + \fp_compare:nF {\l_tmpa_tl = 0} + { + \tl_gput_right:Nn \g_ptxcd_tmp_tl {\__ptxcd_map_points_helper:nn} + \tl_gput_right:Nx \g_ptxcd_tmp_tl {{\thetask} {\l_tmpa_tl}} + } + } + {\bool_gset_false:N \g_tmpa_bool} + \stepcounter{task} + } + \setcounter{task}{\int_use:N \g_ptxcd_tmp_int} + \g_ptxcd_tmp_tl + } +} + + +\newcommand*{\ptxcd@LoadPoints}[2][]{ + \prop_gset_from_keyval:Nn \g__ptxcd_loaded_points_prop { + #2 + } + \fp_gzero:N \g__ptxcd_points_total_fp + \prop_map_inline:Nn \g__ptxcd_loaded_points_prop { + \fp_gadd:Nn \g__ptxcd_points_total_fp {##2} + } +} + + \endinput %End of class tudaexercise.cls |