summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/stex/modules.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/stex/modules.dtx')
-rw-r--r--Master/texmf-dist/source/latex/stex/modules.dtx1054
1 files changed, 1054 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/stex/modules.dtx b/Master/texmf-dist/source/latex/stex/modules.dtx
new file mode 100644
index 00000000000..3f9f8e46d86
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/modules.dtx
@@ -0,0 +1,1054 @@
+% \iffalse meta-comment
+% An Infrastructure for Semantic Macros and Module Scoping
+% Copyright (C) 2004-2006 Michael Kohlhase, all rights reserved
+% this file is released under the
+% LaTeX Project Public License (LPPL)
+%
+% The development version of this file can be found at
+% https://svn.kwarc.info/repos/kwarc/projects/stex/sty/modules.dtx
+% \fi
+%
+% \iffalse
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{modules}[2006/01/13 v0.9a Semantic Markup]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,modules,float}
+\usepackage[show]{ed}
+\usepackage{hyperref}
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{modules.dtx}\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{539}
+%
+% \changes{v0.9}{2005/06/14}{First Version with Documentation}
+% \changes{v0.9a}{2005/07/01}{Completed Documentation}
+% \changes{v0.9b}{2005/08/06}{Complete functionality and Updated Documentation}
+% \changes{v0.9c}{2006/01/13}{more packaging}
+% \changes{v0.9d}{2007/12/12}{fixing double loading of .tex and .sms}
+%
+% \GetFileInfo{modules.sty}
+%
+% \MakeShortVerb{\|}
+%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\stex{{\raisebox{-.5ex}S\kern-.5ex\TeX}}
+% \def\sTeX{\stex}
+% \def\xml{\scsys{Xml}}
+% \def\mathml{\scsys{MathML}}
+% \def\omdoc{\scsys{OMDoc}}
+% \def\openmath{\scsys{OpenMath}}
+% \def\latexml{\scsys{LaTeXML}}
+% \def\perl{\scsys{Perl}}
+% \def\cmathml{Content-{\sc MathML}\index{Content {\sc MathML}}\index{MathML@{\sc MathML}!content}}
+% \def\activemath{\scsys{ActiveMath}}
+% \def\twin#1#2{\index{#1!#2}\index{#2!#1}}
+% \def\twintoo#1#2{{#1 #2}\twin{#1}{#2}}
+% \def\atwin#1#2#3{\index{#1!#2!#3}\index{#3!#2 (#1)}}
+% \def\atwintoo#1#2#3{{#1 #2 #3}\atwin{#1}{#2}{#3}}
+% \title{Semantic Macros and Module Scoping in {\stex}\thanks{Version {\fileversion} (last revised
+% {\filedate})}}
+% \author{Michael Kohlhase \& Rares Ambrus\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% The |modules| packge is a central part of the {\stex} collection, a version of
+% {\TeX/\LaTeX} that allows to markup {\TeX/\LaTeX} documents semantically without
+% leaving the document format, essentially turning {\TeX/\LaTeX} into a document format
+% for mathematical knowledge management (MKM).
+%
+% This package supplies a definition mechanism for semantic macros and a non-standard
+% scoping construct for them, which is oriented at the semantic depency relation rather
+% than the document structure. This structure can be used by MKM systems for
+% added-value services, either directly from the {\sTeX} sources, or after translation.
+% \end{abstract}
+%\newpage
+% \section{Introduction}\label{sec:intro}
+%
+% Following general practice in the {\TeX/\LaTeX} community, we use the term ``semantic
+% macro'' for a macro whose expansion stands for a mathematical object, and whose name
+% takes up the name of the mathematical object. This can range from simple definitions
+% like |\def\Reals{{\mathbb R}}| for indivicual mathematical objects to more complex
+% (functional) ones object constructors like
+% |\def\SmoothFunctionsOn#1{{\cal{C}}^\infty(#1)}|. Semantic macros are traditionally used
+% to make {\TeX/\LaTeX} code more portable. However, the {\TeX/\LaTeX} scoping model
+% (macro definitions are scoped either in the local group or until the rest of the
+% document), does not mirror mathematical practice, where notations are scoped by
+% mathematical environments like statements, theories, or such.
+%
+% \section{The User Interface}
+%
+% The main contributions of the |modules| package are the |module| environment, which
+% allows for lexical scoping of semantic macros with inheritance and the |\symdef| macro
+% for declaration of semantic macros that underly the |module| scoping.
+%
+% \subsection{Modules}\label{sec:modules}
+%
+% \DescribeEnv{module} The |module| environment takes an optional |KeyVal|
+% argument. Currently, only the |id| key is supported for specifying the identifier of a
+% module (also called the {\twintoo{module}{name}}).
+%
+% \DescribeMacro{\importmodule} A module introduced by |\begin{module}[id=foo]| restricts
+% the scope the semantic macros defined by the |\symdef| form to the end of this module
+% given by the corresponding |\end{module}|, and to any other |module| environments that
+% import them by a |\importmodule{foo}| directive. If the module |foo| contains
+% |\importmodule| directives of its own, these are also exported to the importing
+% module. Thus |\importmodule| induces the {\atwintoo{semantic}{inheritance}{relation}}
+% and |usesqualified|\ednote{do an importqualified as well} for macros imported with a
+% prefix (this is used whenever we have conflicting names for macros inherited from
+% different modules).
+%
+% \subsection{Semantic Macros}\label{sec:symdef}
+%
+% \DescribeMacro{\symdef}A call to the |\symdef| macro has the general form
+% \begin{quote}
+% |\symdef[|\meta{keys}|]{|\meta{cseq}|}[|\meta{args}|]{|\meta{definiens}|}|
+% \end{quote}
+% where {\meta{cseq}} is a control sequence (the name of the semantic macro) {\meta{args}}
+% is a number between 0 and 9 for the number of arguments {\meta{definiens}} is the token
+% sequence used in macro expansion for {\meta{cseq}}. Finally {\meta{keys}} is a keyword
+% list that further specifies the semantic status of the defined macro.
+%
+% A key |local| can be added to {\meta{keys}} to specify that the symbol is local to the
+% module and is invisible outside. The key-value pair |aliases=|\meta{symname} specifies
+% that the defined symbol {\meta{cseq}} is a presentational variant of the symbol
+% {\meta{symname}}.
+%
+% Finallly, the keys |cmml|, |cattrs|, and |definitionURL| can be used to specify the
+% {\cmathml} encoding of the symbols. They key-value pair |cmml=|\meta{elt} specifies that
+% the semantic macro corresponds to the {\cmathml} element with the name \meta{elt},
+% |cattrs=|\meta{attrtring} its argument string and |definitionURL| allows to specify the
+% |definitionURL| attribute on that element. The most common case will be a symbol
+% definition of the following form:
+%
+% \begin{quote}
+% |\symdef[cmml=csymbol,definitionURL=|\meta{URI}|]{|\meta{cseq}|}[|\meta{args}|]{|\meta{definiens}|}|
+% \end{quote}
+%
+% where \meta{URI} is the URI pointing to the location of the {\xml} file generated from
+% the current {\LaTeX} file.
+%
+% \DescribeMacro{\abbrdef}The |\abbrdef| macro is a variant of |\symdef| that is only
+% different in semantics, not in presentation. An abbreviative macro is like a semantic
+% macro, and underlies the same scoping and inheritance rules, but it is just an
+% abbreviation that is meant to be expanded, it does not stand for an atomic mathematical
+% object.
+%
+% We will use a simple module for natural number arithmetics as a running example. It
+% defines exponentiation and summation as new concepts while drawing on the basic
+% operations like $+$ and $-$ from {\LaTeX}. In our example, we will define a semantic
+% macro for summation |\Sumfromto|, which will allow us to express an expression like
+% $\sum{i=1}^nx^i$ as |\Sumfromto{i}1n{2i-1}| (see Example~\ref{fig:semmodule} for an
+% example). In this example we have also made use of a local semantic symbol for $n$,
+% which is treated as an arbitrary (but fixed) symbol.
+%
+% \begin{module}[id=arith]
+% \symdef{Sumfromto}[4]{\sum_{#1=#2}^{#3}{#4}}
+% \symdef[local]{arbitraryn}{n}
+%
+%\begin{exfig}
+% \begin{verbatim}
+% \begin{module}[id=arith]
+% \symdef{Sumfromto}[4]{\sum_{#1=#2}^{#3}{#4}}
+% \symdef[local]{arbitraryn}{n}
+% What is the sum of the first $\arbitraryn$ odd numbers, i.e.
+% $\Sumfromto{i}1\arbitraryn{2i-1}?$
+% \end{module}
+% \end{verbatim}
+% \vspace{-2em}is formatted by {\sTeX} to \medskip\par\noindent
+% What is the sum of the first $\arbitraryn$ odd numbers, i.e.
+% $\Sumfromto{i}1\arbitraryn{2i-1}?$
+% \caption{Semantic Markup in a {\tt{module}} context}\label{fig:semmodule}
+% \end{exfig}
+% \end{module}
+%
+% \subsection{Dealing with multiple Files}\label{sec:user:multiple}
+%
+% The infrastructure presented above works well if we are dealing with small files or
+% small collections of modules. In reality, collections of modules tend to grow, get
+% re-used, etc, making it much more difficult to keep everything in one file. This general
+% trend towards increasing enthropy is aggravated by the fact that modules are very
+% self-contiained objects that are ideal for re-used. Therefore in the absence of a
+% content management system for {\LaTeX} document (fragments), module collections tend to
+% develop towards the ``one module one file'' rule, which leads to situations with lots
+% and lots of little files.
+%
+% Moreover, most mathematical documents are not self-contained, i.e. they do not build up
+% the theory from scratch, but pre-suppose the knowledge (and notation) from other
+% documents. In this case we want to make use of the semantic macros from these
+% prerequisite documents without including their text into the current document. One way
+% to do this would be to have {\LaTeX} read the prerequisite documents without producing
+% output. For efficiency reasons, {\stex} chooses a different route. It comes with a
+% utility |sms| (see Section~\ref{sec:utilities}) that exports the modules and macros
+% defined inside them from a particular document and stores them inside |.sms| files. This
+% way we can avoid overloading LaTeX with useless information, while retaining the
+% important information which can then be imported in a more efficient way.
+%
+% \DescribeMacro{\importmodule} For such situations, the |\importmodule| macro can be
+% given an optional first argument that is a path to a file that contains a path to the
+% module file, whose module definition (the |.sms| file) is read. Note that the
+% |\importmodule| macro can be used to make module files truly self-contained. To arrive
+% at a file-based content management system, it is good practice to reuse the module
+% identifiers as module names and to prefix module files with corresponding
+% |\importmodule| statements that pre-load the corresponing module files.
+%
+%\begin{exfig}
+% \begin{verbatim}
+% \begin{module}[id=foo]
+% \importmodule[../other/bar]{bar}
+% \importmodule[../mycolleaguesmodules]{baz}
+% \importmodule[../other/bar]{foobar}
+% ...
+% \end{module}
+% \end{verbatim}
+% \vspace{-1.7em}
+% \caption{Self-contained Modules via {\tt{importmodule}}}\label{exf:importmodule}
+% \end{exfig}
+%
+% In Example~\ref{exf:importmodule}, we have shown the typical setup of a module
+% file. The |\importmodule| macro takes great care that files are only read once, as
+% {\sTeX} allows multiple inheritance and this setup would lead to an exponential (in the
+% module inheritance depth) number of file loads.
+%
+% Note that the recursive (depth-first) nature of the file loads induced by this setup is
+% very natural, but can lead to problems with the depth of the file stack in the {\TeX}
+% formatte (it is usually set to something like 15). Therefore, it may be necessary to
+% circumvent the recursive load pattern providing (logically spurious) |\importmodule|
+% commands. Consider for instance module |bar| in Example~\ref{exf:importmodule}, say that
+% |bar| already has load deph 15, then we cannot naivedly import it in this way. If module
+% |bar| depended say on a module |base| on the critical load path, then we could add a
+% statement \DescribeMacro{\requiremodules} |\requiremodules{../base}| in the second
+% line. This would load the modules from |../base.sms| in advance (uncritical, since it
+% has load depth 10), so that it would not have to be re-loaded in the critical path of
+% the module |foo|. Solving the load depth problem.
+%
+% \subsection{Including Externally Defined Semantic Macros }
+%
+% In some cases, we use an existing {\LaTeX} macro package for typesetting objects that
+% have a conventionalized mathematical meaning. In this case, the macros are ``semantic''
+% even though they have not been defined by a |\symdef|. This is no problem, if we are
+% only interested in the {\LaTeX} workflow. But if we want to e.g. transform them to
+% {\omdoc} via {\latexml}, the {\latexml} bindings will need to contain references to an
+% {\omdoc} theory that semantically correponds to the {\LaTeX} package. In particular,
+% this theory will have to be imported in the generated {\omdoc} file to make it
+% {\omdoc}-valid.
+%
+
+% \DescribeMacro{\requirepackage} To deal with this situation, the |modules| package
+% provides the |\requirepackage| macro. It takes two arguments: a package name, and a URI
+% of the corresponing {\omdoc} theory. In the {\LaTeX} workflow this macro behaves like a
+% |\usepackage| on the first argument, except that it can --- and should --- be used
+% outside the {\LaTeX} preamble. In the {\latexml} workflow, this loads the {\latexml}
+% bindings of the package specified in the first argument and generates an appropriate
+% |imports| element using the URI in the second argument.
+%
+% \StopEventually{\ednotemessage}
+%
+% \section{The Implementation}
+%
+% We declare some switches which will modify the behavior accoring to the package
+% options. Generally, an option |xxx| will just set the appropriate switches to true
+% (otherwise they stay false).
+% \begin{macrocode}
+%<*package>
+\newif\ifmod@env\mod@envfalse
+\newif\ifmod@id\mod@idfalse
+\newif\ifmod@display\mod@displayfalse
+\newif\ifmod@uses\mod@usesfalse
+\newif\ifmod@usesqualified\mod@usesqualifiedfalse
+\DeclareOption{env}{\mod@envtrue}
+\DeclareOption{id}{\mod@idtrue}
+\DeclareOption{uses}{\mod@usestrue}
+\DeclareOption{display}{\mod@displaytrue}
+\DeclareOption{usesqualified}{\mod@usesqualifiedtrue}
+% \end{macrocode}
+% Now, we define two collective options, which are equivalent to turning on all the other
+% options.
+% \begin{macrocode}
+\def\modtrue{\mod@idtrue\mod@usestrue\mod@displaytrue\mod@usesqualifiedtrue}
+\DeclareOption{draft}{\modtrue}
+\DeclareOption{all}{\modtrue}
+% \end{macrocode}
+% Finally, we need to declare the end of the option declaration section to {\LaTeX}.
+% \begin{macrocode}
+\ProcessOptions
+%</package>
+% \end{macrocode}
+%
+% {\latexml} does not support module options yet, so we do not have to do anything here
+% for the {\latexml} bindings. We only set up the {\perl} packages (and tell {\tt{emacs}}
+% about the appropriate mode for convenience
+%
+% The next measure is to ensure that the |KeyVal| package is loaded (in the right
+% version). for {\latexml}, we also initialize the package inclusions.
+% \begin{macrocode}
+%<package>\RequirePackage{keyval}[1997/11/10]
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Global;
+use LaTeXML::Package;
+RequirePackage('keyval');
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Modules}\label{sec:impl:modules}
+%
+% We define the keys for the |module| environment and the actions that are undertaken,
+% when the keys are encountered.
+%
+% \begin{macro}{module:cd}
+% This |KeyVal| key is only needed for {\latexml} at the moment; use this to specify a
+% content dictionary name that is different from the module name.
+% \begin{macrocode}
+%<package>\define@key{module}{cd}{}
+%<*ltxml>
+DefKeyVal('Module','cd','Semiverbatim');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{module:id}
+% For a module with |[id=name]|, we create a macro |\module@defs@name| and initialize
+% it. Furthermore, we save the name in |\mod@id|.
+% \begin{macrocode}
+%<*package>
+\define@key{module}{id}{%
+ \edef\this@module{\expandafter\noexpand\csname module@defs@#1\endcsname}%
+ \edef\this@qualified@module{\expandafter\noexpand\csname module@defs@qualified@#1\endcsname}%
+ \global\@namedef{module@defs@#1}{}
+ \global\@namedef{module@defs@qualified@#1}{}
+ \def\mod@id{#1}}
+%</package>
+%<*ltxml>
+DefKeyVal('Module','id','Semiverbatim');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{module}
+% finally, we define the begin module command for the module environment. All the work
+% has already been done in the keyval bindings, so this is very simple.
+% \begin{macrocode}
+%<package>\newenvironment{module}[1][]{\setkeys{module}{#1}\ifmod@env\show@mod@keys{module}\fi}{}
+% \end{macrocode}
+% for the {\latexml} bindings, we have to do the work all at once.
+% \begin{macrocode}
+%<*ltxml>
+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; });
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{macro}{usemodule}
+% The |use_module| subroutine
+% performs depth-first load of definitions of the used modules
+% \begin{macrocode}
+%<*ltxml>
+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"); }
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\show@mod@keys}
+% The |\show@mod@keys| macro is used for the draft mode, they allow to annotate the
+% document with reminders of the key values in the modules.
+% \begin{macrocode}
+%<*package>
+\def\show@mod@keys@aux{%
+\@ifundefined{mod@id}{}{\ifmod@id{id=\mod@id},\fi}%
+\@ifundefined{mod@display}{}{\ifmod@display{display=\mod@display}\fi}
+\@ifundefined{mod@uses}{\relax}{\ifmod@uses{uses=\mod@uses},\fi}
+\@ifundefined{mod@usesqualified}\relax\else
+ \ifmod@usesqualified{usesqualified=\mod@usesqualified},\fi\fi}
+\def\clear@mod@keys{\let\mod@usesqualified=\relax\mod@uses=\relax
+ \let\st@id=\relax\let\st@display=\relax}
+\def\show@mod@keys#1{\footnote{#1[\show@mod@keys@aux]}\clear@mod@keys}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{activate@defs}
+% To activate the symdefs from a given module xxx, we call the macro |\module@defs@xxx|.
+% \begin{macrocode}
+%<package>\def\activate@defs#1{\csname module@defs@#1\endcsname}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{export@defs}
+% To export a the symdefs from the current module, we all the macros |\module@defs@xxx|
+% to |\module@defs@xxx| (if the current module has a name and it is xxx)
+% \begin{macrocode}
+%<*package>
+\def\export@defs#1{\@ifundefined{mod@id}{}{
+ \expandafter\expandafter\expandafter
+ \g@addto@macro\expandafter
+ \this@module\expandafter{\csname module@defs@#1\endcsname}}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\importmodule}
+% The |\importmodule[|\meta{file}|]{|\meta{mod}|}| macro is an interface macro that
+% loads \meta{file} and activates and re-exports the symdefs from module
+% \meta{mod}.\ednote{document it above, and implement it in {\latexml}}
+% \begin{macrocode}
+%<*package>
+\newcommand{\importmodule}[2][]{\def\@test{#1}%
+\ifx\@test\@empty\else\requiremodules{#1}\fi
+\activate@defs{#2}\export@defs{#2}}
+%</package>
+%<*ltxml>
+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;});
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Semantic Macros}\label{sec:impl:symdef}
+%
+% We first define the optional KeyVal arguments for the |\symdef| form and the actions
+% that are taken when they are encountered.
+%
+% \begin{macro}{symdef:aliases}
+% This optional key aliases for the symdef function allows us to provide additional
+% arguments representing other functions that are aliased by the one currently being
+% defined.
+% \begin{macrocode}
+%<package>\define@key{symdef}{aliases}{}
+%<*ltxml>
+DefKeyVal('symdef','aliases','Semiverbatim');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{symdef:local}
+% The optional argument local specifies the scope of the function to be defined. If
+% local is not present as an optional argument then |\symdef| assumes the scope of the
+% function is global and it will include it in the pool of macros of the current
+% module. Otherwise, if local is present then the function will be defined only locally
+% and it will not be added to the current module (i.e. we cannot inherit a local
+% function). Note, the optional key local does not need a value: we write
+% |\symdef[local]{somefunction}[0]{some expansion}|
+% \begin{macrocode}
+%<package>\define@key{symdef}{local}[true]{\@symdeflocaltrue}
+%<*ltxml>
+DefKeyVal('symdef','local','Semiverbatim','true');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{symdef:}
+% The keys |cmmml|, |cattrs|, and |definitionURL| are not used in {\TeX/\LaTeX}
+% bindings\ednote{decide what we want to do about them in the future.}.
+% \begin{macrocode}
+%<*package>
+\define@key{symdef}{cmml}{}
+\define@key{symdef}{cattrs}{}
+\define@key{symdef}{definitionURL}{}
+%</package>
+%<*ltxml>
+DefKeyVal('symdef','cmml','Semiverbatim','true');
+DefKeyVal('symdef','cattrs','Semiverbatim','true');
+DefKeyVal('symdef','definitionURL','Semiverbatim','true');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\symdef}
+% The the |\symdef|, and |\@symdef| macros just handle optional arguments.
+% \begin{macrocode}
+%<*package>
+\newif\if@symdeflocal
+\def\symdef{\@ifnextchar[{\@symdef}{\@symdef[]}}
+\def\@symdef[#1]#2{\@ifnextchar[{\@@symdef[#1]{#2}}{\@@symdef[#1]{#2}[0]}}
+% \end{macrocode}
+% now comes the real meat: the |\@@symdef| macro does two things, it adds the macro
+% definition to the macro definition pool of the current module and also provides it.
+% \begin{macrocode}
+\def\@@symdef[#1]#2[#3]#4{%
+% \end{macrocode}
+% We use a switch to keep track of the local optional argument. We initialize the switch
+% to false and check for the local keyword. Then we set all the keys that have been
+% provided as arguments: aliases, local. First, using |\providecommand| we
+% initialize the intermediate function, the one that can be changed internally with
+% |\redefine| and then we link the actual function to it, again with |\providecommand|. We
+% check if the switch for the local scope is set: if it is we are done, since this
+% function has a local scope. Otherwise, we add these two functions to the module's pool
+% of defined macros using |\g@addto@macro|. We add both functions so that we can keep the
+% link between the real and the intermediate function whenever we inherit the
+% module. Finally, using |\g@addto@macro| we add the two functions to the qualified
+% version of the module.
+% \begin{macrocode}
+\@symdeflocalfalse\setkeys{symdef}{#1}
+ \expandafter\providecommand\csname modules@#2@pres\endcsname[#3]{#4}
+ \expandafter\def\csname#2\endcsname{\csname modules@#2@pres\endcsname}
+ \if@symdeflocal\else
+ \@ifundefined{mod@id}{}{
+ \expandafter\g@addto@macro\this@module{\expandafter\providecommand\csname modules@#2@pres\endcsname[#3]{#4}}%
+ \expandafter\g@addto@macro\this@module{\expandafter\def\csname#2\endcsname{\csname modules@#2@pres\endcsname}}
+ \expandafter\g@addto@macro\this@qualified@module{\expandafter\providecommand\csname modules@#2@pres@qualified\endcsname[#3]{#4}}%
+ \expandafter\g@addto@macro\this@qualified@module{\expandafter\def\csname#2atqualified\endcsname{\csname modules@#2@pres@qualified\endcsname}}
+ }\fi}
+%</package>
+% \end{macrocode}
+% In the {\latexml} bindings, we have a top-level macro that delegates the work to two
+% internal macros: |\@symdef|, which defines the content macro and |\@symdef@pres|, which
+% generates the {\omdoc} |symbol| and |presentation| elements (see
+% Section~\ref{sec:impl:presentation}).
+% \begin{macrocode}
+%<*ltxml>
+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; });
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{\redefine}
+% We can use this function to redefine our intermediate presentational function inside
+% the modules\ednote{does not seem to have a {\latexml} counterpart yet!}
+% \begin{macrocode}
+%<package>\def\redefine#1[#2]#3{\expandafter\renewcommand\csname modules@#1@pres\endcsname[#2]{#3}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\abbrdef}
+% The |\abbrdef| macro is a variant of |\symdef| that does the same on the {\LaTeX} level.
+% \begin{macrocode}
+%<package>\let\abbrdef\symdef
+%<*ltxml>
+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; });
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Loading Module Signatures}\ednote{talk about module signatures above (SMS
+% files)}
+% Before we can come to the functionality we want to offer, we need some auxiliary
+% functions that deal with path names.
+% \begin{macro}{\mod@simplify}
+% The |\mod@simplify| macro removes |xxx/..| from a string. eg: |aaa/bbb/../ddd| goes to
+% |aaa/ddd|. This is used to normalize relative path names below.
+% \begin{macrocode}
+%<*package>
+\def\mod@simplify#1{\expandafter\mod@simpl#1/\relax}
+% \end{macrocode}
+% It is based on the |\mod@simpl| macro
+% \begin{macrocode}
+\def\mod@simpl#1/#2\relax{%\message{ 1 = #1, 2 = #2 }%
+\def\mod@test{}\ifx\mod@blaaaa\mod@test\edef\mod@savedprefix{}\def\mod@blaaaa{aaa}\else\fi
+\def\mod@comp{#2}\ifx\mod@test\mod@comp\edef\mod@savedprefix{\mod@savedprefix#1}%
+\else\mod@simplhelp#1/#2\relax\fi}
+% \end{macrocode}
+% which in turn is based on a helper macro
+% \begin{macrocode}
+\def\mod@simplhelp#1/#2/#3\relax{%
+\def\mod@test{}\def\mod@tust{#2}\def\mod@tist{#3}\def\mod@tost{..}\ifx\mod@test\mod@tist%
+\ifx\mod@tost\mod@tust\edef\mod@savedprefix{}\else\edef\mod@savedprefix
+{\mod@savedprefix#1/#2}\fi \else\ifx\mod@tost\mod@tust\mod@simpl#3\relax%
+\else\edef\mod@savedprefix{\mod@savedprefix#1/}\mod@simplhelp#2/#3\relax\fi\fi}%
+% \end{macrocode}
+% \end{macro}
+% We will need a switch\ednote{Rares, say why?}
+% \begin{macrocode}
+\newif\ifmodules
+% \end{macrocode}
+% and a ``registry'' macro whose expansion represents the list of added macros (or files)
+% \begin{macro}{\reg}
+% We initialize the |\reg| macro with the empty string.
+% \begin{macrocode}
+\gdef\reg{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@update}
+% This macro provides special append functionality. It takes a string and appends it
+% to the expansion of the |\reg| macro in the following way: |string@\reg|.
+% \begin{macrocode}
+\def\mod@update#1{\def\mod@empty{}
+\ifx\reg\mod@empty\xdef\reg{#1}\else\xdef\reg{#1@\reg}\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@check}
+% The |\mod@check| takes as input a file path (arg 3), and searches the registry. If the
+% file path is not in the registry it means it means it has not been already added, so
+% we make modulestrue, otherwise make modulesfalse. The macro |\mod@search| will look at
+% ifinclude and update the registry for modulestrue or do nothing for modulesfalse.
+% \begin{macrocode}
+\def\mod@check#1@#2///#3\relax{%
+\def\mod@empty{}\def\mod@one{#1}\def\mod@two{#2}\def\mod@three{#3}%
+% \end{macrocode}
+% Define a few intermediate macros so that we can split the registry into separate file
+% paths and compare to the new one
+% \begin{macrocode}
+\expandafter\ifx\mod@three\mod@one\modulestrue\else\ifx\mod@two\mod@empty\modulesfalse%
+\else\mod@check#2///#3\relax\fi\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@search}
+% Macro for updating the registry after the execution of |\mod@check|
+% \begin{macrocode}
+\def\mod@search#1{%
+% \end{macrocode}
+% We put the registry as the first argument for |\mod@check| and the other
+% argument is the new file path.
+% \begin{macrocode}
+\modulesfalse\expandafter\mod@check\reg @///#1\relax%
+% \end{macrocode}
+% We run |\mod@check| with these arguments and the check |\ifmodules| for
+% the result
+% \begin{macrocode}
+\ifmodules\else\mod@update{#1}\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@reguse}
+% The macro operates almost as the |mod@search| function, but it does not update the
+% registry. Its purpose is to check whether some file is or not inside the registry but
+% without updating it. Will be used before deciding on a new sms file
+% \begin{macrocode}
+\def\mod@reguse#1{\modulesfalse\expandafter\mod@check\reg @///#1\relax}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@prefix}
+% This is a local macro for storing the path prefix, we initialize it as the empty
+% string.
+% \begin{macrocode}
+\def\mod@prefix{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@updatedpre}
+% This macro allows to update the path prefix with the last part of the new path
+% \begin{macrocode}
+\def\mod@updatedpre#1{
+ \edef\mod@prefix{\mod@prefix\mod@pathprefix@check#1/\relax}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mod@pathprefix@check}
+% |\mod@pathprefix@check| returns the last word in a string composed of words separated
+% by slashes
+% \begin{macrocode}
+\def\mod@pathprefix@check#1/#2\relax{%
+\ifx\\#2\\% no slash in string
+\else\mod@ReturnAfterFi{#1/\mod@pathprefix@help#2\relax}%
+\fi}
+% \end{macrocode}
+% It needs two helper macros:
+% \begin{macrocode}
+\def\mod@pathprefix@help#1/#2\relax{%
+\ifx\\#2\\% end of recursion
+\else\mod@ReturnAfterFi{#1/\mod@pathprefix@help#2\relax}%
+\fi}
+\long\def\mod@ReturnAfterFi#1\fi{\fi#1}
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{\mod@pathpostfix@check}
+% |\mod@pathpostfix@check| takes a string composed of words separated by slashes and
+% returns the part of the string until the last slash
+% \begin{macrocode}
+\def\mod@pathpostfix@check#1/#2\relax{% slash
+\ifx\\#2\\%no slash in string
+#1\else\mod@ReturnAfterFi{\mod@pathpostfix@help#2\relax}%
+\fi}
+% \end{macrocode}
+% Helper function for the pathpostfix@check function defined above
+% \begin{macrocode}
+\def\mod@pathpostfix@help#1/#2\relax{%
+\ifx\\#2\\%
+#1\else\mod@ReturnAfterFi{\mod@pathpostfix@help#2\relax}%
+\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\def\mod@updatedpost#1{%
+\edef\mod@savedprefix{\mod@savedprefix\mod@pathpostfix@check#1/\relax} }
+% \end{macrocode}
+% Macro that will add a |.sms| extension to a path. Will be used when adding a |.sms| file
+% \begin{macrocode}
+\def\mod@updatesms{\edef\mod@savedprefix{\mod@savedprefix.sms}}
+%</package>
+% \end{macrocode}
+%
+% \subsection{Selective Inclusion}
+%
+% \begin{macro}{\requiremodules}
+% \begin{macrocode}
+%<*package>
+\newcommand{\requiremodules}[1]{%
+{\mod@updatedpre{#1} % add the new file to the already existing path
+\let\mod@savedprefix\mod@prefix % add the path to the new file to the prefix
+\mod@updatedpost{#1}
+\def\mod@blaaaa{} % macro used in the simplify function (remove .. from the prefix)
+\mod@simplify{\mod@savedprefix} % remove |xxx/..| from the path (in case it exists)
+\mod@reguse{\mod@savedprefix}
+\ifmodules\else
+\mod@updatesms % update the file to contain the .sms extension
+\let\newreg\reg % use to compare, in case the .sms file was loaded before
+\mod@search{\mod@savedprefix} % update registry
+\ifx\newreg\reg\else\input{\mod@savedprefix}\fi % check if the registry was updated and load if necessary
+\fi}}
+%</package>
+%<*ltxml>
+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; });
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sinput}
+% \begin{macrocode}
+%<*package>
+\def\sinput#1{
+{\mod@updatedpre{#1} % add the new file to the already existing path
+\let\mod@savedprefix\mod@prefix % add the path to the new file to the prefix
+\mod@updatedpost{#1}
+\def\mod@blaaaa{} % macro used in the simplify function (remove .. from the prefix)
+\mod@simplify{\mod@savedprefix} % remove |xxx/..| from the path (in case it exists)
+\mod@reguse{\mod@savedprefix}
+\let\newreg\reg % use to compare, in case the .sms file was loaded before
+\mod@search{\mod@savedprefix} % update registry
+\ifx\newreg\reg%\message{This file has been previously introduced}
+\else\input{\mod@savedprefix}\fi}}
+%</package>
+%<*ltxml>
+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;});
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+% \ednote{the sinput macro is just faked, it should be more like requiremodules, except
+% that the tex file is inputted; I wonder if this can be simplified.}
+%
+% \subsection{Generating {\texorpdfstring\omdoc{OMDoc}} Presentation Elements}\label{sec:impl:presentation}
+%
+% Additional bundle of code to generate presentation encodings. Redefined to an expandable
+% (macro) so that we can add conversions.
+%
+% \begin{macrocode}
+%<*ltxml>
+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; });
+% \end{macrocode}
+% Generate the expansion of a symdef'd macro using special arguments
+% \begin{macrocode}
+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; }
+% \end{macrocode}
+% The |\@use| macro just generates the contents of the notation element
+% \begin{macrocode}
+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');
+% \end{macrocode}
+% The |get_cd| procedure reads of the cd from our list of keys.
+% \begin{macrocode}
+sub get_cd {
+ my($name,$cd,$role,$cmml,$cattrs,$definitionURL)=@_;
+ return $cd;}
+% \end{macrocode}
+% The |\@symdef@pres@aux| creates the |symbol| element and the outer layer of the of the
+% |notation| element. The content of the latter is generated by applying the {\latexml} to
+% the definiens of the |\symdef| form.
+% \begin{macrocode}
+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))); });
+% \end{macrocode}
+% Convert a macro body (tokens with parameters |#1|,..) into a Presentation |style=TeX| form.
+% walk through the tokens, breaking into chunks of neutralized (|T_OTHER|) tokens and
+% parameter specs.
+% \begin{macrocode}
+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>");
+%</ltxml>
+% \end{macrocode}
+%
+%
+% \subsection{Including Externally Defined Semantic Macros }\label{sec:impl:packages}
+%
+% \begin{macro}{\requirepackage}
+% \begin{macrocode}
+%<package>\def\requirepackage#1#2{\makeatletter\input{#1.sty}\makeatother}
+%<*ltxml>
+DefConstructor('\requirepackage{} Semiverbatim',"<omdoc:imports from='#2'/>",
+ afterDigest=>sub { my ($stomach, $whatsit) = @_;
+ my $select = $whatsit->getArg(1);
+ RequirePackage($select->toString); });
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated Functionality}\label{sec:impl:deprecated}
+%
+% In this section we centralize old interfaces that are only partially supported any more.
+% \begin{macro}{module:uses}
+% For each the module name |xxx| specified in the |uses| key, we activate their symdefs
+% and we export the local symdefs.\ednote{this isue is deprecated, it will be removed
+% before 1.0.}
+% \begin{macrocode}
+%<*package>
+\define@key{module}{uses}{%
+ \@for\module@tmp:=#1\do{\activate@defs\module@tmp\export@defs\module@tmp}}
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{module:usesqualified}
+% This option operates similarly to the module:uses option defined above. The only
+% difference is that here we import modules with a prefix. This is useful when two
+% modules provide a macro with the same name.
+% \begin{macrocode}
+%<*package>
+\define@key{module}{usesqualified}{%
+ \@for\module@tmp:=#1\do{\activate@defs{qualified@\module@tmp}\export@defs\module@tmp}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Finale}
+%
+% Finally, we need to terminate the file with a success mark for perl.
+% \begin{macrocode}
+%<ltxml>1;
+% \end{macrocode}
+%
+% \section {Utility}\label{sec:utilities}
+% \Finale
+\endinput
+% \iffalse
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% LocalWords: GPL structuresharing STR dtx env envfalse idfalse displayfalse
+% LocalWords: usesfalse usesqualified usesqualifiedfalse envtrue idtrue CPERL
+% LocalWords: usestrue displaytrue usesqualifiedtrue RequirePackage keyval tmp
+% LocalWords: defs foreach LookupValue activateScope DefEnvironment keyvals cd
+% LocalWords: OptionalKeyVals getValue toString AssignValue openElement omdoc
+% LocalWords: closeElement beforeDigest useTheoryItemizations afterDigestBegin
+% LocalWords: whatsit setProperty getArg qw symdef cmml cattrs definitionURL
+% LocalWords: DefKeyVal Semiverbatim symdeflocal atqualified DefMacro STDERR
+% LocalWords: args unlist DefPrimitive nargs Stringify eq attr omcd ltx XMTok
+% LocalWords: DefConstructorI convertLaTeXArgs scriptpos XMApp OMA XMArg simpl
+% LocalWords: DefMacroI blaaaa savedprefix aaa simplhelp tust tist tost reguse
+% LocalWords: updatedpre ReturnAfterFi updateall updatedpost updatesms bgroup
+% LocalWords: texclude tinclude getGullet requiredmodule tex sms egroup pmml
+% LocalWords: toks mixfixi mixfixa mixfixii mixfixia mixfixai mixfixiii arg
+% LocalWords: DefConstructor afterDigest setProperties undef tok PARAM
+% LocalWords: getString
+% \fi