diff options
author | Karl Berry <karl@freefriends.org> | 2025-01-27 20:49:57 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2025-01-27 20:49:57 +0000 |
commit | dbafcec247a2331a20c058ec093a3cd9f9e69fe8 (patch) | |
tree | ae04f64a83bbb5d247fa7a38bf73dc60598d9c90 /Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx | |
parent | 7a71e4e9a233a73cbd9626dc9d8cfd12c9bd6153 (diff) |
tuda-ci (27jan25)
git-svn-id: svn://tug.org/texlive/trunk@73608 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx | 1490 |
1 files changed, 1490 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx b/Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx new file mode 100644 index 00000000000..459a78b60e7 --- /dev/null +++ b/Master/texmf-dist/source/latex/tuda-ci/tudaexercise.dtx @@ -0,0 +1,1490 @@ +% \iffalse meta-comment +% +% TUDa-CI -- Corporate Design for TU Darmstadt +% ---------------------------------------------------------------------------- +% +% Copyright (C) 2018--2025 by Marei Peischl <marei@peitex.de> +% +% ============================================================================ +% 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 `maintained'. +% +% The Current Maintainer of this work is +% Marei Peischl <tuda-ci@peitex.de> +% +% The development repository can be found at +% https://github.com/tudace/tuda_latex_templates +% Please use the issue tracker for feedback! +% +% ============================================================================ +% +% \fi +% +% \iffalse% no documentation on this +% \iffalse^^A Preparation for real docstrip documentation +%<*driver> +\ProvidesFile{tudaexercise.dtx}[2025-01-26 v4.00 Exercise sheets and exams using TU Darmstadt's Corporate Desing (TUDa-CI)] +\typeout{***********************************************************} +\typeout{No documentation included in this file! Please see tuda-ci.pdf for more information and DEMO-TUDaExercise.tex/.pdf for an example of use.} +\typeout{***********************************************************} +\stop +%</driver> +%<*class&initialization> +%<@@=ptxcd> +\NeedsTeXFormat{LaTeX2e}[2020/10/01] +\ProvidesExplClass{tudaexercise}{2025-01-26}{4.00}{Exercise sheets and exams using TU Darmstadt's Corporate Desing (TUDa-CI)} +%</class&initialization> +%<*driver>^^A Preparation for real docstrip documentation +\providecommand*{\TUDaDocDTXfiles}{tudaexercise.dtx} +\input{tuda-ci.dtx} +%</driver> +% \fi +% +% \changes{v4.00}{2025-01-26}{Converted to DTX file} +% +% \DoNotIndex{\newcommand,\newenvironment} +% +% +% \maketitle +% +% +% +% \DescribeEnv{solution} +% +% +% \DescribeMacro{\sectionlinesformat} +% +% +% \DescribeMacro{\institution} +% +% +% \DescribeMacro{\titlepagestyle} +% +% +% \DescribeMacro{\titleimage} +% +% +% \DescribeMacro{\author} +% +% +% \DescribeMacro{\title} +% +% +% \DescribeMacro{\sheetnumber} +% +% +% \DescribeMacro{\term} +% +% +% \DescribeMacro{\sheetsep} +% +% +% \DescribeMacro{\tasksep} +% +% +% \DescribeMacro{\solutionsep} +% +% +% \DescribeMacro{\StudentNamesep} +% +% +% \DescribeMacro{\StudentIDname} +% +% +% \DescribeMacro{\StudentIDsep} +% +% +% \DescribeMacro{\creditformat} +% +% +% \DescribeMacro{\creditformatsum} +% +% +% \DescribeMacro{\pointformat} +% +% +% \DescribeMacro{\PointsName} +% +% +% \DescribeMacro{\thetask} +% +% +% \DescribeMacro{\taskformat} +% +% +% \DescribeEnv{task} +% +% +% \DescribeMacro{\thesubtask} +% +% +% \DescribeMacro{\subtaskformat} +% +% +% \DescribeEnv{subtask} +% +% +% \MaybeStop{} +% +% \section{Implementation} +% +% \iffalse +%<*initialization> +% \fi +% +% \begin{macrocode} +\msg_new:nnnn {tudaexercise} {outdated-koma-script} { + Your~KOMA-Script~is~outdated.\\ + To~use~the~feature~'#1'~you~will~be~required~to~update. +} { + Please~do~not~use~this~feature~or~update~your~TeX~distribution.\\ + The~feature~requires~KOMA-Script~v#2~or~newer. +} +\str_const:Nn \c_@@_base_str {exercise} +\prop_new:N \g_ptxcd_clsopts_prop +\prop_new:N \g_ptxcd_unknown_clsopts_prop +\prop_gput:Nnn \g_ptxcd_clsopts_prop {captions} {nooneline} +\prop_gput:Nnn \g_ptxcd_clsopts_prop {parskip} {half-} +\prop_new:N \g_@@_points_collector_prop +\prop_new:N \g_@@_subtask_points_collector_prop +\prop_new:N \g_@@_property_collector_prop +\bool_new:N \l_@@_points_auto_bool +\bool_new:N \g_@@_points_bool +\prop_new:N \g_@@_loaded_points_prop +\fp_new:N \g_@@_points_total_fp +\int_new:N \g_ptxcd_paper_int +\bool_new:N \g_ptxcd_geometry_bool +\bool_new:N \g_ptxcd_custommargins_bool +\bool_new:N \l_@@_solution_bool +\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_@@_ruled_#1_bool} + \bool_gset_true:c {g_@@_ruled_#1_bool} +} +\bool_new:N \g_@@_runin_subtask_bool +% \end{macrocode} +% \begin{documentation} +% \DescribeEnv{solution} +% +% \end{documentation} +% \begin{environment}{solution} +% \begin{macrocode} +\newenvironment{solution}{}{} +% \end{macrocode} +% \end{environment} +% \end{implementation} +% +% \begin{documentation} +% \DescribeEnv{solution*} +% +% \end{documentation} +% \begin{environment}{solution*} +% \begin{macrocode} +\newenvironment{solution*}{}{} +% \end{macrocode} +% \end{environment} +% \end{implementation} +% \changes{v4.00}{2025-01-26}{Remove obsolete use of environ} +% \begin{macrocode} +\cs_new:Nn \_@@_setup_solution: { + \bool_if:NTF \l_@@_solution_bool { + \def\solution{\_@@_solutionheader:} + \def\endsolution{} + \expandafter\def\csname solution*\endcsname{\ignorespaces} + \expandafter\let\csname endsolution*\endcsname\endsolution + }{ + \RenewDocumentEnvironment{solution}{+b}{}{} + \RenewDocumentEnvironment{solution*}{+b}{}{} + } +} +\_@@_setup_solution: +\prg_new_conditional:Nnn \_@@_if_solution: {T,F,TF} { + \bool_if:NTF \l_@@_solution_bool + {\prg_return_true:} + {\prg_return_false:} +} +\let\IfSolutionT \_@@_if_solution:T +\let\IfSolutionF \_@@_if_solution:F +\let\IfSolutionTF \_@@_if_solution:TF +% \end{macrocode} +% Message Declaration for option processing +% \begin{macrocode} +\msg_new:nnn{tudaexercise} {titlepage-option-disabled} { + You~set~the~titlepage~option~to~#1.\\ + This option is not supported by tudaexercise.cls.\\ + The~KOMA-Script~option~titlepage~is~forced~to~"false". +} +% \end{macrocode} +% \changes{v4.00}{2025-01-26}{add bookmarksnumbered option and enable by default} +% The options have to be passed before the package options to allow being changed by the user. +% \begin{macrocode} +\PassOptionsToPackage{pdfusetitle,bookmarksnumbered=true}{hyperref} +\keys_define:nn {ptxcd/exercise} { +% \end{macrocode} +% +% \begin{macrocode} + bookmarksnumbered .code:n = \PassOptionsToPackage{bookmarksnumbered=#1}{hyperref}, + compat .bool_gset:N = \g_@@_compatibility_bool, + compat .initial:n = false, + compatilibity .meta:n = {compat=#1}, + compatibility .default:n = true, + credit .tl_set:N = \l_@@_credit_tl, + credit .initial:n =, + headontitle .bool_gset:N = \g_ptxcd_headontitle_bool, + headontitle .initial:n = false, + headontitle .default:n =true, + titlepage .code:n = {\msg_warning:nnn {tudapub} {titlepage-option-disabled} {#1}}, + match-task-subtask-syntax .bool_gset:N = \g_ptxcd_match_task_subtask_bool, + match-task-subtask-syntax .initial:n = false, + match-task-subtask-syntax .default:n = true, + solution .code:n = { + \bool_set_eq:Nc \l_@@_solution_bool {c_#1_bool} + \_@@_setup_solution: + }, + 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_@@_points_auto_bool\bool_gset_true:N \g_@@_points_bool, + points /false .code:n = \bool_set_false:N \l_@@_points_auto_bool\bool_gset_false:N \g_@@_points_bool, + points / auto .code:n = \bool_set_true:N \l_@@_points_auto_bool\bool_gset_true:N \g_@@_points_bool, + points .initial:n = false, + subtask .choice:, + subtask / ruled .code:n = + \bool_gset_true:N \g_@@_ruled_subtask_bool + \bool_gset_false:N \g_@@_runin_subtask_bool, + subtask / runin .code:n = + \bool_gset_false:N \g_@@_ruled_subtask_bool + \bool_gset_true:N \g_@@_runin_subtask_bool, + subtask / plain .code:n = + \bool_gset_false:N \g_@@_ruled_subtask_bool + \bool_gset_false:N \g_@@_runin_subtask_bool, +%</initialization> +% ^AA} +%<*center> +\ProcessKeyOptions[ptxcd/exercise] +\prop_map_inline:Nn \g_ptxcd_clsopts_prop { + \tl_if_empty:nTF {#2} + {\PassOptionsToClass {#1} {scrartcl}} + { + \clist_map_inline:nn {#2} {\PassOptionsToClass {#1=##1} {scrartcl}} + } +} + \bool_new:N \l_@@_subtask_fallback_bool + \fp_new:N \l_@@_task_points_fp + \fp_new:N \g_@@_ex_collected_points_fp + \tl_new:N \l_@@_task_credit_tl + \keys_define:nn {ptxcd/task}{ + points .choice:, + points / auto .code:n = + \bool_set_true:N \l_@@_points_auto_bool, + points / unknown .code:n = \fp_set:Nn \l_@@_task_points_fp {#1} + \bool_set_false:N \l_@@_points_auto_bool, + credit .code:n = \tl_set:Nn \l_@@_task_credit_tl {#1} + \bool_set_false:N \l_@@_points_auto_bool, + solution .meta:nn ={ptxcd/exercise}{solution=#1}, + } +\fp_new:N \l_@@_subtask_points_fp +\keys_define:nn {ptxcd/subtask} { + credit .tl_set:N = \l_@@_subtask_credit_tl, + credit .initial:n =, + points .code:n = \fp_set:Nn \l_@@_subtask_points_fp {#1} + \bool_set_false:N \l_@@_points_auto_bool, + title .tl_set:N = \l_@@_title_tl, + title .initial:n =, + unknown .code:n = { + \bool_set_true:N \l_@@_subtask_fallback_bool + \tl_clear:N \l_@@_subtask_credit_tl + \fp_zero:N \l_@@_subtask_points_fp + }, +} +\keys_define:nn {ptxcd/exercise/headline} { + headline .code:n = { + \if@twoside + \keys_set:nn {ptxcd/exercise/headline} {odd=#1,even=#1} + \else + \keys_set:nn {ptxcd/exercise/headline} {oneside=#1} + \fi + }, +} +\clist_map_inline:nn {odd, even, oneside} { + \tl_new:c {g_@@_headline_#1_tl} + \box_new:c {g_@@_headline_#1_box} + \keys_define:nn {ptxcd/exercise/headline} { + #1 .choice:, + #1 / title-name-id .meta:n = { + #1 = { + \g_ptxcd_shorttitle_tl\par + \StudentName\StudentID + } + }, + #1 / title-name .meta:n = { + #1 = { + \g_ptxcd_shorttitle_tl\par + \smallskip + \StudentName + } + }, + #1 / title .meta:n = {#1 = {\g_ptxcd_shorttitle_tl}}, + #1 / name-id .meta:n = {#1 = {\StudentName\StudentID}}, + #1 / name .meta:n = {#1 = {\StudentName}}, + #1 / unknown .code:n = \tl_gset:cn {g_@@_headline_#1_tl} {##1} + } +} +% \end{macrocode} +% Load tudasize clo file if available +% \begin{macrocode} +\file_if_exist:nT {tudasize\prop_item:Nn \g_ptxcd_clsopts_prop {fontsize}.clo} +{\providecommand*{\@fontsizefilebase}{tudasize}} +\LoadClass{scrartcl} +\bool_if:NT \g_@@_points_bool { + \cs_if_exist:NF \AddtoDoHook{ + \msg_error:nnnn {tudaexercise} {outdated-koma-script} {points=true/auto} {3.27} + \keys_set:nn {ptxcd/exercise} {points=false} + } +} +\RequirePackage{tudarules} +% \end{macrocode} +% Has to be loaded here due to headwidth options +% \begin{macrocode} +\RequirePackage[draft=false]{scrlayer-scrpage} +\KOMAoptions {twoside = false} +\prop_map_inline:Nn \g_ptxcd_unknown_clsopts_prop { + \cs_if_exist:cT {KV@KOMA.scrartcl.cls@#1} { + \tl_if_empty:nTF {#2} + {\KOMAoptions{#1}} + {\KOMAoption{#1}{#2} + } + } +} +% \end{macrocode} +% \begin{implementation} +% \begin{macro}{\sectionlinesformat} +% \begin{macrocode} +\renewcommand*\sectionlinesformat[4]{% + \parbox{\linewidth}{ + \bool_if:cT {g_@@_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_@@_points_auto_bool { + \exp_args:NNx \prop_get:NnN \g_@@_loaded_points_prop {\thetask} \l_ptxcd_tmp_tl + \quark_if_no_value:NF \l_ptxcd_tmp_tl { + \fp_set:Nn \l_@@_task_points_fp {\l_ptxcd_tmp_tl} + } + } + } + #4 + \tl_if_in:nnT {#1} {task} { + \tl_if_empty:cTF{l_@@_#1_credit_tl} + {\pointformat{\fp_to_decimal:c {l_@@_#1_points_fp}}} + {\creditformat{\tl_use:c {l_@@_#1_credit_tl}}} + } + \rule[-\dp\strutbox]{0pt}{\dp\strutbox}\par}\nointerlineskip + \skip_vertical:n {\ptxcd_titlerule_sep: -\dp\strutbox} + \bool_if:cT {g_@@_ruled_#1_bool} + {\smash{\rule{\linewidth}{\g_ptxcd_titlerule_dim}}} + } +} +\RequirePackage{tudafonts} +% \end{macrocode} +% \iffalse +%</center> +%<*body> +% \fi +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\institution} +% +%^^A TODO Rename and deprecate variable names +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\institution} +% \begin{macrocode} +\newcommand*{\institution}[1]{ + \def\ptxcd_institution{#1} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\ptxcd_datename} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd_datename} +% \begin{macrocode} +\gdef\ptxcd_datename{Datum} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\ptxcd_dateseparator} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd_dateseparator} +% \begin{macrocode} +\gdef\ptxcd_dateseparator{:~} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\setkomafont{disposition}{\sffamily\bfseries} +\cs_new:Nn \ptxcd_titlerule_sep: {\the\dp\strutbox} +\RequirePackage{tudacolors} +\setkomafont{pageheadfoot}{\sffamily\small} +\setkomafont{pagenumber}{} +\addtokomafont{captionlabel}{\sffamily} +\addtokomafont{caption}{\sffamily} +\cs_new:Nn \_@@_preamble_ConfigureHeadline:n { + \tl_if_empty:nF {#1} {\keys_set:nn {ptxcd/exercise/headline} {#1}} +} +\cs_new:Nn \ptxcd_ConfigureHeadline:n { + \_@@_preamble_ConfigureHeadline:n {#1} + \ptxcd_update_headline_boxes: + \_@@_adjust_headheight: +} +\NewDocumentCommand{\ConfigureHeadline}{m}{\_@@_preamble_ConfigureHeadline:n {#1}} +\bool_if:NT \g_@@_compatibility_bool { + \cs_new:Npn \_@@_env_to_tl_aux:w #1 \q_stop { \tl_gset:Nn \g_@@_headline_oneside_tl {#1} } + \NewDocumentEnvironment{examheader}{+b}{}{ + \tl_gset:Nn \g_@@_headline_oneside_tl {#1} + \tl_gset:Nn \g_@@_headline_odd_tl {#1} + \tl_gset:Nn \g_@@_headline_even_tl {#1} + \ptxcd_ConfigureHeadline:n {} + } + \newcommand*{\examheaderdefault}{\par\StudentName\StudentID} +} +\cs_new:Nn \ptxcd_update_headline_boxes: { + \clist_map_inline:nn {even, odd, oneside} + { + \tl_if_empty:cF {g_@@_headline_##1_tl} { + \vbox_gset:cn {g_@@_headline_##1_box} { + \begin{minipage}[b]{\textwidth} + \usekomafont{pagehead} + \raggedright + \leavevmode\rule{\z@}{\dimexpr\ht\strutbox+\c_ptxcd_rulesep_dim} + \ignorespaces + \use:c {g_@@_headline_##1_tl}\ignorespaces\strut + \par\vspace{\z@} + \end{minipage} + } + } + } +} +\cs_new:Nn \_@@_adjust_headheight: { + \if@twoside + \dim_set:Nn \l_tmpa_dim { + \dim_max:nn + {\box_ht:N \g_@@_headline_odd_box+\box_dp:N \g_@@_headline_odd_box} + {\box_ht:N \g_@@_headline_even_box+\box_dp:N \g_@@_headline_even_box} + } + \else + \dim_set:Nn \l_tmpa_dim { + \box_ht:N \g_@@_headline_oneside_box + + \box_dp:N \g_@@_headline_oneside_box + } + \fi + \dim_compare:nT {\l_tmpa_dim > \z@} + { + \dim_add:Nn \l_tmpa_dim {\box_dp:N \ptxcd_headrule_box +\c_ptxcd_rulesep_dim} + \KOMAoptions{headinclude, headheight=\l_tmpa_dim,headsepline = .5\c_ptxcd_smallrule_dim} + \if@twoside + \cehead{\box_use:c {g_@@_headline_even_box}} + \cohead{\box_use:c {g_@@_headline_odd_box}} + \else + \chead{\box_use:c {g_@@_headline_oneside_box}} + \fi + \global\setlength{\headheight}{\l_tmpa_dim} + } +} +\newpairofpagestyles{TUDa.exercise}{ + \KOMAoptions{plainfootsepline,headtopline,plainheadtopline} + \KOMAoptions { + headwidth=text, + footwidth=text + } + \setkomafont{pagehead}{} + \box_if_exist:NF \ptxcd_headrule_box { + \ptxcd_makeheadrule[color=identbarcolor, width=\sls@headwidth]{ptxcd_headrule} + } + \ModifyLayer[ + background, + height=\box_dp:N \ptxcd_headrule_box, + align=tl, + voffset=\g_ptxcd_topMargin_dim, + contents=\raisebox{\depth}{\box_use:N \ptxcd_headrule_box}, + ]{plain.TUDa.exercise.head.above.line} + \ModifyLayer[ + background, + height=\box_dp:N \ptxcd_headrule_box, + align=tl, + voffset=\g_ptxcd_topMargin_dim, + contents=\raisebox{\depth}{\box_use:N \ptxcd_headrule_box}, + ]{TUDa.exercise.head.above.line} + \ofoot[\pagemark]{\pagemark} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{TUDa.exercise.foot.even} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{TUDa.exercise.foot.odd} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{TUDa.exercise.foot.oneside} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{plain.TUDa.exercise.foot.even} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{plain.TUDa.exercise.foot.odd} + \ModifyLayer[addvoffset=\c_ptxcd_rulesep_dim]{plain.TUDa.exercise.foot.oneside} +} +\DeclarePageStyleAlias{TUDa}{TUDa.exercise} +\DeclarePageStyleAlias{plain.TUDa}{plain.TUDa.exercise} +% \end{macrocode} +% \begin{implementation} +% \begin{macrocode} +\renewcommand{\titlepagestyle}{plain.TUDa} +\pagestyle{TUDa} +% \end{macrocode} +% +% \begin{macrocode} +\seq_new:N \g_ptxcd_author_seq +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\author} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\author} +% \begin{macrocode} +\renewcommand*\author[1]{ + \seq_gset_split:Nnn \g_ptxcd_author_seq {\and} {#1} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\msg_new:nnn{tudapub} {unknown-language} { + You~selected~an~unknown~language~#1.\\ + The~Variable~#2~does~not~have~a~predefined~value.\\ + Ensure~to~redefine~#2~to~match~your~language.\\ + Otherwise~the~ngerman~vaue~#3~will~be~used. +} +\cs_new:Nn \ptxcd_define_captionFallback:Nn { + \providecommand*#1{ + \msg_warning:nnxxx{tudapub} {unknown-language} + {\languagename} {\exp_not:N #1} {#2} + \def#1{#2} + } +} +\cs_new:Nn \ptxcd_declare_caption:Nnnn { + \ptxcd_define_captionFallback:Nn #1 {#2} + \defcaptionname{ngerman, german}{#1}{#2} + \defcaptionname{english, USenglish, american}{#1}{#3} + \defcaptionname{UKenglish, british}{#1}{#4} +} +\cs_new:Nn \ptxcd_declare_caption:Nnn { + \ptxcd_declare_caption:Nnnn #1 {#2} {#3} {#3} +} +\ptxcd_declare_caption:Nnn \authorandname {und} {and} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\@author} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\@author} +% \begin{macrocode} +\renewcommand*{\@author}{ + \seq_use:Nnnn \g_ptxcd_author_seq {~\authorandname{}~} {,~} {~\&~} +} +\tl_new:N \g_ptxcd_shorttitle_tl +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\title} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\title} +% \begin{macrocode} +\RenewDocumentCommand{\title}{om}{ + \IfNoValueTF{#1}{ + \tl_gset:Nn \g_ptxcd_shorttitle_tl {#2} + }{ + \tl_gset:Nn \g_ptxcd_shorttitle_tl {#1} + } + \def\@title{#2} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% Define \subsubtitle for compatibility +% \begin{macrocode} +\newcommand*{\subsubtitle}[1]{ + \def\@subsubtitle{#1} +} +\subsubtitle{} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\ptxcd_title@footnote} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd_title@footnote} +% \begin{macrocode} +\newcommand*{\ptxcd_title@footnote}[2][1]{ + \textsuperscript{\@fnsymbol{#1}}#2 +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\@maketitle} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\@maketitle} +% \begin{macrocode} +\renewcommand*{\@maketitle}{% +\global\@topnum=\z@ +\setparsizes{\z@}{\z@}{\z@\@plus 1fil}\par@updaterelative +\vspace*{-\dim_eval:n { + \headheight + -\c_ptxcd_largerule_dim -\c_ptxcd_rulesep_dim + +\headsep + +\ht\strutbox + +\p@ + }} +\par +\nointerlineskip +\begingroup +\setlength{\fboxsep}{\z@} +\bool_if:NT \g_ptxcd_colorback_bool {\colorbox{accentcolor}}{\parbox[t]{\linewidth}{ + \rule{0pt}{\bool_if:NTF \g_ptxcd_smalltitle_bool {.25} {.5}\c_ptxcd_logoheight_dim} + \par\nointerlineskip + \raisebox{-\height}{% + \begin{minipage}[t]{\dimexpr\linewidth-\_@@_logowidth:-1ex} + \bool_if:NT \g_ptxcd_colorback_bool {\begin{addmargin}{3mm}} + \raggedright + \bool_if:NT \g_ptxcd_colorback_bool {\color{textonaccentcolor}} + \tl_if_empty:NF \@titlehead {\usekomafont{titlehead}{\@titlehead\par}} + \leavevmode\usekomafont{title}% + {\usekomafont{title}\bool_if:NTF \g_ptxcd_smalltitle_bool {\LARGE} {\huge} {\@title\par}}% + \vskip 1em + \bool_if:NF \g_@@_compatibility_bool + { + {\ifx\@subtitle\@empty\else\usekomafont{subtitle}\@subtitle\par\fi}% + \gdef\@subtitle{} + \vskip .5em + } + { + \xdef\@author {\@author} + \ifx\@author\@empty\else\usekomafont{author}\@author\par\fi + } + \vskip .5em + \bool_if:NTF \g_ptxcd_colorback_bool {\end{addmargin}} {\par} + \end{minipage}} + \tl_if_empty:NF \g_ptxcd_logofile_tl { + \hfill\raisebox{\dim_eval:n { + \bool_if:NTF \g_ptxcd_colorback_bool + {-\height} + {-.9\c_ptxcd_logoheight_dim} + }} + [0pt] + [\dim_eval:n { + \bool_if:NTF \g_ptxcd_smalltitle_bool + {\bool_if:NTF \g_ptxcd_colorback_bool {1.15}{1}} + {\bool_if:NTF \g_ptxcd_colorback_bool {1.5}{1.3} + }\c_ptxcd_logoheight_dim}] + {\makebox[\_@@_logowidth:][l]{\_@@_insert_logo:}} + } + \par\medskip + }} +\par +\nointerlineskip +\rule{\linewidth}{\g_ptxcd_titlerule_dim} +% \end{macrocode} +% subtitle fields if not compat +% \begin{macrocode} +\exp_args:Nf \tl_if_empty:nF {\g_ptxcd_ex_sheetnum_tl\@date\g_ptxcd_ex_term_tl\use:c {@subsubtitle}\@subtitle}{ + \par\nointerlineskip + \bool_if:NT \g_ptxcd_colorback_bool {\colorbox{accentcolor}}{ + \parbox{\linewidth}{ + \begin{minipage}{\linewidth} + \bool_if:NT \g_ptxcd_colorback_bool { + \color{textonaccentcolor} + \begin{addmargin}{3mm} + } + \null\par + \def\ptxcd_nextsep{} + \clist_map_inline:nn {@subtitle, @subsubtitle, g_ptxcd_ex_term_tl, @date} { + \tl_if_empty:cF {##1} {\ptxcd_nextsep\use:c {##1}\def\ptxcd_nextsep{\\}} + } + \tl_if_empty:NF \g_ptxcd_ex_sheetnum_tl {\ptxcd_nextsep\sheetname\sheetsep\g_ptxcd_ex_sheetnum_tl} + \bool_if:NT \g_ptxcd_colorback_bool {\end{addmargin}} + \end{minipage} + \vspace*{\dp\strutbox} + }}\par\nointerlineskip + \rule{\linewidth}{\g_ptxcd_titlerule_dim} +} +\par +\bool_if:NT \g_ptxcd_headontitle_bool { + \if@twoside + \box_use:N \g_@@_headline_odd_box + \else + \box_use:N \g_@@_headline_oneside_box + \fi + \par + \rule{\linewidth}{\g_ptxcd_titlerule_dim} + \par +} +\endgroup +\vskip 2em +\ConfigureHeadline{} +}% +\setkomafont{subtitle}{\bfseries} +\setkomafont{author}{} +\setkomafont{date}{} +\newkomafont{sheetnumber}{\usekomafont{date}} +\newkomafont{term}{\usekomafont{date}} +\date{} +\tl_new:N \g_ptxcd_ex_sheetnum_tl +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\sheetnumber} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\sheetnumber} +% \begin{macrocode} +\newcommand*{\sheetnumber}[1]{\tl_gset:Nn \g_ptxcd_ex_sheetnum_tl {#1}} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\sheetnumber{} +\tl_new:N \g_ptxcd_ex_term_tl +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\term} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\term} +% \begin{macrocode} +\newcommand*{\term}[1]{\tl_gset:Nn \g_ptxcd_ex_term_tl {#1}} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\term{} +% \end{macrocode} +% Logos +% \begin{macrocode} +\RequirePackage{graphicx} +% \end{macrocode} +% %hyperref +% \begin{macrocode} +\RequirePackage{hyperref} +\hypersetup{hidelinks, unicode} +\providecaptionname{ngerman, german}{\sheetname}{Übungsblatt} +\providecaptionname{english, american, british}{\sheetname}{Sheet} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\sheetsep} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\sheetsep} +% \begin{macrocode} +\newcommand*{\sheetsep}{~} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\taskname}{Aufgabe} +\providecaptionname{english, american, british}{\taskname}{Task} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\tasksep} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\tasksep} +% \begin{macrocode} +\newcommand*{\tasksep}{~}%TODO +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\solutionname}{Lösungsvorschlag} +\providecaptionname{english, american, british}{\solutionname}{Solution} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\solutionsep} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\solutionsep} +% \begin{macrocode} +\newcommand*{\solutionsep}{:~} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\StudentNamename}{Nachname,~Vorname} +\providecaptionname{english, american, british}{\StudentNamename}{Last Name,~ First Name} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\StudentNamesep} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\StudentNamesep} +% \begin{macrocode} +\newcommand*{\StudentNamesep}{:~} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\StudentIDname} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\StudentIDname} +% \begin{macrocode} +\providecommand{\StudentIDname}{Matrikelnummer} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\StudentIDname}{Matrikelnummer} +\providecaptionname{english, american, british}{\StudentIDname}{Enrollment ID} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\StudentIDsep} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\StudentIDsep} +% \begin{macrocode} +\newcommand*{\StudentIDsep}{:~} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\creditformat} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\creditformat} +% \begin{macrocode} +\providecommand{\creditformat}[1]{\space(#1)} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\creditformatsum} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\creditformatsum} +% \begin{macrocode} +\providecommand{\creditformatsum}[1]{\creditformat{#1}} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\pointformat} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\pointformat} +% \begin{macrocode} +\newcommand*{\pointformat}[1]{ + \fp_compare:nF {#1 = 0} { + \bool_if:NTF \l_@@_points_auto_bool + \creditformatsum + \creditformat + { + \fp_to_decimal:n {#1}\space + \fp_compare:nTF {#1=1} + \PointName + \PointsName + } + } +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\PointName}{Punkt} +\providecaptionname{english, american, british}{\PointName}{Point} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\PointsName} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\PointsName} +% \begin{macrocode} +\providecommand{\PointsName}{Punkte} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\providecaptionname{ngerman, german}{\PointsName}{Punkte} +\providecaptionname{english, american, british}{\PointsName}{Points} +% \end{macrocode} +% Has to be initialized after captionnames have been defined +% \begin{macrocode} +\AtBeginDocument{ + \ptxcd_update_headline_boxes: + \_@@_adjust_headheight: + \global\let\ConfigureHeadline\ptxcd_ConfigureHeadline:n +} +% \end{macrocode} +% task environment +% \begin{macrocode} +\DeclareSectionCommand[% + style=section,% + 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},% + tocstyle=section,% + tocindent=\cs_if_exist_use:NF \scr@tso@subsection@indent {1.5em},% + tocnumwidth=\cs_if_exist_use:NF \scr@tso@subsection@numwidth {2.3em},% +]{task} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\thetask} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\thetask} +% \begin{macrocode} +\renewcommand*{\thetask}{ + \g_ptxcd_ex_sheetnum_tl\tl_if_empty:NF \g_ptxcd_ex_sheetnum_tl{.} + \arabic{task} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\taskformat} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\taskformat} +% \begin{macrocode} +\newcommand*{\tasklabel}{\thetask} +\renewcommand*{\taskformat}{\taskname\tasksep\tasklabel{}} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\let\@task\task +\cs_undefine:N \task +% \end{macrocode} +% \begin{documentation} +% \DescribeEnv{task} +% +% \end{documentation} +% \begin{environment}{task} +% \begin{macrocode} +\NewDocumentEnvironment{task}{om}{ + \IfNoValueF{#1}{\keys_set:nn {ptxcd/task}{#1}} + \@task{#2} + \edef\@currenttasklabel{\tasklabel} +}{ + \_@@_save_task_properties:nnnn {} {\thetask} {#2} { + \bool_if:NTF \l_@@_points_auto_bool { + \fp_to_decimal:N \g_@@_ex_collected_points_fp + }{ + \fp_to_decimal:N \l_@@_task_points_fp + } + } + \fp_gzero:N \g_@@_ex_collected_points_fp +} +% \end{macrocode} +% \changes{v4.00}{2025-01-26}{Write task properties diractly per task/subtask} +% \begin{macrocode} +\cs_new:Nn \_@@_save_task_properties:nnnn { + \iow_now:Ne \@auxout { + \exp_not:N \ptxcd@TaskProperties {#1} {#2} { + \tl_if_empty:cF {l_@@_#1credit_tl} {credit=\tl_to_str:v {l_ptxcd_#1credit_tl},} + \tl_if_blank:nF {#3} {title=\tl_to_str:n {#3},} + } {#4} + } + \prop_gput:cee {g_@@_#1points_collector_prop} + {#2} {#4} +} +\cs_generate_variant:Nn \_@@_save_task_properties:nnnn {nnon} +% \end{macrocode} +% +% \begin{macrocode} +\iffalse +\newcommand*{\addsubtasktocentry}[4]{ + \show\subtaskentry + %% {Dateierweiterung }{Ebene }{Gliederungsnummer }{Eintrag } + %\IfArgIsEmpty {#3}{\addcontentsline {#1}{#2}{\protect \nonumberline #4}}{\addcontentsline {#1}{#2}{\protect \numberline {#3}#4}} + \tocbasic@addxcontentsline{#1}{#2}{#3}{#4} + \iow_now:Ne \@auxout { + \exp_not:N \ptxcd@TaskProperties {\the\c@task} {\the\c@subtask} {\tl_to_str:n {#2}} { + \bool_if:NTF \l_@@_points_auto_bool { + \fp_to_decimal:N \l_@@_task_points_fp + }{ + \fp_to_decimal:N \g_@@_ex_collected_points_fp + } + } + } +} +\fi + +%\ptxcd@TaskProperties {}{5.10}{Einheitliche Syntax für Task/Subtask}{0} +\newcommand*\ptxcd@TaskProperties [4]{ + \prop_gput:cnn {g_@@_#1points_collector_prop} + {#2} {#4} + \clist_map_inline:nn {#3} { + \prop_gput_from_keyval:Nn \g_@@_property_collector_prop { + #2-##1 + } + } + \prop_gput:Nnn \g_@@_property_collector_prop {#2-points} {#4} +} +% \end{macrocode} +% \end{environment} +% \end{implementation} +% +% \begin{macrocode} +\cs_set_eq:cN {task*} \task +\cs_set_eq:cN {endtask*} \endtask +% \end{macrocode} +% subtasks +% \begin{macrocode} +\DeclareSectionCommand[% + 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},% + counterwithin=task,% +]{subtask} +\bool_if:NT \g_@@_runin_subtask_bool { + \RedeclareSectionCommand[runin=true]{subtask} +} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\thesubtask} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\thesubtask} +% \begin{macrocode} +\renewcommand*{\thesubtask}{\alph{subtask})} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{documentation} +% \DescribeMacro{\subtaskformat} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\subtaskformat} +% \begin{macrocode} +\newcommand*{\subtasklabel}{\thetask\thesubtask} +\renewcommand*{\subtaskformat}{\subtasklabel\enskip} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\setkomafont{subtask}{\mdseries\normalsize} +\let\@subtask\subtask +\cs_undefine:N \subtask +% \end{macrocode} +% \begin{documentation} +% \DescribeEnv{subtask} +% +% \end{documentation} +% \begin{environment}{subtask} +% \begin{macrocode} +\NewDocumentEnvironment{subtask}{o}{ + \begingroup + \tl_if_in:nnTF {#1} {=} { + \keys_set:nn {ptxcd/subtask} {#1} + } { + \keys_set:nn {ptxcd/subtask} {title={#1}} + } + \bool_if:NTF \l_@@_subtask_fallback_bool { + \@subtask{\IfNoValueF{#1}{#1}} + }{ + \@subtask{\l_@@_title_tl} + } + \edef\@currenttasklabel{\subtasklabel} + \_@@_save_task_properties:nnon {subtask_} {\@currenttasklabel} + {\l_@@_title_tl} {\fp_to_decimal:N \l_@@_subtask_points_fp} + \bool_if:NT \g_@@_runin_subtask_bool \strut + \tl_gset_eq:NN \g_tmpa_tl \@currentlabel + \endgroup + \edef\@currentcounter{subtask} + \protected@edef\@currentlabel{\p@subtask\thesubtask} +}{} +% \end{macrocode} +% \end{environment} +% \end{implementation} +% +% \begin{documentation} +% \DescribeEnv{subtask*} +% +% \end{documentation} +% \begin{environment}{subtask*} +% \begin{macrocode} +\NewDocumentEnvironment{subtask*}{om}{ + \begingroup + \IfNoValueF{#1}{\keys_set:nn {ptxcd/subtask}{#1}} + \@subtask{#2} + \tl_gset_eq:NN \g_tmpa_tl \@currentlabel + \endgroup + \tl_set_eq:NN \@currentlabel \g_tmpa_tl +}{} +% Solution mechanism +% + \DeclareSectionCommand[% + 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} + \setkomafont{@solution}{\normalfont} + \cs_new:Nn \_@@_solutionheader: { + \@solution*{\solutionname\solutionsep} + \if@newlist\global\@newlistfalse\fi + } +% \end{macrocode} +% \end{environment} +% \end{implementation} +% +% \begin{macrocode} +\box_new:N \g_ptxcd_NumberForm_box +\hbox_gset:Nn \g_ptxcd_NumberForm_box { + \rule{\fboxrule}{1ex} + \rule{1em}{\fboxrule} + \rule{\fboxrule}{1ex} + \, +} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\ptxcd_StudentID} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd_StudentID} +% \begin{macrocode} +\newcommand*\ptxcd_StudentID[1][7]{ + \StudentIDname\StudentIDsep\prg_replicate:nn {#1} {\box_use:N \g_ptxcd_NumberForm_box} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\let\StudentID\ptxcd_StudentID +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\ptxcd_StudentName} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd_StudentName} +% \begin{macrocode} +\newcommand*\ptxcd_StudentName{ + \StudentNamename\StudentNamesep\hrulefill\qquad +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\let\StudentName\ptxcd_StudentName +\let\ShortTitle\g_ptxcd_shorttitle_tl +% \end{macrocode} +% Compatibility Features +% +% \begin{macrocode} +\bool_if:NT \g_@@_compatibility_bool { + \cs_set_eq:NN \c@subsection \c@task + \cs_set_eq:NN \subsection \task + \cs_set_eq:NN \c@subsubsection \c@subtask + \cs_set_eq:NN \subsubsection \subtask + \cs_set_eq:NN \thetask \thesubsection + \cs_set_eq:NN \thesubtask \thesubsection +} +\file_if_exist_input:n {\g_@@_config_prefix_tl\g_ptxcd_department_str.cfg} +\ptxcd_makeheadrule[color=identbarcolor, width=\textwidth]{ptxcd_headrule} +% \end{macrocode} +% Point referencing +% \begin{macrocode} +\cs_if_exist:NTF \AddtoDoHook { + \AddtoDoHook{heading/preinit/subtask}{ + \bool_if:NT \g_@@_points_bool { + \fp_gadd:Nn \g_@@_ex_collected_points_fp {\l_@@_subtask_points_fp} + } + } + \AddtoDoHook{heading/preinit/task}{ + \fp_gzero:N \g_@@_ex_collected_points_fp + } +} { + \msg_warning:nnnn {tudaexercise} {outdated-koma-script} {point~references} {3.27} +} +\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_@@_points_bool { + \BeforeClosingMainAux{ + \tl_clear:N \l_tmpa_tl + \tl_clear:N \l_tmpb_tl + \fp_zero:N \l_tmpa_fp + \prop_map_inline:Nn \g_@@_points_collector_prop { + \tl_put_right:Nn \l_tmpa_tl {#1=#2,} + \fp_add:Nn \l_tmpa_fp {#2} + } + \prop_map_inline:Nn \g_@@_subtask_points_collector_prop { + \tl_put_right:Nn \l_tmpa_tl {#1=#2,} + } + \prop_map_inline:Nn \g_@@_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[\the\c@task][\fp_use:N \l_tmpa_fp]{\l_tmpa_tl} + } + } + \cs_new:Nn \_@@_getPoints:n { + \prop_if_in:NnTF \g_@@_loaded_points_prop {#1} + {\prop_item:Nn \g_@@_loaded_points_prop {#1}} + {\nfss@text{\reset@font\bfseries??}} + } + \cs_generate_variant:Nn \_@@_getPoints:n {x} + \newcommand{\getPoints}[1]{\_@@_getPoints:x {#1}} + \newcommand{\refPoints}[1]{ + \edef\x{#1} + \cs_if_exist:cTF {r@\x} { + \str_if_in:cnTF {r@\x} {subtask} { + \tl_set_eq:Nc \l_tmpa_tl {r@\x} + \getPoints{\tl_item:Nn \l_tmpa_tl {2}\tl_item:Nn \l_tmpa_tl {1}} + } { + \getPoints{\tl_head:v {r@\x}} + } + }{ + \nfss@text{\reset@font\bfseries??} + } + } + \newcommand{\getPointsTotal}{ + \fp_use:N \g_@@_points_total_fp + } +% \end{macrocode} +% \DescribeMacro{\getTaskProperty}\oarg{Task Number}{title/credit/points} +% Suggested in PR \# 316 \url{https://github.com/tudace/tuda_latex_templates/pull/316} +% \changes{v4.00}{2025-01-26}{Add Interface to access task title} +% \begin{macrocode} +\NewDocumentCommand{\getTaskProperty}{O{\@currenttasklabel}m}{ + \exp_args:Ne \tl_show:n {#1-#2} + \prop_show:N \g_@@_property_collector_prop + \prop_if_in:NnTF \g_@@_property_collector_prop {#1-#2} + {\prop_item:Nn \g_@@_property_collector_prop {#1-#2}} + {{\nfss@text{\reset@font\bfseries??}}} +} + + \NewDocumentCommand{\mapPoints}{sO{1}m}{ + \mapTasks[skip-zero-points=true,\IfBooleanF{#1}{subtask=false},start-task=#2]{#3}{#3} + } +% \end{macrocode} +% \changes{v4.00}{2025-01-26}{Add mapping Mechanismus including subtasks based on Pull-request 316} +% \begin{Syntax} +% \_@@_point_mapping_aux:nnn \marg{task/subtask} \marg{start value} \marg{action to do before continuing the loop} +% \end{Syntax} +% \begin{macrocode} +\cs_new:Nn \_@@_point_mapping_aux:nnn { + \bool_set_true:c {l_@@_#1_bool} + \cs_set:ce {_@@_cached_#1_counter:} {\int_eval:n {\value{#1}}} + \setcounter{#1}{#2} + \bool_while_do:cn {l_@@_#1_bool} { + \prop_get:NeNTF \g_@@_loaded_points_prop {\use:c {#1label}} \l_tmpa_tl { +% \end{macrocode} +% mechanism to skip item if it doesn't have points +% \begin{macrocode} + \bool_if:NT \l_@@_skip_zero_points_bool + {\fp_compare:nF {\l_tmpa_tl = 0}} + \use:n + { + \tl_build_put_right:Ne \l_ptxcd_tmp_tl { + \exp_not:c {_@@_map_points_#1:nn} {\use:c {#1label}} {\l_tmpa_tl} + } + } + #3 + \stepcounter{#1} + } {\bool_set_false:c {l_@@_#1_bool}} + } + \setcounter{#1}{\use:c {_@@_cached_#1_counter:}} +} +% \end{macrocode} +% \changes{v4.00}{2025-01-26}{Add generic mechanism to iterate over tasks} +% \begin{macrocode} +\keys_define:nn {ptxcd/task-mapping} { + task .bool_set:N = \l_@@_task_bool, + task .initial:n = false, + subtask .bool_set:N = \l_@@_subtask_bool, + subtask .initial:n = false, + skip-zero-points .bool_set:N = \l_@@_skip_zero_points_bool, + skip-zero-points .initial:n = false, + start-task .int_set:N = \l_@@_start_task_int, + start-task .initial:n = 1, +} + +\NewDocumentCommand{\mapTasks}{O{}+m+m}{ + \cs_gset:Ne \_@@_restore_task_counters: { + \exp_not:N \setcounter{task}{\the\value{task}} + \exp_not:N \setcounter{subtask}{\the\value{subtask}} + } + \group_begin: + \keys_set:ne {ptxcd/task-mapping} { + task = true, + subtask=true, + #1 + } + \cs_gset:Nn \_@@_map_points_task:nn {#2} + \cs_gset:Nn \_@@_map_points_subtask:nn {#3} + + \prop_if_empty:NTF \g_@@_loaded_points_prop { + \msg_warning:nn {tudaexercise} {empty-point-mapping} + \tl_set:Nn \l_ptxcd_tmp_tl {\_@@_map_points_task:nn {?task?} {?points?}} + } { + \tl_build_begin:N \l_ptxcd_tmp_tl + \exp_args:Nne \use:n { + \bool_if:NTF \l_@@_task_bool \use:n \use_ii:nn + {\_@@_point_mapping_aux:nnn {task} {\int_use:N \l_@@_start_task_int}} + }{ + \bool_if:NT \l_@@_subtask_bool { + \exp_not:n { + \bool_set_true:N \l_@@_subtask_bool + \_@@_point_mapping_aux:nnn {subtask} {1} {} + } + } + } + \tl_build_end:N \l_ptxcd_tmp_tl + } + \cs_gset_eq:NN \g_ptxcd_tmp_tl \l_ptxcd_tmp_tl + \exp_last_unbraced:No + \group_end: + \g_ptxcd_tmp_tl +% \end{macrocode} +% check if between tabular rows to use \noalign +% \begin{macrocode} + \ifhmode\else\ifvoid\@arstrutbox\else\noalign\fi\fi + {\_@@_restore_task_counters:} + } +} { + \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} + } + \NewDocumentCommand{\mapPoints}{som} { + \msg_error:nnn {tudaexercise} {point-referencing-disabled} {\mapPoints} + } + \NewDocumentCommand{\getTaskProperty}{om}{ + \msg_error:nnn {tudaexercise} {point-referencing-disabled} {\getTaskProperty} + } +} +% \end{macrocode} +% \begin{documentation} +% \DescribeMacro{\ptxcd@LoadPoints} +% +% \end{documentation} +% \begin{implementation} +% \begin{macro}{\ptxcd@LoadPoints} +% \begin{macrocode} +\int_new:N \g_@@_max_task_int +\NewDocumentCommand{\ptxcd@LoadPoints}{oO{0}m}{ + \IfNoValueF{#1}{\int_gset:Nn \g_@@_max_task_int {#1}} + \prop_gset_from_keyval:Nn \g_@@_loaded_points_prop { + #3 + } + \fp_gset:Nn \g_@@_points_total_fp {#2} +} +% \end{macrocode} +% \end{macro} +% \end{implementation} +% +% \begin{macrocode} +\endinput +% \end{macrocode} + +% +% \iffalse +%</body> +% \fi +% \Finale +% \fi^^A No documentation on this +\endinput |