% \iffalse meta-comment %/GitFileInfo=tudscr-base.dtx % % TUD-Script -- Corporate Design of Technische Universität Dresden % ---------------------------------------------------------------------------- % % Copyright (C) Falk Hanisch , 2012-2022 % % ---------------------------------------------------------------------------- % % 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 % 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 and author of this work is Falk Hanisch. % % ---------------------------------------------------------------------------- % % \fi % % \iffalse ins:batch + dtx:driver %<*ins> \ifx\documentclass\undefined \input docstrip.tex \ifToplevel{\batchinput{tudscr.ins}} \else \let\endbatchfile\relax \fi \endbatchfile % %<*dtx> \ProvidesFile{tudscr-base.dtx}[2022/08/09] \RequirePackage{tudscr-gitinfo} \documentclass[english,ngerman,xindy]{tudscrdoc} \iftutex \usepackage{fontspec} \else \usepackage[T1]{fontenc} \usepackage[ngerman=ngerman-x-latest]{hyphsubst} \fi \usepackage{babel} \usepackage{tudscrfonts} \usepackage[babel]{microtype} \GitHubBase{\TUDScriptRepository} \begin{document} \author{Falk Hanisch\TUDScriptContactTitle} \maketitle \tableofcontents \DocInput{\filename} \end{document} % % \fi % % \selectlanguage{ngerman} % % \changes{v2.02}{2014/06/23}{Paket \pkg{titlepage} nicht weiter unterstützt}^^A % % % % \section{Das Paket \pkg{tudscrbase} -- Basisdefinitionen für \TUDScript} % % Für die Erstellung der \TUDScript-Klassen werden die dafür benötigten Pakete % eingebunden und Steuerungsbefehle definiert. Die Klassen sowie einige Pakete % benötigen das Paket und laden dieses auch. % % \begin{macrocode} %<*package&base> \ProvidesPackage{tudscrbase}[% %!TUD@Version package (basics for the bundle)% ] % % \end{macrocode} % % \ToDo{ % Schnittstelle äquivalent zu \cs{KOMA@kav@...}? Dann hierfür % \pkg{etoolbox}-Listen und \cs{listadd} sowie \cs{listremove} nutzen % }[v2.08] % \ToDo{ % Teile im Quelltext suchen, die nur einmalig durchlaufen werden müssen % (bspw. notwendige Pakete und Schriften) und über aux-Eintrag abkürzen?! % siehe \cs{TUD@CheckPackage} % }[v2.07] %^^A\BeforeClosingMainAux{% %^^A \if@tud@xxx\if@filesw% %^^A \immediate\write\@mainaux{% %^^A \string\global\string\let\string\tud@test@xxx\string\relax% %^^A }% %^^A \fi\fi% %^^A} % % % % \begin{macrocode} %<*load> \RequirePackage{tudscrbase}[% %!TUD@Version ] % % \end{macrocode} % % \iffalse %<*package&base> % \fi % % \subsection{Notwendige Kompatibilitätseinstellung für \KOMAScript} % % Die installierte Version und die gewählte Kompatibilitätseinstellung von % \KOMAScript{} wird gerpüft. % \begin{macrocode} \AtBeginDocument{% \ifcsundef{scr@v@first}{}{% % \end{macrocode} % Es wird gerpüft, ob die mindestens benötigte \KOMAScript-Version % (v\csuse{TUD@KOMAVersionNumber}) verfügbar ist. Sollte dies nicht der Fall % sein, wird ein Fehler erzeugt. % \begin{macrocode} \ifcsundef{scr@v@\TUD@KOMAVersionNumber}{% \PackageError{tudscrbase}{% KOMA-Script v\TUD@KOMAVersionNumber\space is required% }{% \TUD@Version\space must be used at least with\MessageBreak% \TUD@KOMAVersion, but only\MessageBreak% \KOMAScriptVersion\space was found.% }% }{% % \end{macrocode} % Ist die mindestens nötige Version von \KOMAScript{} installiert, wird % geprüft, ob die Kompatibilitätseinstellung akzeptabel ist. % \begin{macrocode} \expandafter\ifnum\scr@v@is@lt{3.12}\relax% \PackageError{tudscrbase}{% KOMA-Script compatibility level too low% }{% \TUD@Version\space must be used at least with\MessageBreak% `version=3.12' KOMA-Script compatibility option.% }% \fi% }% }% } % \end{macrocode} % % \subsection{Notwendige Pakete für \TUDScript} % % \changes{v2.06f}{2020/01/14}{Anpassungen für \pkg{scrbase} \val{v3.28}}^^A % Das Paket \pkg{scrbase} wird zur Optionsdefinition benötigt, \pkg{scrlfile} % für verschiedene Hooks vor sowie nach Klassen und Paketen. % \begin{macrocode} \RequirePackage{scrbase}[% %!TUD@KOMAVersion ] % \end{macrocode} % Die folgenden Pakete werden für die Manipulation bereits definierter % Makros, zur erweiterten Auswertung boolescher Ausdrücke und allgemein zur % Ablaufsteuerung benötigt. % \begin{macrocode} \RequirePackage{iftex} \RequirePackage{etoolbox} \RequirePackage{xpatch} \RequirePackage{letltxmacro} % \end{macrocode} % Das Paket \pkg{kvsetkeys} erweitert \pkg{keyval} um die Möglichkeit, das % Verhalten bei der Angabe eines nicht definierten Schlüssels festzulegen. % \ToDo{sollte auch mit KOMA-Option \val{@else@} gehen, besser raus}[v2.07] % \begin{macrocode} \RequirePackage{kvsetkeys} % \end{macrocode} % Mit dem Paket \pkg{trimspaces} können eventuell vorhandene Leerzeichen aus % einem Argument entfernt. Dies wird beispielsweise beim Einlesen von Feldern % oder bei der expliziten Auswahl einer Schrift des \CD sgenutzt. % \begin{macrocode} \RequirePackage{trimspaces} % \end{macrocode} % Für \pkg{hyperref} werden \cs{TUDScript} und \cs{KOMAScript} deaktiviert. % \begin{macrocode} \AfterPackage*{hyperref}{% \pdfstringdefDisableCommands{% \def\TUDScript{TUD-Script}% \def\KOMAScript{KOMA-Script}% }% } % \end{macrocode} % % \subsection{Grundlegende Befehle für \TUDScript} % \subsubsection{Erweiterte Definition von \TeX-Primitiven} % % Mit \LaTeX{} lassen sich einige Primitiven definieren, ohne zu Prüfen, ob % ggf. bereits eine Definition vorhanden ist. Dies wird hiermit umgangen. % \begin{macro}{\tud@newif} % \changes{v2.06o}{2022/07/27}{neu}^^A % \begin{macro}{\tud@newcount} % \changes{v2.06o}{2022/07/27}{neu}^^A % \begin{macro}{\tud@newtoks} % \changes{v2.06o}{2022/07/27}{neu}^^A % \begin{macro}{\tud@newread} % \changes{v2.06o}{2022/07/27}{neu}^^A % \begin{macro}{\tud@newwrite} % \changes{v2.06o}{2022/07/27}{neu}^^A % \begin{macrocode} \newcommand*\tud@newif[1]{\@ifdefinable#1{\newif#1}} \newcommand*\tud@newcount[1]{\@ifdefinable#1{\newcount#1}} \newcommand*\tud@newtoks[1]{\@ifdefinable#1{\newtoks#1}} \newcommand*\tud@newread[1]{\@ifdefinable#1{\newread#1}} \newcommand*\tud@newwrite[1]{\@ifdefinable#1{\newwrite#1}} % \end{macrocode} % \end{macro}^^A \tud@newwrite % \end{macro}^^A \tud@newread % \end{macro}^^A \tud@newtoks % \end{macro}^^A \tud@newcount % \end{macro}^^A \tud@newif % % \subsubsection{Definition von Längen-Registern} % % \begin{macro}{\tud@newglue} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@newdim} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@setglue} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@setdim} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@addtoglue} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@addtodim} % \changes{v2.06o}{2022/07/28}{neu}^^A % Der \LaTeX"~Kernel stellt lediglich \cs{newlength} zur Verfügung, um bereits % bestehende Makros nicht zu überschreiben. Soll jedoch ein \cs{dimen}-Register % definiert werden, gibt es keinen entsprechenden Befehl. Auch die Zuweisung % von Längenwerte kann mit \cs{setlength} nicht sauber erfolgen, da nicht % geprüft wird, ob die Zuweisung an ein \cs{skip}"~ oder \cs{dimen}-Register % erfolgt. Deshalb werden hier für diese Aufgabe interne Befehle definiert. % Siehe dazu auch \GitHubRepo(latex3/latex2e)<227>. % \begin{macrocode} \newcommand*\tud@newglue[1]{\@ifdefinable#1{\newskip#1}} \newcommand*\tud@newdim[1]{\@ifdefinable#1{\newdimen#1}} \newrobustcmd*\tud@setglue[2]{% \ifdefdimen{#1}{% \PackageWarning{tudscrbase}{% You tried to assign dimen \string#1\MessageBreak% so \string\tud@setdim\space is used% }% \tud@setdim{#1}{#2}% }{% \setlength#1{\glueexpr#2\relax}% }% } \newrobustcmd*\tud@setdim[2]{% \begingroup% \@tud@res@swafalse% \setlength\@tempskipa{\glueexpr#2\relax}% \ifdim\gluestretch\@tempskipa=\z@\relax\else% \@tud@res@swatrue% \fi% \ifdim\glueshrink\glueexpr\@tempskipa\relax=\z@\relax\else% \@tud@res@swatrue% \fi% \if@tud@res@swa% \PackageWarning{tudscrbase}{% You tried to use \string\tud@setdim\string#1\MessageBreak% with glue \detokenize{#2} (\the\@tempskipa)\MessageBreak% but only the base value is used% }% \fi% \endgroup% \setlength#1{\dimexpr\glueexpr#2\relax\relax}% } \newrobustcmd*\tud@addtoglue[2]{% \tud@setglue#1{\glueexpr#1+#2\relax}% } \newrobustcmd*\tud@addtodim[2]{% \tud@setdim#1{\glueexpr#1+#2\relax}% } % \end{macrocode} % \end{macro}^^A \tud@addtodim % \end{macro}^^A \tud@addtoglue % \end{macro}^^A \tud@setdim % \end{macro}^^A \tud@setglue % \end{macro}^^A \tud@newdim % \end{macro}^^A \tud@newglue % \begin{macro}{\tud@res@glue} % \changes{v2.06}{2019/06/21}{neu}^^A % Und gleich noch eine temporäre Länge mit dazu. % \begin{macrocode} \tud@newglue\tud@res@glue % \end{macrocode} % \end{macro}^^A \tud@res@glue % \begin{macro}{\tud@if@lengthregister} % \changes{v2.06o}{2022/07/28}{neu}^^A % Prüft, ob der übergebene Befehl ein \cs{skip}"~ oder \cs{dimen}-Register ist. % \begin{macrocode} \newcommand*\tud@if@lengthregister[1]{% \begingroup% \@tud@res@swafalse% \ifdeflength{#1}{\@tud@res@swatrue}{}% \ifdefdimen{#1}{\@tud@res@swatrue}{}% \if@tud@res@swa% \aftergroup\@firstoftwo% \else% \aftergroup\@secondoftwo% \fi% \endgroup% } % \end{macrocode} % \end{macro}^^A \tud@if@lengthregister % \begin{macro}{\tud@length@setabsolute} % \changes{v2.06o}{2022/07/28}{neu}^^A % Um Schlüssel für Längen definieren zu können, die zwingend positiv sind, kann % dieses Makro genutzt werden. Übergeben werden muss entweder eine Länge oder % ein Makro, welches einen Längenausdruck enthält. % \begin{macrocode} \newcommand*\tud@length@setabsolute[1]{% \tud@if@lengthregister{#1}{% \ifdim#1<\z@% \setlength#1{-\glueexpr#1\relax}% \fi% }{% \protected@edef#1{% \noexpand\ifdim\noexpand\glueexpr\expandonce#1\relax<\z@-\noexpand\fi% \noexpand\glueexpr\expandonce#1\relax% }% }% } % \end{macrocode} % \end{macro}^^A \tud@length@setabsolute % % \subsubsection{Temporäre Makros zur internen Verwendung durch \TUDScript} % % Hier werden Makros definiert, die allein für die interne temporäre Nutzung % gedacht sind. % \ToDo{sämtliche \cs{@temp...}-Makros auf \cs{tud@res@...} ändern}[v2.07] % \ToDo{\cs{tud@reserved} in \cs{tud@res@...}, Achtung bei Dopplungen!}[v2.07] % \ToDo{Schlüssel sollten weiterhin \cs{@temp...}-Makros verwenden}[v2.07] % \ToDo{Makros mit \val{@num} in count ändern}[v2.07] % \begin{macro}{\tud@reserved} % \changes{v2.05}{2015/10/27}{neu}^^A % \begin{macro}{\tud@res@a} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\tud@res@b} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\tud@res@c} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\tud@res@d} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\if@tud@res@swa} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\tud@res@cnt} % \changes{v2.06}{2019/06/13}{neu}^^A % Makros zur temporären Verwendung. % \begin{macrocode} \newcommand*\tud@reserved{} \newcommand*\tud@res@a{} \newcommand*\tud@res@b{} \newcommand*\tud@res@c{} \newcommand*\tud@res@d{} \tud@newif\if@tud@res@swa \tud@newcount\tud@res@cnt % \end{macrocode} % \end{macro}^^A \tud@res@cnt % \end{macro}^^A \if@tud@res@swa % \end{macro}^^A \tud@res@d % \end{macro}^^A \tud@res@c % \end{macro}^^A \tud@res@b % \end{macro}^^A \tud@res@a % \end{macro}^^A \tud@reserved % \begin{macro}{\tud@toks@} % \changes{v2.05}{2015/11/01}{neu}^^A % \begin{macro}{\addto@hook@expandafter} % \changes{v2.05}{2015/11/01}{neu}^^A % Es wird ein token-Regsiter reserviert, welches im weiteren Verlauf an allen % möglichen Punkten verwendet wird. Mit \cs{addto@hook@expandafter} wird~-- in % Ergänzung zu \cs{addto@hook} aus dem \LaTeX"~Kernel~-- ein Makro zum Anfügen % des expandierten Arguments an ein token-Register bereitgestellt. % \begin{macrocode} \tud@newtoks\tud@toks@ \newcommand*\addto@hook@expandafter[2]{% \expandafter\addto@hook\expandafter#1\expandafter{#2}% } % \end{macrocode} % \end{macro}^^A \addto@hook@expandafter % \end{macro}^^A \tud@toks@ % % \subsubsection{Verzweigung für Präambel und Dokument} % % \begin{macro}{\tud@if@preamble} % \changes{v2.05o}{2022/07/25}{als Ersatz für \cs{if@atdocument}}^^A % Mit \KOMAScript~v3.37 wurde das Aktivieren des Schalters \cs{if@atdocument} % aufgrund des stark veränderten und damit leider nur bedingt deterministischen % \hrfn{https://sourceforge.net/p/koma-script/tickets/23/}{Hook-Managements} % des Kernels auf |begindocument/before| verschoben. Dieser Befehl wird als % Gegenstück definiert und führt in Abhängigkeit von |begindocument/after| % Quelltext verzweigt aus. % \begin{macrocode} \newcommand*\tud@if@preamble{} \let\tud@if@preamble\@firstoftwo \AfterEndPreamble{\let\tud@if@preamble\@secondoftwo} % \end{macrocode} % \end{macro}^^A \tud@if@preamble % % \subsubsection{Strings} % \minisec{Expandierte Tests} % % \begin{macro}{\tud@if@strequal} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@if@strstart} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@if@strempty} % \changes{v2.06o}{2022/07/28}{neu}^^A % \begin{macro}{\tud@if@strblank} % \changes{v2.06o}{2022/07/28}{neu}^^A % Hiermit wird geprüft, ob ein String gleich, leer oder blank (Leerzeichen) % ist, wobei die gegebene Argumente expandiert werden. In ihrer Syntax sind % sie identisch zu den aus aus \pkg{etoolbox} stammenden und unterlagerten % Befehlen \cs{ifstrequal}, \cs{ifstrempty} und \cs{ifblank}. Der Befehl % \cs{tud@if@strstart} nutzt \cs{Ifstrstart} von \KOMAScript. % \begin{macrocode} \newcommand*\tud@if@strequal[2]{% \begingroup% \protected@edef\tud@res@a{% \endgroup% \noexpand\ifstrequal{#1}{#2}% }% \tud@res@a% } \newcommand*\tud@if@strstart[2]{% \begingroup% \protected@edef\tud@res@a{% \endgroup% \noexpand\Ifstrstart{\noexpand\detokenize{#1}}{\noexpand\detokenize{#2}}% }% \tud@res@a% } \newcommand*\tud@if@strempty{\tud@if@strequal{}} \newcommand*\tud@if@strblank[1]{% \begingroup% \protected@edef\tud@res@a{% \endgroup% \noexpand\ifblank{#1}% }% \tud@res@a% } % \end{macrocode} % \end{macro}^^A \tud@if@strblank % \end{macro}^^A \tud@if@strempty % \end{macro}^^A \tud@if@strstart % \end{macro}^^A \tud@if@strequal % % \minisec{Test auf booleschen Ausdruck in Form eines Strings} % % \begin{macro}{\tud@if@strbool} % \changes{v2.03}{2015/01/09}{neu}^^A % Dieser Befehl dient zum Testen, ob ein gegebener String als boolescher % Ausdruck interpretiert werden kann. Ist der String als \enquote{wahr} % interpretierbar, wird das zweite Argument ausgeführt. Kann der String als % \enquote{falsch} angesehen werden, dementsprechen das dritte. Ist der String % kein logischer Wert, kommt das letzte Argument zum Tragen. Die Syntax lautet: % \newline % \cs{tud@if@strbool}\marg{Argument}\marg{Wahr}\marg{Falsch}\marg{Andernfalls} % \begin{macrocode} \newcommand*\tud@if@strbool[4]{% \TUD@set@ifkey{strbool}{@tempswa}{#1}% \ifx\FamilyKeyState\FamilyKeyStateProcessed% \if@tempswa#2\else#3\fi% \else% #4 \fi% } % \end{macrocode} % \end{macro}^^A \tud@if@strbool % % \minisec{Erzwungene Kleinschreibung von Strings} % % \begin{macro}{\tud@strlowercase} % Dieses Makro expandiert das zweite Argument, setzt es in Minuskeln und % speichert das Ergebnis in den im ersten Argument angegebenen Befehl. Dies % wird zum Beispiel benötigt, um bestimmte Werte bei Schlüssel-Wert-Paaren, % Schlüsselwörtern in einigen Feldern oder auch Einheiten bei Längenangaben % sicher erkennen zu können. Die Syntax lautet: % \newline % \cs{tud@strlowercase}\marg{Zielmakro}\marg{String} benutzt. % \begin{macrocode} \newcommand*\tud@strlowercase[2]{% \protected@edef#1{% \lowercase{\def\noexpand#1{#2}}% }#1% } % \end{macrocode} % \end{macro}^^A \tud@strlowercase % % \minisec{Ausgabe einer Länge als Strings} % % \begin{macro}{\tud@strlength} % \changes{v2.06o}{2022/07/28}{neu}^^A % Die direkte Verwendung von \cs{the} auf ein \cs{skip}-Register hat zur Folge, % dass die Einheit \val{pt} mit die Charactercodes \val{12} zurückgegeben % werden, was bei der Weiterverarbeitung unter Umständen Probleme bereitet. % Dieses Makro löst das Problem. % \begin{macrocode} \newcommand*\tud@strlength[2]{% \begingroup% \def\tud@res@c{\glueexpr#2\relax}% \edef\tud@res@a{\strip@pt\dimexpr\tud@res@c\relax pt}% \edef\tud@res@b{\strip@pt\dimexpr\gluestretch\tud@res@c\relax}% \ifdim\tud@res@b\p@=\z@\relax\else% \eappto\tud@res@a{% \space\@plus\space\tud@res@b% \ifcase\gluestretchorder\tud@res@c pt\or fil\or fill\or filll\fi% }% \fi% \edef\tud@res@b{\strip@pt\dimexpr\glueshrink\tud@res@c\relax}% \ifdim\tud@res@b\p@=\z@\relax\else% \eappto\tud@res@a{% \space\@minus\space\tud@res@b% \ifcase\glueshrinkorder\tud@res@c pt\or fil\or fill\or filll\fi% }% \fi% \edef\tud@res@a{% \endgroup% \unexpanded{\def#1}{\tud@res@a}% }% \tud@res@a% } % \end{macrocode} % \end{macro}^^A \tud@strlength % % \minisec{Entfernen aller Leerzeichen in Strings} % % \begin{macro}{\tud@remove@spaces@within} % Hiermit können in einem gegebenen String \emph{alle} Leerzeichen enthaltenen % entfernt werden. Dies wird verwendet, um für \cs{TUD@set@gluekey} sowie % \cs{TUD@set@dimkey} eine Warnung auszugeben, falls das übergebene Argument % fehlerhaft formatiert ist, wobei Unterschiede bei Leerzeichen ignoriert % werden sollen. % \begin{macrocode} \newcommand*\tud@remove@spaces@within[1]{% \begingroup% \protected@edef\tud@res@a{\noexpand\zap@space#1\space\noexpand\@empty}% \protected@edef\tud@res@a{% \endgroup% \unexpanded{\def#1}{\tud@res@a}% }% \tud@res@a% } % \end{macrocode} % \end{macro}^^A \tud@remove@spaces@within % % \subsubsection{Test auf eine verwendbare Sprache} % % \begin{macro}{\iflanguageloaded} % \changes{v2.05}{2015/11/23}{neu}^^A % Hiermit kann getestet werden, ob das Argument als Sprache nutzbar ist. % \begin{macrocode} \AtEndPreamble{% \providecommand*\iflanguageloaded[1]{% \PackageWarning{tudscrbase}{% `\string\iflanguageloaded' is not defined. Loading\MessageBreak% either package `babel' or package `polyglossia'\MessageBreak% is recommended% }% \def\iflanguageloaded##1{\expandafter\@secondoftwo}% \iflanguageloaded{#1}% }% } \AfterPackage*{babel}{% \providecommand*\iflanguageloaded[1]{% \@expandtwoargs\in@{,#1,}{,\bbl@loaded,}% \ifin@% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% }% } % \end{macrocode} % \end{macro}^^A \iflanguageloaded % % \subsubsection{Expansion geschützter Makros} % % Im \LaTeX"~Kernel wird der Befehl \cs{@expandtwoargs} definiert, welcher zwei % Argumente in ein angegebenes Makro vollständig expandiert. Dabei erfolgt die % Expansion der beiden Argumente aufgrund der standardmäßigen Verwendung von % \cs{edef} allerdings vollständig und ohne die Beachtung von \cs{protect}. % \begin{macro}{\protected@expandtwoargs} % \changes{v2.02}{2014/11/13}{neu}^^A % Der Befehl \cs{protected@expandtwoargs} kann äquivalent genutzt werden, % lässt dabei aber mit \cs{protect} geschützte Makros unberührt. % \begin{macrocode} \providecommand*\protected@expandtwoargs[3]{% \protected@edef\reserved@a{\noexpand#1{#2}{#3}}\reserved@a% } % \end{macrocode} % \end{macro}^^A \protected@expandtwoargs % % \subsubsection{Division für rationale Zahlen} % % Mit \LaTeX{} kann~-- ohne die Verwendung zusätzlicher Pakete~-- nicht ohne % Weiteres eine Division durchgeführt werden, die als Ergenis eine rationale % Zahl liefert. Dem wird hier Abhilfe geleistet. % \begin{macro}{\tud@divide} % \changes{v2.04}{2015/04/09}{neu}^^A % Der Befehl erwartet im ersten Argument das Makro, in welches das Ergebnis % der Division expandiert werden soll, danach folgen Dividend und Divisor. Die % Berechnung erfolgt in einer Gruppe, damit die benötigten Längenregister nach % dieser erhalten bleiben. % \begin{macrocode} \newcommand*\tud@divide[3]{% \begingroup% % \end{macrocode} % Die Division wird über temporäre Längenregister durchgeführt. Die zu % teilenden Zahlen werden normiert, wodurch auch Längen mit unterschiedlichen % Einheiten geteilt werden können. % \begin{macrocode} \@defaultunits\@tempdima #2pt\relax\@nnil% \@defaultunits\@tempdimb #3pt\relax\@nnil% % \end{macrocode} % Danach wird mit der größeren der beiden Zahlen der größtmögliche, durch % \val{2} teilbare Faktor zur Berechnung ermittelt. % \begin{macrocode} \ifdim\@tempdima>\@tempdimb\relax% \@whiledim\@tempdimb>1pt\relax\do{% \setlength\@tempdima{\dimexpr\@tempdima/10\relax}% \setlength\@tempdimb{\dimexpr\@tempdimb/10\relax}% }% \setlength\@tempdimc{\@tempdima}% \else% \@whiledim\@tempdima>1pt\relax\do{% \setlength\@tempdima{\dimexpr\@tempdima/10\relax}% \setlength\@tempdimb{\dimexpr\@tempdimb/10\relax}% }% \setlength\@tempdimc{\@tempdimb}% \fi% \@tempcnta=1\relax% \@whiledim% \dimexpr\@tempcnta\@tempdimc\relax<\dimexpr\maxdimen/100\relax% \do{% \multiply\@tempcnta by 10\relax% }% % \end{macrocode} % Mit dem im temporären Zählerregister \cs{@tempcnta} gespeicherten Faktor % wird der Dividend erweitert und der berechnete Quotient wieder gekürzt. % \begin{macrocode} \setlength\@tempdimc{\dimexpr(\@tempcnta\@tempdima/\@tempdimb*\p@)\relax}% \setlength\@tempdimc{\dimexpr\@tempdimc/\@tempcnta\relax}% % \end{macrocode} % Das Ergebnis wird in das angegebene Makro expandiert. % \begin{macrocode} \edef\@tempa{\endgroup\def\noexpand#1{\strip@pt\@tempdimc}}% \@tempa% } % \end{macrocode} % \end{macro}^^A \tud@divide % % \subsubsection{Test auf vorhandene Dateien von Schriftdefinitionen} % % \begin{macro}{\tud@if@fdfileexists} % \changes{v2.06b}{2019/07/17}{neu}^^A % Der Befehl wird genutzt, um \file{\dots.fd}~Dateien zu suchen. Dabei muss % beachtet werden, dass \cs{IfFileExists} auf unixoiden Betriebssystemen % case-sensitiv ist. % \begin{macrocode} \newcommand*\tud@if@fdfileexists[2]{% \begingroup% % \end{macrocode} % Der Schalter \cs{if@tud@res@swa} wird \val{false} gesetzt, falls die Schrift % gefunden wurde. Der zu prüfenden Schriftname wird dabei in unterschiedlichen % Varianten getestet. Zunächst die Standardvariante in Kleinschreibung\dots % \begin{macrocode} \@tud@res@swatrue% \tud@strlowercase\tud@res@a{#1#2.fd}% \IfFileExists{\tud@res@a}{\@tud@res@swafalse}{}% % \end{macrocode} % \dots gefolgt von der Variante mit Kleinschreibung der Kodierung und dem % Namen der Schrift wie angegeben\dots % \begin{macrocode} \if@tud@res@swa% \tud@strlowercase\tud@res@a{#1}% \edef\tud@res@a{\tud@res@a#2.fd}% \IfFileExists{\tud@res@a}{\@tud@res@swafalse}{}% \fi% % \end{macrocode} % \dots abgeschlossen mit der Variante wie gegeben. % \begin{macrocode} \if@tud@res@swa% \edef\tud@res@a{#1#2.fd}% \IfFileExists{\tud@res@a}{\@tud@res@swafalse}{}% \fi% % \end{macrocode} % Wurde die Schriftdatei gefunden, ist \cs{if@tud@res@swa}|=|\cs{iffalse}. % \begin{macrocode} \if@tud@res@swa% \aftergroup\@secondoftwo% \else% \aftergroup\@firstoftwo% \fi% \endgroup% } % \end{macrocode} % \end{macro}^^A \tud@if@fdfileexists % % \subsubsection{Sicherung und Wiederherstellung originaler Befehle und Längen} % % \begin{macro}{\tud@cs@letltx} % \changes{v2.06}{2019/06/13}{\cs{LetLtxMacro} zum Sichern originärer Makros}^^A % \begin{macro}{\tud@cs@store} % \changes{v2.06}{2018/07/15}{mit \cs{DeclareRobustCommand} definierte Befehle % werden unterstüzt}^^A % \begin{macro}{\tud@cs@restore} % \changes{v2.06}{2018/07/15}{stellt originäre Makros auch wieder her, wenn % diese mit \cs{undef} zwischendurch \emph{undefiniert} gesetzt wurden}^^A % \begin{macro}{\tud@cs@reset} % \begin{macro}{\tud@cs@update} % \changes{v2.04}{2015/03/03}{neu}^^A % \begin{macro}{\tud@cs@use} % \begin{macro}{\tud@cs@check} % \changes{v2.03}{2015/01/09}{neu}^^A % Mit diesen Befehlen wird es möglich, Originalbefehle sichern, nutzen und % wiederherstellen zu können. Dies wird benötigt, um zwischen den einzelnen % Layouts über Optionseinstellungen zu wechseln und dabei von einem definierten % Anfangszustand auszugehen. % % Der Befehl \cs{tud@cs@letltx} nutzt intern \cs{LetLtxMacro} aus dem Paket % \pkg{letltxmacro}, um auch robust definierte Befehle korrekt zu sichern. % \ToDo{Kernel stellt mittlerweiele \cs{NewCommandCopy} bereit}[v2.07] % \begin{macrocode} \newcommand*\tud@cs@letltx[2]{% \expandafter\expandafter\expandafter\LetLtxMacro% \expandafter\csname #1\expandafter\endcsname\csname #2\endcsname% } % \end{macrocode} % Mit dem Aufruf \cs{tud@cs@store}\marg{Befehlsname} wird der im Argument % angegebene Befehl in einem neuem Makro |\@@tud@|\meta{Befehlsname} % gespeichert. Dieser kann danach beliebig angepasst werden. Soll der Befehl zu % einem späteren Zeitpunkt auf den Orginalzustand zurücksetzen, kann hierfür % jederzeit der Befehl \cs{tud@cs@reset}\marg{Befehlsname} verwendet werden. % Durch das Makro \cs{tud@cs@restore}\marg{Befehlsname} wird das mit % \cs{tud@cs@store} erstellte Hilfsmakro zusätzlich noch gelöscht. Der % ursprüngliche Befehl kann als solcher mit \cs{tud@cs@use}\marg{Befehlsname} % weiterhin genutzt werden. Ein zuvor bereits gesicherter Befehl kann mit % \cs{tud@cs@update}\marg{Befehlsname} auf die momentane Definition % aktualisiert werden. % \begin{macrocode} \newrobustcmd*\tud@cs@store[1]{% \tud@cs@check{#1}{% \ifcsdef{@@tud@#1}{}{% \tud@cs@letltx{@@tud@#1}{#1}% }% }% } \newrobustcmd*\tud@cs@restore[1]{% % \end{macrocode} % Sollte ein zuvor gesichertes Makro mit \cs{undef} oder \cs{csundef} % zwischenzeitlich \emph{undefiniert} gesetzt worden sein, wird das originäre % Makro dennoch wiederhergestellt. Hierfür wird es zu \cs{relax} gesetzt, damit % die Überprüfung mit \cs{tud@cs@check} keinen Fehler erzeugt. % \begin{macrocode} \ifcsdef{#1}{}{% \ifcsdef{@@tud@#1}{% \cslet{#1}{\relax}% }{}% }% % \end{macrocode} % Die eigentliche Wiederherstellung. % \begin{macrocode} \tud@cs@check{#1}{% \ifcsdef{@@tud@#1}{% \tud@cs@letltx{#1}{@@tud@#1}% \csundef{@@tud@#1}% }{}% }% } \newrobustcmd*\tud@cs@reset[1]{% \tud@cs@check{#1}{% \ifcsdef{@@tud@#1}{% \tud@cs@letltx{#1}{@@tud@#1}% }{}% }% } \newrobustcmd*\tud@cs@update[1]{% \tud@cs@check{#1}{% \ifcsdef{@@tud@#1}{% \tud@cs@letltx{@@tud@#1}{#1}% }{}% }% } \newrobustcmd*\tud@cs@use[1]{% \tud@cs@check{#1}{% \ifcsdef{@@tud@#1}{% \csuse{@@tud@#1}% }{% \csuse{#1}% }% }% } % \end{macrocode} % Dieses Makro dient zum Überprüfen, ob der zu sichernde beziehungsweise % wiederherzustellende Befehl überhaupt definiert ist. Sollte das nicht der % Fall sein, wird ein Fehler ausgegeben. % \begin{macrocode} \newrobustcmd*\tud@cs@check[1]{% \begingroup% \ifcsdef{#1}{\@tud@res@swatrue}{\@tud@res@swafalse}% \if@tud@res@swa% \ifcscounter{#1}{\@tud@res@swafalse}{}% \ifcslength{#1}{\@tud@res@swafalse}{}% \ifcsdimen{#1}{\@tud@res@swafalse}{}% \fi% \if@tud@res@swa% \aftergroup\@firstofone% \else% \PackageError{tudscrbase}{`\@backslashchar#1' is not a defined macro}{% The macro `\@backslashchar#1' was never defined. \MessageBreak% Please contact the TUD-Script maintainer\MessageBreak% via \TUDScriptContact. A bugfix is urgently required.% }% \aftergroup\@gobble% \fi% \endgroup% } % \end{macrocode} % \end{macro}^^A \tud@cs@check % \end{macro}^^A \tud@cs@use % \end{macro}^^A \tud@cs@update % \end{macro}^^A \tud@cs@reset % \end{macro}^^A \tud@cs@restore % \end{macro}^^A \tud@cs@store % \end{macro}^^A \tud@cs@letltx % \begin{macro}{\tud@cslength@store} % \changes{v2.04}{2015/03/02}{neu}^^A % \changes{v2.05}{2016/07/13}{Verwendung von \cs{tud@cslength@check}}^^A % \begin{macro}{\tud@cslength@restore} % \changes{v2.04}{2015/03/02}{neu}^^A % \changes{v2.05}{2016/07/13}{Verwendung von \cs{tud@cslength@check}}^^A % \begin{macro}{\tud@cslength@reset} % \changes{v2.05}{2016/07/13}{neu}^^A % \begin{macro}{\tud@cslength@check} % \changes{v2.05}{2016/07/13}{neu}^^A % Hiermit können~-- äquivalent zum Sichern und Wiederherstellen von Befehlen~-- % Längenregister abgespeichert werden. % \begin{macrocode} \newcommand*\tud@cslength@store[1]{% \tud@cslength@check{#1}{% \ifcsundef{@@tud@length@#1}{% \csedef{@@tud@length@#1}{\expandafter\the\csname #1\endcsname}% }{}% }% } \newcommand*\tud@cslength@restore[1]{% \tud@cslength@check{#1}{% \ifcsundef{@@tud@length@#1}{}{% \expandafter\setlength\csname #1\endcsname{% \csname @@tud@length@#1\endcsname% }% \csundef{@@tud@length@#1}% }% }% } \newcommand*\tud@cslength@reset[1]{% \tud@cslength@check{#1}{% \ifcsundef{@@tud@length@#1}{}{% \expandafter\setlength\csname #1\endcsname{% \csname @@tud@length@#1\endcsname% }% }% }% } \newcommand*\tud@cslength@check[1]{% \expandafter\tud@if@lengthregister\expandafter{\csname #1\endcsname}{% \expandafter\@firstofone% }{% \PackageError{tudscrbase}{`\@backslashchar#1' is not a defined length}{% The length `\@backslashchar#1' was never defined. \MessageBreak% Please contact the TUD-Script maintainer\MessageBreak% via \TUDScriptContact. A bugfix is urgently required.% }% \expandafter\@gobble% }% } % \end{macrocode} % \end{macro}^^A \tud@cslength@check % \end{macro}^^A \tud@cslength@reset % \end{macro}^^A \tud@cslength@restore % \end{macro}^^A \tud@cslength@store % \begin{macro}{\tud@patch@wrn} % \TUDScript verwendet die Möglichkeiten von \pkg{etoolbox} und \pkg{xpatch}, % um mit den Makros (\cs{[x]apptocmd}, \cs{[x]pretocmd}, \cs{[x]patchcmd}) % bereits definierte Befehle anzupassen. Falls dies nicht gelingt, wird eine % Warnung ausgegeben, die hier definiert wird. % \ToDo{generelle Schnittstelle schaffen und failure hier behandeln}[v2.07] % \begin{macrocode} \newcommand*\tud@patch@wrn[1]{% \PackageWarning{tudscrbase}{% It wasn't possible to patch `\@backslashchar#1'\MessageBreak% Please contact the TUD-Script maintainer\MessageBreak% via \TUDScriptContact. Without a bugfix an\MessageBreak% erroneous output may occur% }% } % \end{macrocode} % \end{macro}^^A \tud@patch@wrn % % \subsection{Schlüsseldefinitionen für \TUDScript} % % In Anlehnung an \KOMAScript{} werden hier Befehle zur Definition und % Ausführung unterschiedlicher Klassenoptionen mithilfe der Funktionen aus % dem \pkg{scrbase}-Paket erstellt. % % \begin{macro}{\TUDProcessOptions} % \begin{macro}{\TUDExecuteOptions} % \begin{macro}{\TUDoptions} % \begin{macro}{\TUDoption} % Zuerst ein paar Makros zur einfacheren Verwendung. % \begin{macrocode} \DefineFamily{TUD} \newcommand*\TUDProcessOptions[1][.\@currname.\@currext]{% \FamilyProcessOptions[{#1}]{TUD}% } \newcommand*\TUDExecuteOptions[1][.\@currname.\@currext]{% \FamilyExecuteOptions[{#1}]{TUD}% } \newcommand*\TUDoptions{\FamilyOptions{TUD}} \newcommand*\TUDoption{\FamilyOption{TUD}} % \end{macrocode} % \end{macro}^^A \TUDoption % \end{macro}^^A \TUDoptions % \end{macro}^^A \TUDExecuteOptions % \end{macro}^^A \TUDProcessOptions % % \subsubsection{Optionsdefinitionen} % % \begin{macro}{\TUD@key} % \begin{macro}{\TUD@key@define} % \changes{v2.06}{2018/07/19}{neu}^^A % \begin{macro}{\TUD@key@@define} % \changes{v2.06}{2018/07/19}{neu}^^A % \begin{macro}{\TUD@key@preset} % \changes{v2.06}{2018/07/19}{neu}^^A % Dies ist der zentrale Befehl zur Definition von Optionen, welcher die von % \KOMAScript{} Schnittstelle \cs{DefineFamilyKey} nutzt. % % Da sich die Klassenoptionen teilweise selbst gegenseitig beeinflussen oder % aber in bestimmten Fällen eine Option in Abhängigkeit von einer anderen % unterschiedliche Standardwerte annehmen soll, wird dafür eine Möglichkeit % geschaffen. Hierfür wird für jede Option ein korrelierende Schalter % |\if@tud@key@|\meta{Schlüssel}|@set| definiert. Dieser wird auf \val{true} % gesetzt, sobald der Schlüssel explizit gesetzt wurde, womit ein Standardwert % einer Klassenoption überschrieben werden kann. Das Setzen der Standardwerte % erfolgt intern mit dem Befehl \cs{TUD@key@preset}. % \begin{macrocode} \newcommand*\TUD@key[2][.\@currname.\@currext]{% % \end{macrocode} % Basierend auf dem Namen des Schalters wird die notwendige, boolesche Variable % erzeugt (|\if@tud@key@|\meta{Schlüssel}|@set|), welche im Falle des direkten % Aufrufs des Schlüssels, ein Überschreiben mit einem Standardwert verhindert. % \begin{macrocode} \providebool{@tud@key@#2@set}% \DefineFamilyMember[{#1}]{TUD}% \kernel@ifnextchar[%] {\TUD@key@define{#1}{#2}}% {\TUD@key@@define{#1}{#2}}% } \newcommand*\TUD@key@define{} \def\TUD@key@define#1#2[#3]#4{% \DefineFamilyKey[{#1}]{TUD}{#2}[{#3}]{% #4% \ifx\FamilyKeyState\FamilyKeyStateProcessed% \booltrue{@tud@key@#2@set}% \fi% }% } \newcommand*\TUD@key@@define{} \def\TUD@key@@define#1#2#3{% \DefineFamilyKey[{#1}]{TUD}{#2}{% #3% \ifx\FamilyKeyState\FamilyKeyStateProcessed% \booltrue{@tud@key@#2@set}% \fi% }% } % \end{macrocode} % Es kann intern über |\if@tud@key@|\meta{Schlüssel}|@set| geprüft werden, ob % einem Schlüssel ein explizites Wert zugewiesen wurde. Sollte dies nicht der % Fall sein, kann dieser hiermit intern beliebig angepasst werden. Da es durch % das Setzen der Option mit \cs{TUDoption} zu einer Sperrung kommt, muss diese % folgend wieder rückgängig gemacht werden. % \begin{macrocode} \newcommand*\TUD@key@preset[2]{% \ifbool{@tud@key@#1@set}{}{% \TUDoption{#1}{#2}% \boolfalse{@tud@key@#1@set}% }% } % \end{macrocode} % \end{macro}^^A \TUD@key@preset % \end{macro}^^A \TUD@key@@define % \end{macro}^^A \TUD@key@define % \end{macro}^^A \TUD@key % % Die folgenden Befehle dienen zum Verarbeiten der Optionen, wobei prinzipiell % auch eine freie Definition mit anschließender Abarbeitung ohne diese möglich % ist. % % \begin{macro}{\TUD@set@ifkey} % \changes{v2.06}{2018/08/01}{forcierte Kleinschreibung Schlüsselwerte}^^A % Hiermit wird der Option ein einfacher Schalterwert zugewiesen. % \begin{macrocode} \newcommand*\TUD@set@ifkey[3]{% \begingroup% \tud@strlowercase\tud@res@a{#3}% \edef\tud@res@a{% \endgroup% \unexpanded{\FamilySetBool{TUD}{#1}{#2}}{\tud@res@a}% }% \tud@res@a% } % \end{macrocode} % \end{macro}^^A \TUD@set@ifkey % \begin{macro}{\TUD@set@numkey} % \changes{v2.02}{2014/11/05}{neu}^^A % \changes{v2.06}{2018/08/01}{forcierte Kleinschreibung Schlüsselwerte}^^A % \begin{macro}{\TUD@bool@numkey} % \changes{v2.03}{2015/01/09}{neu}^^A % Hiermit werden für eine Option mehrere mögliche Werte definiert. % \begin{macrocode} \newcommand*\TUD@set@numkey[4]{% \begingroup% \tud@strlowercase\tud@res@a{#4}% \edef\tud@res@a{% \endgroup% \unexpanded{\FamilySetNumerical{TUD}{#1}{#2}{#3}}{\tud@res@a}% }% \tud@res@a% } % \end{macrocode} % Um Dopplungen im Code zu vermeiden, werden für die numerische Schlüssel die % booleschen Standardwertzuweisungen in einem Makro gespeichert. % \begin{macrocode} \newcommand*\TUD@bool@numkey{% {false}{0},{off}{0},{no}{0},{true}{1},{on}{1},{yes}{1}% } % \end{macrocode} % \end{macro}^^A \TUD@bool@numkey % \end{macro}^^A \TUD@set@numkey % \begin{macro}{\TUD@set@gluekey} % \changes{v2.06o}{2022/08/01}{neu}^^A % \begin{macro}{\tud@normalize@gluekey} % \changes{v2.06o}{2022/08/01}{neu}^^A % \begin{macro}{\tud@normalize@@gluekey} % \changes{v2.06o}{2022/08/01}{neu}^^A % \begin{macro}{\tud@validate@gluekey} % \changes{v2.06o}{2022/08/01}{neu}^^A % Mit \cs{TUD@set@gluekey} und \cs{TUD@set@dimkey} wird der übergebene Wert % entweder als Skip (Länge mit Kleister) oder Dimension (Länge ohne Kleister) % im spezifizierten Makro gespeichert, wobei auf eine gültige Eingabe geprüft % wird. % % Wurde ein Argument übergeben, dass in einen String expandiert, ist einiger % Aufwand notwendig, da das zugrunde liegende \cs{FamilySetLength} einen Fehler % wirft, wenn eine Längenangabe mit falscher Einheit übergeben wird. Das % optionale Argument gibt die gewünschte Längeneinheit an, falls diese im % Argument nicht spezifiert wurde. % \begin{macrocode} \newcommand*\TUD@set@gluekey[4][pt]{% \begingroup% \tud@strlowercase\tud@res@a{#4}% % \end{macrocode} % Es wird geprüft, ob das Argument zu einem String expandiert. Ist dies der % Fall, wird die vermeintliche Längenangabe mit \cs{tud@normalize@gluekey} % normalisiert, wobei das Resultat in das Makro im ersten Argument des Befehls % zurückgeschrieben wird. Sollte das Normalisieren nicht gelingen, wird ein % leerer Wert zurückgegeben. % \begin{macrocode} \edef\tud@res@b{\detokenize\expandafter{\tud@res@a}}% \edef\tud@res@c{\detokenize\expandafter{\@backslashchar}}% \@expandtwoargs\in@{\tud@res@c}{\tud@res@b}% \ifin@\else% \tud@normalize@gluekey\tud@res@a{#1}% \fi% % \end{macrocode} % Konnte eine Längenangabe interpretiert werden, wird für ein falsch % formatiertes Argument mit \cs{tud@validate@gluekey} ggf. eine Warnung % ausgegeben und anschließend der gültige Wert gesetzt. % \begin{macrocode} \protected@edef\tud@res@a{% \endgroup% \ifx\tud@res@a\@empty% \noexpand\FamilyKeyStateUnknownValue% \else% \unexpanded{\tud@validate@gluekey{#2}}{\tud@res@a}{#4}% \unexpanded{\FamilySetUseLengthMacro{TUD}{#2}{#3}}{\tud@res@a}% \fi% }% \tud@res@a% } % \end{macrocode} % Das Makro \cs{tud@normalize@gluekey} erhält im ersten Argument den zu % interpretierenden String und im zweiten die ggf. zu setzende Einheit. Dieser % String wird in den Basiswert und möglichen Kleister aufgetrennt, wobei % hierbei auch eine vertauschte und eigentlich fehlerhafte Angabe von Kleister % in der Form |... minus ... plus ...| verarbeitet wird. % \begin{macrocode} \newcommand*\tud@normalize@gluekey[2]{% \begingroup% \edef\tud@res@c{#1}% \def\tud@res@a##1plus##2plus##3\@nil{% \let\tud@res@a\@empty% \tud@res@b##1minusminus\@nil% \tud@res@b##2minusminus\@nil% }% % \end{macrocode} % Die vier Token \marg{Grundwert}\marg{negativ}\marg{positiv}\marg{negativ} % werden in \cs{tud@res@a} geschrieben, wobei der zweite Token mit negativem % Kleister gesetzt ist, falls dieser \emph{vor} dem positiven angegeben wurde. % \begin{macrocode} \def\tud@res@b##1minus##2minus##3\@nil{% \eappto\tud@res@a{{\trim@spaces{##1}}{\trim@spaces{##2}}}% }% \expandafter\tud@res@a\tud@res@c plusplus\@nil% % \end{macrocode} % Hier wird dementsprechend \cs{tud@res@a} auf drei Token reduziert und so % definiert, dass auf den Grundwert erst der positive und danach der negative % Kleister folgt. % \begin{macrocode} \def\tud@res@b##1##2##3##4{% \IfArgIsEmpty{##2}{% \def\tud@res@a{{##1}{##3}{##4}}% }{% \def\tud@res@a{{##1}{##3}{##2}}% }% }% \expandafter\tud@res@b\tud@res@a% % \end{macrocode} % Jeder der drei Token wird nun mit \cs{tud@normalize@@gluekey} geprüft, ob % es sich tatsächlich um eine Dimensionsangabe oder zumindest einen Zahlenwert % handelt. Für letzteren Fall wird die übergebene Einheit angehangen. Kann ein % Token nicht als Dimensionsangabe interpretiert werden~-- das übergebene Makro % wird zu \cs{relax} gesetzt~-- wird der Prozess abgebrochen. % \begin{macrocode} \edef\tud@res@b{% \unexpanded{\@tfor\tud@res@b:=}\tud@res@a% }% \let\tud@res@c\@empty% \@tud@res@swatrue% \tud@res@b\do{% \tud@normalize@@gluekey\tud@res@a{\tud@res@b}{#2}% \ifx\tud@res@a\relax% \@tud@res@swafalse% \@break@tfor% \else% \eappto\tud@res@c{{\tud@res@a}}% \fi% }% % \end{macrocode} % Nach dem Durchlauf enthält \cs{tud@res@c} alle drei zuvor extrahierten Token, % die ggf. um eine Einheit ergänzt wurden, falls diese gegeben waren. Der erste % Token erhält folgend eine Sonderbehandlung. Wenn dieser leer ist, wird er auf % alle Fälle gesetzt, da es sonst zu Problemen bei der Wertzuweisung an ein % Längenregister gibt. % \begin{macrocode} \let\tud@res@a\@empty% \if@tud@res@swa% \def\tud@res@b##1##2##3{% \IfArgIsEmpty{##1}{\def\tud@res@b{0#2}}{\def\tud@res@b{##1}}% \Ifdimen{\tud@res@b}{% \edef\tud@res@a{% \tud@res@b% \IfArgIsEmpty{##2}{}{\space\@plus\space##2}% \IfArgIsEmpty{##3}{}{\space\@minus\space##3}% }% }{}% }% \expandafter\tud@res@b\tud@res@c% \fi% \edef\tud@res@c{% \endgroup% \unexpanded{\def#1}{\tud@res@a}% }% \tud@res@c% } % \end{macrocode} % Diese Makro behandelt die einzelnen extrahierten Token. Dabei müssen zuerst % die Vorzeichen beachtet werden, welches erst in \cs{tud@res@b} gesichert und % anschließend von \cs{tud@res@a} entfernt wird. % \begin{macrocode} \newcommand*\tud@normalize@@gluekey[3]{% \begingroup% \edef\tud@res@a{#2}% \@tud@res@swafalse% \expandafter\if\expandafter\@car\tud@res@a\relax\@nil+\@tud@res@swatrue\fi% \expandafter\if\expandafter\@car\tud@res@a\relax\@nil-\@tud@res@swatrue\fi% \if@tud@res@swa% \protected@edef\tud@res@b{\expandafter\@car\tud@res@a\relax\@nil}% \protected@edef\tud@res@a{\expandafter\@gobble\tud@res@a}% \else% \let\tud@res@b\@empty% \fi% % \end{macrocode} % Danach wird mit \cs{Ifdimen} geprüft, ob die Angabe tatsächlich eine Länge % ist. Hier kommt zum Tragen, das \cs{Ifdimen} auch wahr ist, wenn lediglich % eine gültige Einheit ohne Maßzahl (\cs{Ifdimen}|{pt}|) angegeben wird. % Für Werte ohne Dimensionsangabe wird gegebenenfalls einfach das optionale % Argument als intendierte angenommen. Sollte es sich bei dem Argument nicht um % einen String sondern um eine \TeX"~Primitive oder ein geschütztes Makro % handeln, wird kein \val{true}-Zweig durchlaufen. % \begin{macrocode} \@tud@res@swatrue% \Ifdimen{\tud@res@a}{}{% \Ifdimen{\tud@res@a#3}{% \appto\tud@res@a{#3}% }{% \@tud@res@swafalse% }% }% % \end{macrocode} % Wertangaben ohne Betrag werden ignoriert. % \begin{macrocode} \if@tud@res@swa% \Ifisdimension{\tud@res@a}{}{% \let\tud@res@a\@empty% \let\tud@res@b\@empty% }% \else% % \end{macrocode} % Sollte keine gültige Dimension angegeben worden sein, wird nun geprüft, ob es % sich um eine dehnbare Länge handelt. Diese \emph{muss} mit einer Maßzahl % genutzt werden. Fehlt diese, wird \val{1} angenommen. Außerdem ist zu % beachten, dass es insgesamt drei Abstufungen der dehnbaren Ausdrücke % existieren. % \begin{macrocode} \def\tud@res@c##1fil##2fil##3\@nil{% \IfArgIsEmpty{##1}{\def\tud@res@a{1}}{\def\tud@res@a{##1}}% \Ifdimen{\tud@res@a pt}{\@tud@res@swatrue}{\@tud@res@swafalse}% \if@tud@res@swa% \appto\tud@res@a{fil##2}% \tud@if@strequal{##2}{}{}{% \tud@if@strequal{##2}{l}{}{% \tud@if@strequal{##2}{ll}{}{\@tud@res@swafalse}% }% }% \fi% }% \expandafter\tud@res@c\tud@res@a filfil\@nil% \fi% % \end{macrocode} % Das Vorzeichen nicht vergessen! % \begin{macrocode} \edef\tud@res@c{% \endgroup% \if@tud@res@swa% \unexpanded{\def#1}{\tud@res@b\tud@res@a}% \else% \unexpanded{\let#1\relax}% \fi% }% \tud@res@c% } % \end{macrocode} % Mit diesem Makro wird ganz am Ende des Interpretationsprozesses das Ergebnis % mit dem angegbenen Argument verglichen und eine Warnung erzeugt, falls die % Formatierung des Argumentes es notwendig machte, dieses zu interpretieren. % \begin{macrocode} \newcommand*\tud@validate@gluekey[3]{% \begingroup% % \end{macrocode} % Unterschiede bei Leerzeichen sollen keine Warnung erzeugen. % \begin{macrocode} \protected@edef\tud@res@a{#2}% \protected@edef\tud@res@b{#3}% \tud@remove@spaces@within\tud@res@a% \tud@remove@spaces@within\tud@res@b% \ifx\tud@res@a\tud@res@b% \aftergroup\@gobble% \else% \aftergroup\@firstofone% \fi% \endgroup{% \PackageWarning{tudscrbase}{% The length `#3'\MessageBreak% seems to be wrong formatted. Assuming, you meant\MessageBreak% `#1=#2'% }% }% } % \end{macrocode} % \end{macro}^^A \tud@validate@gluekey % \end{macro}^^A \tud@normalize@@gluekey % \end{macro}^^A \tud@normalize@gluekey % \end{macro}^^A \TUD@set@gluekey % \begin{macro}{\TUD@set@dimkey} % \changes{v2.05}{2016/06/15}{neu}^^A % \changes{v2.06}{2018/08/01}{forcierte Kleinschreibung Schlüsselwerte}^^A % Zur Angabe von Dimensionen wird auf \cs{TUD@set@gluekey} zurückgegriffen % und anschließend geprüft, ob das Argument für \cs{dimen} genutzt werden kann. % \begin{macrocode} \newcommand*\TUD@set@dimkey[4][pt]{% \begingroup% \TUD@set@gluekey[{#1}]{#2}{\tud@res@a}{#4}% \ifx\FamilyKeyState\FamilyKeyStateProcessed% % \end{macrocode} % Das Ergebnis der Wertzuweisung an \cs{TUD@set@gluekey} wurde im Makro % \cs{tud@res@a} gespeichert. Handelt es sich beim Argument um ein % \cs{skip}"~Register oder eine \cs{glueexpr}, kann nicht sichergestellt % werden, dass diesem später doch noch Kleister hinzugefügt wird, weshalb diese % nicht akzeptiert werden. % \begin{macrocode} \@tud@res@swafalse% \Ifisskip{\tud@res@a}{% \protected@edef\tud@res@a{\dimexpr\tud@res@a\relax}% \def\tud@res@b{a \string\skip\space register}% \@tud@res@swatrue% }{% \Ifisglueexpr{\tud@res@a}{% \protected@edef\tud@res@a{\dimexpr\tud@res@a\relax}% \def\tud@res@b{a glue expression}% \@tud@res@swatrue% }{% % \end{macrocode} % Ebenso wird direkt angegebener Kleister entfernt. Nicht über das Konstrukt % mit \cs{@tempdima} und \cs{glueexpr} wundern. Ohne das Paket \pkg{calc} ist % die Zuweisung von Kleister als String an ein \cs{dimen}-Register nicht ohne % weiteres möglich. Die Verwendung \cs{glueexpr} dient quasi als Umschlag. % \begin{macrocode} \Ifisglue{\tud@res@a}{% \Ifisdimension{\tud@res@a}{}{% \setlength\@tempdima{\dimexpr\glueexpr\tud@res@a\relax\relax}% \tud@strlength\tud@res@a{\@tempdima}% \def\tud@res@b{something containing glue}% \@tud@res@swatrue% }% }{}% }% }% % \end{macrocode} % Sollte einer der zuvor beschriebenen Fälle aufgetreten sein, wird eine % Warnung ausgegeben. % \begin{macrocode} \if@tud@res@swa% \PackageWarning{tudscrbase}{% Using option `#2' with\MessageBreak% \tud@res@b\space(#4)\MessageBreak% is not recommended. You should consider to use\MessageBreak% an expression for a dimen instead. Setting\MessageBreak% `#2=\tud@res@a'% }% \fi% \protected@edef\tud@res@a{% \endgroup% \unexpanded{\FamilySetUseLengthMacro{TUD}{#2}{#3}}{\tud@res@a}% }% \else% \def\tud@res@a{\endgroup\FamilyKeyStateUnknownValue}% \fi% \tud@res@a% } % \end{macrocode} % \end{macro}^^A \TUD@set@dimkey % \begin{macro}{\TUD@unknown@keyval} % Dieser Befehl wird lediglich pro forma definiert. An diesen kann eine Liste % möglicher Wertzuweisungen übergeben werden, welche durch \KOMAScript{} % derzeit jedoch nicht abgearbeitet und ausgegeben wird. % \begin{macrocode} \newcommand*\TUD@unknown@keyval{\FamilyUnknownKeyValue{TUD}} % \end{macrocode} % \end{macro}^^A \TUD@unknown@keyval % % \subsubsection{Voreinstellungen für abhängige Optionen} % % \begin{macro}{\tud@locked@newnum} % \begin{macro}{\tud@locked@num@preset} % \begin{macro}{\tud@locked@num@set} % Mit \cs{tud@locked@newnum}\marg{Name}\marg{Definition} lässt sich ein Makro % definieren, für das mit \cs{tud@locked@num@preset}\marg{Name}\marg{Definition} % eine Voreinstellung definiert werden kann, solange der Wert nicht mit % \cs{tud@locked@num@set}\marg{Name}\marg{Definition} explizit überschrieben % wurde. Damit ist es möglich, Voreinstellungen abhängig von anderen Optionen % zu realisieren. % \begin{macrocode} \newcommand*\tud@locked@newnum[2]{% \expandafter\newcommand\expandafter*\csname #1\endcsname{#2}% \newbool{#1@locked}% \tud@num@set{#1}{#2}% } \newcommand*\tud@locked@num@preset[2]{% \ifbool{#1@locked}{}{% \tud@num@set{#1}{#2}% \boolfalse{#1@locked}% }% } \newcommand*\tud@locked@num@set[2]{% \tud@num@set{#1}{#2}% \booltrue{#1@locked}% } \newcommand*\tud@num@set[2]{% \ifcsundef{#1}{% \PackageError{tudscrbase}{% `\@backslashchar#1' was never defined% }{% You tried using the numerical expression `\@backslashchar#1'\MessageBreak% but you didn't define it with `\string\tud@locked@newnum'.% }% }{% \Ifnumber{#2}{% \csdef{#1}{#2}% }{% \PackageError{tudscrbase}{% `#2' is not a valid numerical expression% }{% You set the numerical expression `\@backslashchar#1'\MessageBreak% to value `#2', which isn't numerical.% }% }% }% } % \end{macrocode} % \end{macro}^^A \tud@locked@num@set % \end{macro}^^A \tud@locked@num@preset % \end{macro}^^A \tud@locked@newnum % \begin{macro}{\tud@locked@newbool} % \begin{macro}{\tud@locked@bool@preset} % \begin{macro}{\tud@locked@bool@set} % \begin{macro}{\tud@bool@set} % \changes{v2.05}{2015/07/03}{neu}^^A % Diese Makros dienen in Anlehnung an die vorherigen zum Definieren und Setzen % von sperrbaren booleschen Schaltern. Dabei wird \cs{tud@bool@set} definiert, % um nicht nur \val{true} und \val{false} sondern auch alle anderen bekannten % booleschen Zuweisungen (\val{yes} und \val{on} sowie \val{no} und \val{off}) % mit diesen Befehlen verwenden zu können. % \begin{macrocode} \newcommand*\tud@locked@newbool[2][false]{% \newbool{#2}% \newbool{#2@locked}% \tud@bool@set{#2}{#1}% } \newcommand*\tud@locked@bool@preset[2]{% \ifbool{#1@locked}{}{% \tud@bool@set{#1}{#2}% \boolfalse{#1@locked}% }% } \newcommand*\tud@locked@bool@set[2]{% \tud@bool@set{#1}{#2}% \booltrue{#1@locked}% } \newcommand*\tud@bool@set[2]{% \tud@if@strbool{#2}{\booltrue{#1}}{\boolfalse{#1}}{% \PackageError{tudscrbase}{% `#2' is not a valid boolean expression% }{% You tried to set the boolean switch `\@backslashchar if#1'\MessageBreak% to value `#2' but only `true' `on' and `yes' as well as \MessageBreak% `false' `no' and `off' are valid values.% }% }% } % \end{macrocode} % \end{macro}^^A \tud@bool@set % \end{macro}^^A \tud@locked@bool@set % \end{macro}^^A \tud@locked@bool@preset % \end{macro}^^A \tud@locked@newbool % % \subsubsection{Parameterdefinitionen} % % \begin{macro}{\TUD@parameter@family} % \begin{macro}{\TUD@parameter@@family} % \begin{macro}{\TUD@parameter@checkfamily} % Mit \cs{TUD@parameter@family}\marg{Familienname}\marg{Definitionen} können % für die optionalen Argumente von Befehlen Schlüssel-Wert-Parameter definiert % werden. Das erste Argument definiert den Familiennamen für den jeweiligen % Befehl, welcher eindeutig gewählt werden sollte. Dieser wird im Hilfsmakro % \cs{TUD@parameter@@family} gesichert. Dies soll im Zusammenspiel mit dem % Makro \cs{TUD@parameter@checkfamily} dafür sorgen, dass die im Folgenden % bereitgestellten Befehle \cs{TUD@parameter@def}, \cs{TUD@parameter@let} und % \cs{TUD@parameter@handler@macro}~-- welche die eigentliche Definition der % Parameter für den Benutzer bewerkstelligen~-- ohne die Angabe der Familie % nur innerhalb des zweiten Argumentes von \cs{TUD@parameter@family} verwendet % werden können. % \ToDo{ % Eine Katastrophe, dringend überarbeiten; generelle Lösung mit \cs{toks@}? % KOMA-Option \val{@else@} verwenden? % }[v2.07] % \begin{macrocode} \newcommand*\TUD@parameter@@family{} \newcommand*\TUD@parameter@family[2]{% \xdef\TUD@parameter@@family{#1}% #2% \gdef\TUD@parameter@@family{}% } % \end{macrocode} % Dieser Befehl prüft, ob eine Familie für den Paramter definiert wurde. % \begin{macrocode} \newcommand*\TUD@parameter@checkfamily[2]{% \tud@if@strblank{#1}{% \PackageError{tudscrbase}{% No family for \@backslashchar#2 defined% }{% You have to use \@backslashchar#2\space within the\MessageBreak% second argument of \string\TUD@parameter@family. The first\MessageBreak% argument of \string\TUD@parameter@family\space has to be\MessageBreak% a unique family name. Alternatively, you can specify\MessageBreak% the family name within the optional argument of\MessageBreak% \@backslashchar#2.% }% }{}% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@checkfamily % \end{macro}^^A \TUD@parameter@@family % \end{macro}^^A \TUD@parameter@family % \begin{macro}{\TUD@parameter@def} % \begin{macro}{\TUD@parameter@let} % \changes{v2.02}{2014/07/25}{Beachtung der gegebenen Standardwerte}^^A % \cs{TUD@parameter@def}\marg{Name}\oarg{Säumniswert}\marg{Verarbeitung} nutzt % \cs{define@key} aus dem \pkg{keyval}-Paket, um einen Schlüssel und dessen % Verarbeitung zu definieren, wobei auf den zugewiesenen Wert innerhalb des % zweiten obligatorischen Argumentes mit |#1| zugegriffen werden kann. % \begin{macrocode} \newcommand*\TUD@parameter@def[1][\TUD@parameter@@family]{% \TUD@parameter@checkfamily{#1}{TUD@parameter@def}% \expandafter\define@key\expandafter{#1}% } % \end{macrocode} % Mit \cs{TUD@parameter@let}\marg{Name}\marg{Name} kann äquivalent zur % \mbox{\TeX-Primitive \cs{let}} die Definition der Verarbeitung eines % Parameters auf einen weiteren übertragen werden. % \begin{macrocode} \newcommand*\TUD@parameter@let[3][\TUD@parameter@@family]{% \TUD@parameter@checkfamily{#1}{TUD@parameter@let}% \@expandtwoargs{\csletcs}{KV@#1@#2}{KV@#1@#3}% \@expandtwoargs{\csletcs}{KV@#1@#2@default}{KV@#1@#3@default}% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@let % \end{macro}^^A \TUD@parameter@def % \begin{macro}{\TUD@parameter@set} % \changes{v2.05}{2016/05/26}{robustere Verarbeitung von Default-Argumenten}^^A % \begin{macro}{\TUD@parameter@nokey} % \changes{v2.05}{2016/05/26}{neu}^^A % Mit \cs{TUD@parameter@set}\marg{Familienname}\marg{Parameterliste} wird die % Verarbeitung aller gegebenen Parameter veranlasst. Normalerweise wird dieser % Befehl \emph{nicht} innerhalb des Argumentes von \cs{TUD@parameter@family} % verwendet. In jedem Fall muss die zu verwendende Familie angegeben werden. % \begin{macrocode} \newcommand*\TUD@parameter@nokey{@nokey@} \newcommand*\TUD@parameter@set[2]{% \IfArgIsEmpty{#2}{}{% % \end{macrocode} % Hierfür wird die angegebene Parameterliste sukzessive abgearbeitet. Elemente, % welche in Schlüssel-Wert-Syntax angegeben wurden, bleiben unverändert\dots % \begin{macrocode} \let\@tempb\@empty% \def\@tempa##1{% \@expandtwoargs\in@{=}{##1}% \ifin@% \appto\@tempb{##1,}% \else% % \end{macrocode} % \dots ebenso wie Schlüssel ohne Wert, falls diese definiert wurden. Zu % beachten ist, dass es mit \cs{TUD@parameter@handler@value} respektive % \cs{TUD@parameter@handler@default} auch möglich ist, für einen mit einem der % beiden Makros gewählten Schlüssel, lediglich den passenden Wert anzugeben. % Dies wird genutzt, um optionale Argumente direkt für den Hauptparameter eines % Makros oder einer Umgebung~-- wie beispielsweise für eine Überschrift~-- % nutzen zu können, aber zusätzlich die Möglichkeit zu bieten, auch eine % Parameterliste zu verwenden. Hierfür werden Umlaute sowie das \enquote*{ß} % unschädlich gemacht. % \begin{macrocode} \begingroup% \let\IeC\@firstofone% \def\"####1{####1e}% \def\ss{ss}% \def\SS{SS}% \protected@edef\tud@reserved{% \endgroup% \noexpand\protected@edef\noexpand\@tempc{KV@#1@##1}% }% \tud@reserved% \ifcsdef{\@tempc}{% \appto\@tempb{##1,}% }{% \protected@eappto\@tempb{\TUD@parameter@nokey=##1,}% }% \fi% }% \forcsvlist\@tempa{#2}% \@expandtwoargs\kvsetkeys{#1}{\@tempb}% }% } % Ursprünglich entwickelte sich dieser Ansatz aus der Situation, dass das Makro % \cs{maketitle} in seiner Standarddefinition ein optionales Argument für eine % Seitenzahl bereithält, bei den \TUDScript-Klassen jedoch auch die Möglichkeit % besteht, verschiedene zusätzliche Parameter für diesen Befehl zu verwenden. % Um allerdings für den Anwender das gewohnte Vorgehen beibehalten zu können, % wurde diese Sonderbehandlung implementiert. % \end{macrocode} % \end{macro}^^A \TUD@parameter@nokey % \end{macro}^^A \TUD@parameter@set % \begin{macro}{\TUD@parameter@handler@macro} % \changes{v2.05}{2016/05/26}{robustere Verarbeitung von Default-Argumenten}^^A % Durch \cs{TUD@parameter@handler@macro} kann definiert werden, wie mit einem % zuvor nicht mit \cs{TUD@parameter@def} definiertem Parameter beziehungsweise % gewöhnlichem optionalen Argument umzugehen ist. Dabei wird unterschieden, ob % es sich bei dem unbekannten Parameter um ein normales optionales Argument % oder um eine Angabe in Schlüssel-Wert-Syntax handelt. Dabei wurden einfache % optionale Argumente zuvor durch \cs{TUD@parameter@set} dem Schlüssel % \cs{TUD@parameter@nokey} als Wert zugewiesen, um Umlaute etc. ohne Bedenken % verwenden zu können. % % Das erste obligatorische Argument von \cs{TUD@parameter@handler@macro} wird % für die Verarbeitung unbekannter Schlüssel-Wert-Paare genutzt, das zweite für % einfache optionale Argumente. % \ToDo{ % Eine Katastrophe, dringend überarbeiten; generelle Lösung mit \cs{toks@}? % KOMA-Option \val{@else@} verwenden? % }[v2.07] % \begin{macrocode} \newcommand*\TUD@parameter@handler@macro[3][\TUD@parameter@@family]{% \TUD@parameter@checkfamily{#1}{TUD@parameter@handler@macro}% \expandafter\kv@set@family@handler\expandafter{#1}{% \tud@if@strequal{\kv@key}{\TUD@parameter@nokey}{#3}{#2}% }% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@handler@macro % \begin{macro}{\TUD@parameter@handler@value} % \changes{v2.05}{2016/05/26}{neu}^^A % Mit diesem Makro wird einem optionalen Argument, welches ohne Schlüssel % angegeben wurde, ein expliziter Parameter zugewiesen, welcher damit gesetzt % wird. Unbekannte Schlüssel-Wert-Argumente werden durch \cs{kv@handled@false} % immer als Fehler zurückgemeldet. % \begin{macrocode} \newcommand*\TUD@parameter@handler@value[2][\TUD@parameter@@family]{% \TUD@parameter@checkfamily{#1}{TUD@parameter@handler@value}% \protected@edef\@tempa{% \noexpand\TUD@parameter@set{#1}{#2=\noexpand\kv@value}% }% \def\@tempb{\TUD@parameter@handler@macro[{#1}]{\kv@handled@false}}% \expandafter\@tempb\expandafter{\@tempa}% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@handler@value % \begin{macro}{\TUD@parameter@handler@default} % Hiermit kann sowohl die zu verwendende Sprache als auch die Anzahl der % gewünschten Spalten für bestimmte Umgebungen ohne die explizite Angabe eines % Schlüssels festgelegt werden. Momentan betrifft das die beiden Umgebungen % \env{abstract} und \env{tudpage} sowie Befehle und Umgebungen, welche auf % letzterer basieren. Unbekannte Argumente in Schlüssel-Wert-Syntax werden % nicht unterstützt. % \begin{macrocode} \newcommand*\TUD@parameter@handler@default[2][\TUD@parameter@@family]{% \TUD@parameter@checkfamily{#1}{TUD@parameter@handler@default}% \tud@if@strblank{#2}{% \def\@tempa{\let\tud@reserved\relax}% }{% \def\@tempa{\def\tud@reserved{#2=\kv@value}}% }% \appto\@tempa{% \tud@if@strequal{\kv@value}{twocolumn}{\def\kv@value{2}}{}% \Ifnumber{\kv@value}{\def\tud@reserved{columns=\kv@value}}{}% \iflanguageloaded{\kv@value}{\def\tud@reserved{language=\kv@value}}{}% \ifx\tud@reserved\relax% \tud@if@strblank{\kv@value}{}{% \PackageError{tudscrbase}{% Unknown default value `\kv@value'% }{% If `\kv@value' is a language, you haven't loaded it. \MessageBreak% Otherwise, there's no handler for the given value. \MessageBreak% You should specify a certian key (=\kv@value).% }% }% \fi% }% \protected@eappto\@tempa{% \noexpand\ifx\noexpand\tud@reserved\noexpand\relax\noexpand\else% \noexpand\TUD@parameter@set{#1}{\noexpand\tud@reserved}% \noexpand\fi% }% \def\@tempb{\TUD@parameter@handler@macro[{#1}]{\kv@handled@false}}% \expandafter\@tempb\expandafter{\@tempa}% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@handler@default % \begin{macro}{\TUD@parameter@err} % Das Makro \cs{TUD@parameter@err}\marg{Parameter}\marg{Werteliste} gibt für % den Fall einer ungültigen Wertzuweisung an einen bestimmten \meta{Parameter} % einen Fehler mit einem entsprechenden Hinweis auf gültige Werte innerhalb von % \meta{Werteliste} aus. % \begin{macrocode} \newcommand*\TUD@parameter@err[2]{% \PackageError{tudscrbase}{Unsupported value for parameter `#1'}{% `#1' can only be used with values:\MessageBreak#2% \MessageBreak Please choose a valid one.% }% } % \end{macrocode} % \end{macro}^^A \TUD@parameter@err % % \subsection{Ausführung von paketspezifischem Quellcode} % % Ab und an ist es notwendig, bestimmten Quelltext gezielt in Abhängigkeit vom % Ladezustand eines Paketes auszuführen. % \begin{macro}{\TUD@UnwindPackage} % \changes{v2.05}{2015/10/28}{neu}^^A % \changes{v2.06o}{2022/08/02}{Sternversion}^^A % Dieser Befehl dient zur Ausführung von Quelltext, falls ein Paket bis zum % Ende der Dokumentpräambel nicht geladen wurde. Im ersten obligatorischen % Argument wird das Paket angegeben, im zweiten der Quellcode. Die Sternversion % führt den Quellcode auch nach dem Laden des Paketes aus. % \begin{macrocode} \NewDocumentCommand\TUD@UnwindPackage{s m m}{% \IfBooleanT{#1}{\AfterPackage*{#2}{#3}}% \AtEndPreamble{\@ifpackageloaded{#2}{}{#3}}% } \@onlypreamble\TUD@UnwindPackage % \end{macrocode} % \end{macro}^^A \TUD@UnwindPackage % \begin{macro}{\TUD@CheckPackage} % \changes{v2.06}{2019/06/21}{neu}^^A % \begin{macro}{\tud@if@packagelater@exists} % \changes{v2.06}{2019/06/21}{neu}^^A % Mit \cs{TUD@CheckPackage} wird geprüft, ob ein Paket mindestens in der % angegebenen Version existiert. Sollte das Paket in einer früheren Version % existieren, wird eine Warnung ausgegeben. Dabei wird das Paket \emph{nicht} % geladen. Damit lässt sich sicherstellen, dass beispielsweise Schriftdateien % in einer bestimmten Version vorhanden sind, ohne diese durch das Paket selbst % zu laden. Ist das Paket gar nicht installiert, wird durch den Aufruf von % \cs{RequirePackage} ein Fehler erzeugt respektive MiKTeX zur automatischen % Nachinstallation animiert. % \ToDo{.aux schreiben, wenn existent und so ggf. nur einmalig ausführen}[v2.07] % \begin{macrocode} \newcommand*\TUD@CheckPackage[2]{% \tud@if@packagelater@exists{#1}{#2}{}{% \PackageWarningNoLine{tudscrbase}{% The version `#2' of package `#1'\MessageBreak% is urgently required. An erroneous output\MessageBreak% may occur. Please update your distribution% }% \IfFileExists{#1.sty}{}{\RequirePackage{#1}[#2]}% }% } \@onlypreamble\TUD@CheckPackage % \end{macrocode} % Hiermit wird geprüft, ob ein installiertes Paket in einer bestimmten Version % vorhanden ist, ohne dieses zu laden. Hierfür wird die Datei zeilenweise % gelesen, bis der Eintrag \cs{ProvidesPackage}\marg{Paketname}\oarg{Version} % gefunden wird. % \ToDo{kann \cs{@ifl@t@r} ersetzt werden?}[v2.07] % \ToDo{Name in \cs{IfPackageExistsAtLeastTF} ändern}[v2.07] % \begin{macrocode} \newcommand*\tud@if@packagelater@exists[2]{% \begingroup% \let\tud@res@a\@empty% \def\tud@res@b[##1]{\def\tud@res@a{##1}}% \def\ProvidesPackage##1{% \kernel@ifnextchar[%] {\tud@res@b}% {\tud@res@b[]}% }% \IfFileExists{#1.sty}{% \openin\@inputcheck=#1.sty% \@tud@res@swatrue% \loop% \read\@inputcheck to\tud@res@c% \@expandtwoargs\in@{\string\ProvidesPackage}% {\expandafter\detokenize\expandafter{\tud@res@c}}% \ifin@% \@tud@res@swafalse% \tud@res@c% \fi% \ifeof\@inputcheck\@tud@res@swafalse\fi% \if@tud@res@swa% \repeat% \closein\@inputcheck% }{}% \edef\tud@res@a{\endgroup\noexpand\@ifl@t@r{\tud@res@a}{#2}}% \tud@res@a% } \@onlypreamble\tud@if@packagelater@exists % \end{macrocode} % \end{macro}^^A \tud@if@packagelater@exists % \end{macro}^^A \TUD@CheckPackage % \begin{macro}{\TUD@RecommendPackage} % \changes{v2.06}{2018/07/12}{neu}^^A % \begin{macro}{\TUD@Recommend@Package} % Bestimmte Pakete sind für die Funktionalität von \TUDScript empfohlen, aber % nicht zwingend erforderlich. Sind diese nicht vorhanden, wird eine Warnung % ausgegeben. % \begin{macrocode} \newcommand*\TUD@RecommendPackage[1]{% \kernel@ifnextchar[%] {\TUD@Recommend@Package#1}% {\TUD@Recommend@Package#1[]}% } \@onlypreamble\TUD@RecommendPackage \newcommand*\TUD@Recommend@Package{} \def\TUD@Recommend@Package#1[#2]{% \IfFileExists{#1.sty}{% \RequirePackage{#1}[#2]% }{% \PackageWarning{tudscrbase}{% The usage of package `#1' (#2) is\MessageBreak% recommended but it isn't installed% }% }% } \@onlypreamble\TUD@Recommend@Package % \end{macrocode} % \end{macro}^^A \TUD@Recommend@Package % \end{macro}^^A \TUD@RecommendPackage % \begin{macro}{\TUD@AfterPackage@set} % \changes{v2.04}{2015/03/09}{neu}^^A % \begin{macro}{\TUD@AfterPackage@do} % \changes{v2.03}{2015/02/15}{neu}^^A % Mit diesen beiden Befehlen wird die Ausführung von Quellcode erst nach dem % Laden des gewünschten Paketes oder~-- falls das Paket geladen wurde~-- % direkt im Dokument ausgeführt. Im ersten Argument wird das Paket angegeben, % im zweiten der Quellcode. % \begin{macrocode} \newcommand*\TUD@AfterPackage@set[1]{% \newbool{@tud@#1@loaded}% \AfterAtEndOfPackage*{#1}{\booltrue{@tud@#1@loaded}}% } \newcommand*\TUD@AfterPackage@do[2]{% \ifcsundef{if@tud@#1@loaded}{% \PackageError{tudscrbase}{\string\TUD@AfterPackage@set{#1} missing}{% You have to set \string\TUD@AfterPackage@set{#1} before\MessageBreak% using \string\TUD@AfterPackage@do{#1}{}.% }% }{% \tud@if@preamble{% \AfterAtEndOfPackage*{#1}{#2}% }{% \ifbool{@tud@#1@loaded}{#2}{}% }% }% } % \end{macrocode} % \end{macro}^^A \TUD@AfterPackage@do % \end{macro}^^A \TUD@AfterPackage@set % % \iffalse % % \fi % % \subsection{Bedingt verzögerte Ausführung von \KOMAScript-Optionen} % % \begin{macro}{\TUD@KOMAoptions} % \changes{v2.05}{2015/07/17}{neu}^^A % Dieses Makro wird verwendet, um innerhalb der \TUDScript-Klassen zu % unterschieden, wie eine \KOMAScript-Option auszuführen ist. Wurde bereits % das Paket \pkg{scrextend} oder eine \KOMAScript-Klasse geladen, erfolgt die % Ausführung des Arguments direkt über \cs{KOMAoptions}. Andernfalls wird das % angegebene Argument an die zuladende Klasse durchgereicht. % \begin{macrocode} %<*package&base> \newcommand*\TUD@KOMAoptions[1]{} \ifundef{\KOMAClassName}{% \renewcommand*\TUD@KOMAoptions[1]{% \PackageWarning{tudscrbase}{% You should load package `scrextend' right after\MessageBreak% the documentclass. The following option is gobbled:\MessageBreak% \string\KOMAoptions{`#1'}% }% }% \AfterPackage*{scrextend}{\def\TUD@KOMAoptions{\KOMAoptions}}% }{% \def\TUD@KOMAoptions{\KOMAoptions}% } % % \end{macrocode} % Nach dem Laden einer \TUDScript-Klasse wird der Befehl so angepasst, dass % dieser vor dem Laden der dazugehörigen \KOMAScript-Elternklasse die Optionen % einfach durchreicht. Nach dem Laden der Klasse steht dann \cs{KOMAoptions} % zur Verfügung. % \begin{macrocode} %<*load&class> %<*!inherit> \renewcommand*\TUD@KOMAoptions[1]{\PassOptionsToClass{#1}{\TUD@Class@KOMA}} \AfterClass{\TUD@Class@KOMA}{\let\TUD@KOMAoptions\KOMAoptions} % %<*inherit> \renewcommand*\TUD@KOMAoptions[1]{\PassOptionsToClass{#1}{\TUD@Class@Parent}} \AfterClass{\TUD@Class@Parent}{\let\TUD@KOMAoptions\KOMAoptions} % % % \end{macrocode} % \end{macro}^^A \TUD@KOMAoptions % % \iffalse %<*class&option> % \fi % % \section{Zusätzliches für die \TUDScript-Klassen} % \subsection{Erweiterung von \KOMAScript-Schriftelementen} % % \begin{macro}{\tud@komafont@set} % \begin{macro}{\tud@komafont@unset} % \begin{macro}{\tud@komafont@reset} % \changes{v2.02}{2014/08/24}{neu}^^A % Es wird die Möglichkeit geschaffen, bestimmten Schriftelementen weitere % Eigenschaften mitzugeben. Damit dies optionsabhängig geschehen kann und % \cs{addtokomafont} nur einmalig verwendete werden muss, wird im Zweifelsfall % einem Schriftelement ein Hilfsmakro |\tud@komafont@|\meta{Element} % zugewiesen, welches intern angepasst werden kann. Mit \cs{tud@komafont@set} % werden dem angegebenen Element die gewünschten Schriftattribute zugeteilt. % \begin{macrocode} \newcommand*\tud@komafont@set[2]{% \ifcsdef{tud@komafont@#1}{}{\addtokomafont{#1}{\csuse{tud@komafont@#1}}}% \csdef{tud@komafont@#1}{#2\nobreak}% } % \end{macrocode} % Mit \cs{tud@komafont@unset} kann das angegebene Element wieder zurückgesetzt % werden. Dabei wird das hinzugefügte Makro auf \cs{relax} gesetzt. % \begin{macrocode} \newcommand*\tud@komafont@unset[1]{% \ifcsdef{tud@komafont@#1}{}{\addtokomafont{#1}{\csuse{tud@komafont@#1}}}% \csdef{tud@komafont@#1}{\relax}% } % \end{macrocode} % Werden \KOMAScript-Schriftelemente auf ihre Ausgangsdefinition zurückgesetzt, % so kann diesen mit \cs{tud@komafont@reset} kann das passende Hilfsmakro % abermals zugewiesen werden. % \begin{macrocode} \newcommand*\tud@komafont@reset[1]{% \ifcsdef{tud@komafont@#1}{\addtokomafont{#1}{\csuse{tud@komafont@#1}}}{}% } % \end{macrocode} % \end{macro}^^A \tud@komafont@unset % \end{macro}^^A \tud@komafont@reset % \end{macro}^^A \tud@komafont@set % % \iffalse % %<*class&body> % \fi % % \subsection{Externe Pakete für die \TUDScript-Klassen} % % \changes{v2.01}{2014/04/24}{Versionsanforderungen bei benötigten Paketen}^^A % \changes{v2.02}{2014/07/08}{Warnung bei Verwendung von \pkg{graphics}}^^A % % Für die Verwendung der hier erstellten \KOMAScript-Wrapper-Klassen werden % einige wenige Pakete eingebunden. Dabei wurde versucht, die Anzahl der % Pakete möglichst gering zu halten und nur die wirklich notwendigen zu % verwenden. % % \subsubsection{Erweiterte Umgebungsdefinition mit dem Paket \pkg{environ}} % % Die \env{abstract}-Umgebung wird im Vergleich zu den \KOMAScript-Klassen % stark erweitert. Für diese sowie für die Umgebungen \env{declarations} und % \env{tudpage} wird das Paket \pkg{environ} für die Umgebungsdefinition % benötigt. % \begin{macrocode} \RequirePackage{environ} % \end{macrocode} % % Innerhalb dieser Umgebungen soll es außerdem möglich sein, ein mehrspaltiges % Layout~-- auch konträr zu den globalen Dokumenteinstellungen~-- zu verwenden. % Mit diesen Befehlen lässt sich die Anzahl der Spalten über einen Parameter % anpassen, falls das Paket \pkg{multicol} geladen wurde. % \begin{macro}{\tud@x@multicol@num} % \begin{macro}{\tud@x@multicol@check} % Im Makro \cs{tud@x@multicol@num} wird die Anzahl der gewünschten Spalten in % einer Umgebung für die Verwendung des \pkg{multicol}-Paketes gespeichert. % \begin{macrocode} \newcommand*\tud@x@multicol@num{1} % \end{macrocode} % Der Befehl \cs{tud@x@multicol@check} prüft, ob das Paket \pkg{multicol} % geladen wurde. Falls dies nicht der Fall ist, wird eine Warnung ausgegeben % und die Änderung des Wertes über einen Parameter der Umgebungen \env{tudpage} % respektive \env{abstract} sowie \env{declarations} verhindert. % \begin{macrocode} \newcommand*\tud@x@multicol@check{% \ifnum\tud@x@multicol@num>\@ne\relax% \ClassWarning{\TUD@Class@Name}{% The option `columns=\tud@x@multicol@num' is only\MessageBreak% supported, when package `multicol' is loaded% }% \renewcommand*\tud@x@multicol@num{1}% \fi% } \AfterPackage{multicol}{\let\tud@x@multicol@check\relax} % \end{macrocode} % \end{macro}^^A \tud@x@multicol@check % \end{macro}^^A \tud@x@multicol@num % % \subsubsection{Pakete für Grafiken und Farben} % % Es folgen die Pakete, welche bei Bedarf am Ende der Präambel geladen werden. % \begin{macrocode} \AtEndPreamble{% % \end{macrocode} % Mit \pkg{graphicx} werden die Logos der TU~Dresden sowie von Dresden Concept % mit dem Befehl \cs{includegraphics} u.\,a. auf der Titelseite eingebunden. % Sollte lediglich das \pkg{graphics}-Paket geladen worden sein, so wird der % Nutzer mit einer Warnung informiert, dass zusätzlich das \pkg{graphicx}-Paket % geladen wird. % \begin{macrocode} \@ifpackageloaded{graphicx}{}{% \@ifpackageloaded{graphics}{% \ClassWarningNoLine{\TUD@Class@Name}{% Package `graphics' was superseded by `graphicx',\MessageBreak% which now will be loaded automatically% }% }{}% \RequirePackage{graphicx} }% % \end{macrocode} % Mit dem Paket \pkg{tudscrcolor} werden die Befehle für die Auswahl der Farben % des \CDs definiert, welches wiederum \pkg{xcolor} lädt. % \begin{macrocode} \RequirePackage{tudscrcolor}[% %!TUD@Version ]% } % \end{macrocode} % % \iffalse % % \fi % % \PrintBackMatter % \endinput