% \CheckSum{3675} % \iffalse meta-comment % ====================================================================== % scrkernel-basics.dtx % Copyright (c) Markus Kohm, 2002-2017 % % This file is part of the LaTeX2e KOMA-Script bundle. % % 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 % version 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 Markus Kohm. % % This work consists of all files listed in manifest.txt. % ---------------------------------------------------------------------- % scrkernel-basics.dtx % Copyright (c) Markus Kohm, 2002-2017 % % Dieses Werk darf nach den Bedingungen der LaTeX Project Public Lizenz, % Version 1.3c, verteilt und/oder veraendert werden. % Die neuste Version dieser Lizenz ist % http://www.latex-project.org/lppl.txt % und Version 1.3c ist Teil aller Verteilungen von LaTeX % Version 2005/12/01 oder spaeter und dieses Werks. % % Dieses Werk hat den LPPL-Verwaltungs-Status "author-maintained" % (allein durch den Autor verwaltet). % % Der Aktuelle Verwalter und Autor dieses Werkes ist Markus Kohm. % % Dieses Werk besteht aus den in manifest.txt aufgefuehrten Dateien. % ====================================================================== % \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: $Id: scrkernel-basics.dtx 2640 2017-05-08 09:36:55Z kohm $ %%%% (run: prepare) % %<*option> % \fi % % \begin{option}{internalonly} % \changes{v2.96}{2006/11/26}{neu}^^A % \changes{v2.97c}{2007/06/20}{geht auch ohne Argument}^^A % \begin{macro}{\dont@let@as@internal@defined} % \changes{v2.96}{2006/11/26}{neu (intern)}^^A % Anweisungen, die mit einem internen und einem Anwendername vorhanden sind, % können vor dem Anwender optional verborgen werden. Wird kein Argument % angegeben, so werden alle Anweisungen verborgen. % \begin{macrocode} %<*base> \newcommand*{\dont@let@as@internal@defined}{/} \newif\if@let@as@internalonly@defined\@let@as@internalonly@definedfalse \DefineFamily{KOMA} \DefineFamilyMember{KOMA} \DefineFamilyKey{KOMA}{internalonly}[\relax]{% \ifx\relax#1\relax \@let@as@internalonly@definedtrue \else \@let@as@internalonly@definedfalse \begingroup \@expandtwoargs\in@{#1}\dont@let@as@internal@defined \expandafter\endgroup \ifin@\else\g@addto@macro\dont@let@as@internal@defined{#1/}\fi \fi } % % \end{macrocode} % \end{macro} % \end{option} % % % \changes{v2.96}{2006/08/20}{Optionen werden abgearbeitet}^^A % \changes{v2.97c}{2007/04/18}{Optionen werden mit \cs{KOMAProcessOptions}^^A % abgearbeitet} % \begin{macrocode} %\KOMAProcessOptions\relax %\FamilyProcessOptions{KOMA}\relax % \end{macrocode} % % \iffalse % %<*body> % \fi % % \subsection{Ein wenig zusätzliche Mathematik für \eTeX} % % \begin{macro}{\XdivY} % \changes{v3.05a}{2010/03/10}{Neu}^^A % Ergebnis ist erster Argument durch zweites abgerundet auf die nächst % kleinere ganze Zahl. % \begin{macrocode} %<*base> \newcommand*{\XdivY}[2]{% \numexpr ( #1 + #2 / 2 ) / #2 - 1\relax } % % \end{macrocode} % \end{macro} % % \begin{macro}{\XmodY} % \changes{v3.05a}{2010/03/10}{Neu}^^A % Ergebnis ist erstes Argument modulo zweites Argument. % \begin{macrocode} %<*base> \newcommand*{\XmodY}[2]{% \numexpr #1 - #2 * \XdivY{#1}{#2}\relax } % % \end{macrocode} % \end{macro} % % \subsection{Häufig benötigte Befehle} % % \begin{macro}{\if@atdocument} % \changes{v2.95}{2002/12/05}{neuer Schalter}^^A % \begin{macro}{\@atdocumenttrue} % \begin{macro}{\@atdocumentfalse} % Dieser Schalter wird bei \cs{begin}\texttt{\{document\}} wahr. Er % wird von \KOMAScript{} für Befehle verwendet, die sich % unterschiedlich verhalten, je nachdem, ob sie in der Präambel oder % danach aufgerufen werden. % \begin{macrocode} %<*base> \newif\if@atdocument \AtBeginDocument{\@atdocumenttrue} \@onlypreamble\@atdocumentrue \@onlypreamble\@atdocumentfalse % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\let@as@internal@defined} % \changes{v2.95}{2002/08/19}{neu (intern)}^^A % \changes{v2.95c}{2006/08/12}{Warnung bei Umdefinierung}^^A % \changes{v2.96}{2006/11/26}{Herausreichen von internen Makros als % Benutzermakros kann verhindert werden}^^A % \changes{v2.97c}{2007/06/20}{Herausreichen von internen Makros kann % generell verhindert werden}^^A % \changes{v3.10}{2010/10/26}{\cs{ignorespaces} beim \cs{document}-Patch % ergänzt} % \changes{v3.13a}{2014/08/13}{potentielle Leerzeichen durch Zeilenumbruch % beseitigt}^^A % Dieses Makro wird intern verwendet, um dokumentierte Makros mit der % Definition von internen Makros zu versehen, falls sie nicht bereits % definiert oder als nicht zu definieren markiert sind. Der Name des % dokumentierten Makros wird als Parameter übergeben. Dies wird gleich % benötigt. % \begin{macrocode} %<*base> \newcommand*{\let@as@internal@defined}[1]{% \begingroup \if@let@as@internalonly@defined \in@true \else \@expandtwoargs\in@{/#1/}\dont@let@as@internal@defined \fi \expandafter\endgroup \ifin@ \PackageInfo{% scrbase% }{% \expandafter\string\csname #1\endcsname\space excluded from being defined% }% \else \@ifundefined{#1}{% \begingroup \expandafter\def\expandafter\reserved@a \expandafter{\csname scr@#1\endcsname}% \expandafter\def\expandafter\reserved@b \expandafter{\csname #1\endcsname}% \expandafter\expandafter\expandafter\endgroup \expandafter\expandafter\expandafter\let\expandafter\reserved@b\reserved@a \if@atdocument\else \g@addto@macro\document{% \expandafter\ifx\csname #1\expandafter\endcsname \csname scr@#1\endcsname \else \PackageWarning{scrbase}{% \expandafter\string\csname #1\endcsname\space was redefined\MessageBreak at the document preamble.\MessageBreak If you did not redefine it by yourself, have a\MessageBreak a look at the description of this command at\MessageBreak the manual of every package you are using\@gobble }% \fi \ignorespaces }% \fi }{% \PackageInfo{% scrbase% }{% \expandafter\string\csname #1\endcsname\space already defined.\MessageBreak If \expandafter\string\csname #1\endcsname\space does not behave like\MessageBreak it was described at the KOMA-Script manual, try to\MessageBreak load `scrbase.\scr@pkgextension' earlier or find out at which\MessageBreak package or class \expandafter\string\csname #1\endcsname\space was defined before\@gobble }% }% \fi } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifundefinedorrelax} % \changes{v2.95}{2002/08/21}{neu}^^A % \changes{v2.95c}{2006/08/12}{über interne Anweisung definiert}^^A % \changes{v2.97c}{2007/06/20}{umbenannt von \cs{ifundefined}} % Dieses Makro arbeitet wie \cs{@ifundefined}, definiert dabei aber % ein undefiniertes Makro nicht als \cs{relax}. % \begin{macrocode} %<*base> \let@as@internal@defined{ifundefinedorrelax} % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifnotundefined} % \changes{v2.95}{2002/08/21}{neu}^^A % \changes{v2.95c}{2006/08/12}{nutzt \eTeX{} wenn möglich} % \changes{v3.02c}{2009/02/19}{\eTeX{} ist zwingend} % Dieses Makro arbeitet genau umgekehrt zu \cs{ifundefined}. Manchmal % ist es ganz nützlich, auch das zu haben. Dieses Makro heißt nicht % \cs{ifdefined}, weil \eTeX\ bereits ein solches Primitiv bietet. % \begin{macrocode} %<*base> \newcommand{\ifnotundefined}[1]{% \ifcsname #1\endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifstr} % \changes{v2.95}{2004/07/20}{if- und then-Teil werden nicht gefressen}^^A % \changes{v3.04b}{2010/01/29}{\cs{edef} durch \cs{protected@edef} ersetzt} % Dieses Makro vergleicht zwei Tokenfolgen. Eigentlich müsste es also % eher \cs{ifequal} oder ähnlich heißen. % \begin{macrocode} %<*base> \newcommand\ifstr[2]{% \begingroup\protected@edef\reserved@a{#1}\protected@edef\reserved@b{#2}% \ifx\reserved@a\reserved@b \endgroup\expandafter\@firstoftwo \else \endgroup\expandafter\@secondoftwo \fi } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifstrstart} % \changes{v3.12}{2013/11/05}{neu}^^A % Falls die Expansion des ersten Arguments mit der Expansion des zweiten % Arguments beginnt, wird das dritte Argument ausgeführt, sonst das vierte. % \begin{macrocode} %<*base> \newcommand*{\ifstrstart}[2]{% \begingroup \edef\reserved@a{\noexpand\@ifstrstart{#1}{#2}}% \reserved@a{\aftergroup\@firstoftwo}{\aftergroup\@secondoftwo}% \endgroup } % \end{macrocode} % \begin{macro}{\@ifstrstart} % \changes{v3.12}{2013/11/05}{neu (intern)}^^A % Hilfsmakro, damit die Argumente vollständig expandiert werden können. % \begin{macrocode} \newcommand*{\@ifstrstart}[2]{% \def\reserved@a ##1#2##2\@nil{% \if\relax\detokenize{##1}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% \reserved@a#1#2\@nil } % % \end{macrocode} % \end{macro}^^A \@ifstrstart % \end{macro}^^A \ifstrstart % % \begin{macro}{\IfArgIsEmpty} % \changes{v3.19}{2015/08/29}{neu}^^A % Falls das erste Argument tatsächlich leer ist, wird das zweite Argument % ausgeführt sonst das dritte. %<*base> % \begin{macrocode} \newcommand*{\IfArgIsEmpty}[1]{% \if\relax\detokenize{#1}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} % % \end{macro}^^A \IfArgIsEmpty % % % \begin{macro}{\ifislengthprimitive} % \changes{v3.20}{2015/10/19}{neu}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einem Primitiv % expandiert, das als Länge verwendet werden kann, wird das erste Argument % ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\ifislengthprimitive}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifislengthprimitive#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifislengthprimitive} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf diverse Primitive prüft. % \begin{macrocode} \newcommand*{\scr@ifislengthprimitive}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifislengthprimitive }{% \def\reserved@c{\aftergroup\scr@secondoftwoAfterNil}% \@for\reserved@a:=\baselineskip,\dp,\hsize,\ht,\lineskip,% \parindent,\parskip,\pdfpageheight,\pdfpagewidth,% \wd,\vsize \do {% \expandafter\ifstr\expandafter{\expandafter\string\reserved@a}{% \meaning #1% }{% \def\reserved@c{\aftergroup\scr@TestDimenAssignTillNil}% }% }% \reserved@c }% \endgroup #1% } % % \end{macrocode} % \end{macro}^^A \scr@ifislengthprimitive % \end{macro}^^A \ifislengthprimitive % % % \begin{macro}{\ifisdimen} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einem % \cs{dimen}-Register (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\ifisdimen}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisdimen#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisdimen} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf ein \cs{dimen}-Register prüft % \begin{macrocode} \newcommand*{\scr@ifisdimen}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisdimen }{% \ifstrstart{\meaning #1}{\string\dimen}{% \aftergroup\scr@TestDimenAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % \end{macrocode} % \end{macro}^^A \scr@ifisdimen % \begin{macro}{\scr@TestDimenAssignTillNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Das durch \cs{@nil} begrenzte Argument wird einer temporären Länge % zugewiesen. Wird dabei das Argument komplett aufgebraucht, so wird das % erste Argument nach \cs{@nil} ausgeführt, sonst das zweite. Das begrenzte % Argument wird in jedem Fall komplett aufgebraucht. % \begin{macrocode} \newcommand*\scr@TestDimenAssignTillNil{} \def\scr@TestDimenAssignTillNil#1\@nil{% \begingroup \afterassignment\scr@AfterEndGroupIfArgIsRelaxTillNnil \@tempdima=#1\relax\@nnil } % \end{macrocode} % \begin{macro}{\scr@IfAfterEndgroupArgIsRelaxTillNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % \begin{macro}{\scr@IfArgIsRelaxAfterRelaxTillNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Die Hilfsmakros lesen ein durch \cs{@nnil} begrenztes Argument. Falls dieses % Argument nur aus einer Folge von \cs{relax} besteht, wird das erste Argument % nach \cs{@nnil} ausgeführt, sonst das zweite. % \begin{macrocode} \newcommand*\scr@AfterEndGroupIfArgIsRelaxTillNnil{} \def\scr@AfterEndGroupIfArgIsRelaxTillNnil#1\@nnil{% \endgroup \ifstr{\detokenize{#1}}{\detokenize{\relax}}{\@firstoftwo}{% \ifstrstart{\detokenize{#1}}{\detokenize{\relax}}{% \scr@IfArgIsRelaxAfterRelaxTillNnil #1\@nnil }{\@secondoftwo}% }% } \newcommand*\scr@IfArgIsRelaxAfterRelaxTillNnil{} \def\scr@IfArgIsRelaxAfterRelaxTillNnil \relax#1\@nnil{% \ifstr{\detokenize{#1}}{\detokenize{\relax}}{\@firstoftwo}{% \ifstrstart{\detokenize{#1}}{\detokenize{\relax}}{% \scr@IfArgIsRelaxAfterRelaxTillNnil #1\@nnil }{\@secondoftwo}% }% } % \end{macrocode} % \end{macro}^^A \scr@IfArgIsRelaxAfterRelaxTillNnil % \end{macro}^^A \scr@IfArgIsRelaxTillNnil % \end{macro}^^A \scr@TestSkipAssignTillNil % \begin{macro}{\scr@secondoftwoAfterNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Das Hilfsmakro liest ein durch \cs{@nil} begrenztes Argument und führt dann % das zweite Argument nach \cs{@nil} aus. Dabei wird auch Sorge dafür getrage, % dass das Argument eventuell leer sein könnte, was normalerweise dazu führen % würde, dass \cs{@nil} zum Argument selbst wird. % \begin{macro}{\scr@@secondoftwoAfterNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Zu diesem Zweck wird ein zweites Hilfsmakro benötigt. % \begin{macrocode} \newcommand*{\scr@secondoftwoAfterNil}{\scr@@secondoftwoAfterNil\@empty} \newcommand*{\scr@@secondoftwoAfterNil}{} \def\scr@@secondoftwoAfterNil#1\@nil{\@secondoftwo} % % \end{macrocode} % \end{macro}^^A \scr@@secondoftwoAfterNil % \end{macro}^^A \scr@secondoftwoAfterNil % \end{macro}^^A \ifisdimen % % \begin{macro}{\ifisskip} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.18a}{2015/07/07}{\cs{baselineskip} und \cs{parskip} werden als % skips akzeptiert}^^A % \changes{v3.20}{2015/10/19}{\cs{baselineskip} und \cs{parskip} sind keine % skips}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einem % \cs{skip}-Register (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\ifisskip}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisskip#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisskip} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf ein \cs{skip}-Register prüft % \begin{macrocode} \newcommand*{\scr@ifisskip}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisskip }{% \ifstrstart{\meaning #1}{\string\skip}{% \aftergroup\scr@TestSkipAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % \end{macrocode} % \end{macro}^^A \scr@ifisskip % \begin{macro}{\scr@TestSkipAssignTillNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Das durch \cs{@nil} begrenzte Argument wird einer temporären Länge % zugewiesen. Wird dabei das Argument komplett aufgebraucht, so wird das % erste Argument nach \cs{@nil} ausgeführt, sonst das zweite. Das begrenzte % Argument wird in jedem Fall komplett aufgebraucht. % \begin{macrocode} \newcommand*\scr@TestSkipAssignTillNil{} \def\scr@TestSkipAssignTillNil#1\@nil{% \begingroup \afterassignment\scr@AfterEndGroupIfArgIsRelaxTillNnil \@tempskipa=#1\relax\@nnil } % % \end{macrocode} % \end{macro}^^A \scr@TestSkipAssignTillNil % \end{macro}^^A \ifiskip % % \begin{macro}{\ifiscount} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einem % \cs{count}-Register (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\ifiscount}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifiscount#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifiscount} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf ein \cs{count}-Register prüft % \begin{macrocode} \newcommand*{\scr@ifiscount}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifiscount }{% \ifstrstart{\meaning #1}{\string\count}{% \aftergroup\scr@TestCountAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % \end{macrocode} % \end{macro}^^A \scr@ifiscount % \begin{macro}{\scr@TestSkipCountTillNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Das durch \cs{@nil} begrenzte Argument wird einer temporären Länge % zugewiesen. Wird dabei das Argument komplett aufgebraucht, so wird das % erste Argument nach \cs{@nil} ausgeführt, sonst das zweite. Das begrenzte % Argument wird in jedem Fall komplett aufgebraucht. % \begin{macrocode} \newcommand*\scr@TestCountAssignTillNil{} \def\scr@TestCountAssignTillNil#1\@nil{% \begingroup \afterassignment\scr@AfterEndGroupIfArgIsRelaxTillNnil \@tempcnta=#1\relax\@nnil } % % \end{macrocode} % \end{macro}^^A \scr@TestCountAssignTillNil % \end{macro}^^A \ifiscount % % % \begin{macro}{\ifisdimexpr} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einer % \cs{dimexpr} (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. Dies unterscheidet sich in einem % wichtigen Punkt von \cs{ifisdimen}: Sollte das ganze zwar als \cs{dimexpr} % beginnen, aber syntaktisch nicht korrekt sein, so wird dies nicht erkannt, % sondern führt tatsächlich zu einer Fehlermeldung. % \begin{macrocode} %<*base> \newcommand*{\ifisdimexpr}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisdimexpr#1\relax\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisdimexpr} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf eine \cs{dimexpr} prüft % \begin{macrocode} \newcommand*{\scr@ifisdimexpr}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisdimexpr }{% \ifstrstart{\meaning #1}{\string\dimexpr}{% \aftergroup\scr@TestDimenAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % % \end{macrocode} % \end{macro}^^A \scr@ifisdimexpr % \end{macro}^^A \ifisdimexpr % % % \begin{macro}{\ifisglueexpr} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einer % \cs{glueexpr} (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. Dies unterscheidet sich in einem % wichtigen Punkt von \cs{ifisskip}: Sollte das ganze zwar als \cs{glueexpr} % beginnen, aber syntaktisch nicht korrekt sein, so wird dies nicht erkannt, % sondern führt tatsächlich zu einer Fehlermeldung. % \begin{macrocode} %<*base> \newcommand*{\ifisglueexpr}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisglueexpr#1\relax\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisglueexpr} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf eine \cs{glueexpr} prüft % \begin{macrocode} \newcommand*{\scr@ifisglueexpr}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisglueexpr }{% \ifstrstart{\meaning #1}{\string\glueexpr}{% \aftergroup\scr@TestSkipAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % % \end{macrocode} % \end{macro}^^A \scr@ifisglueexpr % \end{macro}^^A \ifisglueexpr % % % \begin{macro}{\ifisnumexpr} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einer % \cs{numexpr} (und zu nichts weiterem!) expandiert, wird das erste % Argument ausgeführt, sonst das zweite. Dies unterscheidet sich in einem % wichtigen Punkt von \cs{ifiscount}: Sollte das ganze zwar als \cs{numexpr} % beginnen, aber syntaktisch nicht korrekt sein, so wird dies nicht erkannt, % sondern führt tatsächlich zu einer Fehlermeldung. % \begin{macrocode} %<*base> \newcommand*{\ifisnumexpr}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisnumexpr#1\relax\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisnumexpr} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf eine \cs{numexpr} prüft % \begin{macrocode} \newcommand*{\scr@ifisnumexpr}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisnumexpr }{% \ifstrstart{\meaning #1}{\string\numexpr}{% \aftergroup\scr@TestCountAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % % \end{macrocode} % \end{macro}^^A \scr@ifisnumexpr % \end{macro}^^A \ifisnumexpr % % % \begin{macro}{\ifisdefchar} % \changes{v3.20}{2015/10/19}{neu}^^A % Falls das erste Argument ggf. über mehrere Stufen hinweg zu einem mit % \cs{chardef} definierten Wert (und zu nichts weiterem!) expandiert, wird das % erste Argument ausgeführt, sonst das zweite. Dies unterscheidet sich in einem % wichtigen Punkt von \cs{ifiscount}: Sollte das ganze zwar wie ein \cs{char} % beginnen, aber syntaktisch nicht korrekt sein, so wird dies nicht erkannt, % sondern führt tatsächlich zu einer Fehlermeldung. % \begin{macrocode} %<*base> \newcommand*{\ifisdefchar}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisdefchar#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisdefchar} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf eine \cs{char} prüft % \begin{macrocode} \newcommand*{\scr@ifisdefchar}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisdefchar }{% \ifstrstart{\meaning #1}{\string\char\string"}{% \aftergroup\scr@TestCountAssignTillNil }{% \aftergroup\scr@secondoftwoAfterNil }% }% \endgroup #1% } % % \end{macrocode} % \end{macro}^^A \scr@ifisdefchar % \end{macro}^^A \ifisdefchar % % % \begin{macro}{\ifiscounter} % \changes{v3.12}{2013/11/05}{neu}^^A % Falls die Expansion des ersten Arguments ein \LaTeX-Zähler ist, wird das % zweite Argument ausgeführt, sonst das dritte. % \begin{macrocode} %<*base> \newcommand*{\ifiscounter}[1]{% \begingroup \scr@ifundefinedorrelax{c@#1}{% \aftergroup\@secondoftwo }{% \aftergroup\@firstoftwo }% \endgroup } % % \end{macrocode} % \end{macro}^^A \ifiscounter % % % \begin{macro}{\ifisinteger} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.12a}{2014/01/24}{Leerzeichenfehler korrigiert}^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}^^A % Falls die Expansion des ersten Arguments eine (positive oder negative) ganze % Zahl ist, wird das zweite Argument ausgeführt, sonst das dritte. % \begin{macrocode} %<*base> \newcommand*{\ifisinteger}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisinteger#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisinteger} % \changes{v3.20}{2015/10/19}{neu (intern)}^^A % Hilfsmacro, das ggf. rekusiv auf ein Vorzeichen oder eine positive Zahl % prüft. % \begin{macrocode} \def\scr@ifisinteger#1{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisinteger\aftergroup#1% }{% \ifstrstart{\meaning #1}{\detokenize{the character}}{% \if #1-\aftergroup\scr@ifisinteger \else \if #1+\aftergroup\scr@ifisinteger \else \ifnum 0=0\if #10\else\if #11\else\if #12\else\if #13\else \if #14\else\if #15\else\if #16\else\if #17\else \if #18\else\if #19\else 1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \relax \aftergroup\scr@TestCountAssignTillNil \aftergroup#1% \else \aftergroup\scr@secondoftwoAfterNil \aftergroup#1% \fi \fi \fi }{% \ifstrstart{\meaning #1}{\string\char\string"}{% \aftergroup\scr@TestCountAssignTillNil }{% \def\reserved@c{% \aftergroup\scr@secondoftwoAfterNil }% \@for\reserved@a:=\abovedisplayskip,\abovedisplayshortskip,% \adjdemerits,% \baselineskip,\belowdisplayskip,% \belowdisplayshortskip,\binoppenalty,\boxmaxdepth,% \brokenpenalty,% \clubpenalty,\count,% \dimen,\dimexpr,\doublehyphendemerits,\dp,% \emergenystretch,\exhyphenpenalty,% \finalhyphendemerits,% \glueexpr,% \hbadness,\hfuzz,\hsize,\ht,\hyphenpenalty,% \lastskip,\lastpenalty,\linepenalty,% \lineskip,\lineskiplimit,% \maxdepth,\numexpr,% \overfullrule,% \parfillskip,\parindent,\parskip,% \pdfpageheight,\pdfpagewidth,% \predisplaypenalty,\pretolerance,% \relpenalty,\widowpenalty,% \skip,\splitmaxdepth,\splittopskip,% \tolerance,\topskip,% \wd,\vbadness,\vfuzz,\vsize \do {% \expandafter\ifstr\expandafter{\expandafter\string\reserved@a}{% \meaning #1% }{% \def\reserved@c{\aftergroup\scr@TestCountAssignTillNil}% }% }% \reserved@c }% \aftergroup#1% }% }% \endgroup } % % \end{macrocode} % \end{macro}^^A \scr@ifisinteger % \end{macro}^^A \ifisinteger % % % \begin{macro}{\scr@ifrelax@to@nnil} % \changes{v3.12}{2013/11/05}{neu (intern)}^^A % Hilfsmakro, zur Verwendung beispielsweise nach Zuweissungen. Falls alles bis % zum ersten \cs{@nnil} aus genau einem \cs{relax} besteht, wird das erste % Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\scr@ifrelax@to@nnil}{} \def\scr@ifrelax@to@nnil#1\@nnil{% \begingroup \def\reserved@a{#1}\def\reserved@b{\relax}% \ifx\reserved@a\reserved@b \aftergroup\@firstoftwo \else \aftergroup\@secondoftwo \fi \endgroup } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifisdimension} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.12a}{2014/01/24}{Leerzeichenfehler korrigiert}^^A % \changes{v3.20}{2015/10/20}{Reimplementierung}^^A % Falls die stufenweise Expansion des ersten Arguments eine (positive oder % negative) Länge ist, wird das zweite Argument ausgeführt, sonst das % dritte. % \begin{macrocode} %<*base> \newcommand*{\ifisdimension}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisdimension#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisdimension} % \changes{v3.20}{2015/10/20}{neu (intern)} % Eigentlich wäre dieses Hilfsmakro extrem aufwändig, da eine Dimension recht % komplex aufgebaut sein darf. Ich habe aber beschlossen, hier mit einer % Heuristik zu Werke zu gehen: Wenn das Argument mit einer beliebigen Anzahl % Vorzeichen, gefolgt von max. einem Punkt, Komma oder einer Ziffer oder % gefolgt einem der für Längen zulässigen Primitiv beginnt, dann probieren wir % eine Zuweisung. Ist diese syntaktisch nicht korrekt, kann ein Fehler die % Folge sein. Das mag unschön sein, vereinfacht den Test aber erheblich! % \begin{macrocode} \newcommand*{\scr@ifisdimension}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisdimension\aftergroup#1% }{% \ifstrstart{\meaning #1}{\detokenize{the character}}{% \if #1-\aftergroup\scr@ifisdimension \else \if #1-\aftergroup\scr@ifisdimension \else \if #1.% \aftergroup\scr@TestDimensionAssignTillNil \aftergroup#1% \else \if #1,% \aftergroup\scr@TestDimensionAssignTillNil \aftergroup#1% \else \ifnum 0=0\if #10\else\if #11\else\if #12\else\if #13\else \if #14\else\if #15\else\if #16\else\if #17\else \if #18\else\if #19\else 1\fi\fi \fi\fi\fi\fi \fi\fi\fi\fi \relax \aftergroup\scr@TestDimensionAssignTillNil \aftergroup#1% \else \aftergroup\scr@secondoftwoAfterNil \aftergroup#1% \fi \fi \fi \fi \fi }{% \ifstrstart{\meaning #1}{\string\char\string"}{% \aftergroup\scr@TestDimensionAssignTillNil }{% \def\reserved@c{% \aftergroup\scr@secondoftwoAfterNil \aftergroup\@empty }% \@for\reserved@a:=\abovedisplayskip,\abovedisplayshortskip,% \adjdemerits,% \baselineskip,\belowdisplayskip,% \belowdisplayshortskip,\binoppenalty,\boxmaxdepth,% \brokenpenalty,% \clubpenalty,\count,% \dimen,\dimexpr,\doublehyphendemerits,\dp,% \emergenystretch,\exhyphenpenalty,% \finalhyphendemerits,% \glueexpr,% \hbadness,\hfuzz,\hsize,\ht,\hyphenpenalty,% \lastskip,\lastpenalty,\linepenalty,% \lineskip,\lineskiplimit,% \maxdepth,\numexpr,% \overfullrule,% \parfillskip,\parindent,\parskip,% \pdfpageheight,\pdfpagewidth,% \predisplaypenalty,\pretolerance,% \relpenalty,\widowpenalty,% \skip,\splitmaxdepth,\splittopskip,% \tolerance,\topskip,% \wd,\vbadness,\vfuzz,\vsize \do {% \expandafter\ifstr\expandafter{\expandafter\string\reserved@a}{% \meaning #1% }{% \def\reserved@c{\aftergroup\scr@TestDimensionAssignTillNil}% }% }% \reserved@c }% \aftergroup#1% }% }% \endgroup } % \end{macrocode} % \begin{macro}{\scr@TestDimenionAssignTillNil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Das durch \cs{@nil} begrenzte Argument wird einer temporären Länge % zugewiesen. Wird dabei das Argument komplett aufgebraucht, so wird das % erste Argument nach \cs{@nil} ausgeführt, sonst das zweite. Das begrenzte % Argument wird in jedem Fall komplett aufgebraucht. % \begin{macrocode} \newcommand*\scr@TestDimensionAssignTillNil{} \def\scr@TestDimensionAssignTillNil#1\@nil{% \begingroup \afterassignment\scr@AfterEndGroupIfArgIsRelaxTillptNnil \@tempdima=#1pt\@nnil } % \end{macrocode} % \begin{macro}{\scr@IfAfterEndgroupArgIsRelaxTillptNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % \begin{macro}{\scr@IfArgIsRelaxAfterRelaxTillptNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % Die Hilfsmakros lesen ein durch \cs{@nnil} begrenztes Argument. Falls dieses % Argument nur aus einer Folge von \cs{relax} besteht, wird das erste Argument % nach \cs{@nnil} ausgeführt, sonst das zweite. % \begin{macrocode} \newcommand*\scr@AfterEndGroupIfArgIsRelaxTillptNnil{} \def\scr@AfterEndGroupIfArgIsRelaxTillptNnil#1\@nnil{% \endgroup \ifstr{\detokenize{#1}}{\detokenize{pt}}{\@firstoftwo}{% \ifstrstart{\detokenize{#1}}{\detokenize{\relax}}{% \scr@IfArgIsRelaxAfterRelaxTillptNnil #1\@nnil }{\@secondoftwo}% }% } \newcommand*\scr@IfArgIsRelaxAfterRelaxTillptNnil{} \def\scr@IfArgIsRelaxAfterRelaxTillptNnil \relax#1pt\@nnil{% \ifstr{\detokenize{#1}}{\detokenize{pt}}{\@firstoftwo}{% \ifstrstart{\detokenize{#1}}{\detokenize{\relax}}{% \scr@IfArgIsRelaxAfterRelaxTillptNnil #1\@nnil }{\@secondoftwo}% }% } % % \end{macrocode} % \end{macro}^^A \scr@IfArgIsRelaxAfterRelaxTillptNnil % \end{macro}^^A \scr@IfArgIsRelaxTillptNnil % \end{macro}^^A \scr@DimensionSkipAssignTillNil % \end{macro}^^A \scr@ifisdimension % \end{macro}^^A \ifisdimension % % % \begin{macro}{\ifisglue} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.12a}{2014/01/24}{Leerzeichenfehler korrigiert}^^A % \changes{v3.20}{2015/10/21}{Reimplementierung}^^A % Falls die stufenweise Expansion des ersten Arguments eine (positive oder % negative) Länge mit Leim ist, wird das zweite Argument ausgeführt, sonst das % dritte. % \begin{macrocode} %<*base> \newcommand*{\ifisglue}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisglue#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisglue} % \changes{v3.20}{2015/10/21}{neu (intern)} % Eigentlich wäre dieses Hilfsmakro extrem aufwändig, da Leim recht % komplex aufgebaut sein darf. Ich habe aber beschlossen, hier mit einer % Heuristik zu Werke zu gehen: Wenn das Argument mit einer beliebigen Anzahl % Vorzeichen, gefolgt von max. einem Punkt, Komma oder einer Ziffer oder % gefolgt einem der für Leim zulässigen Primitiv beginnt, dann probieren wir % eine Zuweisung. Ist diese syntaktisch nicht korrekt, kann ein Fehler die % Folge sein. Das mag unschön sein, vereinfacht den Test aber erheblich! % \begin{macrocode} \newcommand*{\scr@ifisglue}[1]{% \begingroup \ifstrstart{\meaning #1}{\detokenize{macro:}}{% \aftergroup\expandafter\aftergroup\scr@ifisglue\aftergroup#1% }{% \ifstrstart{\meaning #1}{\detokenize{the character}}{% \if #1-\aftergroup\scr@ifisglue \else \if #1-\aftergroup\scr@ifisdimension \else \if #1.% \aftergroup\scr@TestGlueAssignTillNil \aftergroup#1% \else \if #1,% \aftergroup\scr@TestGlueAssignTillNil \aftergroup#1% \else \ifnum 0=0\if #10\else\if #11\else\if #12\else\if #13\else \if #14\else\if #15\else\if #16\else\if #17\else \if #18\else\if #19\else 1\fi\fi \fi\fi\fi\fi \fi\fi\fi\fi \relax \aftergroup\scr@TestGlueAssignTillNil \aftergroup#1% \else \aftergroup\scr@secondoftwoAfterNil \aftergroup#1% \fi \fi \fi \fi \fi }{% \ifstrstart{\meaning #1}{\string\char\string"}{% \aftergroup\scr@TestGlueAssignTillNil }{% \def\reserved@c{% \aftergroup\scr@secondoftwoAfterNil \aftergroup\@empty }% \@for\reserved@a:=\abovedisplayskip,\abovedisplayshortskip,% \adjdemerits,% \baselineskip,\belowdisplayskip,% \belowdisplayshortskip,\binoppenalty,\boxmaxdepth,% \brokenpenalty,% \clubpenalty,\count,% \dimen,\dimexpr,\doublehyphendemerits,\dp,% \emergenystretch,\exhyphenpenalty,% \finalhyphendemerits,% \glueexpr,% \hbadness,\hfuzz,\hsize,\ht,\hyphenpenalty,% \lastskip,\lastpenalty,\linepenalty,% \lineskip,\lineskiplimit,% \maxdepth,\numexpr,% \overfullrule,% \parfillskip,\parindent,\parskip,% \pdfpageheight,\pdfpagewidth,% \predisplaypenalty,\pretolerance,% \relpenalty,\widowpenalty,% \skip,\splitmaxdepth,\splittopskip,% \tolerance,\topskip,% \wd,\vbadness,\vfuzz,\vsize \do {% \expandafter\ifstr\expandafter{\expandafter\string\reserved@a}{% \meaning #1% }{% \def\reserved@c{\aftergroup\scr@TestGlueAssignTillNil}% }% }% \reserved@c }% \aftergroup#1% }% }% \endgroup } % \end{macrocode} % \begin{macro}{\scr@TestGlueAssignTillNil} % \changes{v3.20}{2015/10/21}{neu (intern)} % Das durch \cs{@nil} begrenzte Argument wird einer temporären Länge % zugewiesen. Wird dabei das Argument komplett aufgebraucht, so wird das % erste Argument nach \cs{@nil} ausgeführt, sonst das zweite. Das begrenzte % Argument wird in jedem Fall komplett aufgebraucht. % \begin{macrocode} \newcommand*\scr@TestGlueAssignTillNil{} \def\scr@TestGlueAssignTillNil#1\@nil{% \begingroup \afterassignment\scr@AfterEndGroupIfArgIsRelaxTillptNnil \@tempskipa=#1pt\@nnil } % % \end{macrocode} % \end{macro}^^A \scr@TestGlueAssignTillNil % \end{macro}^^A \scr@ifisglue % \end{macro}^^A \ifisglue % % % \begin{macro}{\ifnumber} % \changes{v3.12}{2013/10/30}{using \cs{aftergroup} instead of % \cs{endgroup}\cs{expandafter}}^^A % \changes{v3.12a}{2014/01/24}{Leerzeichenfehler korrigiert}^^A % Dieses Makro testet, ob ein übergebener Parameter eine positive, % ganze Zahl ist. Ist dies der Fall, wird der zweite Parameter % ausgeführt, sonst der dritte. % \begin{macrocode} %<*base> \newcommand\ifnumber[1]{% \begingroup\@tempswafalse\let\scr@next\test@number \expandafter\scr@next#1\scr@next \if@tempswa \aftergroup\@firstoftwo \else \aftergroup\@secondoftwo \fi \endgroup } % \end{macrocode} % \begin{macro}{\test@number} % Für den eigentlichen Test wird der erste Parameter Token für Token % gescannt und beurteilt. % \begin{macrocode} \newcommand*{\test@number}[1]{% \ifx \scr@next#1% \let\scr@next\relax \else % \end{macrocode} % Dabei wird für einen schnelleren Vergleich die Tatsache genutzt, dass % Ziffernzeichen immer im selben durchgängigen Bereich liegen % \begin{macrocode} \@tempcnta=\expandafter\expandafter\expandafter\number \expandafter`#1\relax \ifnum \@tempcnta>47 \ifnum \@tempcnta<58 \@tempswatrue \else\@tempswafalse\fi \else\@tempswafalse\fi % \end{macrocode} % Das zeichenweise Scannen und Parsen kann natürlich nicht einfach % abgebrochen werden. Stattdessen ist der Parameterrest noch zu % entfernen. % \begin{macrocode} \if@tempswa\else\let\scr@next\gobble@till@scr@next\fi \fi \scr@next } % \end{macrocode} % \begin{macro}{\gobble@tillscr@@next} % Das geschieht mit einem einzigen "`Leermacro"'. % \begin{macrocode} \newcommand*{\gobble@till@scr@next}{} \def\gobble@till@scr@next#1\scr@next{} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ifintnumber} % \changes{v3.12}{2013/10/30}{neu}^^A % Ist das erste Argument eine positive oder negative ganze Zahl, to wird das % zweite Argument ausgeführt, sonst das dritte. Wie bei \TeX{} auch sind % beliebig viele Vorzeichen erlaubt. % \begin{macrocode} %<*base> \newcommand\ifintnumber[1]{% \begingroup\@tempswafalse\let\scr@next\scr@test@sign \expandafter\scr@next#1\scr@next \if@tempswa \aftergroup\@firstoftwo \else \aftergroup\@secondoftwo \fi \endgroup } % \end{macrocode} % \begin{macro}{\scr@test@sign} % \changes{v3.12}{2013/10/30}{neu (intern)}^^A % \begin{macrocode} \newcommand*{\scr@test@sign}[1]{% \ifx \scr@next#1 \let\scr@next\relax \else \if #1-% \else \ifx #1+% \else \def\scr@next{\let\scr@next\test@number\scr@next #1}% \fi \fi \fi \scr@next } % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ifdimen} % Dieses Makro testet, ob ein übergebener Parameter eine Dimension % ist und führt in Abhängigkeit davon den zweiten oder dritten % Parameter aus. % \begin{macrocode} %<*base> \newcommand{\ifdimen}[1]{% \begingroup\@tempswatrue\let\scr@next\test@posdimen \expandafter\test@dimen#1\scr@next \if@tempswa \endgroup\expandafter\@firstoftwo \else \endgroup\expandafter\@secondoftwo \fi } % \end{macrocode} % \begin{macro}{\test@dimen} % Als erste muss ein Vorzeichen entfernt werden. % \begin{macrocode} \newcommand*{\test@dimen}[1]{% \ifx -#1\else\ifx +#1\else \def\scr@next{\let\scr@next\test@posdimen\scr@next#1}\fi\fi \scr@next } % \end{macrocode} % \begin{macro}{\test@posdimen} % Dann muss getestet werden, ob es sich beim Rest um eine Dimension % handelt. Dabei werden der Einfachheit halber mehrere Dezimalkomma % und -punkte erlaubt. Natürlich könnte man es auch wirklich richtig % machen, aber das wäre nochmal etwas aufwendiger. Ist das wirklich % notwendig? % \begin{macrocode} \newcommand*{\test@posdimen}[1]{% \ifx \scr@next#1% \@tempswafalse\let\scr@next\relax \else \if .#1\else\if ,#1\else \@tempcnta=% \expandafter\expandafter\expandafter\number\expandafter`#1\relax \ifnum \@tempcnta>47 \ifnum \@tempcnta<58 \else\def\scr@next{\test@dimunt#1}\fi \else\def\scr@next{\test@dimunt#1}\fi \fi\fi \fi \scr@next } % \end{macrocode} % \begin{macro}{\test@dimunt} % \begin{macro}{\test@trueunt} % Außer einer Gleitkomma- bzw. Gleitpunktzahl muss auch noch die Einheit % behandelt werden. Dabei sind sowohl die neun Standardeinheiten als auch % deren "`true"'-Variante zu berücksichtigen. Deshalb wird zuerst ein % eventuelles "`\texttt{true}"' weggeworfen. % \begin{macrocode} \newcommand*{\test@dimunt}{} \def\test@dimunt#1\scr@next{% \expandafter\test@trueunt#1truetrue\test@trueunt } \newcommand*{\test@trueunt}{} \def\test@trueunt#1true#2true#3\test@trueunt{% \edef\reserved@a{#1}% \ifx\reserved@a\@empty\test@@ifdimunt{#2}\else\test@@ifdimunt{#1}\fi } % \end{macrocode} % \begin{macro}{\test@@ifdimunt} % \changes{v3.21}{2016/05/27}{elf bis zwölf Einheiten nicht neun} % Anschließend wird dann getestet, ob es sich um eine der elf bis zwölf % üblichen Einheiten handelt. % \begin{macrocode} \newcommand*\test@@ifdimunt[1]{% \@tempswafalse \ifstr{#1}{pt}{\@tempswatrue}{% \ifstr{#1}{pc}{\@tempswatrue}{% \ifstr{#1}{in}{\@tempswatrue}{% \ifstr{#1}{bp}{\@tempswatrue}{% \ifstr{#1}{cm}{\@tempswatrue}{% \ifstr{#1}{mm}{\@tempswatrue}{% \ifstr{#1}{dd}{\@tempswatrue}{% \ifstr{#1}{cc}{\@tempswatrue}{% \ifstr{#1}{sp}{\@tempswatrue}{% \ifstr{#1}{ex}{\@tempswatrue}{% \ifstr{#1}{em}{\@tempswatrue}{% \scr@ifpdfoutput{% \ifstr{#1}{px}{\@tempswatrue}{}% }{}% }% }% }% }% }% }% }% }% }% }% }% } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\ifpdftex} % \changes{v2.95}{2002/08/19}{neu}^^A % \begin{macro}{\scr@ifpdftex} % \changes{v2.95}{2002/08/19}{neu (intern)}^^A % If-then-else-Konstrukt, um zu testen, ob pdf\TeX{} verwendet wird. % \begin{macrocode} %<*base> \newcommand{\scr@ifpdftex}{\ifnotundefined{pdftexversion}} \let@as@internal@defined{ifpdftex} \BeforePackage{pdfcprot}{\let\ifpdftex\relax} \AfterPackage{pdfcprot}{\let@as@internal@defined{ifpdftex}} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\scr@ifluatex} % \changes{v3.21}{2016/05/27}{neu (intern)}^^A % If-the-else-Konstrukt, um zu testen, ob lua\TeX{} verwendet wird. % \begin{macrocode} %<*base> \newcommand{\scr@ifluatex}{\ifnotundefined{luatexversion}} % % \end{macrocode} % \end{macro} % % \begin{macro}{\scr@ifpdforluatex} % \changes{v3.21}{2016/05/27}{neu (intern)}^^A % If-then-else-Konstrukt, um zu testen, ob pdf\TeX{} oder lua\TeX{} verwendet % wird. % \begin{macrocode} %<*base> \newcommand*{\scr@ifpdforluatex}{% \scr@ifpdftex{\@firstoftwo}{\scr@ifluatex{\@firstoftwo}{\@secondoftwo}}% } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ifVTeX} % \changes{v2.95}{2002/08/19}{neu}^^A % \changes{v2.97c}{2007/06/20}{umdefiniert von \cs{ifvtex}} % \begin{macro}{\scr@ifVTeX} % \changes{v2.95}{2002/08/19}{neu}^^A % \changes{v2.97c}{2007/06/20}{umdefiniert von \cs{scr@ifvtex}} % If-then-else-Konstrukt, um zu testen, ob V\TeX{} verwendet wird. % \begin{macrocode} %<*base> \newcommand{\scr@ifVTeX}{\ifnotundefined{VTeXversion}} \let@as@internal@defined{ifVTeX} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ifpdfoutput} % \changes{v2.7g}{2001/04/17}{neu}^^A % \changes{v2.8q}{2001/10/19}{\cs{pdfoutput} wird nicht mehr zu % \cs{relax}, wenn zuvor undefiniert} % \changes{v2.8q}{2001/10/19}{darf bereits definiert sein}^^A % \changes{v2.8q}{2001/10/19}{Verwendung von \cs{scr@ifpdfoutput}} % \begin{macro}{\scr@ifpdfoutput} % \changes{v2.8q}{2001/10/19}{neu (intern)}^^A % \changes{v2.8q}{2001/11/13}{funktioniert}^^A % \changes{v2.95}{2002/08/21}{berücksichtigt V\TeX}^^A % \changes{v2.95}{2004/07/20}{Expandierbarkeit verbessert}^^A % \changes{v3.21}{2016/05/27}{lua\TeX{} nach 0.85 berücksichtigt}^^A % If-then-else-Konstrukt, um abhängig davon, ob als \texttt{pdf} % ausgegeben wird oder nicht, Befehle auszuführen. Dieses Makro wird % für die Deklaration der Option \texttt{pagesize} benötigt. % \begin{macrocode} %<*base> \newcommand{\scr@ifpdfoutput}{% \scr@ifundefinedorrelax{pdfoutput}{% \scr@ifundefinedorrelax{outputmode}{% \scr@ifundefinedorrelax{OpMode}{% \expandafter\@secondoftwo% }{% \ifnum\OpMode=1 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% }{% \ifnum\outputmode>0 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% }{% \ifnum\pdfoutput>0 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% }% \let@as@internal@defined{ifpdfoutput} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ifpsoutput} % \changes{v2.95}{2002/08/21}{neu}^^A % \begin{macro}{\scr@ifpsoutput} % \changes{v2.95}{2002/08/21}{neu (intern)}^^A % \changes{v2.95}{2004/07/20}{Expandierbarkeit verbessert}^^A % If-then-else-Konstrukt, um abhängig davon, ob früher oder später % \texttt{ps} ausgegeben wird oder nicht, Befehle auszuführen. % \begin{macrocode} %<*base> \newcommand*{\scr@ifpsoutput}{% \ifnotundefined{if@dvips}{% \if@dvips \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }{% \ifnotundefined{OpMode}{% \ifnum\OpMode=2 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }{% \expandafter\@secondoftwo }% }% } \let@as@internal@defined{ifpsoutput} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ifdvioutput} % \changes{v2.95}{2002/08/21}{neu}^^A % \begin{macro}{\scr@ifdvioutput} % \changes{v2.95}{2002/08/21}{neu (intern)}^^A % \changes{v2.95}{2004/07/20}{Expandierbarkeit verbessert}^^A % \changes{v3.23}{2017/02/14}{lua\TeX{} nach 0.85 berücksichtigt}^^A % If-then-else-Konstrukt, um abhängig davon, ob \texttt{dvi} % ausgegeben wird oder nicht, Befehle auszuführen. % \begin{macrocode} %<*base> \newcommand*{\scr@ifdvioutput}{% \scr@ifundefinedorrelax{pdfoutput}{% \scr@ifundefinedorrelax{outputmode}{% \scr@ifundefinedorrelax{OpMode}{% \expandafter\@firstoftwo }{% \ifnum\OpMode=0 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% }{% \ifnum\outputmode>0 \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi }% }{% \ifnum\pdfoutput=0 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% } \let@as@internal@defined{ifdvioutput} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\scr@smashdp} % \changes{v2.97c}{2007/09/17}{neu (intern)}^^A % \changes{v3.02a}{2009/01/23}{\cs{smash} nicht direkt verwenden, weil % \textsf{amsmath} das inkompatibel umdefiniert} % Gibt Material aus, erzeugt dabei aber nur Höhe und Breite, jedoch keine % Tiefe. % \begin{macrocode} %<*base> \newcommand*{\scr@smashdp}[1]{% \begingroup \def\finsm@sh{\dp\z@\z@\box\z@}% \ifmmode \expandafter\mathpalette\expandafter\mathsm@sh \else \expandafter\makesm@sh \fi {#1}% \endgroup } % % \end{macrocode} % \end{macro} % % \begin{macro}{\IfRTL} % \changes{v3.24}{2017/05/04}{neu} % Die Anweisung testet, ob wir uns gerade im Von-Rechts-Nach-Links-Modus von % Paketen wie \textsf{bidi} befinden. Ist das der Fall, wird das erste % Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\IfRTL}{% \scr@ifundefinedorrelax{if@RTL}{\@secondoftwo}{% \expandafter\ifx\csname if@RTL\expandafter\endcsname \csname iftrue\endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } } % % \end{macrocode} % \end{macro}^^A \IfRTL % \begin{macro}{\IfLTR} % \changes{v3.24}{2017/05/04}{neu} % Die Anweisung testet, ob wir uns gerade nicht im % Von-Rechts-Nach-Links-Modus von Paketen wie \textsf{bidi} befinden. Ist % das der Fall, wird das erste Argument ausgeführt, sonst das zweite. % \begin{macrocode} %<*base> \newcommand*{\IfLTR}{% \scr@ifundefinedorrelax{if@RTL}{\@firstoftwo}{% \expandafter\ifx\csname if@RTL\expandafter\endcsname \csname iftrue\endcsname \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } } % % \end{macrocode} % \end{macro}^^A \IfLTR % % \begin{macro}{\PackageInfoNoLine} % \changes{v2.97d}{2007/10/03}{neu}^^A % Arbeitet wie \cs{PackageInfo} aber ohne Ausgabe der Zeilennummer. % \begin{macrocode} %<*base> \providecommand*{\PackageInfoNoLine}[2]{% \PackageInfo{#1}{#2\@gobble}% } % % \end{macrocode} % \end{macro} % % \begin{macro}{\ClassInfoNoLine} % \changes{v2.98c}{2008/02/15}{neu}^^A % Arbeitet wie \cs{ClassInfo} aber ohne Ausgabe der Zeilennummer. % \begin{macrocode} %<*base> \providecommand*{\ClassInfoNoLine}[2]{% \ClassInfo{#1}{#2\@gobble}% } % % \end{macrocode} % \end{macro} % % \begin{macro}{\@removefromreset} % \changes{v3.15}{2014/11/21}{neue Anweisung, kompatibel mit % \textsf{remreset} und \textsf{chngcntr}}^^A % Dieser alte Bekannte aus dem Paket \textsf{remreset} wird auch von % \KOMAScript{} benötigt. Es ist einfacher, ihn selbst zu definieren, als sich % auf andere Pakete zu verlassen. % \begin{macrocode} %<*base> \providecommand*\@removefromreset[2]{% {% \expandafter\let\csname c@#1\endcsname\@removefromreset \def\@elt##1{% \expandafter\ifx\csname c@##1\endcsname\@removefromreset \else\noexpand\@elt{##1}\fi }% \expandafter\xdef\csname cl@#2\endcsname{\csname cl@#2\endcsname}% }% } % % \end{macrocode} % \end{macro} % % \subsection{Definition von KOMA-\textsf{keyval}-Schlüsseln (Hauptteil)} % % \begin{macro}{\FamilyExecuteOptions} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % \changes{v3.04b}{2010/01/29}{\cs{edef} durch \cs{protected@edef} ersetzt}^^A % \changes{v3.04b}{2010/02/02}{\cs{scr@key@atlist} und \cs{scr@key@name}^^A % vor Überschreiben in \cs{serkeys} geschützt}^^A % \changes{v3.12}{2013/03/04}{neue Implementierung}^^A % \changes{v3.12}{2013/03/04}{darf auch noch nach der Präambel verwendet % werden}^^A % \changes{v3.14}{2014/10/17}{das dritte Argument wird \cs{long}^^A % verarbeitet}^^A % \begin{macro}{\@FamilyExecuteOptions} % \changes{v3.14}{2014/10/17}{Neue streng interne Anweisung}^^A % \changes{v3.23}{2017/02/16}{Korrektur: Haken danach verwendet die Familie % statt des Mitglieds}^^A % Entspriche \cs{ExecuteOptions} jedoch \textsf{keyval}-Optionen. Insbesondere % ist die Anweisung reentrant! Es ist jedoch zu beachten, dass der hook lokal % zum jeweiligen Aufruf ist. % \begin{macrocode} %<*base> \newcommand*{\FamilyExecuteOptions}[2][.\@currname.\@currext]{% \@FamilyExecuteOptions[{#1}]{#2}% } \newcommand{\@FamilyExecuteOptions}[3][.\@currname.\@currext]{% \scr@ifundefinedorrelax{scr@after@options@#2@hook}{% \@namedef{scr@after@options@#2@hook}{% \@namedef{scr@after@options@#2@hook}{}% }% }{% \expandafter\edef\csname scr@after@options@#2@hook\endcsname{% \noexpand\@namedef{scr@after@options@#2@hook}{% \unexpanded\expandafter\expandafter\expandafter {\csname scr@after@options@#2@hook\endcsname}% }% }% }% \@for\scr@key@atlist:=#3\do{% \expandafter\scr@key@split@name@value\scr@key@atlist==\@nil \ifx\scr@key@name\@empty\else \ifx\scr@key@name\space\else \scr@ifundefinedorrelax{KV@#2@\scr@key@name}{% \scr@ifundefinedorrelax{KV@#2#1@\scr@key@name}{% % \end{macrocode} % \changes{v3.20}{2015/11/18}{Besondere Behandlung der % \texttt{@else@}-Option}^^A % Es existiert zwar weder eine Familienoption noch eine Mitgliedsoption, aber % vielleicht existiert ja die Spezialoption \texttt{@else@}, die in einem % solchen Fall die eigentliche Option als Wert erhält. % \begin{macrocode} \scr@ifundefinedorrelax{KV@#2#1@@else@}{% \PackageError{scrbase}{% unknown option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% }{% Member `#1' of family `#2'\MessageBreak cannot handle option `\scr@key@name'.\MessageBreak So it cannot be set% \ifx\scr@key@value\@empty\else \space to value `\expandafter\detokenize\expandafter{\scr@key@value}'% \fi.% }% }{% \scr@execute@elseoption{#2#1}% % \end{macrocode} % Im Gegensatz zu anderen Optionen bedeuten bei der \texttt{@else@}-Option % alle von \cs{FamilyKeyStateProcessed} abweichenden Ergebnisse, dass die % Option nicht korrekt verarbeitet werden konnte und deshalb die ursprüngliche % Option als Fehler zu melden ist. % \begin{macrocode} \ifx\FamilyKeyState\FamilyKeyStateProcessed\else \PackageError{scrbase}{% unknown option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% }{% Member `#1' of family `#2'\MessageBreak cannot handle option `\scr@key@name'.\MessageBreak So it cannot be set% \ifx\scr@key@value\@empty\else \space to value `\expandafter\detokenize\expandafter{\scr@key@value}'% \fi.% }% \fi }% }{% \scr@execute@option{#2#1}% }% }{% \scr@execute@option{#2}% \ifstr{#1}{}{}{% % \end{macrocode} % \changes{v3.20}{2015/11/18}{Memberoptionstest nach Familyoptionsausführung % korrigiert}^^A % Auch wenn eine Familienoption ausgeführt wurde, muss eine existierende % Mitgliederoption ggf. noch ausgeführt werden. Existiert sie nicht, wird % ebenfalls eine existierende \texttt{@else@}-Option ausgeführt. Allerdings % führen in diesem Fall von \cs{FamilyKeyStateProcessed} abweichende % Ergebnisse nicht zu einer Fehlermeldung. % \begin{macrocode} \scr@ifundefinedorrelax{KV@#2#1@\scr@key@name}{% \scr@ifundefinedorrelax{KV@#2#1@@else@}{}{% \scr@execute@elseoption{#2#1}% }% }{% \ifx\FamilyKeyState\FamilyKeyStateProcessed \scr@execute@option{#2#1}% \FamilyKeyStateProcessed \else \scr@execute@option{#2#1}% \fi }% }% }% \scr@show@key@state@error \fi \fi }% \@nameuse{scr@after@options@#2@hook}% } % % \end{macrocode} % \begin{macro}{\scr@show@key@state@error} % \changes{v3.12}{2013/03/04}{Neue Anweisung (intern)}% % Zeige abhängig von \cs{FamilyKeyState} eine Fehlermeldung. Alle % Informationen zu dem Fehler müssen in \cs{FamilyMemberOfKey} % (Familienmitglied oder \cs{@empty}), \cs{FamilyOfKey} (Familie oder % \cs{@empty}), \cs{scr@key@atlist} (Option, wie sie in der Liste stand), % \cs{scr@key@name} (Name der Option) und \cs{scr@key@value} (Wert der % Option) stehen. Es ist zu beachten, dass \cs{scr@key@atlist} und % \cs{scr@key@value} ebenfalls Macros enthalten können. Deshalb werden diese % Werte ggf. über \cs{detokenize} ausgegeben. % \begin{macrocode} %<*base> \newcommand*{\scr@show@key@state@error}{% \ifx\FamilyKeyState\FamilyKeyStateProcessed\else \PackageError{scrbase}{% unknown option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% }{% Option `\expandafter\detokenize\expandafter{\scr@key@name}'\MessageBreak \ifx\FamilyMemberOfKey\@empty\else of member `\FamilyMemberOfKey'\MessageBreak \fi \ifx\FamilyOfKey\@empty\else of family `\FamilyOfKey'\MessageBreak \fi \ifx\FamilyKeyState\FamilyKeyStateNeedValue expects a value, but has been used without any value.% \else cannot handle value\MessageBreak `\expandafter\detokenize\expandafter{\scr@key@value}',% \MessageBreak \ifx\FamilyKeyState\FamilyKeyStateUnknownValue because this is an unsupported value.% \else because \FamilyKeyState. \fi \fi }% \fi } % % \end{macrocode} % \end{macro}^^A \scr@show@key@state@error % \end{macro}^^A \@FamilyExecuteOptions % \end{macro}^^A \FamilyExecuteOptions % % \begin{macro}{\KOMAExecuteOptions} % \changes{v2.97c}{2007/04/19}{Neue Anweisung}^^A % \changes{v3.00}{2008/04/30}{Kein optionales Argument mehr}^^A % \changes{v3.12}{2013/03/04}{darf auch noch nach der Präambel verwendet % werden}^^A % Liste von Optionen für ein Mitglied der Familie \texttt{KOMA} ausführen. % \begin{macrocode} %<*koma> \newcommand*{\KOMAExecuteOptions}[1][.\@currname.\@currext]{% \FamilyExecuteOptions[#1]{KOMA}% } % % \end{macrocode} % \end{macro} % % \begin{macro}{\FamilyOptions} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % \changes{v3.12}{2013/03/02}{Neue Implementierung}^^A % \changes{v3.12}{2013/03/02}{\cs{scr@after@options@\#1@hook}}^^A % \changes{v3.14}{2014/10/17}{zweites Argument wird \cs{long} behandelt}^^A % \begin{macro}{\@FamilyOptions} % \changes{v3.14}[2014/10/17]{Neue streng interne Anweisung}^^A % \begin{macro}{\Family@Options} % \changes{v3.00}{2008/04/30}{Neues Makro (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt}^^A % \end{macro}^^A \FamilyOptions % Es werden Schlüssel einer Familie verwendet. Existiert ein Schlüssel nicht, % oder ist der Wert für alle Schlüssel unbekannt, so wird ein Fehler % ausgegeben. Diese Anweisung selbst ist reentrant, das heißt sie kann auch % innerhalb der Ausführung von Optionen aufgerufen werden. Es sei jedoch % erwähnt, dass der hook dabei nur die jeweilige Anweisung umfasst. % \begin{macrocode} %<*base> \newcommand{\FamilyOptions}[1]{\@FamilyOptions{#1}} \newcommand{\@FamilyOptions}[2]{% \scr@ifundefinedorrelax{scr@after@options@#1@hook}{% \@namedef{scr@after@options@#1@hook}{% \@namedef{scr@after@options@#1@hook}{}% }% }{% \expandafter\edef\csname scr@after@options@#1@hook\endcsname{% \noexpand\@namedef{scr@after@options@#1@hook}{% \unexpanded\expandafter\expandafter\expandafter {\csname scr@after@options@#1@hook\endcsname}% }% }% }% % \end{macrocode} % \changes{v3.23}{2017/02/16}{neuer Haken für \cs{AtEndOfFamilyOptions*}}^^A % Seit Version 3.23 wird hier auch der neuen Haken vor % \cs{AtEndOfFamilyOptions*} initialisiert. Zunächst findet eine Art % Vorinitialisierung statt, bei der der Haken lediglich leer definiert wird, % falls er noch nicht existiert. Falls er nämlich existiert, kann an einem % leeren Haken die oberste Ebene erkannt werden. % \begin{macrocode} \scr@ifundefinedorrelax{scr@after@options@#1@hook@topmost}{% \@namedef{scr@after@options@#1@hook@topmost}{}% }{}% % \end{macrocode} % Dann wird an einem leeren Haken die oberste Ausführungsebene erkennt. In % diesem Fall wird zum einen die Ausführung des Hakens in den normalen % Ebenen-Haken (das ist dann automatische der oberste Ebenen-Haken) % eingehängt und zum anderen der Haken selbst so initialisiert, dass er sich % bei seiner Ausführung als erstes selbst löscht. Gleichzeitig ist der Haken % selbst dadurch nicht mehr leer, so dass sich tiefere Ebenen von der höchsten % eindeutig unterscheiden. % \begin{macrocode} \expandafter\ifx\csname scr@after@options@#1@hook@topmost\endcsname\@empty \expandafter\l@addto@macro\csname scr@after@options@#1@hook\endcsname{% \@nameuse{scr@after@options@#1@hook@topmost}% }% \@namedef{scr@after@options@#1@hook@topmost}{% \@namedef{scr@after@options@#1@hook@topmost}{}% }% \fi % \end{macrocode} % \begin{description} % \item[Anmerkung:] Es wird nicht auf \textsf{xkeyval} und den dortigen Befehl % \cs{setkeys+} gesetzt, weil dieser die Optionen nicht in der Reihenfolge % der Optionen, sondern in der Reihenfolge der Familien ausführt. Das passt % mir aber hier gar nicht. % \end{description} % In einer Schleife über alle Optionen werden die Optionen zunächst in Option % und Wert aufgespaltet. % \begin{macrocode} \@for\scr@key@atlist:=#2\do{% % \end{macrocode} % \changes{v3.08}{2010/11/05}{leere Argumente in der Optionenliste}% % Auf vielfachen Wunsch und entgegen meiner Überzeugung, sind auch leere % Argumente in der Optionenliste erlaubt. Die erste Form wäre, wenn zwei % Kommas diret aufeinander folgen: % \begin{macrocode} \ifx\scr@key@atlist\@empty\else % \end{macrocode} % Die zweite Möglichkeit wäre, dass noch Leerzeichen zwischen den Komma % übrig bleiben: % \begin{macrocode} \ifx\scr@key@atlist\space\else \expandafter\scr@key@split@name@value\scr@key@atlist==\@nil % \end{macrocode} % Die dritte Möglichkeit, dass auch noch ein Gleichheitszeichen übrig % gelassen wurde, werde ich aber nicht abfangen. Irgendwann müssen die % Anwender auch mal ihre Fehler einsehen und korrigieren! % % Wir haben jetzt also eine Option und diese aufgespaltet in Schlüssel und % Wert. % \changes{v3.12}{2013/03/04}{der Gesamtstatus wird gespeichert}^^A % Jetzt speichern wir den Gesamtstatus einfach, indem der Fehlerspeicher % gelöscht wird. Bei \cs{relax} wird er nicht weiter benötigt und es liegt % ebenso wie bei \cs{@empty} kein auszugebender Fehler vor. Bei anderen % Werten, enthält er Fehler, die zu melden sind. % \begin{macrocode} \let\scr@key@run@errors\@empty % \end{macrocode} % % \changes{v3.04b}{2010/01/29}{\cs{edef} durch \cs{protected@edef} ersetzt} % \changes{v3.09a}{2011/06/07}{weniger Expansion durch sinnvollen Gebrauch % von \cs{unexpanded}} % Dann wird in einer Schleife über alle Familien festgestellt, ob die Option % in einer Familie bekannt ist und ggf. ausgeführt. Hier ist wichtig, dass % keines der internen Macros vom Aufruf verändert wird. Außerdem muss der % Status und die daraus resultierenden Meldungen aufgesammelt werden. % \begin{macrocode} \scr@key@found@false \edef\reserved@a{\csname #1@key@familylist\endcsname}% \@for\reserved@a:=\reserved@a\do{% \scr@ifundefinedorrelax{KV@\reserved@a @\scr@key@name}{}{% \expandafter\scr@execute@option\expandafter{\reserved@a}% \scr@key@found@true \ifx\scr@key@run@errors\relax\else \ifx\FamilyKeyState\FamilyKeyStateProcessed \let\scr@key@run@errors\relax \else \ifx\FamilyKeyState\FamilyKeyStateUnknownValue \edef\scr@key@run@errors{% \unexpanded\expandafter{\scr@key@run@errors}% \noexpand\MessageBreak \FamilyMemberOfKey: unkown value `\expandafter\detokenize\expandafter{\scr@key@value}'.% }% \else \ifx\FamilyKeyState\FamilyKeyStateNeedValue \edef\scr@key@run@errors{% \unexpanded\expandafter{\scr@key@run@errors}% \noexpand\MessageBreak \FamilyMemberOfKey: value expected. }% \else \edef\scr@key@run@errors{% \unexpanded\expandafter{\scr@key@run@errors}% \noexpand\MessageBreak \FamilyMemberOfKey: \FamilyKeyState. }% \fi \fi \fi \fi }% }% \ifscr@key@found@ \ifx\scr@key@run@errors\relax\else \ifx\scr@key@run@errors\@empty\else \PackageError{scrbase}{% unknown option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% }{% The members of family `#1' cannot set option `\scr@key@name' \ifx\scr@key@value\@empty\else \MessageBreak to value `\expandafter\detokenize\expandafter{\scr@key@value}'% \fi.\MessageBreak Here's what each member says: \scr@key@run@errors }% \fi \fi \else \PackageError{scrbase}{% unknown option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% }{% No one of the members of family `#1'\MessageBreak can handle option `\scr@key@name'.\MessageBreak So it cannot be set% \ifx\scr@key@value\@empty\else \space to value `\expandafter\detokenize\expandafter{\scr@key@value}'% \fi.% }% \fi \fi \fi }% \@nameuse{scr@after@options@#1@hook}% } % \end{macrocode} % \begin{macro}{\scr@execute@option} % \changes{v3.12}{2013/03/04}{Neue Anweisung (intern)}^^A % \changes{v3.13}{2014/06/30}{fehlendes \cs{expandafter} in \cs{PackageInfo} % ergänzt}^^A % \changes{v3.13a}{2014/08/13}{Leerzeichen durch fehlendes Prozentzeichen % beseitigt}^^A % \changes{v3.23}{2017/02/16}{den \cs{AtEndOfFamilyOptions} Haken hier zu % sichern nützt nichts}^^A % Es wird die bereits gesplittete Option ausgeführt, ohne dass die dabei % wesentlichen Macros (aber nicht \cs{reserved@a}!) verändert werden. Das % erste Argument ist bereits der Besitzer in \textsf{keyval}-Syntax. % \begin{macrocode} \newcommand*{\scr@execute@option}[1]{% \protected@edef\reserved@a{% \noexpand\let\noexpand\KV@err\noexpand\scr@KV@err \noexpand\setkeys{#1}{% \unexpanded\expandafter{\scr@key@atlist}}% \noexpand\def\noexpand\scr@key@atlist{% \unexpanded\expandafter{\scr@key@atlist}}% \noexpand\def\noexpand\scr@key@name{% \unexpanded\expandafter{\scr@key@name}}% \noexpand\def\noexpand\scr@key@value{% \unexpanded\expandafter{\scr@key@value}}% \ifx\scr@key@run@errors\relax \noexpand\let\noexpand\scr@key@run@errors\relax \else \noexpand\def\noexpand\scr@key@run@errors{% \unexpanded\expandafter{\scr@key@run@errors}}% \fi \ifx\AtEndOfFamilyOptions\scr@AtEndOfFamilyOptions@immediate \noexpand\let\noexpand\AtEndOfFamilyOptions \noexpand\scr@AtEndOfFamilyOptions@immediate \fi }% \let\AtEndOfFamilyOptions\scr@AtEndOfFamilyOptions \reserved@a \ifx\FamilyKeyState\FamilyKeyStateUnknown \PackageInfo{scrbase}{Unknown processing state.\MessageBreak Processing option `\expandafter\detokenize\expandafter{\scr@key@atlist}'\MessageBreak \ifx\FamilyMemberOfKey\@empty\else of member `\FamilyMemberOfKey'\MessageBreak \fi of family `\FamilyOfKey'\MessageBreak doesn't set a valid state.\MessageBreak This will be interpreted\MessageBreak as \string\FamilyKeyStateProcessed }% \FamilyKeyStateProcessed \fi } % \end{macrocode} % \begin{macro}{\scr@KV@err} % \changes{v3.12a}{2013/03/04}{missing internal command added}^^A % We just have to signal, that the option needs a value, that is missing. % \begin{macrocode} \newcommand*{\scr@KV@err}[1]{% \FamilyKeyStateNeedValue } % \end{macrocode} % \end{macro} % \begin{macro}{\scr@key@run@errors} % \changes{v3.12}{2013/03/04}{Neue Anweisung (intern)}^^A % Wird innerhalb von \cs{FamilyOptions} benötigt, um die Fehlermeldungen % aufzusammeln, aber erst auszugeben, wenn tatsächlich kein Mitglied die % Option verarbeiten konnte. Wir definieren das hier, damit oben die % Wiederherstellung korrekt funktioniert. % \begin{macrocode} \newcommand*{\scr@key@run@errors}{} % \end{macrocode} % \end{macro}^^A \scr@key@run@errors} % \end{macro}^^A \scr@execute@option % \begin{macro}{\scr@execute@elseoption} % \changes{v3.20}{2015/11/18}{neu (intern)} % Ist eine Spezialoption mit dem Namen \texttt{@else@} definiert, so wird % diese von \cs{FamilyExecuteOptions} genau dann ausgeführt, wenn keine % passende Option gefunden wurde. Dafür dient dieses Makro, dessen Argumente % und Aufrufstatus genau \cs{scr@execute@option} entspricht. Es soll auch % genau dasselbe tun, außer dass es nicht die Option selbst aufruft, sondern % die Option als Wert an die \texttt{@else@}-Option übergibt. Es muss also % temporär \cs{scr@key@atlist}, \cs{scr@key@name} und \cs{scr@key@value} % geändert werden, bevor \cs{scr@execute@option} ausgeführt wird. % \begin{macrocode} \newcommand*{\scr@execute@elseoption}[1]{% \protected@edef\reserved@a{% \noexpand\def\noexpand\scr@key@name{@else@}% \noexpand\def\noexpand\scr@key@value{% \unexpanded\expandafter{\scr@key@atlist}}% \noexpand\def\noexpand\scr@key@atlist{% @else@={\unexpanded\expandafter{\scr@key@atlist}}}% \noexpand\scr@execute@option{#1}% \noexpand\def\noexpand\scr@key@atlist{ \unexpanded\expandafter{\scr@key@atlist}}% \noexpand\def\noexpand\scr@key@name{% \unexpanded\expandafter{\scr@key@name}}% \noexpand\def\noexpand\scr@key@value{% \unexpanded\expandafter{\scr@key@value}}% }\reserved@a } % \end{macrocode} % \end{macro}^^A \scr@execute@elseoption % \begin{macro}{\ifscr@key@found@} % \changes{v2.97c}{2007/04/19}{Neuer Schalter (intern)}^^A % \changes{v3.00}{2008/04/30}{umbenannt von \cs{ifKOMA@key@found}} % \begin{macro}{\scr@key@atlist} % \changes{v2.97c}{2007/04/19}{Neues Makro (intern)}^^A % \changes{v3.00}{2008/04/30}{umbenannt von \cs{KOMA@key@atlist}} % \begin{macro}{\scr@key@name} % \changes{v2.97c}{2007/04/19}{Neues Makro (intern)}^^A % \changes{v3.00}{2008/04/30}{umbenannt von \cs{KOMA@key@name}} % \begin{macro}{\scr@key@value} % \changes{v2.97c}{2007/04/19}{Neues Makro (intern)}^^A % \changes{v3.00}{2008/04/30}{umbenannt von \cs{KOMA@key@value}} % \begin{macro}{\scr@key@split@name@value} % \changes{v2.97c}{2007/04/19}{Neues Makro (intern)}^^A % \changes{v2.97e}{2007/11/10}{verwendet \cs{KV@@sp@def} zur Entsorgung von % Leerzeichen} % \changes{v3.00}{2008/04/30}{umbenannt von \cs{KOMA@key@split@name@value}} % \changes{v3.13}{2014/10/17}{\cs{long}} % \begin{macrocode} \newif\ifscr@key@found@ \newcommand*{\scr@key@atlist}{} \newcommand*{\scr@key@name}{} \newcommand*{\scr@key@value}{} \newcommand*{\scr@key@split@name@value}{} \long\def\scr@key@split@name@value#1=#2=#3\@nil{% \KV@@sp@def\scr@key@name{#1}% \KV@@sp@def\scr@key@value{#2}% } % % \end{macrocode} % \end{macro}^^A \scr@key@split@name@value % \end{macro}^^A \scr@key@value % \end{macro}^^A \scr@key@name % \end{macro}^^A \scr@key@atlist % \end{macro}^^A \@FamilyOptions % \end{macro}^^A \FamilyOptions % % \begin{macro}{\FamilyOption} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % \begin{macro}{\@FamilyOptions} % \changes{v3.14}[2014/10/17]{Neue streng interne Anweisung}^^A % \begin{macro}{\Family@Option} % \changes{v3.00}{2008/04/30}{Neu (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt}^^A % \end{macro} % \changes{v3.04b}{2010/01/29}{\cs{edef} durch \cs{protected@edef} ersetzt} % Im Gegensatz zu \cs{FamilyOptions} kann man mit dieser Anweisung nur eine % einzige Option setzen. Dafür kann man gleich mehrere durch Komma getrennte % Argumente für diese Option setzen. Das erste obligatorische Argument ist % wieder die Familie, das zweite obligatorische Argument ist die Option, das % dritte, obligatorische Argument ist die Liste der Werte für diese Option. % \begin{macrocode} %<*base> \newcommand*{\FamilyOption}[2]{\@FamilyOption{#1}{#2}} \newcommand{\@FamilyOption}[3]{% \expandafter\KV@@sp@def\expandafter\scr@key@name\expandafter{#2}% % \end{macrocode} % Der einfachste Weg ist nun schlicht, die Liste der Werte durchzugehen und so % nach und nach eine Liste von Werten für \cs{FamilyOptions} zu erzeugen. % \begin{macrocode} \let\reserved@a\@empty \@for\reserved@b:=#3\do{% % \end{macrocode} % \changes{v3.08}{2010/11/05}{leere Argumente in der Werteliste}^^A % Auf vielfachen Wunsch und entgegen meiner Überzeugung, sind auch leere % Argumente in der Werteliste erlaubt, werden jedoch ignoriert: % \begin{macrocode} \ifx\reserved@b\@empty\else % \end{macrocode} % \changes{v3.12}{2012/03/04}{auch Leerzeichenargumente werden ignoriert}^^A % Auch Argumente, die nur aus einem Leerzeichen bestehen, werden ignoriert: % \begin{macrocode} \ifx\reserved@b\space\else \edef\reserved@a{\unexpanded\expandafter{\reserved@a},% \scr@key@name=\unexpanded\expandafter{\reserved@b}}% \fi \fi }% \def\reserved@b{\FamilyOptions{#1}}% \expandafter\reserved@b\expandafter{\reserved@a}% } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\KOMAoptions} % \changes{v2.96}{2006/08/20}{Neuer Hook nach den Optionen}^^A % \changes{v2.97c}{2007/04/19}{Optionen aller KOMA-Familien abarbeiten}^^A % \changes{v3.12}{2013/03/04}{Hook-Mechanismus von \cs{FamilyOptions}^^A % verwendent} % Simple kleine Abkürzung. % \begin{macrocode} %<*koma> \newcommand*{\KOMAoptions}{\FamilyOptions{KOMA}} % % \end{macrocode} % \begin{macro}{\KOMA@options} % \changes{v2.97c}{2007/04/19}{Neues Makro (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt}^^A % \end{macro}^^A \KOMA@options % \end{macro}^^A \KOMAoptions % % \begin{macro}{\KOMAoptionsOf} % \changes{v3.17}{2015/02/25}{neue Anweisung}^^A % Mit dieser Anweisung können die aktuell gesetzten \KOMAScript-Optionen % eines Pakets oder einer Klasse abgefragt werden, sobald ein Paket oder eine % Klasse das unterstützt. Das erste (optionale) Argument gibt dabei eine % Anweisung an, die für die Optionenliste ausgeführt werden soll. Das zweite % (nicht optionale Argument) ist der Name eines KOMA-Script-Pakets oder einer % KOMA-Script-Klasse einschließlich Dateiendung. % \begin{macrocode} %<*koma> \newcommand*{\KOMAoptionsOf}[2][\@firstofone]{% \scr@ifundefinedorrelax{scr@kav@KOMA.#2}{% \PackageError{scrkbase}{\string\KOMAoptionsOf\space not supported}{% #2 is not the name of a KOMA-Script package or\MessageBreak KOMA-Script class, that supports \string\KOMAoptionsOf.}% }{% \begingroup \def\reserved@a{#1}% \KOMA@kav@defall\reserved@b{.#2}% \expandafter\expandafter\expandafter\endgroup \expandafter\reserved@a\expandafter{\reserved@b}% }% } % % \end{macrocode} % \end{macro}^^A \KOMAoptionsOf % % \begin{macro}{\KOMAoptionOf} % \changes{v3.17}{2015/02/26}{neue Anweisung}^^A % Mit dieser Anweisung kann eine aktuell gesetzte \KOMAScript-Option % eines Pakets oder einer Klasse abgefragt werden, sobald ein Paket oder eine % Klasse das unterstützt. Das erste (optionale) Argument gibt dabei eine % Anweisung an, die für die Optionenliste ausgeführt werden soll. Das zweite % (nicht optionale Argument) ist der Name eines KOMA-Script-Pakets oder einer % KOMA-Script-Klasse einschließlich Dateiendung, das dritte (nicht optionale % Argument) ist der Name der Option, die abgefragt werden soll. % \begin{macrocode} %<*koma> \newcommand*{\KOMAoptionOf}[3][\@firstofone]{% \scr@ifundefinedorrelax{scr@kav@KOMA.#2}{% \PackageError{scrkbase}{\string\KOMAoptionOf\space not supported}{% #2 is not the name of a KOMA-Script package or\MessageBreak KOMA-Script class, that supports \string\KOMAoptionOf.}% }{% \begingroup \def\reserved@a{#1}% \KOMA@kav@defone\reserved@b{.#2}{#3}% \ifx\reserved@b\@empty \PackageWarning{scrkbase}{option `#3' for `#2' unset}% \endgroup \else \expandafter\expandafter\expandafter\endgroup \expandafter\reserved@a\expandafter{\reserved@b}% \fi }% } % % \end{macrocode} % \end{macro} % % \begin{macro}{\post@kopt@hook} % \changes{v3.12}{2013/03/04}{entfernt}^^A % \end{macro}^^A \post@kopt@hook % \begin{macro}{\AfterKOMAoptions} % \changes{v3.12}{2013/03/04}{Verwendung von \cs{AtEndOfFamilyOptions}}^^A % \changes{v3.23}{2017/02/16}{kein \cs{let}}^^A % Eine Option kann dafür sorgen, dass nach den Optionen noch etwas passiert. % \begin{macrocode} %<*koma> \newcommand*{\AfterKOMAoptions}{\AtEndOfFamilyOptions} % % \end{macrocode} % \end{macro}^^A \AfterKOMAoptions % % \begin{macro}{\l@addto@macro} % \changes{v2.8p}{2001/09/22}{neu (intern)} % Damit \cs{AfterKOMAoptions} lokal möglich ist, wird eine lokal arbeitende % Variante von \cs{g@addto@macro} benötigt, wie sie hier vorgestellt wird. % \changes{v2.95}{2006/06/02}{korrigiert, damit es sich bezüglich % Erweiterung um Makrodefinitonen mit Argumenten wie \cs{g@addto@macro}^^A % verhält} % \changes{v3.12}{2013/04/20}{veraltete \eTeX-freie Version entfernt}^^A % \changes{v3.12}{2013/04/20}{Warnung, falls eine inkompatible Definition % von \cs{l@addto@macro} entdeckt wird} % \changes{v3.23}{2017/02/16}{in den Optionen-Teil verschoben}^^A % \begin{macrocode} % %<*base&prepare> \@ifundefined{l@addto@macro}{}{% \begingroup \long\def\reserved@a#1#2{% \edef#1{\unexpanded\expandafter{#1#2}}% }% \ifx\reserved@a\l@addto@macro\else \PackageWarning{scrbase}{% Someone also uses macro name \string\l@addto@macro.\MessageBreak When KOMA-Script author decided to use macro name\MessageBreak \string\l@addto@macro\space first, there was no other free\MessageBreak LaTeX package using this macro name.\MessageBreak In the meantime other package authers decided to use\MessageBreak same macro name, but unfortunatly not all of those\MessageBreak are compatible with KOMA-Script's definition, e.g.,\MessageBreak while adding definitions with arguments to macros.\MessageBreak Because of such potentially incompatible definitions,\MessageBreak KOMA-Script will redefine the command now.\MessageBreak Please ask the author of the other package to\MessageBreak rename his macro, if a problem results in the\MessageBreak redefinition% }% \fi \endgroup } \long\def\l@addto@macro#1#2{% \edef#1{\unexpanded\expandafter{#1#2}}% }% % %<*body> % \end{macrocode} % \end{macro}^^A \l@addto@macro % % \begin{macro}{\l@addto@macro@a} % \changes{v3.20}{2015/11/20}{neu (intern)} % So eine ähnliche Anweisung benötige ich außerdem für den Fall, dass eine % Anweisung erweitert werden soll, die genau ein obligatorisches Argument % benötigt. Achtung! Diese Anweisung funktioniert deutlich weniger allgemein % als \cs{l@addto@macro} und wird deshalb nie offiziell dokumentiert! % \begin{macrocode} %<*base> \begingroup \catcode`\^^A=\catcode`\# \@makeother\# \gdef\l@addto@macro@a^^A1{% \begingroup \@makeother\# \def\l@addto@macro@a@cmd{^^A1}% \l@addto@macro@a@ } \gdef\l@addto@macro@a@^^A1{% \def\l@addto@macro@a@add{^^A1}% \l@addto@macro@a@@ } \endgroup \begingroup \@makeother\# \gdef\l@addto@macro@a@@{% \@makeother\# \edef\reserved@a{% \detokenize{\endgroup\def}% \detokenize\expandafter{\l@addto@macro@a@cmd#1}% {% \expandafter\detokenize% \expandafter\expandafter\expandafter{\l@addto@macro@a@cmd{#1}}% \expandafter\detokenize\expandafter{\l@addto@macro@a@add}% }% }% \expandafter\scantokens\expandafter{\reserved@a}% }% \endgroup % % \end{macrocode} % \end{macro}^^A \l@addto@macro@a % % \begin{macro}{\l@preto@macro} % \changes{v3.20}{2015/11/25}{neu (intern)}^^A % In gewisser Weise das gleiche wie \cs{l@appto@macro}, allerdings wird vorn % statt hinten angefügt. % \begin{macrocode} %<*base> \newcommand\l@preto@macro[2]{% \edef#1{\unexpanded{#2}\unexpanded\expandafter{#1}}% }% % % \end{macrocode} % \end{macro}^^A \l@preto@macro % % \begin{macro}{\l@preto@macro@a} % \changes{v3.20}{2015/11/25}{neu (intern)} % So eine ähnliche Anweisung benötige ich außerdem für den Fall, dass eine % Anweisung erweitert werden soll, die genau ein obligatorisches Argument % benötigt. Achtung! Diese Anweisung funktioniert deutlich weniger allgemein % als \cs{l@preto@macro} und wird deshalb nie offiziell dokumentiert! % \begin{macrocode} %<*base> \begingroup \catcode`\^^A=\catcode`\# \@makeother\# \gdef\l@preto@macro@a^^A1{% \begingroup \@makeother\# \def\l@preto@macro@a@cmd{^^A1}% \l@preto@macro@a@ } \gdef\l@preto@macro@a@^^A1{% \def\l@preto@macro@a@add{^^A1}% \l@preto@macro@a@@ } \endgroup \begingroup \@makeother\# \gdef\l@preto@macro@a@@{% \@makeother\# \edef\reserved@a{% \detokenize{\endgroup\def}% \detokenize\expandafter{\l@preto@macro@a@cmd#1}% {% \expandafter\detokenize\expandafter{\l@preto@macro@a@add}% \expandafter\detokenize% \expandafter\expandafter\expandafter{\l@preto@macro@a@cmd{#1}}% }% }% \expandafter\scantokens\expandafter{\reserved@a}% }% \endgroup % % \end{macrocode} % \end{macro}^^A \l@preto@macro@a % % \begin{macro}{\KOMAoption} % \changes{v2.98c}{2008/03/12}{Neue Anweisung}^^A % \changes{v3.12}{2013/03/04}{Einfacher Aufruf von \cs{FamilyOption}} % \begin{macrocode} %<*koma> \newcommand*{\KOMAoption}{\FamilyOption{KOMA}} % % \end{macrocode} % \end{macro} % % \begin{macro}{\FamilyUnknownKeyValue} % \changes{v3.10}{2011/09/12}{no error while processing global options}^^A % \changes{v3.11a}{2012/05/28}{prevent remove from list of unused global % options globally}^^A % \changes{v3.14}{2014/10/17}{\cs{long}}^^A % Dieses Makro berichtet über Fehler wegen unbekannter Wertübergabe an einen % Schlüssel. Das erste Argument ist die Familie, das zweite der Schlüssel, % das dritte der Wert und das vierte die Liste der möglichen Werte. % \begin{macrocode} %<*base> \newcommand{\FamilyUnknownKeyValue}[4]{% \FamilyKeyStateUnknownValue \ifx\FamilyElseValues\@empty\else \PackageWarning{scrbase}{non empty \string\FamilyElseValue ignored.\MessageBreak Setting this command to a non empty\MessageBreak value for option `#2' of\MessageBreak family `#1' is deprecated,\MessageBreak but has been found }% \fi } % % \end{macrocode} % \begin{macro}{\FamilyElseValues} % \changes{v3.00}{2008/05/02}{Neue Anweisung}^^A % \changes{v3.12}{2013/03/04}{wird intern nicht mehr verwendet}^^A % Diese Anweisung konnte ursprünglich vor dem Setzen eines Wertes definiert % werden, um bei einer etwaigen Fehlermeldung weitere Werte als erlaubt % auszugeben. Am Ende von \cs{FamilySetBool} und \cs{FamilySetNumerical} % wird die Anweisung automatisch zu \cs{@empty}. Seit Version~3.12 wird % diese Anweisung jedoch nicht mehr ausgewertet. % \begin{macrocode} %<*base> \newcommand*{\FamilyElseValues}{} % % \end{macrocode} % \end{macro}^^A \FamilyUnknownKeyValue % \end{macro}^^A \FamilyElseValue % % \begin{macro}{\FamilyBoolKey} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % Dieses Makro definiert einen Schlüssel für eine Familie. Dieser Schlüssel % ist ein Schalter, der über diverse Werte geschaltet werden kann. % Das erste, optionale Argument ist das Familienmitglied, das zweite, % obligatorische Argument ist die Familie, das dritte der Name des Schlüssels, % das vierte der Schalter. % \begin{macrocode} %<*base> \newcommand*{\FamilyBoolKey}[4][.\@currname.\@currext]{% \@ifundefined{if#4}{% \expandafter\newif\csname if#4\endcsname }{}% \DefineFamilyKey[{#1}]{#2}{#3}[true]{\FamilySetBool{#2}{#3}{#4}{##1}}% } % \end{macrocode} % \begin{macro}{\FamilySetBool} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % \changes{v3.11a}{2012/05/25}{Argument in Fehlermeldung korrigiert}^^A % Über diese Anweisung wird der Wert dann gesetzt. Dabei ist das erste % Argument die Familie, das zweite der Name des Schlüssels, das dritte der % Schalter und das vierte schließlich der gewünschte Wert. % \begin{macrocode} \newcommand*{\FamilySetBool}[4]{% \ifstr{#4}{true}{\@nameuse{#3true}\FamilyKeyStateProcessed}{% \ifstr{#4}{on}{\@nameuse{#3true}\FamilyKeyStateProcessed}{% \ifstr{#4}{yes}{\@nameuse{#3true}\FamilyKeyStateProcessed}{% \ifstr{#4}{false}{\@nameuse{#3false}\FamilyKeyStateProcessed}{% \ifstr{#4}{off}{\@nameuse{#3false}\FamilyKeyStateProcessed}{% \ifstr{#4}{no}{\@nameuse{#3false}\FamilyKeyStateProcessed}{% \FamilyUnknownKeyValue{#1}{#2}{#4}{% `true', `on', `yes', `false', `off', `no'% }% }% }% }% }% }% }% \let\FamilyElseValues\@empty } % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\KOMA@unknown@keyval} % Dieses Makro berichtet über Fehler wegen unbekannter Wertübergabe an % einen Schlüssel. Das erste Argument ist der Schlüssel, das zweite % der Wert und das dritte die Liste der möglichen Werte. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@unknown@keyval}{\FamilyUnknownKeyValue{KOMA}} % % \end{macrocode} % \end{macro} % % \begin{macro}{\KOMA@ifkey} % \changes{v3.02c}{2009/02/04}{definiert ebenfalls das Familienmitglied}^^A % \changes{v3.17}{2015/03/02}{ersetzt den gespeicherten Wert}^^A % Dieses Makro definiert einen Schlüssel, der einen Schalter an Hand des % Wertes setzt. Als Werte sind "`\texttt{true}"', "`\texttt{false}"', % "`\texttt{on}"', "`\texttt{off}"', "`\texttt{yes}"' und % "`\texttt{no}"' erlaubt. Der Default-Wert für den Schalter ist % grundsätzlich "`false"', so dass der Default-Wert für die Verwendung % des Schküssels grundsätzlich "`true"' ist. Das erste Argument ist % der Name des Schlüssels, der zweite ist der Name des Schalters. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@ifkey}[2][.\@currname.\@currext]{% \begingroup\edef\reserved@a{\noexpand\KOMA@@ifkey{#1}{#2}}% \expandafter\endgroup\reserved@a } \newcommand*{\KOMA@@ifkey}[3]{% \@ifundefined{if#3}{% \expandafter\newif\csname if#3\endcsname }{}% \KOMA@key[{#1}]{#2}[true]{% \KOMA@set@ifkey{#2}{#3}{##1}% \KOMA@kav@replacebool{#1}{#2}{#3}% }% \csname if#3\endcsname \KOMA@kav@xadd{#1}{#2}{true}% \else \KOMA@kav@xadd{#1}{#2}{false}% \fi } % % \end{macrocode} % \begin{macro}{\KOMA@set@ifkey} % Die eigentliche Arbeit bei der ganzen Sache wird von diesem internen % Makro erledigt. Dabei wird der Name des Schlüssels zu Argument 1, der % Name des Schalters zu Argument 2 und der Wert des Schlüssels wird % Argument 3. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@set@ifkey}{\FamilySetBool{KOMA}} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\FamilyCounterKey} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2014/12/03}{er wird ein (optionaler) Säumniswert % unterstützt}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % Dieses Makro definiert einen Schlüssel, der einen \LaTeX-Zähler an Hand % des Wertes setzt. Das erste, optionale Argument ist das Familienmitglied, % das zweite, obligatorische Argument ist die Familie, das dritte der Name % des Schlüssels, das vierte, optionale ist der Säumniswert, das fünfte der % Name des \LaTeX-Zählers. Erlaubt sind alle Integer-Werte. % \begin{macro}{\Family@@Counter@@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macro}{\Family@Counter@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macrocode} %<*base> \newcommand*{\FamilyCounterKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@Counter@@Key{#1}{#2}{#3}}% {\Family@Counter@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@Counter@@Key}{} \def\Family@@Counter@@Key#1#2#3[#4]#5{% \@ifundefined{c@#5}{\newcounter{#5}}{}% \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\FamilySetCounter{#2}{#3}{#5}{##1}}% } \newcommand*{\Family@Counter@Key}[4]{% \@ifundefined{c@#4}{\newcounter{#4}}{}% \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetCounter{#2}{#3}{#4}{##1}}% } % \end{macrocode} % \begin{macro}{\FamilySetCounter} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.18a}{2015/07/06}{korrekte Verwendung von % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.23}{2017/02/23}{Leerzeichen durch \cs{relax} ersetzt}^^A % Über diese Anweisung wird der Wert dann gesetzt. Dabei ist das erste % Argument die Familie, das zweite der Name des Schlüssels, das dritte der % Name des \LaTeX-Zählers, das vierte schließlich der gewünschte Wert. % \begin{macrocode} \newcommand*{\FamilySetCounter}[4]{% \begingroup \protected@edef\reserved@a{#4}% \def\reserved@b{\endgroup\value{#3}=#4\relax\FamilyKeyStateProcessed}% \expandafter\ifiscount\expandafter{\reserved@a}{}{% \expandafter\ifisdimen\expandafter{\reserved@a}{}{% \expandafter\ifisskip\expandafter{\reserved@a}{}{% \expandafter\ifisnumexpr\expandafter{\reserved@a}{}{% \expandafter\ifisdimexpr\expandafter{\reserved@a}{}{% \expandafter\ifisinteger\expandafter{\reserved@a}{}{% \expandafter\ifiscounter\expandafter{\reserved@a}{% \def\reserved@b{% \endgroup\value{#3}=\value{#4}\FamilyKeyStateProcessed }% }{% \def\reserved@b{% \endgroup \FamilyUnknownKeyValue{#1}{#2}{#4}{% integer numbers, counters, lengths, skips, dimens }% }% }% }% }% }% }% }% }% \reserved@b } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\FamilyCounterMacroKey} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2014/12/03}{er wird ein (optionaler) Säumniswert % unterstützt}^^A % Diese Anweisung arbeitet fast wie \cs{FamilyCounterKey}, allerdings wird % dabei nicht ein Zähler, sondern ein Marko auf einen Wert definiert. Dabei % ist das erste (optionale) Argument das Mitglied, das zweite die Familie, das % dritte der Schlüssel, das vierte (optionale) der Säumniswert, das fünfte das % Makro. % \begin{macro}{\FamilySetCounterMacro} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2014/12/17}{\cs{aftergroup} vor % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.18a}{2015/07/06}{korrekte Verwendung von % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % Diese Anweisung arbeitet fast wie \cs{FamilySetCounter}, allerdings wird % nicht ein Zähler gesetzt, sondern ein Makro auf einen Wert definiert. Dabei % ist das erste Argument die Familie, das zweite der Name des Schlüssels, das % dritte das Makro, das vierte schließlich der gewünschte Wert. % \begin{macro}{\Family@@Counter@@Macro@@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macro}{\Family@Counter@Macro@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macrocode} %<*base> \newcommand*{\FamilyCounterMacroKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@Counter@@Macro@@Key{#1}{#2}{#3}}% {\Family@Counter@Macro@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@Counter@@Macro@@Key}{} \def\Family@@Counter@@Macro@@Key#1#2#3[#4]#5{% \ifdefined#4\else\let#4\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\FamilySetCounterMacro{#2}{#3}{#5}{##1}}% } \newcommand*{\Family@Counter@Macro@Key}[4]{% \ifdefined#4\else\let#4\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetCounterMacro{#2}{#3}{#4}{##1}}% } \newcommand*{\FamilySetCounterMacro}[4]{% \begingroup % \end{macrocode} % An dieser Stelle wird nun der immer definierte Zähler page als lokaler % Zähler verwendet. Das ist nur möglich, weil \cs{FamilySetCounter} nicht % global mit \cs{setcounter} arbeitet, sondern lokal mit einer Zuweisung an % \cs{value}. % \begin{macrocode} \FamilySetCounter{#1}{#2}{page}{#4}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \edef\reserved@a{% \unexpanded{\endgroup\def#3}% {\the\value{page}}% \noexpand\FamilyKeyStateProcessed }% \else \def\reserved@a{% \endgroup \FamilyUnknownKeyValue{#1}{#2}{#4}{% integer numbers, counters, lengths, skips, dimens }% }% \fi \reserved@a } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\FamilyLengthKey} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2014/12/03}{er wird ein (optionaler) Säumniswert % unterstützt}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % Dieses Makro definiert einen Schlüssel, der eine \LaTeX-Länge an Hand % des Wertes setzt. Das erste, optionale Argument ist das Familienmitglied, % das zweite, obligatorische Argument ist die Familie, das dritte der Name % des Schlüssels, das vierte der name der \LaTeX-Länge. % \begin{macro}{\Family@@Length@@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macro}{\Family@Length@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macrocode} %<*base> \newcommand*{\FamilyLengthKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@Length@@Key{#1}{#2}{#3}}% {\Family@Length@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@Length@@Key}{} \def\Family@@Length@@Key#1#2#3[#4]#5{% \ifdefined#5\else\newlength{#5}\fi \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\FamilySetLength{#2}{#3}{#5}{##1}}% } \newcommand*{\Family@Length@Key}[4]{% \ifdefined#4\else\newlength{#4}\fi \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetLength{#2}{#3}{#4}{##1}}% } % \end{macrocode} % \begin{macro}{\FamilySetLength} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2015/01/02}{\cs{ifglueexpr} hinzugefügt}^^A % \changes{v3.18a}{2015/07/06}{korrekte Verwendung von % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.20}{2016/04/27}{Expansion vor dem Test}^^A % Über diese Anweisung wird der Wert dann gesetzt. Dabei ist das erste % Argument die Familie, das zweite der Name des Schlüssels, das dritte der % Name der \LaTeX-Länge, das vierte schließlich der gewünschte Wert. % \begin{macrocode} \newcommand*{\FamilySetLength}[4]{% \begingroup \protected@edef\reserved@a{#4}% \expandafter\ifiscount\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisdimen\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisskip\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisnumexpr\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisdimexpr\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisglueexpr\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\ifisglue\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \aftergroup\@secondoftwo }% }% }% }% }% }% }% \endgroup {#3=#4\FamilyKeyStateProcessed}% {% \FamilyUnknownKeyValue{#1}{#2}{#4}{% length values, counters, lengths, skips, dimens }% }% } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\FamilyLengthMacroKey} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.15}{2014/12/03}{er wird ein (optionaler) Säumniswert % unterstützt}^^A % \begin{macro}{\FamilySetLengthMacro} % \changes{v3.12}{2013/11/05}{neu}^^A % \changes{v3.14a}{2014/11/24}{fix: \cs{@tempskipa} statt \cs{@temskipa}}^^A % \changes{v3.15}{2014/12/17}{\cs{aftergroup} vor % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.15}{2015/01/02}{\cs{ifglueexpr} hinzugefügt}^^A % \changes{v3.18a}{2015/07/06}{korrekte Verwendung von % \cs{FamilyKeyStateProcessed}}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} ersetzt durch % \cs{kernel@ifnextchar}}^^A % \changes{v3.20}{2016/04/27}{interne Verwendung von \cs{FamilySetLength}}^^A % Diese Anweisungen arbeitet fast wie \cs{FamilyLengthKey} und % \cs{FamilySetLengt}, allerdings wird nicht eine Länge gesetzt, sondern % ein Makro auf einen Wert definiert. Dabei ist das erste Argument die % Familie, das zweite der Name des Schlüssels, das dritte das Makro, das % vierte schließlich der gewünschte Wert. % \begin{macro}{\Family@@Length@@Macro@@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macro}{\Family@Length@Macro@Key} % \changes{v3.15}{2014/12/03}{neu (intern)}^^A % \begin{macrocode} %<*base> \newcommand*{\FamilyLengthMacroKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@Length@@Macro@@Key{#1}{#2}{#3}}% {\Family@Length@Macro@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@Length@@Macro@@Key}{} \def\Family@@Length@@Macro@@Key#1#2#3[#4]#5{% \ifdefined#5\else\let#5\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\FamilySetLengthMacro{#2}{#3}{#5}{##1}}% } \newcommand*{\Family@Length@Macro@Key}[4]{% \ifdefined#4\else\let#4\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetLengthMacro{#2}{#3}{#4}{##1}}% } \newcommand*{\FamilySetLengthMacro}[4]{% \begingroup \FamilySetLength{#1}{#2}{\@tempskipa}{#4}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \edef\reserved@a{% \unexpanded{\endgroup\def#3}% {\the\@tempskipa}% \noexpand\FamilyKeyStateProcessed }% \else \def\reserved@a{% \endgroup \FamilyUnknownKeyValue{#1}{#2}{#4}{% length values, counters, lengths, skips, dimens }% }% \fi \reserved@a } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\FamilyUseLengthMacroKey} % \changes{v3.20}{2016/04/27}{neu}^^A % \begin{macro}{\FamilySetLengthMacro} % \changes{v3.20}{2016/04/27}{neu}^^A % Diese Anweisungen arbeitet fast wie \cs{FamilyLengthKey} und % \cs{FamilySetLengt}, allerdings wird das Makro nicht als den Wert des Werts, % sondern als den Wert selbst definiert. Eine Expansion des Werts findet nur % für die Prüfung statt. Änderungen am Wert wirken sich also ggf. weiterhing % aus. Dabei ist das erste Argument die Familie, das zweite der Name des % Schlüssels, das dritte das Makro, das vierte schließlich der gewünschte % Wert. % \begin{macro}{\Family@@UseLength@@Macro@@Key} % \changes{v3.20}{2016/04/27}{neu (intern)}^^A % \begin{macro}{\Family@USeLength@Macro@Key} % \changes{v3.20}{2016/04/27}{neu (intern)}^^A % \begin{macrocode} %<*base> \newcommand*{\FamilyUseLengthMacroKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@UseLength@@Macro@@Key{#1}{#2}{#3}}% {\Family@UseLength@Macro@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@UseLength@@Macro@@Key}{} \def\Family@@UseLength@@Macro@@Key#1#2#3[#4]#5{% \ifdefined#5\else\let#5\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{% \FamilySetUseLengthMacro{#2}{#3}{#5}{##1}% }% } \newcommand*{\Family@UseLength@Macro@Key}[4]{% \ifdefined#4\else\let#4\z@\fi \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetUseLengthMacro{#2}{#3}{#4}{##1}}% } \newcommand*{\FamilySetUseLengthMacro}[4]{% \begingroup \FamilySetLength{#1}{#2}{\@tempskipa}{#4}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \def\reserved@a{% \endgroup\def#3{#4}% \FamilyKeyStateProcessed }% \else \def\reserved@a{% \endgroup \FamilyUnknownKeyValue{#1}{#2}{#4}{% length values, counters, lengths, skips, dimens }% }% \fi \reserved@a } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\FamilyNumericalKey} % \changes{v3.00}{2008/04/30}{Neue Anweisung}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % \begin{macro}{\Family@Numerical@Key} % \changes{v3.00}{2008/05/28}{Neu (intern)}^^A % \changes{v3.08b}{2011/03/31}{fehlendes Argument bei \cs{ifundefined}} % Ein ähnliches Makro definiert einen Schlüssel, der ein nummerisches Makro % auf einen bestimmten Wert setzt. Dabei können auch verschiedene symbolische % Werte auf denselben nummerischen Wert abgebildet werden. Das erste, % optionale Argument ist das Familienmitglied, das zweite, obligatorische % Argument ist die Familie, das dritte, obligatorische Argument ist der Name % der Option, das vierte, optionale Artument ist der Defaultwert für den % Schlüssel, das fünfte, obligatorische Argument ist der Name des Makros, das % (in der Voreinstellung als 0) definiert werden soll, das sechste, % obligatorische Argument ist die Liste der symbolischen und nummerischen % Werte. Die Liste hat die Form: % \{\emph{Symbol}\}\{\emph{Wert}\},\{\emph{Symbol}\}\{\emph{Wert}\}\dots % Das interne Makro wird benötigt, um das vierte, optionale Argument zu % ermöglichen. Dabei ist dann das erste Argument nicht mehr optional, sondern % obligatorisch. % \begin{macrocode} %<*base> \newcommand*{\FamilyNumericalKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@Numerical@Key{#1}{#2}{#3}}{\Family@Numerical@Key{#1}{#2}{#3}[]}% } \newcommand*{\Family@Numerical@Key}{} \def\Family@Numerical@Key#1#2#3[#4]#5#6{% \@ifundefined{#5}{\@namedef{#5}{0}}{}% \ifx\relax#4\relax \DefineFamilyKey[{#1}]{#2}{#3}{\FamilySetNumerical{#2}{#3}{#5}{#6}{##1}}% \else \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{% \FamilySetNumerical{#2}{#3}{#5}{#6}{##1}}% \fi } % \end{macrocode} % \begin{macro}{\FamilySetNumerical} % \changes{v3.11a}{2012/05/28}{call of \cs{FamilyUnknownKeyValue} outside of % local group} % Die eigentliche Arbeit dabei wird von diesem Makro erledigt. Dabei % wird die Familie zu Argument 1, der Name des Schlüssels zu Argument 2, der % Name des Makros, das definiert werden soll zu Argument 3, die Liste zu % Argument 4 und der Wert, auf den gesetzt werden soll, zu Argument 5. % \begin{macrocode} \newcommand*{\FamilySetNumerical}[5]{% \begingroup \edef\@searched{#5}% \let\reserved@a=\@empty \let\reserved@b=\@empty \@tempswafalse \@for\@valuelist:=#4\do{% \if@tempswa\else \edef\reserved@c{\expandafter\@firstoftwo\@valuelist}% \edef\reserved@a{\reserved@a\reserved@b`\reserved@c'}% \edef\reserved@b{, }% \ifx\reserved@c\@searched \@tempswatrue \edef\reserved@a{\expandafter\@secondoftwo\@valuelist}% \fi \fi }% \if@tempswa \edef\reserved@a{\endgroup \noexpand\@namedef{#3}{\reserved@a}% \noexpand\FamilyKeyStateProcessed }% \else \edef\reserved@a{\endgroup \noexpand\FamilyUnknownKeyValue{#1}{#2}{#5}{\reserved@a}% }% \fi \reserved@a \let\FamilyElseValues\@empty } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\KOMA@ncmdkey} % \changes{v3.02c}{2009/02/04}{definiert ebenfalls das Familienmitglied}^^A % \changes{v3.17}{2015/03/16}{neu implementiert mit Speicherung der % Werte und optionalem erstem Argument}^^A % \begin{macro}{\KOMA@@ncmdkey} % \changes{v3.17}{2015/03/16}{neu (intern)}^^A % \begin{macro}{\KOMA@@@ncmdkey} % \changes{v3.17}{2015/03/16}{neu (intern)}^^A % Wie \cs{FamilyNumericalKey} mit zwei entscheidenden Unterschieden: % \begin{itemize} % \item Die Familien ist immer \texttt{KOMA} und entfällt daher als zweites % Argument. % \item Der gespeicherte Wert wird ausgetauscht. Daher kann es nicht nur für % Optionen verwendet werden, bei denen die Werte exklusiv sind. % \end{itemize} % Wichtig: Die Voreinstellung muss anschließend noch in jedem Fall mit % \cs{KOMA@kav@add} gesetzt werden! % \begin{macrocode} %<*koma> \newcommand*{\KOMA@ncmdkey}[2][.\@currname.\@currext]{% \begingroup\edef\reserved@a{\noexpand\KOMA@@ncmdkey{#1}{#2}}% \expandafter\endgroup\reserved@a } \newcommand*{\KOMA@@ncmdkey}[2]{% \kernel@ifnextchar [%] {\KOMA@@@ncmdkey{#1}{#2}}{\KOMA@@@ncmdkey{#1}{#2}[]} } \newcommand*{\KOMA@@@ncmdkey}{} \def\KOMA@@@ncmdkey#1#2[#3]#4#5{% \@ifundefined{#4}{\@namedef{#4}{0}}{}% \ifx\relax#3\relax \KOMA@key[{#1}]{#2}{% \KOMA@set@ncmdkey{#2}{#4}{#5}{##1}% \KOMA@kav@replacevalue{#1}{#2}{##1}% }% \else \KOMA@key[{#1}]{#2}[{#3}]{% \KOMA@set@ncmdkey{#2}{#4}{#5}{##1}% \KOMA@kav@replacevalue{#1}{#2}{##1}% }% \fi } % % \end{macrocode} % \begin{macro}{\KOMA@set@ncmdkey} % Die eigentliche Arbeit dabei wird wahlweise von diesem Makro erledigt. Dabei % wird der Name des Schlüssels zu Argument 1, der Name des Makros, % das definiert werden soll zu Argument 2, die Liste zu Argument 3 und % der Wert, auf den gesetzt werden soll, zu Argument 4. Dabei wird allerdings % kein gespeicherter Wert ersetzt! % \begin{macrocode} %<*koma> \newcommand*{\KOMA@set@ncmdkey}{\FamilySetNumerical{KOMA}} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\FamilyStringKey} % \changes{v3.08}{2010/11/05}{Neue Anweisung}^^A % \changes{v3.08b}{2011/03/31}{\cs{Family@String@Key} und % \cs{Family@@String@@Key} vertauscht}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % \begin{macro}{\Family@String@Key} % \changes{v3.08}{2010/11/05}{Neu (intern)}^^A % \begin{macro}{\Family@@String@@Key} % \changes{v3.08}{2010/11/05}{Neu (intern)}^^A % Ein ähnliches Makro definiert einen Schlüssel, der ein Makro auf einen % beliegigen Wert setzt. Das erste, optionale Argument ist das % Familienmitglied, das zweite, obligatorische Argument ist die Familie, das % dritte, obligatorische Argument ist der Name der Option, das vierte, % optionale Artument ist der Defaultwert für den Schlüssel, das fünfte, % obligatorische Argument ist der Name des Makros, das (in der Voreinstellung % als leer) definiert werden soll. Die internen Makro werden benötigt, um das % vierte, optionale Argument zu ermöglichen. Dabei ist dann das erste Argument % nicht mehr optional, sondern obligatorisch. % \begin{macrocode} %<*base> \newcommand*{\FamilyStringKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@String@@Key{#1}{#2}{#3}}{\Family@String@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@String@@Key}{} \long\def\Family@@String@@Key#1#2#3[#4]#5{% \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\def#5{##1}}% } \newcommand{\Family@String@Key}[4]{% \DefineFamilyKey[{#1}]{#2}{#3}{\def#4{##1}\FamilyKeyStateProcessed}% } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\KOMA@DeclareDeprecatedOption} % \changes{v3.01a}{2008/11/20}{neu (intern)}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % \begin{macro}{\KOMA@@DeclareDeprecatedOption} % \changes{v3.01a}{2008/11/20}{neu (intern)}^^A % \begin{macro}{\KOMA@@@DeclareDeprecatedOption} % \changes{v3.01a}{2008/11/20}{neu (intern)}^^A % Mit Hilfe dieses Makros kann eine Option definiert werden, die % eigentlich obsolete ist. Statt dieser Option wird dann ein Schlüssel % verwendet. Das erste Argument ist optional und muss dann der Paketname % sein. Ist es nicht gesetzt, so wird stattdessen die Klasse % \cs{KOMAClassName} angenommen. Das zweite Argument ist der Name der % Option. Das vierte Argument ist das Setzen des gewünschten Schlüssels. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@DeclareDeprecatedOption}{% \kernel@ifnextchar [%] {\KOMA@@DeclareDeprecatedOption}% {\KOMA@@@DeclareDeprecatedOption{\ClassWarningNoLine{\KOMAClassName}}}% } \newcommand*{\KOMA@@DeclareDeprecatedOption}[1][]{% \KOMA@@@DeclareDeprecatedOption{\PackageWarningNoLine{#1}}% } \newcommand*{\KOMA@@@DeclareDeprecatedOption}[3]{% \DeclareOption{#2}{\KOMA@UseDeprecatedOption{#1}{#2}{#3}}% } % \end{macrocode} % \begin{macro}{\KOMA@UseDeprecatedOption} % \changes{v3.01a}{2008/11/20}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{Test für \texttt{version!=first}}^^A % \changes{v3.12a}{2014/01/22}{vertauschte Logic für % \texttt{version!=first} korrigiert}^^A % \changes{v3.22}{2016/07/29}{diverse \cs{detokenize} eingefügt}^^A % Die eigentliche Arbeit wird von diesem Makro erledigt. Die Argumente sind % 1. Meldungsbefehl, 2. obsolete Option, 3. Setzen des Schlüssels. % \begin{macrocode} \newcommand*{\KOMA@UseDeprecatedOption}[3]{% \begingroup \scr@ifundefinedorrelax{KV@KOMA.\@currname.\@currext @version}{% \edef\reserved@a{\noexpand\endgroup \noexpand#1{% You've used obsolete option `\detokenize{#2}'.\noexpand\MessageBreak Usage of this option is deprecated.\noexpand\MessageBreak You should simply replace `\detokenize{#2}'\noexpand\MessageBreak by `\detokenize{#3}'% }% \noexpand\KOMAExecuteOptions{#3}% \noexpand\def\noexpand\CurrentOption{\CurrentOption}% }% }{% \edef\reserved@a{\noexpand\endgroup \noexpand#1{% You've used obsolete option `\detokenize{#2}'.\noexpand\MessageBreak Usage of this option indicates an old document\noexpand\MessageBreak and changes compatibility level using\noexpand\MessageBreak `\detokenize{#3},version=first,\noexpand\MessageBreak enabledeprecatedfontcommands' that may result\noexpand\MessageBreak in further warnings.\noexpand\MessageBreak If you don't want this, you should simply\noexpand\MessageBreak replace option `\detokenize{#2}' by `\detokenize{#3}'% }% \noexpand\KOMAExecuteOptions{% #3,version=first}% \noexpand\ExecuteOptions{enabledeprecatedfontcommands}% \noexpand\def\noexpand\CurrentOption{\CurrentOption}% }% }% \reserved@a } % % \end{macrocode} % \end{macro}^^A \KOMA@UseDeprecatedOption % \end{macro}^^A \KOMA@@@DeclareDeprecatedOption % \end{macro}^^A \KOMA@@DeclareDeprecatedOption % \end{macro}^^A \KOMA@DeclareDeprecatedOption % % % \begin{macro}{\KOMA@DeclareStandardOption} % \changes{v3.01a}{2008/11/21}{neu (intern)}^^A % \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by % \cs{kernel@ifnextchar}}^^A % \begin{macro}{\KOMA@@DeclareStandardOption} % \changes{v3.01a}{2008/11/21}{neu (intern)}^^A % \begin{macro}{\KOMA@@@DeclareStandardOption} % \changes{v3.01a}{2008/11/21}{neu (intern)}^^A % Mit Hilfe dieses Makros kann eine Option definiert werden, die % eigentlich obsolete ist. Statt dieser Option wird dann ein Schlüssel % verwendet. Das erste Argument ist optional und muss dann der Paketname % sein. Ist es nicht gesetzt, so wird stattdessen die Klasse % \cs{KOMAClassName} angenommen. Das zweite Argument ist der Name der % Option. Das vierte Argument ist das Setzen des gewünschten Schlüssels. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@DeclareStandardOption}{% \kernel@ifnextchar [%] {\KOMA@@DeclareStandardOption}% {\KOMA@@@DeclareStandardOption{\ClassInfoNoLine{\KOMAClassName}}}% } \newcommand*{\KOMA@@DeclareStandardOption}[1][]{% \KOMA@@@DeclareStandardOption{\PackageInfoNoLine{#1}}% } \newcommand*{\KOMA@@@DeclareStandardOption}[3]{% \DeclareOption{#2}{\KOMA@UseStandardOption{#1}{#2}{#3}}% } % \end{macrocode} % \begin{macro}{\KOMA@UseStandardOption} % \changes{v3.01a}{2008/11/21}{neu (intern)}^^A % Die eigentliche Arbeit wird von diesem Makro erledigt. Die Argumente sind % 1. Meldungsbefehl, 2. obsolete Option, 3. Setzen des Schlüssels. % \begin{macrocode} \newcommand*{\KOMA@UseStandardOption}[3]{% \begingroup \edef\reserved@a{\noexpand\endgroup \noexpand#1{% You've used standard option `#2'.\noexpand\MessageBreak This is correct!\noexpand\MessageBreak Internally I'm using `#3'.\noexpand\MessageBreak If you'd like to set the option with \string\KOMAoptions,% \noexpand\MessageBreak you'd have to use `#3' there\noexpand\MessageBreak instead of `#2', too% }% \noexpand\KOMAExecuteOptions{#3}% \noexpand\def\noexpand\CurrentOption{\CurrentOption}% }% \reserved@a } % % \end{macrocode} % \begin{macro}{\scr@sr@co} % \changes{v2.96}{2006/08/20}{neu (intern)}^^A % \changes{v3.12a}{2014/01/22}{beseitigt}^^A % \end{macro}^^A \scr@sr@co % \end{macro}^^A \KOMA@UseStandardOption % \end{macro}^^A \KOMA@@@DeclareStandardOption % \end{macro}^^A \KOMA@@DeclareStandardOption % \end{macro}^^A \KOMA@DeclareStandardOption % % % \begin{macro}{\KOMA@DeclareObsoleteOption} % \changes{v2.96}{2006/08/20}{\cs{CurrentOption wir geschützt}} % \changes{v3.12}{2013/03/04}{entfernt weil unbenutzt}^^A % \begin{macro}{\KOMA@@DeclareObsoleteOption} % \changes{v2.98c}{2008/02/18}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt weil unbenutzt}^^A % \begin{macro}{\KOMA@@@DeclareObsoleteOption} % \changes{v2.98c}{2008/02/18}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt weil unbenutzt}^^A % \begin{macro}{\KOMA@iv@DeclareObsoleteOption} % \changes{v2.98c}{2008/02/18}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt weil unbenutzt}^^A % \begin{macro}{\KOMA@UseObsoleteOption} % \changes{v2.97c}{2007/04/19}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{entfernt weil unbenutzt}^^A % \end{macro}^^A \KOMA@UseObsoleteOption % \end{macro}^^A \KOMA@iv@DeclareObsoleteOption % \end{macro}^^A \KOMA@iii@DeclareObsoleteOption % \end{macro}^^A \KOMA@ii@DeclareObsoleteOption % \end{macro}^^A \KOMA@i@DeclareObsoleteOption % % % \begin{macro}{\KOMA@newdeprecatedcommand} % \changes{v3.12}{2013/03/04}{renamed \cs{KOMA@newobsoletecommand} into % \cs{KOMA@newdeprecatedcommand}} % Mit Hilfe dieses Makros kann ein Makro definiert werden, das % eigentlich obsolete ist. Das Makro verwendet dann schlicht einen % Schlüssel. Das erste Argument ist optional und muss dann entweder % \cs{PackageInfo}, \cs{PackageInfoNoLine}, \cs{PackageWarning} oder % \cs{PackageWarningNoLine} sein. Das zweite Argument ist das Makro. % Das dritte Argument ist das Setzen des gewünschten Schlüssels. Das % definierte Makro selbst hat Schaltercharakter, ist also nicht % \cs{long} und versteht auch keine Argumente. % \begin{macrocode} %<*koma> \newcommand*{\KOMA@newdeprecatedcommand}[3][\@gobbletwo]{% \newcommand*{#2}{\KOMA@UseDeprecatedCommand{#1}{\string#2}{#3}}% } % \end{macrocode} % \begin{macro}{\KOMA@UseDeprecatedCommand} % \changes{v2.97c}{2007/04/19}{neu (intern)}^^A % \changes{v3.12}{2013/03/04}{renamed \cs{KOMA@UseObsoleteCommand} into % \cs{KOMA@UseDeprecatedCommand}} % Die eigentliche Arbeit wird von diesem Makro erledigt. Die Argumente sind % dieselben. % \begin{macrocode} \newcommand*{\KOMA@UseDeprecatedCommand}[3]{% #1{% scrkbase% }{% You've used deprecated command `#2'.\MessageBreak \protect\KOMAoptions{#3} will be used instead.\MessageBreak You should also replace `#2' by `\protect\KOMAoptions{#3}'% }% \KOMAoptions{#3}% } % % \end{macrocode} % \end{macro}^^A \KOMA@UseDeprecatedCommand % \end{macro}^^A \KOMA@newdeprecatedcommand % % % \iffalse % % \fi % % \Finale % \endinput % % end of file `scrkernel-basics.dtx' %%% Local Variables: %%% mode: doctex %%% TeX-master: t %%% End: