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.
272
Chapter 12.
\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
\fi
Internally,
\FamilyNumericalKey
uses
\FamilySetNumerical
as
action
of
\DefineFamilyKey
. If a unknown value is assigned to such a key, \FamilySetNumerical
will call \FamilyUnkownKeyValue with the arguments family , key and value . This will
normally result in an error message about assigning an unknown value.
273
Chapter 12.
\FamilyCounterKey[family member ]{family }{key }
[default ]{L
A
TEX counter }
\FamilySetCounter{family }{key }{L
A
TEX counter }{ value }
Beside
v3.12
\FamilyNumercialKey
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.
In difference to this, \FamilyLengthMacroKey and \FamilySetLengthMacro do not assign
value
to a length , but define a \macro with this value .
274
Chapter 12.
\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.
\FamilyUnkownKeyValue{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.
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.
275
Chapter 12.
\@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 277
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 ’ . . .
Since release 3.12 \FamilyUnknownValue does not report errors itself, but signals them us-
ing \FamilyKeyState. Therefore, \FamilyElseValues became deprecated. Nevertheless, its
former usage is recognised by scrbase and results in a code change demand message.
276
Chapter 12.
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 263
).
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).
\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).
277
Chapter 12.
\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.
\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.
278
Chapter 12.
\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.
\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
279
Chapter 12.
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.
\ifdimen{string }{then instructions }{else instructions }
Note that this does not compare dimensions. The then instructions will be executed, if
the one step expansion of string consists of digits and a valid unit of length. Otherwise, the
else instructions
will be used. There is no corresponding internal command.
\if@atdocument the instructions \else else instructions \fi
This command exists intentionally as internal command only. In the document preamble
\if@atdocument
is same as \iffalse. After \begin{document} it’s the same as \iftrue.
Authors of classes and packages may use this if a command should work somehow different
depending on whether it has been used in the preamble or inside the documents body. Please
note that this is a condition in TEX syntax not in L
A
TEX syntax!
12.4. Definition of Language-Dependent Terms
Normally, one has to change or define language-dependent terms like \captionsenglish in
such a way that, in addition to the available terms, the new or redefined terms are defined.
This is made more difficult by the fact that some packages like german or ngerman redefine
those settings when the packages are loaded. These definitions unfortunately occur in such a
manner as to destroy all previous private settings. That is also the reason why it makes sense to
delay changes with \AtBeginDocument until \begin{document}; that is, after package loading
280
Chapter 12.
is completed. The user can also use \AtBeginDocument or redefine the language-dependent
terms after \begin{document}; that is, not put them in the preamble at all. The package
scrbase provides some additional commands for defining language-dependent terms.
\defcaptionname{language list }{term }{definition }
\providecaptionname{language list }{term }{definition }
\newcaptionname{language list }{term }{definition }
\renewcaptionname{language list }{term }{definition }
\defcaptionname*{language list }{term }{definition }
\providecaptionname*{language list }{term }{definition }
\newcaptionname*{language list }{term }{definition }
\renewcaptionname*{language list }{term }{definition }
Using one of these commands, the user can assign a definition for a particular language to
a term . Several languages can be concatenated with comma to a language list . The term
is always a macro. The commands differ depending on whether a given language or a term
within a given language are already defined or not at the time the command is called.
If a language is not defined, then \providecaptionname does nothing other than write a
message in the log file. This happens only once for each language. If a language is defined,
but term is not yet defined for it, then it will be defined using definition . The term will
not be redefined if the language already has such a definition; instead, an appropriate message
is written to the log file.
The command \newcaptionname has a slightly different behaviour. If a language is
not yet defined, then a new language command will be created and a message written to
the log file. For language USenglish, for example, this would be the language command
\captionsUSenglish
. If term is not yet defined in a language, then it will be defined using
definition
. If term already exists in a language, then this results in an error message.
The command \renewcaptionname again behaves differently. It requires an existing defini-
tion of term in the languages. If neither a language nor term exist or term is unknown in a
defined language, then an error message is given. Otherwise, the term for the language will
be redefined according to definition .
The
v3.12
command \defcaptionname always defines the term . So previous definitions of term
for the given language will be overwritten. You may use this command even for undefined
languages.
KOMA-Script employs \providecaptionname in order to define the commands in
sec-
tion 22.6
.
Dostları ilə paylaş: |