Chapter 12: Basic Functions of Package scrbase
316
this may result in an error message about unknown value assignment (see also
page 319
and
page 310
).
Example: The key coldcuts should be declared somehow more robust. Additionally, all
sausage packages should use the same key. So either all or none of them will
produce cold cuts.
\FamilyBoolKey{butcher}{coldcuts}%
{@coldcuts}
A test, whether or not to produce cold cuts, may be:
\if@coldcuts
...
\else
...
\fi
This would be the same in each of the three sausage packages, thereby defining
the attribute “coldcuts” as a family option:
\@ifundefined{if@coldcuts}{%
\expandafter\newif\csname if@coldcuts\endcsname
}{}%
\DefineFamilyKey[]{butcher}{coldcuts}[true]{%
\FamilySetBool{butcher}{coldcuts}%
{@coldcuts}%
{#1}%
}
or shorter:
\FamilyBoolKey[]{butcher}{coldcuts}%
{@coldcuts}
using the additional information at
page 310
, this is not only valid for
\DefineFamilyKey
but for \FamilyBoolKey too.
\FamilyNumericalKey[family member ]{family }{key }[default ]{command }{values list }
\FamilySetNumerical{family }{key }{command }{values list }{value }
In contrast to switches that may be either true or false, a key exists that accept several
values. For example an alignment may not only be left or not left, but left, centered, or right.
Internally such differentiation often is made using \ifcase. This TEX command expects a
numerical value. Because of this the command to define a macro by a key has been named
\FamilyNumericalKey
in scrbase. The values list thereby has the form:
{value }{definition },{value }{definition },
. . .
Chapter 12: Basic Functions of Package scrbase
317
Therefore, the values list does not solely define the supported values to the key . For each
of the value s, the definition of macro \command also is given. Usually, definition is just
a numerical value. Nevertheless, other content is possible and allowed. Currently, the only
limitation is that definition has to be fully expandable and will be expanded during the
assignment.
Example: The sausage may be cut different. For example the cold cuts may stay uncut or
will be cut roughly or may be cut thinly. This information should be stored in
command \cuthow.
\FamilyNumericalKey{butcher}%
{saladcut}{cuthow}{%
{none}{none},{no}{none},{not}{none}%
{rough}{rough},%
{thin}{thin}%
}
Not cutting anything may be selected either by
\ FamilyOptions{butcher}{saladcut=none}
or
\FamilyOptions{butcher}{saladcut=no}
or
\FamilyOptions{butcher}{saladcut=not}
In all three cases \cuthow would be defined with content none. It may be very
useful to provide several values for the same result as shown in this example.
Now, it’s most likely, that the kind of cutting will not be printed, but should be
evaluated later. In this case a textual definition would not be useful. If the key is
defined like this:
\FamilyNumericalKey{butcher}%
{saladcut}{cuthow}{%
{none}{0},{no}{0},{not}{0}%
{rough}{1},%
{thin}{2}%
}
then a condition like the following may be used:
\ ifcase\cuthow
% no cut
\or
% rough cut
\else
% thin cut
Chapter 12: Basic Functions of Package scrbase
318
\fi
Internally,
\FamilyNumericalKey
uses
\FamilySetNumerical
as
action
of
\DefineFamilyKey
. If a unknown value is assigned to such a key, \FamilySetNumerical
will call
\FamilyUnknownKeyValue
with the arguments family , key and value . This will
normally result in an error message about assigning an unknown value.
\FamilyCounterKey[family member ]{family }{key }[default ]{L
A
TEX counter }
\FamilySetCounter{family }{key }{L
A
TEX counter }{ value }
Beside
v3.12
\FamilyNumericalKey
that defines a macro to a numeric value depending on a sym-
bolic value, there are circumstances when a key directly represents a L
A
TEX counter , that
should be assigned directly to a numeric value. In those cases, \FamilyCounterKey can be
used that internally will call \FamilySetCounter. A primary test of the value argument is
done that only detects whether or not usage of value as a number is plausible. The assign-
ment is done, only if this plausibility test is successful. Nevertheless the assignment can still
fail and result in a TEX error. But if the plausibility test fails already, this is signalled by
\FamilyKeyStateUnknownValue
.
If
v3.15
the value is omitted, the default is used instead. If there is no default , the key can
be used only with a value being defined.
\FamilyCounterMacroKey[family member ]{family }{key }[default ]{macro }
\FamilySetCounterMacro{family }{key }{macro }{value }
These
v3.12
two commands differ from the previously described
\FamilyCounterKey
and
\FamilySetCounter
only by the fact, that they do not assign a value to a L
A
TEXcounter ,
but define a \macro with the value .
\FamilyLengthKey[family member ]{family }{key }[default ]{length }
\FamilySetLength{family }{key }{length }{value }
\FamilyLengthMacroKey[family member ]{family }{key }[default ]{Makro }
\FamilySetLengthMacro{family }{key }{Makro }{value }
With
v3.12
\FamilyLengthKey
you can define a key that represents a length . It does not matter
whether the length is a L
A
TEX length, a TEX skip or a TEX dimension. Internally the length
will be set to the value using \FamilySetLength. Thereby a primary test is used to decide,
whether or not it is plausible to assign length to value . The assignment is done only if this
plausibility test is successful. Nevertheless, not all assignment errors can be recognised, so an
inaccurate value can still result in TEX error. Recognised errors however will be signalled by
\FamilyKeyStateUnknownValue
.
If
v3.15
the value is omitted, the default is used instead. If there is no default , the key can
be used only with a value being defined.
Chapter 12: Basic Functions of Package scrbase
319
In difference to this, \FamilyLengthMacroKey and \FamilySetLengthMacro do not assign
value
to a length , but define a \macro with this value .
\FamilyStringKey[family member ]{family }{key }[default ]{command }
This defines
v3.08
a key that accepts every value. The value will be stored into the given \command.
If there is no optional argument for the default , \FamilyStringKey is the same as:
\DefineFamilyKey
[family member ]{family }{key }
{\defcommand {#1}
\FamilyKeyStateProcessed
}
.
If an optional argument default is used, \FamilyStringKey is the same as:
\DefineFamilyKey
[family member ]{family }{key }
[default ]{\defcommand {#1}}
.
If command is not been defined, an empty macro will be defined.
Example: By default an amount of 250 g sausage salad should be produced. The amount
should be configurable by an option. The wanted amount will be stored in the
macro \saladweight. The option should be named saladweight, too:
\newcommand*{\saladweight}{250g}
\FamilyStringKey{butcher}%
{saladweight}[250g]{\saladweight}
To switch back to the default weight after changing it, the user may simply use
the option without weight:
\FamilyOptions{butcher}{saladweight}
This may be done, because the default weight has been set as default at the
definition of the option above.
In this case there are not unknown values because all values are simply used for a macro
definition. Nevertheless, you should note that paragraph breaks at the value assignment to
the key are not allowed.
\FamilyUnknownKeyValue{family }{key }{value }{values list }
The command \FamilyUnknownKeyValue throws and error message about unknown values
assigned to a known key. The values list is a comma separated list of allowed values in the
form:
‘ value ’, ‘ value ’ . . .
Currently
v3.12
, values list is not used by scrbase.
Chapter 12: Basic Functions of Package scrbase
320
Example: Now, for the cold cuts, the choices should be cut or no-cut and in case of cut rough
or thin. Rough should be the default for cutting.
\@ifundefined{if@thincut}{%
\expandafter
\newif\csname if@thincut\endcsname}{}%
\@ifundefined{if@coldcuts}{%
\expandafter
\newif\csname if@coldcuts\endcsname}{}
\DefineFamilyKey{butcher}%
{coldcuts}[true]{%
\FamilySetBool{butcher}{coldcuts}%
{@coldcuts}%
{#1}%
\ifx\FamilyKeyState\FamilyKeyStateProcessed
\@thincutfalse
\else
\ifstr{#1}{thin}{%
\@coldcutstrue
\@thincuttrue
\FamilyKeyStateProcessed
}{}%
\fi
}%
Let’s have a look at the definition of butcher: First of all, we try to set the
boolean switch of cold cuts using
\FamilySetBool
. After this command, we test
whether or not
\FamilyKeyState
signals the success of the command with state
\FamilyKeyStateProcessed
. If so, only the thin cut has to be deactivated.
In the other case, the value will be tested to be equal to thin. In that
case, cold cuts and thin cut are activated and the state will be switched to
\FamilyKeyStateProcessed
. If the last test failed also, the failure state of
\FamilySetBool
is still valid at the end of the execution.
Command \ifstr is used for the thin test. It is described on
page 322
in
sec-
tion 12.3
.
\FamilyElseValues
With
former
releases
v3.12
of
scrbase,
additional
allowed
values
reported
by
\FamilyUnknownKeyValue
can be set re-defining \FamilyElseValues in the form:
,
‘value ’, ‘value ’ . . .
Chapter 12: Basic Functions of Package scrbase
321
Since release 3.12
\FamilyUnknownKeyValue
does not report errors itself, but signals them
using
\FamilyKeyState
. Therefore, \FamilyElseValues became deprecated. Nevertheless,
its former usage is recognised by scrbase and results in a code change demand message.
12.3. Conditional Execution
The package scrbase provides several commands for conditional execution. other than the TEX
syntax of conditionals, e. g.,
\iftrue
...
\else
...
\fi
yet the L
A
TEX syntax also known from L
A
TEX commands like \IfFileExists, \@ifundefined,
\@ifpackageloaded
, and many others, is used. Nevertheless, some package authors prefer
to use the TEX syntax even for users at the L
A
TEX interface level that could inevitably lead
to naming conflicts with the scrbase conditionals. In fact, the conditionals of scrbase are
very basic. Because of this scrbase firstly defines these conditionals as internal commands
with prefix \scr@. Additional user commands without this prefix are subsequently defined.
But the definition of the user commands may be suppressed with option
internalonly
(see
section 12.1
,
page 308
).
Authors of packages and classes should use the internal commands as KOMA-Script itself
does. Nevertheless, for completeness the user commands are described separately.
\scr@ifundefinedorrelax{name }{then instructions }{else instructions }
\ifundefinedorrelax{name }{then instructions }{else instructions }
This command has almost the same functionality as \@ifundefined from the L
A
TEX kernel (see
[
BCJ
+
05
]). So the then instructions will be executed if name is the name of a command
that is currently either not defined or \relax. Otherwise, the else instructions will be
executed. In contrast to \@ifundefined, \name is not defined to be \relax in the event it
was not defined before. Moreover, using ε-TEX this case will not consume any hash memory.
\scr@ifpdftex{then instructions }{else instructions }
\ifpdftex{then instructions }{else instructions }
If pdfTEX has been used, the then instructions will be executed, otherwise the else
instructions
. Whether or not a PDF-file is generated does not matter, and the pdfTEX
test is rarely useful. In general, test for the desired command instead (see previous
\scr@ifundefinedorrelax
and
\ifundefinedorrelax
).
Chapter 12: Basic Functions of Package scrbase
322
\scr@ifVTeX{then instructions }{else instructions }
\ifVTeX{then instructions }{else instructions }
If VTEX has been used, the then instructions will be executed, otherwise the else
instructions
. This test is seldom useful. Test for the desired command instead (see previous
\scr@ifundefinedorrelax
and
\ifundefinedorrelax
).
\scr@ifpdfoutput{then instructions }{else instructions }
\ifpdfoutput{ then instructions }{ else instructions }
When generating a PDF-file the then instructions will be executed, otherwise the else
instructions
. Whether pdfTEX or VTEX or another TEX engine is used to generate the
PDF-file does not matter.
\scr@ifpsoutput{then instructions }{else instructions }
\ifpsoutput{then instructions }{else instructions }
When generating a PostScript-file the then instructions will be executed, otherwise the
else instructions
. VTEX provides direct PostScript generation that will be recognised
here. If VTEX is not used, but a switch \if@dvips has been defined, the decision depends on
that switch. KOMA-Script provides \if@dvips in typearea.
\scr@ifdvioutput{then instructions }{else instructions }
\ifdvioutput{then instructions }{else instructions }
When generating a DVI-file the then instructions will be executed, otherwise the else
instructions
. If neither a direct PDF-file generation nor a direct PostScript-file generation
has been detected, DVI-file generation is assumed.
\ifnotundefined{name }{then instructions }{else instructions }
ε
-TEX will be used to test, whether or not a command with the given name has already been
defined. The then instructions will be executed if the command is defined, otherwise the
else instructions
. There is no corresponding internal command.
\ifstr{string }{string }{then instructions }{else instructions }
Both string arguments are expanded and afterwards compared. If the expansions are the
same, the then instructions will be executed, otherwise the else instructions . There
is no corresponding internal command.
Chapter 12: Basic Functions of Package scrbase
323
\ifstrstart{string }{string }{then instructions }{else instructions }
Both
v3.12
string
arguments are expanded and afterwards compared. If aside from white spaces
the first string starts with the second one, the then instructions will be executed, other-
wise the else instructions . The command is not completely expandable and there is no
corresponding internal command.
\ifisdimen{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \dimen, which is also known as TEX length register, the
then instructions
will be executed, otherwise the else instructions . The command is
not completely expandable and there is no corresponding internal command.
\ifisdimension{code }{then instructions }{else instructions }
If
v3.12
code
expands to something with the syntax of the value of a length, the then instructions
will be executed, otherwise the else instructions . Please note that currently an invalid
unit will result in an error message. The command is not completely expandable and there is
no corresponding internal command.
\ifisdimexpr{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \dimexpr, which is also known as TEX length expression,
the then instructions will be executed, otherwise the else instructions . Note that
illegal expressions will result in error messages. The command is not completely expandable
and there is no corresponding internal command.
\ifisskip{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \skip, which is also known as TEX distance register, the
then instructions
will be executed, otherwise the else instructions . The command is
not completely expandable and there is no corresponding internal command.
\ifisglue{code }{then instructions }{else instructions }
If
v3.12
code
expands to something with the syntax of the value of a skip, the then instructions
will be executed, otherwise the else instructions . Please note that currently an invalid
unit will result in an error message. The command is not completely expandable and there is
no corresponding internal command.
Chapter 12: Basic Functions of Package scrbase
324
\ifisglueexpr{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \glueexpr, which is also known as TEX distance expres-
sion, the then instructions will be executed, otherwise the else instructions . Note,
that illegal expressions will result in error messages. The command is not completely expand-
able and there is no corresponding internal command.
\ifiscount{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \count, which is also known as TEX counter register, the
then instructions
will be executed, otherwise the else instructions . The command is
not completely expandable and there is no corresponding internal command. For test with
L
A
TEX counters, see
\ifiscounter
.
\ifisinteger{code }{then instructions }{else instructions }
If
v3.12
code
expands to something with the syntax of the value of a counter, which would be a
negative or positive integer, the then instructions will be executed, otherwise the else
instructions
. The command is not completely expandable and there is no corresponding
internal command.
\ifisnumexpr{code }{then instructions }{else instructions }
If
v3.12
the expansion of code results in a \numexpr, which is also known as TEX number expression,
the then instructions will be executed, otherwise the else instructions . Note that
illegal expressions will result in error messages. The command is not completely expandable
and there is no corresponding internal command.
\ifiscounter{counter }{then instructions }{else instructions }
If
v3.12
counter
is an already defined L
A
TEX counter, the then instructions will be executed,
otherwise the else instructions . The command is not completely expandable and there is
no corresponding internal command.
\ifnumber{string }{then instructions }{else instructions }
Note that this does not compare numbers. The then instructions will be executed if the
one step expansion of string consists of digits only. Otherwise the else instructions will
be used. There is no corresponding internal command.
|