# -*- 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"||'';
}
DefEnvironment('{assertion} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
."\n");
DefEnvironment('{example} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
. "\n");
DefEnvironment('{axiom} OptionalKeyVals:omtext',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#body"
. "\n");
DefEnvironment('{symboldec} OptionalKeyVals:symboldec',
""
. "?&KeyVal(#1,'title')(&KeyVal(#1,'title'))()"
. "#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;
}}
if ($props{theory}) {
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;
if ($props{theory}) {
$doc->openElement('omdoc:definition', %attrs);
} else {
$attrs{'type'}='definition';
$doc->openElement('omdoc:omtext', %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->absorb($props{body}) if $props{body};
$doc->maybeCloseElement('omdoc:CMP');
if ($props{theory}) {
$doc->closeElement('omdoc:definition');
} else {
$doc->closeElement('omdoc:omtext');
}
return; }
DefEnvironment('{definition} OptionalKeyVals:omtext', sub{definitionBody(@_)},
afterDigestBegin=>sub {
my ($stomach, $whatsit) = @_;
my @symbols = ();
$whatsit->setProperty(theory=>LookupValue('current_module'));
$whatsit->setProperty(defs=>\@symbols);
AssignValue('defs', \@symbols); return; },
afterDigest => sub { AssignValue('defs', undef); return; });#$
DefEnvironment('{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('\defi[]{}',
""
. ""
. "#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=>'\defi');
DefConstructor('\adefi[]{}{}',
""
. ""
. "#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=>'\adefi');
DefConstructor('\defii[]{}{}',
""
. ""
. ""
. "#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=>'\defii');#$
DefConstructor('\adefii[]{}{}{}',
""
. ""
. ""
. "#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=>'\defii');#$
DefConstructor('\defiii[]{}{}{}',
""
. ""
. "#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=>'\defiii');
DefConstructor('\adefiii[]{}{}{}{}',
""
. ""
. "#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=>'\defiii');
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{'class'} = 'inlinedef';
$document->openElement('ltx:text',%attrs);
$document->absorb($body);
$document->closeElement('ltx:text'); },
#Prepare 'defs' hooks for \defi 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"
."",
afterDigest=>sub{$_[1]->setProperty(module=>LookupValue('current_module'))});
RawTeX('
\newcommand\atrefi[3][]{\def\@test{#1}\ifx\@test\@empty\termref[name=#3]{#2}\else\termref[cd=#1,name=#3]{#2}\fi}
\newcommand\atrefii[4][]{\atrefi[#1]{#2}{#3-#4}}
\newcommand\atrefiii[5][]{\atrefi[#1]{#2}{#3-#4-#5}}
\newcommand{\trefi}[2][]{\atrefi[#1]{#2}{#2}}
\newcommand{\trefii}[3][]{\atrefi[#1]{#2 #3}{#2-#3}}
\newcommand{\trefiii}[4][]{\atrefi[#1]{#2 #3 #4}{#2-#3-#4}}
');
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);
RawTeX('
\newcommand\defin[2][]{\defi[#1]{#2}%
\PackageWarning{statements}{\protect\defin\space is deprecated, use \protect\defi\space instead}}
\newcommand\twindef[3][]{\defii[#1]{#2}{#3}%
\PackageWarning{statements}{\protect\twindef\space is deprecated, use \protect\defii\space instead}}
\newcommand\atwindef[4][]{\defiii[#1]{#2}{#3}{#4}%
\PackageWarning{statements}{\protect\atwindef\space is deprecated, use \protect\defiii\space instead}}
\newcommand\definalt[3][]{\adefi[#1]{#2}{#3}%
\PackageWarning{statements}{\protect\definalt\space is deprecated, use \protect\adefi\space instead}}
\newcommand\twindefalt[4][]{\adefii[#1]{#2}{#3}{#4}%
\PackageWarning{statements}{\protect\twindefalt\space is deprecated, use \protect\adefii\space instead}}
\newcommand\atwindefalt[5][]{\adefiii[#1]{#2}{#3}{#4}{#5}%
\PackageWarning{statements}{\protect\atwindefalt\space is deprecated, use \protect\adefiii\space instead}}
\newcommand\twinref[3][]{\trefii[#1]{#2}{#3}%
\PackageWarning{statements}{\protect\twinref\space is deprecated, use \protect\trefii\space instead}}
\newcommand\atwinref[4][]{\atrefiii[#1]{#2}{#3}{#4}%
\PackageWarning{statements}{\protect\atwindef\space is deprecated, use \protect\trefiii\space instead}}
');
1;