# -*- CPERL -*-
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Package;
RequirePackage('omtext');
RequirePackage('modules');
sub lowcase {my ($string) = @_; $string ? return lc(ToString($string)) : return('')}#$
sub dashed { join('-',map($_->toString,@_));}#$
sub makeNCName {
my ($name) = @_;
my $ncname=$name;
$ncname=~s/\s/_/g; #Spaces to underscores
$ncname="_$ncname" if $ncname!~/^(\w|_)/; #Ensure start with letter or underscore
##More to come...
$ncname;
}
sub simple_wrapper {
#Deref if array reference
my @input;
foreach (@_) {
if (ref $_ && $_ =~ /ARRAY/ && $_ !~ /LaTeXML/) {
@input=(@input,@$_);
} else
{ push (@input,$_); }
}
return '' if (!@input);
@input = map(split(/\s*,\s*/,ToString($_)),@input);
my $output=join(" ",@input);
$output=~s/(^ )|[{}]//g; #remove leading space and list separator brackets
$output||'';
}
sub hash_wrapper{
#Deref if array reference
my @input;
foreach (@_) {
if (ref $_ && $_ =~ /ARRAY/ && $_ !~ /LaTeXML/) {
@input=(@input,@$_);
} else
{ push (@input,$_); }
}
return '' if (!@input);
@input = map(split(/\s*,\s*/,ToString($_)),@input);
my $output=join(".sym #",@input);
$output=~s/(^\.sym )|[{}]//g; #remove leading space and list separator brackets
"#$output"||'';
}
DefCMPEnvironment('{assertion} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
."\n");
DefCMPEnvironment('{example} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
. "\n");
DefCMPEnvironment('{axiom} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
. "\n");
DefEnvironment('{symboldec} OptionalKeyVals:symboldec',
""
. "#body"
."\n");
DefConstructor('\symtype{}{}',
"#2");
sub definitionBody {
my ($doc, $keyvals, %props) = @_;
my $for = $keyvals->getValue('for') if $keyvals;
my $type = $keyvals->getValue('type') if $keyvals;
my %for_attr=();
if (ToString($for)) {
$for = ToString($for);
$for =~ s/^{(.+)}$/$1/eg;
foreach (split(/,\s*/,$for)) {
$for_attr{$_}=1;
}}
my @symbols = @{$props{defs} || []};
foreach my $symb(@symbols) {
next if $for_attr{$symb};
$for_attr{$symb}=1;
$doc->insertElement('omdoc:symbol', undef, (name=>$symb, "xml:id"=>makeNCName("$symb.def.sym")));
}
my %attrs = ();
$for = join(" ",(keys %for_attr));
$attrs{'for'} = $for if $for;
my $id = $keyvals->getValue('id') if $keyvals;
$attrs{'xml:id'} = $id if $id;
$attrs{'type'} = $type if $type;
$doc->openElement('omdoc:definition', %attrs);
my $title = $keyvals->getValue('title') if $keyvals;
if ($title) {
$doc->openElement('omdoc:metadata');
$doc->openElement('dc:title');
$doc->absorb($title);
$doc->closeElement('dc:title');}
$doc->openElement('omdoc:CMP');
$doc->openElement('omdoc:p');
$doc->absorb($props{body}) if $props{body};
$doc->maybeCloseElement('omdoc:p');
$doc->maybeCloseElement('omdoc:CMP');
$doc->closeElement('omdoc:definition');
return; }
DefCMPEnvironment('{definition} OptionalKeyVals:omtext', sub{definitionBody(@_)},
afterDigestBegin=>sub {
my ($stomach, $whatsit) = @_;
my @symbols = ();
$whatsit->setProperty(defs=>\@symbols);
AssignValue('defs', \@symbols); return; },
afterDigest => sub { AssignValue('defs', undef); return; });
DefCMPEnvironment('{notation} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
. "\n");
DefConstructor('\notatiendum OptionalKeyVals:notation {}',
"#2");
DefConstructor('\definiendum [] {}',
"#2",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $whatsit->getArg(2) unless $name;
$whatsit->setProperty(name=>$name->toString);
push(@$addr, $name->toString) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));
return; });#$
DefConstructor('\defin[]{}',
""
. ""
. "#2"
. ""
. "#2"
."",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $whatsit->getArg(2) unless $name;
push(@$addr, $name->toString) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));#$
return; },
alias=>'\defin');
DefConstructor('\definalt[]{}{}',
""
. ""
. "#2"
. ""
. "#3"
."",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $whatsit->getArg(3) unless $name;
push(@$addr, $name->toString) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));#$
return; },
alias=>'\definalt');
DefConstructor('\twindef[]{}{}',
""
. ""
. ""
. "#2 #3"
. ""
. ""
. ""
. "#2"
. "#3"
. ""
."",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $name->toString if $name;
$name = $whatsit->getArg(2)->toString.'-'.$whatsit->getArg(3)->toString unless $name;
push(@$addr, $name) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));
return; },
alias=>'\twindef');#$
DefConstructor('\twindefalt[]{}{}{}',
""
. ""
. ""
. "#2"
. ""
. ""
. ""
. "#3"
. "#4"
. ""
."",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $name->toString if $name;
$name = $whatsit->getArg(3)->toString.'-'.$whatsit->getArg(4)->toString unless $name;
push(@$addr, $name) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));
return; },
alias=>'\twindef');#$
DefConstructor('\atwindef[]{}{}{}',
""
. ""
. "#2 #3 #4"
. ""
. ""
. "#2"
. "#3"
. "#4"
. ""
. "",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $name->toString if $name;
$name = $whatsit->getArg(2)->toString.'-'.$whatsit->getArg(3)->toString.'-'.$whatsit->getArg(4)->toString unless $name;
push(@$addr, $name) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));
return; },
alias=>'\atwindef');
DefConstructor('\atwindefalt[]{}{}{}{}',
""
. ""
. "#2"
. ""
. ""
. "#3"
. "#4"
. "#5"
. ""
. "",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $addr = LookupValue('defs');
my $name = $whatsit->getArg(1);
$name = $name->toString if $name;
$name = $whatsit->getArg(3)->toString.'-'.$whatsit->getArg(4)->toString.'-'.$whatsit->getArg(5)->toString unless $name;
push(@$addr, $name) if ($addr and $name);
$whatsit->setProperty(theory=>LookupValue('current_module'));
return; },
alias=>'\atwindef');
DefConstructor('\inlineex OptionalKeyVals:omtext {}',
"#2");
DefConstructor('\inlinedef OptionalKeyVals:omtext {}', sub {
my ($document, $keyvals, $body, %props) = @_;
my $for = $keyvals->getValue('for') if $keyvals;
my %for_attr=();
if (ToString($for)) {
$for = ToString($for);
$for =~ s/^{(.+)}$/$1/eg;
foreach (split(/,\s*/,$for)) {
$for_attr{$_}=1;
}}
my @symbols = @{$props{defs} || []};
#Prepare for symbol insertion -insert before the parent of the closest ancestor CMP element
my $original_node = $document->getNode;
my $xc = XML::LibXML::XPathContext->new( $original_node );
$xc->registerNs('omdoc', 'http://omdoc.org/ns');
my ($statement_ancestor) = $xc->findnodes('./ancestor::omdoc:CMP/..');
foreach my $symb(@symbols) {
next if $for_attr{$symb};
$for_attr{$symb}=1;
my $symbolnode = XML::LibXML::Element->new('symbol');
$symbolnode->setAttribute(name=>$symb);
$symbolnode->setAttribute("xml:id"=>makeNCName("$symb.def.sym"));
$statement_ancestor->parentNode->insertBefore($symbolnode,$statement_ancestor);
}
#Restore the insertion point
$document->setNode($original_node);
my %attrs = ();
$for = join(" ",(keys %for_attr));
$attrs{'for'} = $for if $for;
my $id = $keyvals->getValue('id') if $keyvals;
$attrs{'xml:id'} = $id if $id;
$attrs{'type'} = 'inlinedef';
$document->openElement('omdoc:phrase',%attrs);
$document->absorb($body);
$document->closeElement('omdoc:phrase'); },
#Prepare 'defs' hooks for \defin and \definiendum symbol names
beforeDigest=>sub {
my @symbols = ();
AssignValue('defs', \@symbols); return; },
#Adopt collected names as 'defs' property, remove hooks
afterDigest=>sub {
my ($stomach, $whatsit) = @_;
my $defsref = LookupValue('defs');
my @defs = @$defsref;
$whatsit->setProperty('defs',\@defs);
AssignValue('defs',undef);
return; });
DefConstructor('\termref OptionalKeyVals:termref {}',
""
. "#2"
."");
DefConstructor('\twinref OptionalKeyVals:termref {}{}',
""
. "#2"
."");
DefConstructor('\atwinref OptionalKeyVals:termref {}{}{}',
""
. "#2"
."");
DefConstructor('\termin OptionalKeyVals:term {}',
""
. ""
. "#2"
. ""
. "#2"
. "");
DefConstructor('\symref{}{}',
""
. "#2"
."");
Tag('omdoc:assertion',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:definition',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:example',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:requation',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:axiom',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:symbol',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:type',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:term',afterOpen=>\&numberIt,afterClose=>\&locateIt);
1;