% \iffalse meta-comment % ====================================================================== % scrkernel-basics.dtx % Copyright (c) Markus Kohm, 2002-2021 % % 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-2021 % % 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. % ====================================================================== % %%% From File: $Id: scrkernel-basics.dtx 3606 2021-06-08 08:28:35Z 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 % \changes{v3.27a}{2019/11/04}{\cs{FamilyKeyStateProcessed} ergänzt}%^^A % \changes{v3.27a}{2019/11/04}{nur innerhalb des Pakets definiert}%^^A % \changes{v3.27a}{2019/11/04}{temporär in den Klassen definiert}%^^A % \changes{v3.28}{2019/11/18}{Option ist veraltet}%^^A % \begin{macro}{\dont@let@as@internal@defined} % \changes{v2.96}{2006/11/26}{neu (intern)}%^^A % \changes{v3.28}{2019/11/18}{entfernt}%^^A % \begin{macrocode} %<*base> \DefineFamily{KOMA} \DefineFamilyMember{KOMA} \DefineFamilyKey{KOMA}{internalonly}[\relax]{% \PackageInfo{scrbase}{Ignoring deprecated option `internalonly'}% \FamilyKeyStateProcessed } \AtEndOfPackage{% \RelaxFamilyKey[.scrbase.sty]{KOMA}{internalonly}% } % % \end{macrocode} % Da \textsf{scrbase} von den Klassen bereits vor der Verarbeitung der % Optionen geladen wird, wird die Option zwar verarbeitet aber dann trotzdem % als unbekannt gemeldet. Das kann man notdürftig beheben, indem die Klasse % vorrübergehend eine Dummy-Option erhält. % \begin{macrocode} % %<*load&class&neveruse> \KOMA@key{internalonly}[\relax]{% \FamilyKeyStateProcessed } \AtEndOfClass{\RelaxFamilyKey[.\KOMAClassFileName]{KOMA}{internalonly}}% % %<*option> % \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} % % \selectlanguage{english}%^^A % \begin{macro}{\scr@ForEachTrimmedListElement} % \changes{v3.27}{2019/04/16}{new (internal)}%^^A % Executes \cs{\#2\{\meta{element}\}} for each \meta{element} of the comma % separated list \#1. Spaces before for after \meta{element} are eliminated % and empty elements are ignored. % \begin{macrocode} %<*base> \newcommand{\scr@ForEachTrimmedListElement}[2]{% \begingroup \def\reserved@a{\endgroup}% \@for \reserved@b:=#1 \do {% \scr@trim@spaces\reserved@b \ifx\reserved@b\@empty\else \edef\reserved@a{% \unexpanded\expandafter{\reserved@a#2}% {\unexpanded\expandafter{\reserved@b}}% }% \fi }% \reserved@a } % % \end{macrocode} % \end{macro}%^^A \scr@ForEachTrimmedListElement % \selectlanguage{ngerman}%^^A % % \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 % \changes{v3.28}{2019/11/18}{entfernt}%^^A % \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}}%^^A % \changes{v3.28}{2019/11/18}{umbenannt in \cs{Ifundefinedorrelax}}%^^A % \changes{v3.29}{2020/01/17}{fix of missing backslash}%^^A % \begin{macro}{\Ifundefinedorrelax}%^^A % Dieses Makro arbeitet wie \cs{@ifundefined}, definiert dabei aber % ein undefiniertes Makro nicht als \cs{relax}. % \begin{macrocode} %<*base> \newcommand*{\Ifundefinedorrelax}{\scr@ifundefinedorrelax}% % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ifnotundefined} % \changes{v2.95}{2002/08/21}{neu}%^^A % \changes{v2.95c}{2006/08/12}{nutzt \eTeX{} wenn möglich}%^^A % \changes{v3.02c}{2009/02/19}{\eTeX{} ist zwingend}%^^A % \changes{v3.28}{2019/11/18}{umdefiniert in \cs{Ifnotundefined}}%^^A % \begin{macro}{\Ifnotundefined} % \changes{v3.28}{2019/11/18}{neu Umbenennung von \cs{ifnotundefinded}}%^^A % 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> \providecommand*{\ifnotundefined}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifnotundefined'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifnotundefined' by `\string\Ifnotundefined'% }% \Ifnotundefined } \newcommand{\Ifnotundefined}[1]{% \ifcsname #1\endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % % \end{macrocode} % \end{macro} % \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}%^^A % \changes{v3.28}{2019/11/18}{umbenannt in \cs{IfStr}}%^^A % \begin{macro}{\Ifstr} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifstr}}%^^A % Dieses Makro vergleicht zwei Tokenfolgen. Eigentlich müsste es also % eher \cs{ifequal} oder ähnlich heißen. % \begin{macrocode} %<*base> \providecommand*{\ifstr}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifstr'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifstr' by `\string\Ifstr'% }% \Ifstr } \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} % \end{macro} % % \begin{macro}{\Ifstrstart} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifstrstart}}%^^A % \begin{macro}{\ifstrstart} % \changes{v3.12}{2013/11/05}{neu}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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> \providecommand*{\ifstrstart}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifstrstart'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifstrstart' by `\string\Ifstrstart'% }% \Ifstrstart } \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 % \end{macro}%^^A \Ifstrstart % % \begin{macro}{\IfArgIsEmpty} % \changes{v3.19}{2015/08/29}{neu}%^^A % \changes{v3.27}{2019/03/11}{\cs{long}}%^^A % \changes{v3.27}{2019/07/19}{wird bereits vor den Optionen benötigt}%^^A % Falls das erste Argument tatsächlich leer ist, wird das zweite Argument % ausgeführt sonst das dritte. % %<*prepare> %<*base> % \begin{macrocode} \newcommand{\IfArgIsEmpty}[1]{% \if\relax\detokenize{#1}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} % % %<*body> % \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisdimen}}%^^A % \begin{macro}{\Ifisdimen} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisdimen}}%^^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> \providecommand*{\ifisdimen}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisdimen'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisdimen' by `\string\Ifisdimen'% }% \Ifisdimen } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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)} % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % \begin{macro}{\scr@IfArgIsRelaxAfterRelaxTillNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % 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 % \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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisskip}}%^^A % \begin{macro}{\Ifisskip} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisskip}}%^^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> \providecommand*{\ifisskip}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisskip'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisskip' by `\string\Ifisskip'% }% \Ifisskip } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 \Ifisskip % \end{macro}%^^A \ifiskip % % \begin{macro}{\ifiscount} % \changes{v3.12}{2013/11/05}{neu}%^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}%^^A % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifiscount}}%^^A % \begin{macro}{\Ifiscount} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifiscount}}%^^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> \providecommand*{\ifiscount}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifiscount'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifiscount' by `\string\Ifiscount'% }% \Ifiscount } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \end{macro}%^^A \ifiscount % % % \begin{macro}{\ifisdimexpr} % \changes{v3.12}{2013/11/05}{neu}%^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}%^^A % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisdimexpr}}%^^A % \begin{macro}{\Ifisdimexpr} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisdimexpr}}%^^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> \providecommand*{\ifisdimexpr}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisdimexpr'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisdimexpr' by `\string\Ifisdimexpr'% }% \Ifisdimexpr } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \end{macro}%^^A \ifisdimexpr % % % \begin{macro}{\ifisglueexpr} % \changes{v3.12}{2013/11/05}{neu}%^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}%^^A % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisglueexpr}}%^^A % \begin{macro}{\Ifisglueexpr} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisglueexpr}}%^^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> \providecommand*{\ifisglueexpr}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisglueexpr'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisglueexpr' by `\string\Ifisglueexpr'% }% \Ifisglueexpr } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \end{macro}%^^A \ifisglueexpr % % % \begin{macro}{\ifisnumexpr} % \changes{v3.12}{2013/11/05}{neu}%^^A % \changes{v3.20}{2015/10/19}{Reimplementierung}%^^A % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisnumexpr}}%^^A % \begin{macro}{\Ifisnumexpr} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisnumexpr}}%^^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> \providecommand*{\ifisnumexpr}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisnumexpr'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisnumexpr' by `\string\Ifisnumexpr'% }% \Ifisnumexpr } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifiscounter}}%^^A % \begin{macro}{\Ifiscounter} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifiscounter}}%^^A % Falls die Expansion des ersten Arguments ein \LaTeX-Zähler ist, wird das % zweite Argument ausgeführt, sonst das dritte. % \begin{macrocode} %<*base> \providecommand*{\ifiscounter}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifiscounter'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifiscounter' by `\string\Ifiscounter'% }% \Ifiscounter } \newcommand*{\Ifiscounter}[1]{% \begingroup \scr@ifundefinedorrelax{c@#1}{% \aftergroup\@secondoftwo }{% \aftergroup\@firstoftwo }% \endgroup } % % \end{macrocode} % \end{macro}%^^A \Ifiscounter % \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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisinteger}}%^^A % \begin{macro}{\Ifisinteger} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisinteger}}%^^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> \providecommand*{\ifisinteger}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisinteger'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisinteger' by `\string\Ifisinteger'% }% \Ifisinteger } \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 % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^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 % \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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisdimension}}%^^A % \begin{macro}{\Ifisdimension} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisdimension}}%^^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> \providecommand*{\ifisdimension}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisdimension'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisdimension' by `\string\Ifisdimension'% }% \Ifisdimension } \newcommand*{\Ifisdimension}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisdimension#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisdimension} % \changes{v3.20}{2015/10/20}{neu (intern)} % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % \changes{v3.28}{2019/11/23}{Vorzeichenfall \texttt{+} korrigiert}%^^A % 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)} % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % \begin{macro}{\scr@IfArgIsRelaxAfterRelaxTillptNnil} % \changes{v3.20}{2015/10/19}{neu (intern)} % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in \cs{Ifstrstart}}%^^A % 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 % \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 % \changes{v3.28}{2019/11/19}{umdefiniert in \cs{Ifisglue}}%^^A % \begin{macro}{\Ifisglue} % \changes{v3.28}{2019/11/19}{neu aus Umdefinierung von \cs{ifisglue}}%^^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> \providecommand*{\ifisglue}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifisglue'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifisglue' by `\string\Ifisglue'% }% \Ifisglue } \newcommand*{\Ifisglue}[1]{% \IfArgIsEmpty{#1}{\@secondoftwo}{\scr@ifisglue#1\@nil}% } % \end{macrocode} % \begin{macro}{\scr@ifisglue} % \changes{v3.20}{2015/10/21}{neu (intern)} % \changes{v3.28}{2019/11/18}{\cs{ifstrstart} umbenannt in % \cs{Ifstrstart}}%^^A % \changes{v3.28}{2019/11/23}{Vorzeichenfall \texttt{+} korrigiert}%^^A % \changes{v3.28}{2019/11/23}{im Plusfall \cs{ifisdimension} durch % \cs{ifisglue} ersetzt}%^^A % 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@ifisglue \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 % \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 % \changes{v3.27}{2019/08/26}{leere Argumente werden korrekt behandelt}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifnumber} umbenannt in \cs{Ifnumber}}%^^A % \begin{macro}{\Ifnumber} % \changes{v3.28}{2019/11/18}{Neu aus Umbenennung von \cs{ifnumber}}%^^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> \providecommand*{\ifnumber}{% % \end{macrocode} % Die Warnung darf nicht ausgegeben werden, wenn \textsf{babelbib} geladen % wurde, weil das Paket die Anweisung ebenfalls definiert, aber nur, wenn sie % nicht bereits definiert war. Dabei werden übrigens teilweise Makronamen mit % dem Präfix \cs{scr@} definiert, was ich gar nicht lustig finde. Überhaupt % geht das böse in die Hose, wenn \textsf{babelbib} vor \texttt{scrbase} % geladen wird, was ja durchaus passieren kann. Möglichweise werde ich daher % die Sonderbehandlung an dieser Stelle auch wieder entfernen, sobald ich die % Anleitung von \textsf{babelbib} auf \textsf{biblatex} umgestellt habe. % \begin{macrocode} \scr@ifundefinedorrelax{ver@babelbib.sty}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifnumber'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifnumber' by `\string\Ifnumber'% }% }{}% \Ifnumber } \newcommand\Ifnumber[1]{% \begingroup\@tempswafalse\let\scr@next\test@number \IfArgIsEmpty{#1}{}{\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} % \end{macro} % % \begin{macro}{\ifintnumber} % \changes{v3.12}{2013/10/30}{neu}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifintnumber} umbenannt in % \cs{Ifintnumber}}%^^A % \begin{macro}{\Ifintnumber} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifintnumber}} % 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> \providecommand*{\ifintnumber}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifintnumber'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifintnumber' by `\string\Ifintnumber'% }% \Ifintnumber } \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} % \end{macro} % % \begin{macro}{\ifdimen} % \changes{v3.28}{2019/11/18}{umbenannt in \cs{Ifdimen}}%^^A % \begin{macro}{\Ifdimen} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifdimen}}%^^A % 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> \providecommand*{\ifdimen}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifdimen'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifdimen' by `\string\Ifdimen'% }% \Ifdimen } \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} % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % 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} % \end{macro} % % % \begin{macro}{\ifpdftex} % \changes{v2.95}{2002/08/19}{neu}%^^A % \changes{v3.28}{2019/11/18}{entfernt}%^^A % \begin{macro}{\scr@ifpdftex} % \changes{v2.95}{2002/08/19}{neu (intern)}%^^A % \changes{v3.30}{2020/03/06}{veralteten Befehl \cs{ifnotundefined} durch % \cs{Ifnotundefined} ersetzt}%^^A % If-then-else-Konstrukt, um zu testen, ob pdf\TeX{} verwendet wird. % \begin{macrocode} %<*base> \newcommand{\scr@ifpdftex}{\Ifnotundefined{pdftexversion}} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\scr@ifluatex} % \changes{v3.21}{2016/05/27}{neu (intern)}%^^A % \changes{v3.30}{2020/03/06}{veralteten Befehl \cs{ifnotundefined} durch % \cs{Ifnotundefined} ersetzt}%^^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}}%^^A % \changes{v3.28}{2019/11/18}{entfernt}%^^A % \begin{macro}{\scr@ifVTeX} % \changes{v2.95}{2002/08/19}{neu}%^^A % \changes{v2.97c}{2007/06/20}{umdefiniert von \cs{scr@ifvtex}} % \changes{v3.30}{2020/03/06}{veralteten Befehl \cs{ifnotundefined} durch % \cs{Ifnotundefined} ersetzt}%^^A % If-then-else-Konstrukt, um zu testen, ob V\TeX{} verwendet wird. % \begin{macrocode} %<*base> \newcommand{\scr@ifVTeX}{\Ifnotundefined{VTeXversion}} % % \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}}%^^A % \changes{v3.28}{2019/11/18}{Umbenannt in \cs{Ifpdfoutput}}%^^A % \begin{macro}{\Ifpdfoutput} % \changes{v3.28}{2019/11/18}{Neu aus Umbenennung von \cs{ifpdfoutput}}%^^A % \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 }% }% \providecommand*{\ifpdfoutput}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifpdfoutput'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifpdfoutput' by `\string\Ifpdfoutput'% }% \Ifpdfoutput } \newcommand*{\Ifpdfoutput}{\scr@ifpdfoutput} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ifpsoutput} % \changes{v2.95}{2002/08/21}{neu}%^^A % \changes{v3.28}{2019/11/18}{umbenannt in \cs{Ifpsoutput}}%^^A % \begin{macro}{\Ifpsoutput} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifpsoutput}}%^^A % \begin{macro}{\scr@ifpsoutput} % \changes{v2.95}{2002/08/21}{neu (intern)}%^^A % \changes{v2.95}{2004/07/20}{Expandierbarkeit verbessert}%^^A % \changes{v3.30}{2020/03/06}{veralteten Befehl \cs{ifnotundefined} durch % \cs{Ifnotundefined} ersetzt}%^^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 }% }% } \providecommand*{\ifpsoutput}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifpsoutput'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifpsoutput' by `\string\Ifpsoutput'% }% \Ifpsoutput } \newcommand*{\Ifpsoutput}{\scr@ifpsoutput} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ifdvioutput} % \changes{v2.95}{2002/08/21}{neu}%^^A % \changes{v3.28}{2019/11/18}{umbenannt in \cs{Ifdvioutput}}%^^A % \begin{macro}{\Ifdvioutput} % \changes{v3.28}{2019/11/18}{neu aus Umbenennung von \cs{ifdvioutput}}%^^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 }% } \providecommand*{\ifdvioutput}{% \PackageWarning{scrbase}{Usage of deprecated command `\string\ifdvioutput'.\MessageBreak The command has been renamed because of a\MessageBreak recommendation of The LaTeX Project Team.\MessageBreak Please replace `\string\ifdvioutput' by `\string\Ifdvioutput'% }% \Ifdvioutput } \newcommand*{\Ifdvioutput}{\scr@ifdvioutput} % % \end{macrocode} % \end{macro} % \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. Ab \LaTeX~2018-04-01 ist das aber auch % Bestandteil von \LaTeX. Deshalb ist es in jedem Fall sinnvoll die Definition % nur vorzunehmen, wenn es nicht definiert ist. % \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} % % \selectlanguage{english}% % \begin{macro}{\IfActiveMkBoth} % \changes{v3.26}{2018/09/03}{new}%^^A % \begin{macro}{\if@scrActiveMkBoth} % \changes{v3.26}{2018/09/03}{new}%^^A % \changes{v3.27}{2019/07/26}{handling for \cs{marks}}%^^A % This command test, whether or not \cs{@mkboth} does change a mark or not. % \begin{macrocode} %<*base> \newif\ifscr@ActiveMkBoth \def\scr@ActiveMkBothfalse{\global\let\ifscr@ActiveMkBoth\iffalse} \def\scr@ActiveMkBothtrue {\global\let\ifscr@ActiveMkBoth\iftrue} \newcommand*{\IfActiveMkBoth}{% \begingroup \def\markboth##1##2{\scr@ActiveMkBothtrue}% \def\markright##1{\scr@ActiveMkBothtrue}% \def\markleft##1{\scr@ActiveMkBothtrue}% \def\markboth##1{\scr@ActiveMkBothtrue}% \def\markdouble##1{\scr@ActiveMkBothtrue}% \def\mark##1{\scr@ActiveMkBothtrue}% \def\marks##1##2{\scr@ActiveMkBothtrue}% \scr@ActiveMkBothfalse \setbox\@tempboxa\vbox{\@mkboth{}{}}% \endgroup \ifscr@ActiveMkBoth \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % % \end{macrocode} % \end{macro}%^^A\if@scrActiveMkBoth % \end{macro}%^^A\IfActiveMkBoth % \selectlanguage{ngerman}% % % \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{setkeys} 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 % \changes{v3.27}{2019/10/02}{Fehlermeldungen verbessert}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^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 \ifx\FamilyKeyState\FamilyKeyStateUnknownValue value at \fi `\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)}%^^A % \changes{v3.27}{2019/10/02}{Fehlermeldungen verbessert}%^^A % 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 \ifx\FamilyKeyState\FamilyKeyStateUnknownValue value at \fi `\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 % \changes{v3.27}{2019/10/02}{Fehlermeldungen verbessert}%^^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 Familienmitglieder festgestellt, ob % die Option bei einem Mitglied 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. Hilfreich ist, dass \cs{\meta{Familie}@key@familylist} eine Liste % aus Familie + Mitglied ist und nicht nur aus dem Namen der Mitglieder. % \changes{v3.27}{2019/07/19}{Fix: Familienoptionen werden zuerst % ausgeführt}%^^A % \begin{macrocode} \scr@key@found@false \edef\reserved@a{#1,\csname #1@key@familylist\endcsname}% \@for\reserved@a:=\reserved@a\do{% \scr@ifundefinedorrelax{KV@\reserved@a @\scr@key@name}{% % \end{macrocode} % \changes{v3.27}{2019/07/19}{Behandlung für \texttt{@else@}-Optionen}%^^A % Wenn das Familiemitglied keine entsprechende Option besitzt, kann es noch % immer eine \texttt{@else@}-Option besitzen. In diesem Fall wird selbige % ausgeführt. Die Ausführung hat aber nur dann Einfluss auf den % Fehlerspeicher, wenn sie erfolgreich war. In diesem Fall wird der % Fehlerspeicher gelöscht. Ausnahme ist, wenn das aktuelle Mitglied die % Familie selbst ist. In diesem Fall wird die \texttt{@else@}-Option nicht % hier ausgeführt. Das erledigen wir später und nur in dem Fall, dass % tatsächlich kein Mitglied eine solche Option oder eine % \texttt{@else@}-Option hatte. % \begin{macrocode} \Ifstr{\reserved@a}{#1}{}{% \scr@ifundefinedorrelax{KV@\reserved@a @@else@}{}{% \expandafter\scr@execute@elseoption\expandafter{\reserved@a}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \scr@key@found@true \let\scr@key@run@errors\relax \fi }% }% }{% % \end{macrocode} % Wurde hingegen eine Option für ein Familienmitglied gefunden, so wird sie % ausgeführt und bei Bedarf der Fehlerspeicher angepasst. % \begin{macrocode} \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 \space\space- `\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 \space\space- `\FamilyMemberOfKey': value expected }% \else \edef\scr@key@run@errors{% \unexpanded\expandafter{\scr@key@run@errors}% \noexpand\MessageBreak \space\space- `\FamilyMemberOfKey': \FamilyKeyState }% \fi \fi \fi \fi }% }% \ifscr@key@found@ \ifx\scr@key@run@errors\relax\else \ifx\scr@key@run@errors\@empty\else % \end{macrocode} % \changes{v3.28}{2019/11/23}{Fehlermeldungen und Infos korrigiert}%^^A % Jetzt muss gegebenenfalls noch eine \texttt{@else@} Option behandelt und % abhängig davon entweder ein Fehler oder eine Info ausgegeben werden. % \begin{macrocode} \scr@ifundefinedorrelax{KV@#1@@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 }% }{% \scr@execute@elseoption{#1}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \PackageInfo{scrbase}{% option `\expandafter\detokenize\expandafter{\scr@key@atlist}'% \MessageBreak processed by `@else@' option of family\MessageBreak `#1', after the members said: \scr@key@run@errors\MessageBreak o\expandafter\@gobble }% \let\scr@key@run@errors\relax \else \PackageError{scrbase}{% unknown option \ifx\FamilyKeyState\FamilyKeyStateUnknownValue value at \fi `\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 \fi \else \scr@ifundefinedorrelax{KV@#1@@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.% }% }{% \scr@execute@elseoption{#1}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \else \PackageError{scrbase}{% unknown option \ifx\FamilyKeyState\FamilyKeyStateUnknownValue value at \fi `\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 \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)}%^^A % \changes{v3.25}{2017/11/16}{Gruppe eingefügt}%^^A % \changes{v3.25}{2017/11/16}{\cs{scr@key@name@else} und % \cs{scr@key@value@else} neu}%^^A % \changes{v3.27}{2019/03/10}{missing percent added to avoid spaces}%^^A % 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. Da % allerdings die Originalwerte ggf. von der \texttt{@else@}-Option ausgewertet % werden sollen, wird das originale \cs{scr@key@atlist} zum Wert der % \texttt{@else@}-Option. Damit diese nicht erneut aufgespaltet werden muss, % werden die originalen \cs{scr@key@name} und \cs{scr@key@value} zusätzlich in % \cs{scr@key@name@else} und \cs{scr@key@value@else} gespeichert. % \begin{macrocode} \newcommand*{\scr@execute@elseoption}[1]{% \begingroup \protected@edef\reserved@a{% \unexpanded{% \endgroup \let\scr@key@name@else\scr@key@name \let\scr@key@value@else\scr@key@value \def\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}}% \scr@ifundefinedorrelax{scr@key@name@else}{% \unexpanded{\let\scr@key@name@else\relax}% }{% \noexpand\def\noexpand\scr@key@name@else{% \unexpanded\expandafter{\scr@key@name@else}% }% }% \scr@ifundefinedorrelax{scr@key@value@else}{% \unexpanded{\let\scr@key@value@else\relax}% }{% \noexpand\def\noexpand\scr@key@value@else{% \unexpanded\expandafter{\scr@key@value@else}% }% }% }\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}}%^^A % \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}}%^^A % \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}}%^^A % \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}}%^^A % \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}%^^A % \changes{v3.00}{2008/04/30}{umbenannt von \cs{KOMA@key@split@name@value}}%^^A % \changes{v3.13}{2014/10/17}{\cs{long}}%^^A % \changes{v3.26}{2018/08/29}{Verwendung von \cs{scr@sp@def} statt % \cs{KV@@sp@def}}%^^A % \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{% \scr@sp@def\scr@key@name{#1}% \scr@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 % \changes{v3.26b}{2019/01/09}{Tyischen Fehler abgefangen}%^^A % \begin{macro}{\@FamilyOptions} % \changes{v3.14}[2014/10/17]{Neue streng interne Anweisung}%^^A % \changes{v3.26}{2018/08/29}{Verwendung von \cs{scr@sp@def} statt % \cs{KV@@sp@def}}%^^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]{% \begingroup \def\reserved@a##1,##2\@nil{\IfArgIsEmpty{##2}{}{\@tempswatrue}}% \@tempswafalse\expandafter\reserved@a#2,\@nil \if@tempswa \PackageError{scrbase}{% syntax error in key `\detokenize{#2}'% }{% You've used `\string\...Option' to set the key `\detokenize{#2}'\MessageBreak to new value(s), but `,' is not allowed in the key of an option\MessageBreak (and `\string\...Option' does not use `,' to separate several keys).\MessageBreak Maybe you've meant \string\...Options\space instead of \string\...Option.\MessageBreak If you'll continue, I'll give it a try, but you should expect further\MessageBreak and even strange error messages.% }% \else \def\reserved@a##1=##2\@nil{% \IfArgIsEmpty{##2}{}{\@tempswatrue\def\reserved@a{=}}}% \expandafter\reserved@a#2=\@nil \if@tempswa \PackageError{scrbase}{% syntax error in key `\detokenize{#2}'% }{% You've used `\string\...Option' to set the key `\detokenize{#2}'\MessageBreak to new value(s), but `=' is not allowed in the key of an option\MessageBreak (and `\string\...Option' does not use `=' to separate key and value).\MessageBreak Maybe you've meant \string\...Options\space instead of \string\...Option.\MessageBreak If you'll continue, I'll give it a try, but you should expect further\MessageBreak and even strange error messages.% }% \fi \fi \endgroup \@FamilyOption{#1}{#2}% } \newcommand{\@FamilyOption}[3]{% \expandafter\scr@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 % \changes{v3.30}{2020/02/25}{spurious space in warning message removed}%^^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 % \changes{v3.27}{2019/07/08}{Leeres Argument ist \texttt{true}}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^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}{}{\@nameuse{#3true}\FamilyKeyStateProcessed}{% \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} % \selectlanguage{english} % \begin{macro}{\FamilyInverseBoolKey} % \changes{3.27}{2019/07/08}{new} % \begin{macro}{\FamilySetInverseBool} % \changes{3.27}{2019/07/08}{new} % These are similar to \cs{FamilyBoolKey} and \cs{FamilySetBoolKey} but use % inverse logic (true sets false and false sets true). % \begin{macrocode} %<*base> \newcommand*{\FamilyInverseBoolKey}[4][.\@currname.\@currext]{% \@ifundefined{if#4}{% \expandafter\newif\csname if#4\endcsname \@nameuse{#4true}% }{}% \DefineFamilyKey[{#1}]{#2}{#3}[true]{\FamilySetInverseBool{#2}{#3}{#4}{##1}}% } \newcommand*{\FamilySetInverseBool}[4]{% \FamilySetBool{#1}{#2}{#3}{#4}% \ifx\FamilyKeyState\FamilyKeyStateProcessed \expandafter\ifx\csname if#3\expandafter\endcsname\csname iftrue\endcsname \@nameuse{#3false}% \else \@nameuse{#3true}% \fi \fi } % % \end{macrocode} % \end{macro}%^^A \FamilySetInverseBool % \end{macro}%^^A \FamilyInverseBoolKey % \selectlanguage{ngerman} % % \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}% % \end{macrocode} % Zusammen mit \cs{@defaultsunits} (siehe unten) wäre hier das sinnvoll: % \begin{macrocode} %<*neveruse> \expandafter\Ifiscount\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% % \expandafter\Ifisdimen\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% \expandafter\Ifisskip\expandafter{\reserved@a}{% \aftergroup\@firstoftwo }{% % \end{macrocode} % Zusammen mit \cs{@defaultsunits} (siehe unten) wäre hier das sinnvoll: % \begin{macrocode} %<*neveruse> \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 }% }% }% %<*neveruse> }% % }% }% %<*neveruse> }% % \endgroup % \end{macrocode} % TODO: An der Stelle wäre etwas wie: % \begin{macrocode} %<*neveruse> {\@defaultunits#3=#4pt\relax\@nnil\FamilyKeyStateProcessed} % % schön. Aber aus irgend einem Grund habe ich mich seinerzeit dafür % entschieden, die einfacher Form zu wählen: % \begin{macrocode} {#3=#4\FamilyKeyStateProcessed}% {% \FamilyUnknownKeyValue{#1}{#2}{#4}{% length values, %<*neveruse> 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}{\FamilySetUseLengthMacro} % \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. weiterhin % 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}%^^A % \changes{v3.25}{2017/12/04}{komplett leere Listenelemente werden % ignoriert}%^^A % 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{% \ifx\@valuelist\@empty\else \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 \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 das 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}{\FamilyCSKey} % \changes{v3.25}{2017/12/08}{Neue Anweisung}%^^A % \begin{macro}{\Family@CS@Key} % \changes{v3.25}{2017/12/08}{Neu (intern)}%^^A % \begin{macro}{\Family@@CS@@Key} % \changes{v3.25}{2017/12/08}{Neu (intern)}%^^A % \changes{v3.26}{2018/11/06}{Es wird wirklich diese Anweisung (statt erneut % \cs{Family@@String@@Key}) definiert}%^^A % Ein ähnliches Makro definiert einen Schlüssel, der eine Befehlssequenz 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*{\FamilyCSKey}[3][.\@currname.\@currext]{% \kernel@ifnextchar [%] {\Family@@CS@@Key{#1}{#2}{#3}}{\Family@CS@Key{#1}{#2}{#3}}% } \newcommand*{\Family@@CS@@Key}{} \long\def\Family@@CS@@Key#1#2#3[#4]#5{% \DefineFamilyKey[{#1}]{#2}{#3}[{#4}]{\@namedef{#5}{##1}}% } \newcommand{\Family@CS@Key}[4]{% \DefineFamilyKey[{#1}]{#2}{#3}{\@namedef{#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 % % % \selectlanguage{english} % \subsection{Do Hook Mechanism} % \label{sec:dohook} % % \changes{v3.27}{2019/02/02}{Do hook mechanism added}%^^A % From \KOMAScript~v3.27 there is a new general hook mechanism called ``do % hook mechanism''. This mechanism is mentioned to provide extended hooks for % package authors. All hooks newly implemented in \KOMAScript{} \emph{should} % use this new mechanism. % % % \begin{macro}{\ForDoHook} % \changes{v3.27}{2019/02/05}{New}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % \changes{v3.30}{2020/03/07}{\cs{loop}\dots\cs{repeat} inside group}%^^A % \changes{v3.30}{2020/03/07}{using \cs{rloop} instead of \cs{loop}}%^^A % Arguments: % \begin{description} % \item[\meta{specificator}:] % \meta{string} or \meta{string}\texttt{/}\meta{specificator} % \item[\meta{code}:] \LaTeX{} code % \end{description} % Executes \meta{code} for earch level of a do-hook. This is a helper command % normally not interesting for users or package authors. However, I define it % in the user context to be consistent with the other do-hook commands. Note, % there will be two arguments appended to the \meta{code}. The first one is % the name of the hook, the second one the hook argument. % See \cs{ExecuteDoHook} as an example. % \begin{macrocode} %<*base> \newcommand*{\ForDoHook}[2]{% \Ifstr{#1}{}{% \PackageError{scrbase}{empty do-hook specificator}{% You've tried to use an empty do-hook specificator,\MessageBreak but do-hook specificators must not be empty.% }% }{% \begingroup \def\scr@hookrun{\endgroup}% \let\scr@hookname\relax \edef\scr@hookargument{#1}% \rloop \scr@hooksplit@specificator\scr@hookname\scr@hookargument \scr@hookargument \edef\scr@hookrun{% \unexpanded\expandafter{\scr@hookrun}% \unexpanded{#2}{\scr@hookname}{\scr@hookargument}% }% \ifx\scr@hookargument\@empty\else \repeat \scr@hookrun }% } % \end{macrocode} % \begin{macro}{\SplitDoHook} % \changes{v3.27}{2019/02/04}{New}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % Arguments: % \begin{description} % \item[\meta{specificator}:] % \meta{string} or \meta{string}\texttt{/}\meta{specificator} % \item[\meta{prefix command}:] \LaTeX{} macro % \item[\meta{postfix command}:] \LaTeX{} macro % \end{description} % Splits of the \emph{last} element of the \meta{specificator}. The % \meta{postfix command} is defined to be that last element, the \meta{prefix % command} is defined to be the rest. % \begin{macrocode} \newcommand*{\SplitDoHook}[3]{% \Ifstr{#1}{}{% \PackageWarning{scrbase}{empty do-hook specificator}% \let#2\@empty\let#3\@empty }{% \let#2\relax \edef\reserved@a{% \unexpanded{\scr@hooksplit@specificator{#2}{#3}}{#1}% }\reserved@a }% } % \end{macrocode} % \begin{macro}{\scr@hooksplit@specificator} % \changes{v3.27}{2019/02/02}{New internal}%^^A % Split of the first string of the specificator argument, append it to % \cs{scr@hookname} and store the rest in \cs{scr@hookargument}. The argument % must not be empty! % \begin{macro}{\scr@@hooksplit@specificator} % \changes{v3.27}{2019/02/02}{New internal}%^^A % \begin{macrocode} \newcommand*{\scr@hooksplit@specificator}[3]{% \expandafter\scr@@hooksplit@specificator\expandafter#1\expandafter#2#3/\@nil } \newcommand*{\scr@@hooksplit@specificator}{} \def\scr@@hooksplit@specificator#1#2#3/#4\@nil{% \scr@ifundefinedorrelax{scr@hookname}{\def#1{#3}}{% \edef#1{#1/#3}% }% \def#2{#4}% \ifx#2\@empty\else \scr@@hookargument#2#4\@nil\fi } \newcommand*{\scr@@hookargument}{} \def\scr@@hookargument#1#2/\@nil{\def#1{#2}}% % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ExecuteDoHook} % \changes{v3.27}{2019/02/02}{New}%^^A % Arguments: % \begin{description} % \item[\meta{specificator}:] % \meta{string} or \meta{string}\texttt{/}\meta{specificator} % \end{description} % Each string of the \meta{specificator} defines a hook subgroup. The % execution is done in a loop, first all hook elements of the first % \meta{string} of the \meta{specificator} are executed with the rest of the % \meta{specificator} as an argument. Then the hook elements of the % composition of the first and the second \meta{string} are executed again % with the rest of the \meta{specificator} as an agument and so on until the % hook elements of the whole \meta{specificator} has been executed with an % empty argument. So every hook element has to expect an argument that is % itself a \meta{specificator}. At each loop level the one-time hooks % are executed after the permanent hooks. % \begin{macrocode} \newcommand*{\ExecuteDoHook}[1]{% \@ifundefined{scr@execute@dohook}{% \def\scr@execute@dohook##1##2{% \def\scr@hook@do####1{####1{##2}}% \@nameuse{scr@dohook@##1}% \@nameuse{scr@otdohook@##1}% \expandafter\global\expandafter\let \csname scr@otdohook@##1\endcsname\@empty \let\scr@hook@do\relax }% \ForDoHook{#1}{\scr@execute@dohook}% \let\scr@execute@dohook\relax }{% \PackageWarning{scrbase}{cascaded do-hook detected.\MessageBreak It seems, that the do-hook `\detokenize{#1}'\MessageBreak is be executed, while another do-hook is active.\MessageBreak This is not allowed and therefore ignored% }% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\AddtoDoHook} % \changes{v3.27}{2019/02/02}{New}%^^A % Arguments: % \begin{description} % \item[\meta{specificator}:] % \meta{string} or \meta{string}\texttt{/}\meta{specificator} % \item[\meta{element}:] % a \LaTeX command, that expects exactly one argument. % \end{description} % For the \meta{specificator} see \cs{ExecuteDoHook}. Here you can add an % \meta{element} to a hook defined by the \meta{specificator}. Adding a hook % is local to the current group. % \begin{macrocode} \newcommand*{\AddtoDoHook}[2]{% \Ifstr{#1}{}{% \PackageError{scrbase}{empty hook specificator}{% As hook specificators can never be empty, the first argument\MessageBreak of \string\AddtoDoHook\space must expand to an not empty string.% }% }{% \scr@ifundefinedorrelax{scr@dohook@#1}{\@namedef{scr@dohook@#1}{}}{}% \expandafter\l@addto@macro\csname scr@dohook@#1\endcsname{% \scr@hook@do{#2}% }% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\AddtoOneTimeDoHook} % \changes{v3.27}{2019/02/02}{New}%^^A % \changes{v3.28}{2019/11/18}{\cs{ifstr} umbenannt in \cs{Ifstr}}%^^A % Arguments: % \begin{description} % \item[\meta{specificator}:] % \meta{string} or \meta{string}\texttt{/}\meta{specificator} % \item[\meta{element}:] % a \LaTeX command, that expects exactly one argument. % \end{description} % This is almost the same as \cs{AddtoDoHook} but a hook added by this command % is executed only once. % \begin{macrocode} \newcommand*{\AddtoOneTimeDoHook}[2]{% \Ifstr{#1}{}{% \PackageError{scrbase}{empty hook specificator}{% As hook specificators can never be empty, the first argument\MessageBreak of \string\AddtoDoHook\space must expand to an not empty string.% }% }{% \scr@ifundefinedorrelax{scr@otdohook@#1}{\@namedef{scr@otdohook@#1}{}}{}% \expandafter\l@addto@macro\csname scr@otdohook@#1\endcsname{% \scr@hook@do{#2}% }% }% } % % \end{macrocode} % \end{macro} % % \selectlanguage{ngerman} % % \iffalse % % \fi % % \Finale % \endinput % % end of file `scrkernel-basics.dtx' %%% Local Variables: %%% mode: doctex %%% TeX-master: t %%% End: