diff options
Diffstat (limited to 'macros/latex/contrib/tudscr/source/tudscr-base.dtx')
-rw-r--r-- | macros/latex/contrib/tudscr/source/tudscr-base.dtx | 1467 |
1 files changed, 1467 insertions, 0 deletions
diff --git a/macros/latex/contrib/tudscr/source/tudscr-base.dtx b/macros/latex/contrib/tudscr/source/tudscr-base.dtx new file mode 100644 index 0000000000..746e696de4 --- /dev/null +++ b/macros/latex/contrib/tudscr/source/tudscr-base.dtx @@ -0,0 +1,1467 @@ +% \CheckSum{821} +% \iffalse meta-comment +% +% TUD-Script -- Corporate Design of Technische Universität Dresden +% ---------------------------------------------------------------------------- +% +% Copyright (C) Falk Hanisch <hanisch.latex@outlook.com>, 2012-2019 +% +% ---------------------------------------------------------------------------- +% +% This work may be distributed and/or modified under the conditions of the +% LaTeX Project Public License, version 1.3c of the license. 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 2005/12/01 +% or later and of this work. This work has the LPPL maintenance status +% "author-maintained". The current maintainer and author of this work +% is Falk Hanisch. +% +% ---------------------------------------------------------------------------- +% +% Dieses Werk darf nach den Bedingungen der LaTeX Project Public Lizenz +% in der Version 1.3c, verteilt und/oder verändert werden. Die aktuelle +% Version dieser Lizenz ist http://www.latex-project.org/lppl.txt und +% Version 1.3c oder später ist Teil aller Verteilungen von LaTeX 2005/12/01 +% oder später und dieses Werks. Dieses Werk hat den LPPL-Verwaltungs-Status +% "author-maintained", wird somit allein durch den Autor verwaltet. Der +% aktuelle Verwalter und Autor dieses Werkes ist Falk Hanisch. +% +% ---------------------------------------------------------------------------- +% +% \fi +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \iffalse +%%% From File: tudscr-base.dtx +%<*dtx> +% \fi +% +\ifx\ProvidesFile\undefined\def\ProvidesFile#1[#2]{}\fi +\ProvidesFile{tudscr-base.dtx}[2019/08/27 v2.06d TUD-Script\space% +% +% \iffalse +%</dtx> +%<package&base>\ProvidesPackage{tudscrbase}[% +%<*package&base> +%!TUD@Version +%</package&base> +%<package&base> package +%<*dtx|package&base> +% \fi + (basics for the bundle)% +] +% \iffalse +%</dtx|package&base> +%<*dtx> +\documentclass[english,ngerman,xindy]{tudscrdoc} +\ifpdftex{ + \usepackage[T1]{fontenc} + \usepackage[ngerman=ngerman-x-latest]{hyphsubst} +}{ + \usepackage{fontspec} +} +\usepackage{babel} +\usepackage{tudscrfonts} +\KOMAoptions{parskip=half-} +\usepackage{bookmark} +\usepackage[babel]{microtype} + +\CodelineIndex +\RecordChanges +\GetFileInfo{tudscr-base.dtx} +\title{\file{\filename}} +\author{Falk Hanisch\qquad\expandafter\mailto\expandafter{\tudscrmail}} +\date{\fileversion\nobreakspace(\filedate)} + +\begin{document} + \maketitle + \tableofcontents + \DocInput{\filename} +\end{document} +%</dtx> +% \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. +% +% \ToDo{% +% Schnittstelle äquivalent zu \cs{KOMA@kav@\dots}? Dann hierfür +% \pkg{etoolbox}-Listen und \cs{listadd} sowie \cs{listremove} nutzen +% }[v2.??] +% \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.??] +%^^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} +% +% +% \StopEventually{\PrintIndex\PrintChanges\PrintToDos} +% +% \begin{macrocode} +%<*load> +\RequirePackage{tudscrbase}[\TUD@Version] +%</load> +% \end{macrocode} +% +% \subsection{Notwendige Pakete für \TUDScript} +% +% \iffalse +%<*package&base> +% \fi +% +% 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}[2018/03/30] +% \end{macrocode} +% Die folgenden Pakete werden für die Manipulation bereits definierter +% Makros sowie zur erweiterten Auswertung boolescher Ausdrücke benötigt. +% \begin{macrocode} +\RequirePackage{etoolbox}[2011/01/03] +\RequirePackage{xpatch}[2012/10/02] +\RequirePackage{letltxmacro}[2016/05/16] +\RequirePackage{etexcmds}[2011/02/16] +% \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 eigentlich auch mit KOMA-Option \val{@else@} gehen}[v2.07] +% \begin{macrocode} +\RequirePackage{kvsetkeys}[2012/04/25] +% \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}[2009/09/17] +% \end{macrocode} +% +% \subsection{Grundlegende Befehle für \TUDScript} +% \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\dots}-Makros auf \cs{tud@res@\dots} ändern}[v2.??] +% \ToDo{\cs{tud@reserved} in \cs{tud@res@?}, Achtung bei Dopplungen!}[v2.??] +% \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}{\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 +% \begin{macro}{\tud@res@read} +% \changes{v2.06}{2019/06/21}{neu}^^A +% Makros zur temporären Verwendung. +% \begin{macrocode} +\newcommand*\tud@reserved{} +\newcommand*\tud@res@a{} +\newcommand*\tud@res@b{} +\newcommand*\tud@res@c{} +\newif\if@tud@res@swa +\newcount\tud@res@cnt +\newread\tud@res@read +% \end{macrocode} +% \end{macro}^^A \tud@res@read +% \end{macro}^^A \tud@res@cnt +% \end{macro}^^A \if@tud@res@swa +% \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}{\eaddto@hook} +% \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{eaddto@hook} wird~-- in Ergänzung +% zu \cs{addto@hook}~-- ein Makro zum Anfügen des expandierten Arguments an ein +% token-Register bereitgestellt. +% \begin{macrocode} +\newtoks\tud@toks@ +\newcommand*\eaddto@hook[2]{% + \expandafter\addto@hook\expandafter#1\expandafter{#2}% +} +% \end{macrocode} +% \end{macro}^^A \eaddto@hook +% \end{macro}^^A \tud@toks@ +% +% \subsubsection{Robuster Test auf leeres Argument} +% +% \begin{macro}{\ifxblank} +% Hiermit kann ein Argument geprüft werden, ob dieses blank ist (leer oder +% Leerzeichen). In seiner Syntax ist er identisch zu \cs{ifblank}, allerdings +% expandiert er im Gegensatz zu diesem das gegebene Argument. +% \begin{macrocode} +\newcommand*\ifxblank{\ifstr{}} +% \end{macrocode} +% \end{macro}^^A \ifxblank +% +% \subsubsection{Test auf booleschen Ausdruck in Form eines Strings} +% +% \begin{macro}{\ifstrbool} +% \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: +% +% \cs{ifstrbool}\marg{Argument}\marg{Wahr}\marg{Falsch}\marg{Andernfalls} +% \begin{macrocode} +\newcommand*\ifstrbool[4]{% + \ifstr{#1}{true}{#2}{% + \ifstr{#1}{on}{#2}{% + \ifstr{#1}{yes}{#2}{% + \ifstr{#1}{false}{#3}{% + \ifstr{#1}{no}{#3}{% + \ifstr{#1}{off}{#3}{% + #4% + }% + }% + }% + }% + }% + }% +} +% \end{macrocode} +% \end{macro}^^A \ifstrbool +% +% \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} +\newcommand*\iflanguageloaded[1]{% + \PackageWarning{tudscrbase}{% + Whether package `babel' nor package `polyglossia' has been loaded% + }% + \expandafter\@secondoftwo% +} +\AfterPackage*{babel}{% + \renewcommand*\iflanguageloaded[1]{% + \@expandtwoargs\in@{,#1,}{,\bbl@loaded,}% + \ifin@% + \expandafter\@firstoftwo% + \else% + \expandafter\@secondoftwo% + \fi% + }% +} +\AfterPackage*{polyglossia}{% + \renewcommand*\iflanguageloaded[1]{\ifcsdef{#1@loaded}}% +} +% \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 \LaTeXe{} 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{.1\@tempdima}% + \setlength\@tempdimb{.1\@tempdimb}% + }% + \setlength\@tempdimc{\@tempdima}% + \else% + \@whiledim\@tempdima>1pt\relax\do{% + \setlength\@tempdima{.1\@tempdima}% + \setlength\@tempdimb{.1\@tempdimb}% + }% + \setlength\@tempdimc{\@tempdimb}% + \fi% + \@tempcnta=1\relax% + \@whiledim\dimexpr\@tempcnta\@tempdimc\relax<.01\maxdimen\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{Erzwungene Kleinschreibung von Strings} +% +% Um angegebene Werte bei Schlüssel-Wert-Paaren oder Schlüsselwörter in +% bestimmten Feldern mit Sicherheit erkennen zu können, werden diese zwingend +% in Kleinbuchstaben geschieben. +% \begin{macro}{\tud@lowerstring} +% Das Makro wird mit \cs{tud@lowerstring}\marg{Zielmakro}\marg{String} benutzt. +% \ToDo{geht das eleganter als mit \cs{expandafter}?}[v2.07] +% \begin{macrocode} +\newcommand*\tud@lowerstring[2]{% + \protected@edef#1{#2}% + \lowercase\expandafter{% + \expandafter\def\expandafter #1\expandafter{#1}% + }% +} +% \end{macrocode} +% \end{macro}^^A \tud@lowerstring +% +% \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@lowerstring\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@lowerstring\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 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. +% \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 \cs{@@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]{% + \ifcsdef{#1}{}{% + \PackageError{tudscrbase}{% + `\@backslashchar#1' is not defined}{% + The command `\@backslashchar#1' was never defined. \MessageBreak% + Please contact the TUD-Script maintainer\MessageBreak% + via \tudscrmail. A bugfix is urgently required.% + }% + }% +} +% \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@skip@store} +% \changes{v2.04}{2015/03/02}{neu}^^A +% \changes{v2.05}{2016/07/13}{Verwendung von \cs{tud@skip@check}}^^A +% \begin{macro}{\tud@skip@restore} +% \changes{v2.04}{2015/03/02}{neu}^^A +% \changes{v2.05}{2016/07/13}{Verwendung von \cs{tud@skip@check}}^^A +% \begin{macro}{\tud@skip@reset} +% \changes{v2.05}{2016/07/13}{neu}^^A +% \begin{macro}{\tud@skip@set} +% \changes{v2.04}{2015/05/05}{neu}^^A +% \changes{v2.05}{2016/07/13}{Verwendung von \cs{tud@skip@check}}^^A +% \begin{macro}{\tud@skip@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@skip@store[1]{% + \tud@skip@check{#1}{% + \ifcsdef{@@tud@skip@#1}{}{% + \csedef{@@tud@skip@#1}{\expandafter\the\csname #1\endcsname}% + }% + }% +} +\newcommand*\tud@skip@restore[1]{% + \tud@skip@check{#1}{% + \ifcsdef{@@tud@skip@#1}{% + \csname #1\endcsname=\csname @@tud@skip@#1\endcsname% + \csundef{@@tud@skip@#1}% + }{}% + }% +} +\newcommand*\tud@skip@reset[1]{% + \tud@skip@check{#1}{% + \ifcsdef{@@tud@skip@#1}{% + \csname#1\endcsname=\csname @@tud@skip@#1\endcsname% + }{}% + }% +} +\newcommand*\tud@skip@set[2]{% + \tud@skip@check{#1}{% + \expandafter\setlength\csname #1\endcsname{#2}% + }% +} +\newcommand*\tud@skip@check[1]{% + \begingroup% + \@tempswafalse% + \expandafter\ifisskip\expandafter{\csname#1\endcsname}{\@tempswatrue}{}% + \expandafter\ifisdimen\expandafter{\csname#1\endcsname}{\@tempswatrue}{}% + \if@tempswa% + \aftergroup\@firstofone% + \else% + \aftergroup\@gobble% + \fi% + \endgroup% +} +% \end{macrocode} +% \end{macro}^^A \tud@skip@check +% \end{macro}^^A \tud@skip@set +% \end{macro}^^A \tud@skip@reset +% \end{macro}^^A \tud@skip@restore +% \end{macro}^^A \tud@skip@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. +% \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 \tudscrmail. 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{\FamilyProcessOptions{TUD}} +\newcommand*\TUDExecuteOptions{\FamilyExecuteOptions{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 +% \cs{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 (\cs{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 \cs{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 +% \begin{macro}{\TUD@set@ifkey} +% \changes{v2.06}{2018/08/01}{forcierte Kleinschreibung Schlüsselwerte}^^A +% \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 +% \begin{macro}{\TUD@set@dimenkey} +% \changes{v2.05}{2016/06/15}{neu}^^A +% \changes{v2.06}{2018/08/01}{forcierte Kleinschreibung Schlüsselwerte}^^A +% \begin{macro}{\TUD@unknown@keyval} +% Dies sind die Befehle zum Setzen der Optionen. Diese können entweder als +% Schalter (\cs{TUD@set@ifkey}) oder aber mit mehreren möglichen Werten +% (\cs{TUD@set@numkey}) definiert werden. Prinzipiell ist auch eine freie +% Definition mit anschließender Abarbeitung ohne die zuvor genannten Befehle +% möglich. +% \begin{macrocode} +\newcommand*\TUD@set@ifkey[3]{% + \tud@lowerstring\tud@res@a{#3}% + \edef\tud@res@b{% + \etex@unexpanded{\FamilySetBool{TUD}{#1}{#2}}{\tud@res@a}% + }\tud@res@b% +} +\newcommand*\TUD@set@numkey[4]{% + \tud@lowerstring\tud@res@a{#4}% + \edef\tud@res@b{% + \etex@unexpanded{\FamilySetNumerical{TUD}{#1}{#2}{#3}}{\tud@res@a}% + }\tud@res@b% +} +% \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} +% Mit \cs{TUD@set@dimenkey} wird der übergebene Längenwert im spezifiezierten +% Makro gespeichert. +% \begin{macrocode} +\newcommand*\TUD@set@dimenkey[3]{% + \tud@lowerstring\tud@res@a{#3}% + \edef\tud@res@b{% + \etex@unexpanded{\FamilySetUseLengthMacro{TUD}{#1}{#2}}{\tud@res@a}% + }\tud@res@b% +} +% \end{macrocode} +% 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 +% \end{macro}^^A \TUD@set@dimenkey +% \end{macro}^^A \TUD@set@numkey +% \end{macro}^^A \TUD@bool@numkey +% \end{macro}^^A \TUD@set@ifkey +% \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. +% \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]{% + \ifcsdef{#1}{% + \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.% + }% + }% + }{% + \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'.% + }% + }% +} +% \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]{% + \ifstrbool{#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 +% Schlüssel"=Wert"=Parameter für die optionalen Argumente von Befehle 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]{% + \ifxblank{#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}{% + \ifstr{\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}% + \ifxblank{#2}{% + \def\@tempa{\let\tud@reserved\relax}% + }{% + \def\@tempa{\def\tud@reserved{#2=\kv@value}}% + }% + \appto\@tempa{% + \ifstr{\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% + \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 (<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@error} +% Das Makro \cs{TUD@parameter@wrn}\marg{Parameter}\marg{Werteliste} gibt für +% den Fall einer ungültigen Wertzuweisung an einen bestimmten \meta{Parameter} +% eine Warnung mit einem entsprechenden Hinweis auf gültige Werte innerhalb von +% \meta{Werteliste} aus. +% \begin{macrocode} +\newcommand*\TUD@parameter@error[2]{% + \PackageError{tudscrbase}{Unsupported value for parameter `#1'}{% + `#1' can only be used with values:\MessageBreak#2% + }% +} +% \end{macrocode} +% \end{macro}^^A \TUD@parameter@error +% +% \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 +% 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. +% \begin{macrocode} +\newcommand*\TUD@UnwindPackage[2]{\AtEndPreamble{\@ifpackageloaded{#1}{}{#2}}} +\@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. +% \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 +% installiert ist, ohne dieses zu laden. Hierfür wird die Datei zeilenweise +% gelesen, bis der Eintrag \cs{ProvidesPackage\marg{Paketname}\oarg{Version}} +% gefunden wird. +% \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{% + \@ifnextchar[%] + {\tud@res@b}{\tud@res@b[]}% + }% + \IfFileExists{#1.sty}{% + \openin\tud@res@read=#1.sty% + \@tud@res@swatrue% + \loop% + \read\tud@res@read to\tud@res@c% + \@expandtwoargs\in@{\string\ProvidesPackage}% + {\expandafter\detokenize\expandafter{\tud@res@c}}% + \ifin@% + \@tud@res@swafalse% + \tud@res@c% + \fi% + \ifeof\tud@res@read\@tud@res@swafalse\fi% + \if@tud@res@swa% + \repeat% + \closein\tud@res@read% + }{}% + \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 +% 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@@RecommendPackage#1}% + {\TUD@@RecommendPackage#1[]}% +} +\@onlypreamble\TUD@RecommendPackage +\newcommand*\TUD@@RecommendPackage{} +\def\TUD@@RecommendPackage#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@@RecommendPackage +% \end{macrocode} +% \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}% + \AfterPackage!{#1}{\booltrue{@tud@#1@loaded}}% +} +\newcommand*\TUD@AfterPackage@do[2]{% + \ifcsdef{if@tud@#1@loaded}{% + \if@atdocument% + \ifbool{@tud@#1@loaded}{#2}{}% + \else% + \AfterPackage!{#1}{#2}% + \fi% + }{% + \PackageError{tudscrbase}{\string\TUD@AfterPackage@set{#1} missing}{% + You have to set \string\TUD@AfterPackage@set{#1} before\MessageBreak% + the usage of \string\TUD@AfterPackage@do{#1}{<code>} is\MessageBreak% + possible.% + }% + }% +} +% \end{macrocode} +% \end{macro}^^A \TUD@AfterPackage@do +% \end{macro}^^A \TUD@AfterPackage@set +% +% \iffalse +%</package&base> +% \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 the\MessageBreak% + documentclass. Option \string\TUD@KOMAoptions{`#1'} is gobbled% + }% + }% + \AfterPackage*{scrextend}{\let\TUD@KOMAoptions\KOMAoptions}% +}{% + \let\TUD@KOMAoptions\KOMAoptions% +} +%</package&base> +% \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> +%<*inherit> +\renewcommand*\TUD@KOMAoptions[1]{\PassOptionsToClass{#1}{\TUD@Class@Parent}} +\AfterClass{\TUD@Class@Parent}{\let\TUD@KOMAoptions\KOMAoptions} +%</inherit> +%</load&class> +% \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 \cs{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&option> +%<*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}[2013/04/01] +% \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}[1999/02/16]% + }% +% \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 +%</class&body> +% \fi +% +% \Finale +% +\endinput + +% +% \begin{macro}{\TUD@noworlater} +% \changes{v2.05}{2015/07/03}{neu implementiert}^^A +% \begin{macro}{\TUD@noworlater@simple} +% \changes{v2.05}{2015/07/03}{neu}^^A +% Hiermit kann die Abarbeitung der Optionen an das Ende der verwendeten +% Klasse bzw. des Paketes verzögert werden. Aufgrund der Besonderheiten der +% Befehle \cs{AtEndOfClass} und \cs{AtEndOfPackage} können diese nicht +% innerhalb von \pkg{tudscrbase} sondern erst außerhalb nach dem Laden +% definiert werden. Damit keine Probleme dabei auftreten, falls das Paket +% geladen wird ohne daran anschließend die notwendigen Redefinitionen +% durchzuführen, werden die beiden Varianten des Befehls \cs{TUD@noworlater} +% im Paket definiert. +% +% Im ersten Argument von \cs{TUD@noworlater} wird einer der wertzuweisenden +% Befehle für Optionen (\cs{TUD@set@\dots}) erwartet. Dieser wird immer +% ausgeführt, um ungültige Wertzuweisungen einer Option, welche als globale +% Klassenoption angegeben wurde, über die \LaTeX-Standardroutine als Warnung +% auszugeben. Bei der eigentlichen~-- sprich verzögerten~-- Ausführung der +% Option wird die Wertzuweisung abermals ausgeführt, gefolgt von der im +% zweiten Argument definierten Abarbeitung dieser. +% \begin{macrocode} +%<*package&base> +\newcommand*\TUD@noworlater[2]{} +\newcommand*\TUD@noworlater@simple[2]{% + \PackageWarning{tudscrbase}{% + The content of \string\TUD@noworlater will be executed immediately% + }% + #1#2% +} +\let\TUD@noworlater\TUD@noworlater@simple +%</package&base> +% \end{macrocode} +% Nach dem Laden des Paketes wird geprüft, ob die ursprüngliche Definition +% des Befehls aus dem Paket noch besteht. Ist dies der Fall, wird der Befehl +% zur Verzögerung an das Ende der Klasse bzw. des Paketes umdefiniert. +% \begin{macrocode} +%<*load> +\ifx\TUD@noworlater\TUD@noworlater@simple +%<*class> + \renewcommand*\TUD@noworlater[2]{#1\AtEndOfClass{#1#2}}% + \AtEndOfClass{\renewcommand*\TUD@noworlater[2]{#1#2}}% +%</class> +%<*package> + \renewcommand*\TUD@noworlater[2]{#1\AtEndOfPackage{#1#2}}% + \AtEndOfPackage{\renewcommand*\TUD@noworlater[2]{#1#2}}% +%</package> +\fi +%</load> +% \end{macrocode} +% \end{macro}^^A \TUD@noworlater@simple +% \end{macro}^^A \TUD@noworlater +% |