LaTeXML
view release on metacpan or search on metacpan
lib/LaTeXML/Core/KeyVal.pm view on Meta::CPAN
delete $options{prefix};
define($prefix, $keyset, $key, $type, $default, %options);
return; }
# check if a key-value pair is defined
sub HasKeyVal {
my ($prefix, $keyset, $key) = @_;
my $qname = keyval_qname($prefix, $keyset, $key);
return $STATE->lookupValue('KEYVAL@defined@' . $qname)
|| (defined $STATE->lookupMeaning(T_CS('\\' . $qname))); }
# disable a given key-val
sub DisableKeyVal {
my ($prefix, $keyset, $key) = @_;
my $qname = keyval_qname($prefix, $keyset, $key);
keyval_set($qname, 'disabled', 1);
# disable the key
defineOrdinary($qname, sub {
LaTeXML::Package::Tokenize("\\PackageWarning{keyval}{`" . $key . "' has been disabled. }");
});
return; }
# useful (only) for LaTeXML::Core::KeyVals
sub keyval_qname {
my ($prefix, $keyset, $key) = @_;
return ($prefix || 'KV') . '@' . $keyset . '@' . $key; }
sub keyval_get {
my ($qname, $prop) = @_;
return $STATE->lookupValue('KEYVAL@' . $prop . '@' . $qname); }
sub keyval_set {
my ($qname, $prop, $value) = @_;
return $STATE->assignValue('KEYVAL@' . $prop . '@' . $qname, $value); }
#======================================================================
# Key Definition
#======================================================================
# (re-)define this key
sub define {
my ($prefix, $keyset, $key, $type, $default, %options) = @_;
my $qname = keyval_qname($prefix, $keyset, $key);
# define that the key exists and is not disabled
keyval_set($qname, exists => 1);
keyval_set($qname, disabled => 0);
# set the type
my $paramlist = LaTeXML::Package::parseParameters($type || "{}",
"KeyVal $key in set $keyset with prefix $prefix");
if (scalar(@$paramlist) != 1) {
Warn('unexpected', 'keyval', $key,
"Too many parameters in keyval $key (in set $keyset with prefix $prefix)"
. "taking only first", $paramlist); }
keyval_set($qname, type => $$paramlist[0]);
# set the default
# Question: Why was $default converted ToString ???
if (defined $default) {
my @tdefault = LaTeXML::Package::Tokenize($default);
keyval_set($qname, default => Tokens(@tdefault));
LaTeXML::Package::DefMacroI('\\' . $qname . '@default', undef,
Tokens(T_CS('\\' . $qname), T_BEGIN, @tdefault, T_END)); }
# figure out the kind of key-val parameter we are defining
my $kind = $options{kind} || 'ordinary';
if ($kind eq 'ordinary') {
defineOrdinary($qname, $options{code}); }
elsif ($kind eq 'command') {
my $macroname = ($options{macroprefix} ? $options{macroprefix} . $key : "cmd" . $qname);
defineCommand($qname, $options{code}, $macroname); }
elsif ($kind eq 'choice') {
defineChoice($qname, $options{code}, $options{mismatch},
$options{choices}, ($options{normalize} || 0), $options{bin}); }
elsif ($kind eq 'boolean') {
my $macroname = ($options{macroprefix} ? $options{macroprefix} . $key : $qname);
defineBoolean($qname, $options{code}, $options{mismatch}, $macroname); }
else {
Warn('unknown', undef, "Unknown KeyVals kind $kind",
"should be one of 'ordinary', 'command', 'choice', 'boolean'. "); }
return; }
sub defineOrdinary {
my ($qname, $code) = @_;
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', (defined($code) ? $code : ''));
return; }
sub defineCommand {
my ($qname, $code, $macroname) = @_;
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', sub {
my ($gullet, $value) = @_;
my $orig = '\\ltxml@orig@' . $qname;
LaTeXML::Package::DefMacroI($orig, '{}', $code);
Tokens(T_CS("\\def"), T_CS('\\' . $macroname), T_BEGIN, $value, T_END,
T_CS($orig), T_BEGIN, T_PARAM, $value, T_END); # $value !?!??! Is it a number 1--9 ???
});
return; }
sub defineChoice {
my ($qname, $code, $mismatch, $choices, $normalize, $bin) = @_;
my $norm = ($normalize ? sub { lc $_[0]; } : sub { $_[0]; });
my ($varmacro, $idxmacro) = defined($bin) ? $bin->unlist : (undef, undef);
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', sub {
my ($gullet, $value) = @_;
# Store the normalized value (if applicable)
my $nvalue = &$norm(ToString($value));
LaTeXML::Package::DefMacro($varmacro, sub { Explode($nvalue); }) if defined($varmacro);
# iterate over the possible choices and store them
my $ochoice;
my $index = 0;
my $valid = 0;
foreach my $choice (@{$choices}) {
if (&$norm(ToString($choice)) eq $nvalue) {
$ochoice = $choice;
$valid = 1;
LaTeXML::Package::DefMacro($idxmacro, Explode(ToString($index))) if defined($idxmacro); }
$index += 1; }
# find a name for the original macro to store in
my @tokens = ();
my $orig = '\\ltxml@orig@' . $qname;
# if we have chosen a valid index, run $code
if ($valid) {
if (defined($code)) {
LaTeXML::Package::DefMacroI($orig, '{}', $code);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); } }
# else run $mismatch
elsif (defined($mismatch)) {
LaTeXML::Package::DefMacroI($orig, '{}', $mismatch);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); }
@tokens; });
return; }
sub defineBoolean {
my ($qname, $code, $mismatch, $macroname) = @_;
LaTeXML::Package::DefConditional(T_CS("\\if$macroname")); # We might need to $scope here
defineChoice($qname, sub {
my ($gullet, $value) = @_;
# set the value to true (if needed)
my @tokens = ();
push(@tokens, T_CS('\\' . $macroname . (((lc ToString($value)) eq 'true') ? 'true' : 'false')));
# Store and invoke the original macro if needed
if ($code) {
my $orig = '\\ltxml@@rig@' . $qname;
LaTeXML::Package::DefMacroI($orig, '{}', $code);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); }
@tokens; },
$mismatch, [("true", "false")], 1);
return; }
#======================================================================
1;
__END__
=pod
=head1 NAME
C<LaTeXML::Core::KeyVal> - Key-Value Definitions in LaTeXML
=head1 DESCRIPTION
Provides an interface to define and access KeyVal definition.
Used in conjunction with C<LaTeXML::Core::KeyVals> to fully implement KeyVal
pairs. It extends L<LaTeXML::Common::Object>.
=head2 Exposed Methods
=over 4
=item C<DefKeyVal(I<keyset>, I<key>, I<type>, I<default>, I<%options>); >
Defines a new KeyVal Parameter in the given I<keyset>, I<key> and with optional
prefix I<option{prefix}>. For descriptions of further parameters, see I<LaTeXML::Core::KeyVal::define>.
=item C<HasKeyVal(I<prefix>, I<keyset>, I<key>); >
Checks if the given KeyVal pair exists.
=item C<DisableKeyVal(I<prefix>, I<keyset>, I<key>); >
Disables the given KeyVal so that it can not be used.
=back
=head2 Constructors
=over 4
=item C<<LaTeXML::Core::KeyVal->new(I<preset>, I<keyset>, I<key>); >>
Creates a new I<KeyVal> object. This serves as a simple reference to the given
KeyVal object, regardless of its existence or not.
=back
=head2 KeyVal Key Definition
=over 4
=item C<< $keyval->define($type, $default, %options); >>
(Re-)defines this Key of kind 'kind'.
Defines a keyword I<key> used in keyval arguments for the set I<keyset> and,
( run in 0.828 second using v1.01-cache-2.11-cpan-d8267643d1d )