vereinssatzung/tudaexercise.cls
2024-04-09 14:53:08 +02:00

1075 lines
33 KiB
TeX

%% This is file `tudaexercise.cls' version 3.36 (2024-01-05),
%% it is part of
%% TUDa-CI -- Corporate Design for TU Darmstadt
%% ----------------------------------------------------------------------------
%%
%% Copyright (C) 2018--2023 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 Maintainers of this work are
%% Marei Peischl <tuda-ci@peitex.de>
%%
%% The development respository can be found at
%% https://github.com/tudace/tuda_latex_templates
%% Please use the issue tracker for feedback!
%%
%% ============================================================================
%%
\def\fileversion{3.36}
\def\filedate{2024-01-05}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplClass{tudaexercise}
{\filedate}{\fileversion}{Exercise sheets and exams using TU Darmstadt's Corporate Desing (TUDa-CI)}
\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__ptxcd_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__ptxcd_points_collector_prop
\prop_new:N \g__ptxcd_subtask_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
\bool_new:N \g_ptxcd_custommargins_bool
\bool_new:N \l_ptxcd_ex_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__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}{}{}
\newenvironment{solution*}{}{}
\cs_new:Nn \ptxcd_setup_solution: {
\bool_if:NTF \l_ptxcd_ex_solution_bool {
\def\solution{\ptxcd_ex_solutionheader:}
\def\endsolution{}
\expandafter\def\csname solution*\endcsname{\ignorespaces}
\expandafter\let\csname endsolution*\endcsname\endsolution
}{
\RenewEnviron{solution}{
\if_false:
\BODY
\fi:
}
\RenewEnviron{solution*}{
\if_false:
\BODY
\fi:
}
}
}
\ptxcd_setup_solution:
\prg_new_conditional:Nnn \__ptxcd_if_solution: {T,F,TF} {
\bool_if:NTF \l_ptxcd_ex_solution_bool
{\prg_return_true:}
{\prg_return_false:}
}
\let\IfSolutionT \__ptxcd_if_solution:T
\let\IfSolutionF \__ptxcd_if_solution:F
\let\IfSolutionTF \__ptxcd_if_solution:TF
%Message Declaration for option processing
\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".
}
\keys_define:nn {ptxcd/exercise} {
color .code:n = {\PassOptionsToPackage{color=#1}{tudacolors}},
accentcolor .code:n = {\PassOptionsToPackage{accentcolor=#1}{tudacolors}},
textaccentcolor .code:n = {\PassOptionsToPackage{textaccentcolor=#1}{tudacolors}},
textonaccentcolor .code:n = {\PassOptionsToPackage{textaccentcolor=#1}{tudacolors}},
identbarcolor .code:n = {\PassOptionsToPackage{identbarcolor=#1}{tudacolors}},
color .initial:n = 0b,
custommargins .choice:,
custommargins / true .code:n ={
\bool_gset_true:N \g_ptxcd_custommargins_bool
\bool_gset_false:N \g_ptxcd_geometry_bool
},
custommargins / false .code:n ={
\bool_gset_false:N \g_ptxcd_custommargins_bool
\bool_gset_true:N \g_ptxcd_geometry_bool
},
custommargins / geometry .code:n = {
\bool_gset_true:N \g_ptxcd_custommargins_bool
\bool_gset_true:N \g_ptxcd_geometry_bool
},
custommargins .initial:n = false,
custommargins .default:n = true,
fontsize .code:n = \prop_gput:Nnn \g_ptxcd_clsopts_prop {fontsize} {#1},
fontsize .initial:n = {10pt},
BCOR .code:n = \PassOptionsToPackage{bindingoffset=#1}{geometry},
bindingoffset .meta:n = {BCOR=#1},
captions .code:n = {\prop_gput:Nnx \g_ptxcd_clsopts_prop {captions} {
\use:n {\prop_item:Nn \g_ptxcd_clsopts_prop {captions}}, #1}
},
titlepage .code:n = {\msg_warning:nnn {tudapub} {titlepage-option-disabled} {#1}},
paper .choices:nn = {a0,a1,a2,a3,a4,a5,a6}{
\int_gset_eq:NN \g_ptxcd_paper_int \l_keys_choice_int
\exp_args:Nx \PassOptionsToPackage{paper=\l_keys_choice_tl}{tudarules}
\exp_args:Nx \PassOptionsToPackage{paper=\l_keys_choice_tl}{typearea}
\exp_args:Nx \PassOptionsToPackage{\l_keys_choice_tl paper}{geometry}
},
paper .initial:n = a4,
logofile .tl_gset:N = \g_ptxcd_logofile_tl,
logofile .initial:n = tuda_logo,
compat .bool_gset:N = \g_ptxcd_ex_compatibility_bool,
compat .initial:n = false,
compatilibity .meta:n = {compat=#1},
compatibility .default:n = true,
credit .tl_set:N = \l_ptxcd_ex_credit_tl,
credit .initial:n =,
headontitle .bool_gset:N = \g_ptxcd_headontitle_bool,
headontitle .initial:n = false,
headontitle .default:n =true,
colorback .bool_gset:N = \g_ptxcd_colorback_bool,
colorback .default:n = true,
colorback .initial:n = true,
title .choice:,
title / default .meta:n = {title=large},
title / large .code:n = \bool_gset_false:N \g_ptxcd_smalltitle_bool,
title / small .code:n = \bool_gset_true:N \g_ptxcd_smalltitle_bool,
title .initial:n = default,
department .choice:,
department / default .code:n = \str_gset:Nn \g_ptxcd_department_str {default},
department / mecheng .code:n = {
\str_gset:Nn \g_ptxcd_department_str {mecheng}
\keys_set:nn {ptxcd/exercise}{colorback=false,departmentlogofile=tuda_maschinenbau_logo,color=Primary1}
},
department .initial:n = default,
department / unknown .code:n = {
\str_gset:Nx \g_ptxcd_department_str {\l_keys_value_tl}
},
departmentconfigprefix .tl_gset:N = \g__ptxcd_config_prefix_tl,
departmentconfigprefix .initial:n = tuda,
mecheng .meta:n = {department=mecheng},
departmentlogofile .tl_gset:N = \g_ptxcd_departmentlogo_tl,
departmentlogofile .initial:n =,
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_ptxcd_ex_solution_bool {c_#1_bool}
\ptxcd_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__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,
}
\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}}
}
}
\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 .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,
credit .code:n = \tl_set:Nn \l_ptxcd_ex_task_credit_tl {#1}
\bool_set_false:N \l__ptxcd_points_auto_bool,
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 .code:n = \fp_set:Nn \l_ptxcd_ex_subtask_points_fp {#1}
\bool_set_false:N \l__ptxcd_points_auto_bool,
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 \fp_zero:N \l_ptxcd_ex_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_ptxcd_ex_headline_#1_tl}
\keys_define:nn {ptxcd/exercise/headline} {
#1 .choice:,
#1 / title-name-id .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {
\g_ptxcd_shorttitle_tl\par
\StudentName\StudentID},
#1 / title-name .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {
\g_ptxcd_shorttitle_tl\par
\smallskip
\StudentName},
#1 / title .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {\g_ptxcd_shorttitle_tl},
#1 / name-id .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {\StudentName\StudentID},
#1 / name .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {\StudentName},
#1 / unknown .code:n = \tl_gset:cn {g_ptxcd_ex_headline_#1_tl} {##1}
}
}
%Load tudasize clo file if available
\file_if_exist:nT {tudasize\prop_item:Nn \g_ptxcd_clsopts_prop {fontsize}.clo}
{\providecommand*{\@fontsizefilebase}{tudasize}}
\LoadClass{scrartcl}
\bool_if:NT \g__ptxcd_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}
%Has to be loaded here due to headwidth options
\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}
}
}
}
\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{\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}
\bool_if:cT {g__ptxcd_ruled_#1_bool} {\smash{\rule{\linewidth}{\g_ptxcd_titlerule_dim}}}
}}
\RequirePackage{tudafonts}
\dim_new:N \g_ptxcd_innerMargin_dim
\dim_new:N \g_ptxcd_outerMargin_dim
\dim_new:N \g_ptxcd_bottomMargin_dim
\dim_new:N \g_ptxcd_topMargin_dim
%a3,a4
\int_compare:nTF {4<=\g_ptxcd_paper_int<=5}
{
\dim_gset:Nn \g_ptxcd_bottomMargin_dim {20mm}
\dim_gset:Nn \g_ptxcd_outerMargin_dim {15mm}
\dim_gset_eq:NN \g_ptxcd_innerMargin_dim \g_ptxcd_outerMargin_dim
\dim_gset_eq:NN \g_ptxcd_topMargin_dim \g_ptxcd_outerMargin_dim
}{
%a0, a1, a2
\int_compare:nT {1<=\g_ptxcd_paper_int<=3}
{
\dim_gset:Nn \g_ptxcd_bottomMargin_dim {35mm}
\dim_gset:Nn \g_ptxcd_outerMargin_dim {30mm}
\dim_gset_eq:NN \g_ptxcd_innerMargin_dim \g_ptxcd_outerMargin_dim
\dim_gset_eq:NN \g_ptxcd_topMargin_dim \g_ptxcd_outerMargin_dim
}
%a5
\int_compare:nT {\g_ptxcd_paper_int<=6}
{
\dim_gset:Nn \g_ptxcd_bottomMargin_dim {16mm}
\dim_gset:Nn \g_ptxcd_outerMargin_dim {12mm}
\dim_gset_eq:NN \g_ptxcd_innerMargin_dim \g_ptxcd_outerMargin_dim
\dim_gset_eq:NN \g_ptxcd_topMargin_dim \g_ptxcd_outerMargin_dim
}
%a6
\int_compare:nT {\g_ptxcd_paper_int<=7}
{
\dim_gset:Nn \g_ptxcd_bottomMargin_dim {15mm}
\dim_gset:Nn \g_ptxcd_outerMargin_dim {10mm}
\dim_gset_eq:NN \g_ptxcd_innerMargin_dim \g_ptxcd_outerMargin_dim
\dim_gset_eq:NN \g_ptxcd_topMargin_dim \g_ptxcd_outerMargin_dim
}
}
\dim_new:N \g_ptxcd_columnSep_dim
\dim_gset:Nn \g_ptxcd_columnSep_dim {10pt}
\dim_new:N \g_ptxcd_headheight_dim
\dim_new:N \g_ptxcd_headwidth_dim
\dim_gset:Nn \g_ptxcd_headheight_dim {\c_ptxcd_largerule_dim +\c_ptxcd_rulesep_dim +\c_ptxcd_smallrule_dim}
%%%%%Anfang Randeinstellungen Geometry
\bool_if:NTF \g_ptxcd_geometry_bool {
\RequirePackage[top=\g_ptxcd_topMargin_dim, inner=\g_ptxcd_innerMargin_dim, outer=\dim_eval:n {\g_ptxcd_outerMargin_dim}, bottom=\g_ptxcd_bottomMargin_dim, columnsep= \g_ptxcd_columnSep_dim, includehead, includefoot, headheight=\g_ptxcd_headheight_dim
]{geometry}
}{
\KOMAoptions{headinclude, footinclude, headwidth=text,footwidth=text}
}
%%%%%%%%
%Ende Randeinstellungen klassisch
\newcommand*{\institution}[1]{
\def\ptxcd_institution{#1}
}
\gdef\ptxcd_datename{Datum}
\gdef\ptxcd_dateseparator{:~}
\setkomafont{disposition}{\sffamily\bfseries}
\cs_new:Nn \ptxcd_titlerule_sep: {\the\dp\strutbox}
\RequirePackage{tudacolors}
\RequirePackage{environ}
\setkomafont{pageheadfoot}{\sffamily\small}
\setkomafont{pagenumber}{}
\addtokomafont{captionlabel}{\sffamily}
\addtokomafont{caption}{\sffamily}
\box_new:N \g_ptxcd_ex_headline_odd_box
\box_new:N \g_ptxcd_ex_headline_even_box
\box_new:N \g_ptxcd_ex_headline_oneside_box
\cs_new:Nn \ptxcd_preamble_ConfigureHeadline:n {
\tl_if_empty:nF {#1} {\keys_set:nn {ptxcd/exercise/headline} {#1}}
}
\cs_new:Nn \ptxcd_ConfigureHeadline:n {
\ptxcd_preamble_ConfigureHeadline:n {#1}
\ptxcd_update_headline_boxes:
\ptxcd_ex_adjust_headheight:
}
\let\ConfigureHeadline\ptxcd_preamble_ConfigureHeadline:n
\bool_if:NT \g_ptxcd_ex_compatibility_bool {
\cs_new:Npn \ptxcd_ex_env_to_tl_aux:w #1 \q_stop { \tl_gset:Nn \g_ptxcd_ex_headline_oneside_tl {#1} }
\NewEnviron{examheader}{
\tl_gset:No \g_ptxcd_ex_headline_oneside_tl {\BODY}
\tl_gset:No \g_ptxcd_ex_headline_odd_tl {\BODY}
\tl_gset:No \g_ptxcd_ex_headline_even_tl {\BODY}
\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_ptxcd_ex_headline_##1_tl} {
\vbox_gset:cn {g_ptxcd_ex_headline_##1_box} {
\begin{minipage}[b]{\textwidth}
\usekomafont{pagehead}
\raggedright
\leavevmode\rule{\z@}{\dimexpr\ht\strutbox+\c_ptxcd_rulesep_dim}
\ignorespaces
\use:c {g_ptxcd_ex_headline_##1_tl}\ignorespaces\strut
\par\vspace{\z@}
\end{minipage}
}
}
}
}
\cs_new:Nn \ptxcd_ex_adjust_headheight: {
\if@twoside
\dim_set:Nn \l_tmpa_dim {
\dim_max:nn
{\box_ht:N \g_ptxcd_ex_headline_odd_box+\box_dp:N \g_ptxcd_ex_headline_odd_box}
{\box_ht:N \g_ptxcd_ex_headline_even_box+\box_dp:N \g_ptxcd_ex_headline_even_box}
}
\else
\dim_set:Nn \l_tmpa_dim {
\box_ht:N \g_ptxcd_ex_headline_oneside_box
+ \box_dp:N \g_ptxcd_ex_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_ptxcd_ex_headline_even_box}}
\cohead{\box_use:c {g_ptxcd_ex_headline_odd_box}}
\else
\chead{\box_use:c {g_ptxcd_ex_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}
\renewcommand{\titlepagestyle}{plain.TUDa}
\pagestyle{TUDa}
%Titelseite
\tl_new:N \g_ptxcd_titleimage_code_tl
\tl_gset_eq:NN \g_ptxcd_titleimage_code_tl \c_empty_tl
\newcommand{\titleimage}[1]{\tl_gset:Nn \g_ptxcd_titleimage_code_tl {#1}}
\box_new:N \g_ptxcd_title_box
\skip_new:N \g_ptxcd_title_fill_skip
\seq_new:N \g_ptxcd_author_seq
\renewcommand*\author[1]{
\seq_gset_split:Nnn \g_ptxcd_author_seq {\and} {#1}
}
\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}
\renewcommand*{\@author}{
\seq_use:Nnnn \g_ptxcd_author_seq {~\authorandname{}~} {,~} {~\&~}
}
\tl_new:N \g_ptxcd_shorttitle_tl
\RenewDocumentCommand{\title}{om}{
\IfNoValueTF{#1}{
\tl_gset:Nn \g_ptxcd_shorttitle_tl {#2}
}{
\tl_gset:Nn \g_ptxcd_shorttitle_tl {#1}
}
\def\@title{#2}
}
% Define \subsubtitle for compatibility
\newcommand*{\subsubtitle}[1]{
\def\@subsubtitle{#1}
}
\subsubtitle{}
\newcommand*{\ptxcd_title@footnote}[2][1]{
\textsuperscript{\@fnsymbol{#1}}#2
}
\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-\__ptxcd_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_ptxcd_ex_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[\__ptxcd_logowidth:][l]{\includegraphics[height=\c_ptxcd_logoheight_dim]{\g_ptxcd_logofile_tl}}}
}
\par\medskip
}}
\par
\nointerlineskip
\rule{\linewidth}{\g_ptxcd_titlerule_dim}
% subtitle fields if not compat
\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_ptxcd_ex_headline_odd_box
\else
\box_use:N \g_ptxcd_ex_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
\newcommand*{\sheetnumber}[1]{\tl_gset:Nn \g_ptxcd_ex_sheetnum_tl {#1}}
\sheetnumber{}
\tl_new:N \g_ptxcd_ex_term_tl
\newcommand*{\term}[1]{\tl_gset:Nn \g_ptxcd_ex_term_tl {#1}}
\term{}
%Logos
\RequirePackage{graphicx}
%%hyperref
\PassOptionsToPackage{pdfusetitle}{hyperref}
\RequirePackage{hyperref}
\hypersetup{hidelinks, unicode}
\providecaptionname{ngerman, german}{\sheetname}{Übungsblatt}
\providecaptionname{english, american, british}{\sheetname}{Sheet}
\newcommand*{\sheetsep}{~}
\providecaptionname{ngerman, german}{\taskname}{Aufgabe}
\providecaptionname{english, american, british}{\taskname}{Task}
\newcommand*{\tasksep}{~}%TODO
\providecaptionname{ngerman, german}{\solutionname}{Lösungsvorschlag}
\providecaptionname{english, american, british}{\solutionname}{Solution}
\newcommand*{\solutionsep}{:~}
\providecaptionname{ngerman, german}{\StudentNamename}{Nachname,~Vorname}
\providecaptionname{english, american, british}{\StudentNamename}{Last Name,~ First Name}
\newcommand*{\StudentNamesep}{:~}
\providecommand{\StudentIDname}{Matrikelnummer}
\providecaptionname{ngerman, german}{\StudentIDname}{Matrikelnummer}
\providecaptionname{english, american, british}{\StudentIDname}{Enrollment ID}
\newcommand*{\StudentIDsep}{:~}
\providecommand{\creditformat}[1]{\space(#1)}
\providecommand{\creditformatsum}[1]{\creditformat{#1}}
\newcommand*{\pointformat}[1]{
\fp_compare:nF {#1 = 0} {
\bool_if:NTF \l__ptxcd_points_auto_bool
\creditformatsum
\creditformat
{
\fp_to_decimal:n {#1}\space
\fp_compare:nTF {#1=1}
\PointName
\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:
\ptxcd_ex_adjust_headheight:
\global\let\ConfigureHeadline\ptxcd_ConfigureHeadline:n
}
%task environment
\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}
\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
\cs_undefine:N \task
\NewDocumentEnvironment{task}{om}{
\IfNoValueF{#1}{\keys_set:nn {ptxcd/task}{#1}}
\@task{#2}
\bool_if:NF \l__ptxcd_points_auto_bool {
\cs_if_exist_use:NF \prop_gput:Nxx
{\exp_args:NNx \prop_gput:Nnx}
\g__ptxcd_points_collector_prop
{\thetask} {\fp_to_decimal:N \l_ptxcd_ex_task_points_fp}
}
}{
\bool_if:NT \l__ptxcd_points_auto_bool {
\cs_if_exist_use:NF \prop_gput:Nxx
{\exp_args:NNx \prop_gput:Nnx}
\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
% subtasks
\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__ptxcd_runin_subtask_bool {
\RedeclareSectionCommand[runin=true]{subtask}
}
\renewcommand*{\thesubtask}{\alph{subtask})}
\renewcommand*{\subtaskformat}{\thetask{}\thesubtask\enskip}
\setkomafont{subtask}{\mdseries\normalsize}
\let\@subtask\subtask
\cs_undefine:N \subtask
\NewDocumentEnvironment{subtask}{o}{
\begingroup
\tl_if_in:nnT {#1} {=} {
\keys_set:nn {ptxcd/subtask} {#1}
}
\bool_if:NTF \l_ptxcd_ex_subtask_fallback_bool {
\@subtask{\IfNoValueF{#1}{#1}}
}{
\@subtask{\l_ptxcd_ex_title_tl}
}
\cs_if_exist_use:NF \prop_gput:Nxx
{\exp_args:NNx \prop_gput:Nnx}
\g__ptxcd_subtask_points_collector_prop
{\thetask\thesubtask} {\fp_to_decimal:N \l_ptxcd_ex_subtask_points_fp }
\bool_if:NT \g__ptxcd_runin_subtask_bool \strut
\tl_gset_eq:NN \g_tmpa_tl \@currentlabel
\endgroup
\tl_set_eq:NN \@currentlabel \g_tmpa_tl
}{}
\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 \ptxcd_ex_solutionheader: {
\@solution*{\solutionname\solutionsep}
\if@newlist\global\@newlistfalse\fi
}
\box_new:N \g_ptxcd_NumberForm_box
\hbox_gset:Nn \g_ptxcd_NumberForm_box {
\rule{\fboxrule}{1ex}
\rule{1em}{\fboxrule}
\rule{\fboxrule}{1ex}
\,
}
\newcommand*\ptxcd_StudentID[1][7]{
\StudentIDname\StudentIDsep\prg_replicate:nn {#1} {\box_use:N \g_ptxcd_NumberForm_box}
}
\let\StudentID\ptxcd_StudentID
\newcommand*\ptxcd_StudentName{
\StudentNamename\StudentNamesep\hrulefill\qquad
}
\let\StudentName\ptxcd_StudentName
\let\ShortTitle\g_ptxcd_shorttitle_tl
% Compatibility Features
\bool_if:NT \g_ptxcd_ex_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__ptxcd_config_prefix_tl\g_ptxcd_department_str.cfg}
\ptxcd_makeheadrule[color=identbarcolor, width=\textwidth]{ptxcd_headrule}
% Point referencing
\cs_if_exist:NTF \AddtoDoHook {
\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_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__ptxcd_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__ptxcd_points_collector_prop {
\tl_put_right:Nn \l_tmpa_tl {#1=#2,}
\fp_add:Nn \l_tmpa_fp {#2}
}
\prop_map_inline:Nn \g__ptxcd_subtask_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][\fp_use:N \l_tmpa_fp]{\l_tmpa_tl}
}
}
\cs_new:Nn \__ptxcd_getPoints:n {
\prop_if_in:NnTF \g__ptxcd_loaded_points_prop {#1}
{\prop_item:Nn \g__ptxcd_loaded_points_prop {#1}}
{\nfss@text{\reset@font\bfseries??}}
}
\cs_generate_variant:Nn \__ptxcd_getPoints:n {x}
\newcommand{\getPoints}[1]{\__ptxcd_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__ptxcd_points_total_fp
}
\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{\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}
}
}
\cs_new:Nn \__ptxcd_map_points_helper:nn {#1-#2}
\NewDocumentCommand{\ptxcd@LoadPoints}{oO{0}m}{
\prop_gset_from_keyval:Nn \g__ptxcd_loaded_points_prop {
#3
}
\fp_gset:Nn \g__ptxcd_points_total_fp {#2}
}
\endinput
%End of class tudaexercise.cls