diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/stex/modules.sty.ltxml')
-rw-r--r-- | Master/texmf-dist/tex/latex/stex/modules.sty.ltxml | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/stex/modules.sty.ltxml b/Master/texmf-dist/tex/latex/stex/modules.sty.ltxml new file mode 100644 index 00000000000..4d1313374a4 --- /dev/null +++ b/Master/texmf-dist/tex/latex/stex/modules.sty.ltxml @@ -0,0 +1,246 @@ + +# -*- CPERL -*- +package LaTeXML::Package::Pool; +use strict; +use LaTeXML::Global; +use LaTeXML::Package; +RequirePackage('keyval'); +DefKeyVal('Module','cd','Semiverbatim'); +DefKeyVal('Module','id','Semiverbatim'); +DefEnvironment('{module} OptionalKeyVals:Module', + "?#excluded()(<omdoc:theory ?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')> #body</omdoc:theory>)", +#closed bracket ) seems to work fine now + +#commented this out - do we need current_theory? +#plus: keyvals->getValue seems to be undefined?! + + #beforeConstruct=> sub { + #my ($doc, $keyvals, %props) = @_; + #my $theory = $keyvals->getValue('id') if $keyvals; + #$theory = ref $theory ? $theory->toString : 'UNDEFINED'; + #AssignValue(current_theory => $theory); + #return;}, +# $Doc->openElement('omdoc:theory', 'xml:id' => $theory); +# my $uses = $keyvals->getValue('usses'); +# $uses = ref $uses ? $uses->toString || '' : ''; +# $uses =~ s/\s+//g; $uses=~ s/^\{//; $uses=~ s/\}$//; +# my $module_paths = LookupValue('module_paths') || {}; +# foreach my $used(split(',',$uses)) { +# my $file = $module_paths->{$used}; $file .= '.omdoc#' if $file; +# $doc->openElement('omdoc:imports', 'from' => $file.$used); +# $doc->closeElement('omdoc:imports'); } +# $doc->absorb($props{body}) if $props{body}; +# $doc->closeElement('omdoc:theory'); } +# return; }, + beforeDigest=>\&useTheoryItemizations, + afterDigestBegin=>sub { + my($stomach, $whatsit)=@_; + $whatsit->setProperty(excluded=>LookupValue('excluding_modules')); + + my $keys = $whatsit->getArg(1); + my($id, $cd)=$keys + && map(ToString($keys->getValue($_)),qw(id cd)); + $cd = $id unless $cd; + # update the catalog with paths for modules + my $module_paths = LookupValue('module_paths') || {}; + $module_paths->{$id} = LookupValue('last_module_path'); + AssignValue('module_paths', $module_paths, 'global'); + + #Update the current module position + AssignValue(current_module => $id); + AssignValue(module_cd => $cd) if $cd; +# my @uses = (); +# if($uses){ +# $uses =~ s/\s//g; $uses=~ s/^\{//; $uses=~ s/\}$//; +# @uses = split(',',$uses); } +############### AssignValue("module_${id}_uses" => [@uses], 'global'); +#Idea: introdcue global list of used modules and activateScope on it once at the +# main block. + #use_module($id); #22.02.08 need to ALWAYS invoke this to make things global + + #activate the module in our current scope + $STATE->activateScope("module:".$id); #changed from use_module as only needs to take care of current module + return; }); +sub use_module { + my($module)=@_; + $module = ToString($module); + # Depth-first load definitions from used modules + foreach my $used_module (@{ LookupValue("module_${module}_uses") || []}){ + use_module($used_module); } + # then load definitions for this module + $STATE->activateScope("module:$module"); } +DefConstructor('\importmodule[]{}',"<omdoc:imports from='?#1(#1)\# #2'/>", + afterDigest=>sub { + my($stomach,$whatsit)=@_; + my $file = $whatsit->getArg(1); + my $module = $whatsit->getArg(2); + $module = ToString($module); + #if filepath is not supply simply look for the $module.sms file + if (!$file) {$file=ToString($module)}; + my $containing_module = LookupValue('current_module'); + #set the relation between the current module and the one to be imported + PushValue("module_".$containing_module."_uses"=>$module); + #check if we've already loaded this module + if(LookupValue('module_'.$module.'_loaded')) {use_module($module);} #if so activate it! + else { + #if not: + my $gullet = $stomach->getGullet; + #1) mark as loaded + AssignValue('module_'.$module.'_loaded' => 1, 'global'); + #open a group for its definitions so that they are localized + $stomach->bgroup; + #update the last module path + AssignValue('last_module_path', $file); + #queue the closing tag for this module in the gullet where it will be executed + #after all other definitions of the imported module have been taken care of + $gullet->unread(Invocation(T_CS('\end@requiredmodule'), T_OTHER($module))->unlist); + #we only need to load the sms definitions without generating any xml output, so we set the flag to 1 + AssignValue('excluding_modules' => 1); + #queue this module's sms file in the gullet so that its definitions are imported + $gullet->input($file,['sms']); + } + return;}); +DefKeyVal('symdef','aliases','Semiverbatim'); +DefKeyVal('symdef','local','Semiverbatim','true'); +DefKeyVal('symdef','cmml','Semiverbatim','true'); +DefKeyVal('symdef','cattrs','Semiverbatim','true'); +DefKeyVal('symdef','definitionURL','Semiverbatim','true'); +DefMacro('\symdef OptionalKeyVals:symdef {}[][]{}', + sub { +my($self,@args)=@_; +# print STDERR "excluding" if LookupValue('excluding_modules'); +((Invocation(T_CS('\@symdef'),@args)->unlist), + (LookupValue('excluding_modules') ? () + : (Invocation(T_CS('\@symdef@pres'), @args)->unlist))); +}); + +DefPrimitive('\@symdef OptionalKeyVals:symdef {}[][]{}', sub { + my($stomach,$keys,$cs,$nargs,$opt,$presentation)=@_; + my($name,$cd,$role,$cmml,$cattrs,$definitionURL)=$keys + && map($_ && $_->toString,map($keys->getValue($_), qw(name cd role cmml cattrs definitionURL))); + $cd = LookupValue('module_cd') unless $cd; + $nargs = (ref $nargs ? $nargs->toString : $nargs || 0); + my $module = LookupValue('current_module'); +# print STDERR "Define ".Stringify($cs)." in $module\n"; + my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":".$module; + my $attr="name='#name' meaning='#meaning' omcd='#omcd'"; + DefConstructorI("\\".$cs->toString,convertLaTeXArgs($nargs,$opt), + ($nargs == 0 + ? "<ltx:XMTok $attr scriptpos='#scriptpos'/>" + : "<ltx:XMApp scriptpos='#scriptpos'>" + . "<ltx:XMTok $attr scriptpos='#operator_scriptpos'/>" + . join('',map("<ltx:XMArg>#$_</ltx:XMArg>", (1..$nargs))) + ."</ltx:XMApp>"), + properties => {name=>$name, meaning=>$cs->toString,omcd=>$cd,role => $role}, + scope=>$scope); + return; }); +DefPrimitive('\abbrdef OptionalKeyVals:symdef {}[][]{}', sub { + my($stomach,$keys,$cs,$nargs,$opt,$presentation)=@_; + my $module = LookupValue('current_module'); + my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":$module"; + DefMacroI("\\".$cs->toString,convertLaTeXArgs($nargs,$opt),$presentation, + scope=>$scope); + return; }); +DefPrimitive('\requiremodules{}', sub { + my($stomach,$module)=@_; + my $GULLET = $stomach->getGullet; + $module = Digest($module)->toString; + if(LookupValue('module_'.$module.'_loaded')) {} + else { + AssignValue('module_'.$module.'_loaded' => 1, 'global'); + $stomach->bgroup; + AssignValue('last_module_path', $module); + $GULLET->unread(T_CS('\end@requiredmodule')); + AssignValue('excluding_modules' => 1); + $GULLET->input($module,['sms']); + } + return;}); + +DefPrimitive('\end@requiredmodule{}',sub { + #close the group + $_[0]->egroup; + #print STDERR "END: ".ToString(Digest($_[1])->toString); + #Take care of any imported elements in this current module by activating it and all its dependencies + #print STDERR "Important: ".ToString(Digest($_[1])->toString)."\n"; + use_module(ToString(Digest($_[1])->toString)); + return; }); +DefPrimitive('\sinput{}', sub { + my($stomach,$module)=@_; + my $GULLET = $stomach->getGullet; + $module = Digest($module)->toString; + AssignValue('module_'.$module.'_loaded' => 1, 'global'); + $stomach->bgroup; + AssignValue('last_module_path', $module); + $GULLET->unread(Invocation(T_CS('\end@requiredmodule'),T_OTHER($module))->unlist); + $GULLET->input($module,['tex']); + return;}); +DefMacro('\@symdef@pres OptionalKeyVals:symdef {}[][]{}', sub { + my($self,$keys, $cs,$nargs,$opt,$presentation)=@_; + Invocation(T_CS('\@symdef@pres@aux'), + $cs, + ($nargs || Tokens(T_OTHER(0))), + symdef_presentation_pmml($cs,ToString($nargs)||0,$presentation), + symdef_presentation_TeX($presentation), + $keys)->unlist; }); +sub symdef_presentation_pmml { + my($cs,$nargs,$presentation)=@_; + my @toks = $presentation->unlist; + while(@toks && $toks[0]->equals(T_SPACE)){ pop(@toks); } # Remove leading space + $presentation = Tokens(@toks); + # Wrap with \@use, unless already has a recognized formatter. + $presentation = Invocation(T_CS('\@use'),$presentation) # Using simple text for now, until getting a proper \@use + unless @toks && ($toks[0]->toString =~ /^\\(infix|prefix|postfix|assoc|use|mixfixi|mixfixa|mixfixii|mixfixia|mixfixai|mixfixiii)$/); + # Low level substitution. + my @args = map(Invocation(T_CS('\@SYMBOL'),T_OTHER("pres_arg:".($_+1))),1..$nargs); + $presentation = Tokens(LaTeXML::Expandable::substituteTokens($presentation,@args)); + $presentation; } +DefConstructor('\@use {}', + "<omdoc:prototype>" + . "<om:OMS cd='' name=''/>" + ."</omdoc:prototype>" + ."<omdoc:rendering>" + . "<ltx:Math><ltx:XMath>#1</ltx:XMath></ltx:Math>" + ."</omdoc:rendering>", + mode=>'inline_math'); +sub get_cd { + my($name,$cd,$role,$cmml,$cattrs,$definitionURL)=@_; + return $cd;} +DefConstructor('\@symdef@pres@aux{}{}{}{} OptionalKeyVals:symdef', + "<omdoc:symbol name='#1'/>" + ."<omdoc:notation name='#name' cd='&get_cd(#5)'>" + ."#3" + ."</omdoc:notation>", + afterDigest=>sub { my ($stomach, $whatsit) = @_; + my $keys = $whatsit->getArg(5); + my $module = LookupValue('current_module'); + $whatsit->setProperties(for=>ToString($whatsit->getArg(1))); + $whatsit->setProperty(role=>($keys ? $keys->getValue('role') + : (ToString($whatsit->getArg(2)) ? 'applied' + : undef))); }); +sub symdef_presentation_TeX { + my($presentation)=@_; + my @tokens = $presentation->unlist; + my(@frag,@frags) = (); + while(my $tok = shift(@tokens)){ + if($tok->equals(T_PARAM)){ + push(@frags,Invocation(T_CS('\@symdef@pres@text'),Tokens(@frag))) if @frag; + @frag=(); + my $n = shift(@tokens)->getString; + push(@frags,Invocation(T_CS('\@symdef@pres@arg'),T_OTHER($n+1))); } + else { + push(@frag,T_OTHER($tok->getString)); }} # IMPORTANT! Neutralize the tokens! + push(@frags,Invocation(T_CS('\@symdef@pres@text'),Tokens(@frag))) if @frag; + Tokens(map($_->unlist,@frags)); } + +DefConstructor('\@symdef@pres@arg{}', "<omdoc:recurse select='#select'/>", + afterDigest=>sub { my ($stomach, $whatsit) = @_; + my $select = $whatsit->getArg(1); + $select = ref $select ? $select->toString : ''; + $whatsit->setProperty(select=>"*[".$select."]"); }); + +DefConstructor('\@symdef@pres@text{}', "<omdoc:text>#1</omdoc:text>"); +DefConstructor('\requirepackage{} Semiverbatim',"<omdoc:imports from='#2'/>", + afterDigest=>sub { my ($stomach, $whatsit) = @_; + my $select = $whatsit->getArg(1); + RequirePackage($select->toString); }); +1; |