% \iffalse meta-comment
% An Infrastructure for Semantic Macros and Module Scoping
% Copyright (C) 2004-2010 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
% $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/modules/modules.dtx $
% \fi
%  
% \iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{modules}[2012/01/28 v1.1 Semantic Markup]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{stex-logo,modules}
\usepackage{url,array,float,textcomp}
\usepackage[show]{ed}
\usepackage[hyperref=auto,style=alphabetic]{biblatex}
\usepackage{listings}
\usepackage{amsfonts}
\bibliography{kwarc}
\usepackage[eso-foot,today]{svninfo}
\svnInfo $Id: modules.dtx 1999 2012-01-28 07:32:11Z kohlhase $
\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/modules/modules.dtx $
\usepackage{../ctansvn}
\usepackage{hyperref} 
\makeindex
\floatstyle{boxed}
\newfloat{exfig}{thp}{lop}
\floatname{exfig}{Example}
\def\tracissue#1{\cite{sTeX:online}, \hyperlink{http://trac.kwarc.info/sTeX/ticket/#1}{issue #1}}
\begin{document}\DocInput{modules.dtx}\end{document} 
%</driver>
% \fi
% 
% \CheckSum{941}
%
% \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}
% \changes{v0.9e}{2008/06/17}{fixing LaTeXML}
% \changes{v0.9f}{2008/06/17}{remove unused options uses and usesqualified}
% \changes{v0.9g}{2009/05/02}{adding resymdef functionality}
% \changes{v0.9g}{2009/08/12}{adding importOMDocmodule}
% \changes{v0.9h}{2010/01/19}{using {\texttt{\textbackslash mod@newcommand}} instead of
% {\texttt{\textbackslash providecommand}} for more intuitive inheritance.}
% \changes{v0.9h}{2010/03/05}{adding {\texttt{\textbackslash metalanguage}}}
% \changes{v1.0}{2010/06/18}{minor fixes}
% \changes{v1.1}{2010/12/30}{adding optional arguments to semantic macros for display
%   variants. The resymdef functionality introduced in 0.9g is now deprecated. It was hardly
%   used.}
% 
% \GetFileInfo{modules.sty}
% 
% \MakeShortVerb{\|}
%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
% \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}}
% \def\cT{\mathcal{T}}\def\cD{\mathcal{D}}
% \title{{\texttt{modules.sty}}: Semantic Macros and Module Scoping   in {\stex}\thanks{Version {\fileversion} (last revised
%        {\filedate})}}
%    \author{Michael Kohlhase \& Deyan Ginev \& Rares Ambrus\\
%            Jacobs University, Bremen\\
%            \url{http://kwarc.info/kohlhase}}
% \maketitle
%
% \begin{abstract}
%   The |modules| package 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 dependency 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\setcounter{tocdepth}{2}\tableofcontents\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
% (the command sequence) is inspired by the name of the mathematical object.  This can
% range from simple definitions like |\def\Reals{\mathbb{R}}| for individual mathematical
% objects to more complex (functional) ones object constructors like
% |\def\SmoothFunctionsOn#1{\mathcal{C}^\infty(#1,#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. For an in-depth discussion
% of semantic macros and scoping we refer the reader~\cite{Kohlhase:ulsmf08}.
% 
% The |modules| package provides a {\LaTeX}-based markup infrastructure for defining
% module-scoped semantic macros and {\latexml} bindings~\cite{Miller:latexml:online} to
% create {\omdoc}~\cite{Kohlhase:omdoc1.2} from {\stex} documents. In the {\stex} world
% semantic macros have a special status, since they allow the transformation of
% {\TeX/\LaTeX} formulae into a content-oriented markup format like
% {\openmath}~\cite{BusCapCar:2oms04} and (strict) content
% {\mathml}~\cite{CarlisleEd:MathML3}; see Figure~\ref{fig:omsemmac} for an example, where
% the semantic macros above have been defined by the |\symdef| macros (see
% Section~\ref{sec:symdef}) in the scope of a |\begin{module}[id=calculus]| (see
% Section~\ref{sec:modules}).
% 
% \begin{exfig}\lstset{basicstyle=\scriptsize,aboveskip=-.5em,belowskip=-1.5em}
% \begin{tabular}{l|p{9.7cm}}
% \LaTeX  & \verb|\SmoothFunctionsOn\Reals| \\\hline
% PDF/DVI & ${\mathcal{C}^\infty(\mathbb{R},\mathbb{R})}$\\\hline
%  {\openmath} & \lstset{morekeywords={OMA,OMS}}
% \begin{lstlisting}
% <OMA>
%   <OMS cd="calculus" name="SmoothFunctionsOn"/>
%   <OMS cd="calculus" name="Reals"/>
% </OMA>\end{lstlisting}\\\hline
% {\mathml}  & \lstset{morekeywords={apply,csymbol}}
% \begin{lstlisting}
% <apply>
%   <csymbol cd="calculus">SmoothFunctionsOn</csymbol>
%   <csymbol cd="calculus">Reals</csymbol>
% </apply>\end{lstlisting}\\
% \end{tabular}
% \caption{{\openmath} and {\mathml} generated from Semantic Macros}\label{fig:omsemmac}
% \end{exfig}
% 
% \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{Package Options}\label{sec:options}
%
% The |modules| package takes two options: If we set \DescribeMacro{showviews}|showviews|,
% then the views (see Section~\ref{sec:user:views}) are shown. If we set the
% \DescribeMacro{qualifiedimports}|qualifiedimports| option, then qualified imports are
% enabled. Qualified imports give more flexibility in module inheritance, but consume more
% internal memory. As qualified imports are not fully implemented at the moment, they are
% turned off by default see Limitation~\ref{sec:limitations:qualified-imports}.
% 
% If the \DescribeMacro{showmeta}|showmeta| is set, then the metadata keys are shown
% (see~\cite{Kohlhase:metakeys:ctan} for details and customization options).
% 
% \subsection{Semantic Macros}\label{sec:symdef}
%
% The \DescribeMacro{\symdef} is the main constructor for semantic macros in {\sTeX}. 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.
% 
% The two semantic macros in Figure~\ref{fig:omsemmac} would have been declared by
% invocations of the |\symdef| macro of the form:
% \begin{verbatim}
% \symdef{Reals}{\mathbb{R}}
% \symdef{SmoothFunctionsOn}[1]{\mathcal{C}^\infty(#1,#1)}
% \end{verbatim}
% 
% Note that both semantic macros correspond to {\openmath} or {\mathml} ``symbols'',
% i.e. named representations of mathematical concepts (the real numbers and the
% constructor for the space of smooth functions over a set); we call these names the
% {\textbf{symbol name}} of a semantic macro. Normally, the symbol name of a semantic
% macro declared by a |\symdef| directive is just \meta{cseq}. The key-value pair
% \DescribeMacro{name}|name=|\meta{symname} can be used to override this behavior and
% specify a differing name. There are two main use cases for this. 
% 
% The first one is shown in Example~\ref{fig:symvariant}, where we define semantic macros
% for the ``exclusive or'' operator. Note that we define two semantic macros: |\xorOp| and
% |\xor| for the applied form and the operator. As both relate to the same mathematical
% concept, their symbol names should be the same, so we specify |name=xor| on the
% definition of |\xorOp|.
% 
% A key \DescribeMacro{local}|local| can be added to {\meta{keys}} to specify that the
% symbol is local to the module and is invisible outside. Note that even though |\symdef|
% has no advantage over |\def| for defining local semantic macros, it is still considered
% good style to use |\symdef| and |\abbrdef|, if only to make switching between local and
% exported semantic macros easier.
% 
% \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{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*{-3.5ex}\hrule\vspace*{1ex}
% \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}
% \caption{Semantic Markup in a {\texttt{module}} Context}\label{fig:semmodule}
% \end{exfig}
%
% The \DescribeMacro{\symvariant}|\symvariant| macro can be used to define presentation
% variants for semantic macros previously defined via the |\symdef| directive. In an
% invocation 
% \begin{quote}
% |\symdef[|\meta{keys}|]{|\meta{cseq}|}[|\meta{args}|]{|\meta{pres}|}|\\
% |\symvariant{|\meta{cseq}|}[|\meta{args}|]{|\meta{var}|}{|\meta{varpres}|}|
% \end{quote}
% the first line defines the semantic macro |\|\meta{cseq} that when applied to
% \meta{args} arguments is presented as \meta{pres}. The second line allows the semantic
% macro to be called with an optional argument \meta{var}: |\|\meta{cseq}|[var]| (applied
% to \meta{args} arguments) is then presented as \meta{varpres}. We can define a variant
% presentation for |\xor|; see Figure~\ref{fig:symvariant} for an example.
%
%\begin{exfig}
% \begin{verbatim}
% \begin{module}[id=xbool]
%   \symdef[name=xor]{xorOp}{\oplus}
%   \symvariant{xorOp}{uvee}{\underline{\vee}}
%   \symdef{xor}[2]{#1\xorOp #2}
%   \symvariant{xor}[2]{uvee}{#1\xorOp[uvee] #2}
%   Exclusive disjunction is commutative: $\xor{p}q=\xor{q}p$\\
%   Some authors also write exclusive or with the $\xorOp[uvee]$ operator, 
%   then the formula above is $\xor[uvee]{p}q=\xor[uvee]{q}p$
% \end{module}
% \end{verbatim}
% \vspace*{-3.5ex}\hrule\vspace*{1ex}
% \begin{module}[id=xbool]
%   \symdef[name=xor]{xorOp}{\oplus}
%   \symvariant{xorOp}{uvee}{\underline{\vee}}
%   \symdef{xor}[2]{#1\xorOp #2}
%   \symvariant{xor}[2]{uvee}{#1\xorOp[uvee] #2}
%   Exclusive disjunction is commutative: $\xor{p}q=\xor{q}p$\\
%   Some authors also write exclusive or with the $\xorOp[uvee]$ operator, 
%   then the formula above is $\xor[uvee]{p}q=\xor[uvee]{q}p$
% \end{module}
% \caption{Presentation Variants of a Semantic Macro}\label{fig:symvariant}
% \end{exfig}
%
% Version 1.0 of the |modules| package had the \DescribeMacro{\resymdef}|\resymdef| macro
% that allowed to locally redefine the presentation of a macro. But this did not interact
% well with the |beamer| package and was less useful than the |\symvariant|
% functionality. Therefore it is deprecated now and leads to an according error message.
% 
% \subsection{Symbol and Concept Names}\label{sec:user:termdef}
% 
% Just as the |\symdef| declarations define semantic macros for mathematical symbols, the
% |modules| package provides an infrastructure for {\emph{mathematical concepts}} that are
% expressed in mathematical vernacular. The key observation here is that concept names
% like ``finite symplectic group'' follow the same scoping rules as mathematical symbols,
% i.e. they are module-scoped. The \DescribeMacro{\termdef}|\termdef| macro is an analogue
% to |\symdef| that supports this: use
% |\termdef[|\meta{keys}|]{|\meta{cseq}|}{|\meta{concept}|}| to declare the macro
% |\|\meta{cseq} that expands to \meta{concept}. See Figure~\ref{fig:termref} for an
% example, where we use the \DescribeMacro{\capitalize}|\captitalize| macro to adapt
% \meta{concept} to the sentence beginning.\ednote{continue, describe \meta{keys}, they
% will have to to with plurals,\ldots once implemented}. The main use of the
% |\termdef|-defined concepts lies in automatic cross-referencing facilities via the
% \DescribeMacro{\termref}|\termref| and \DescribeMacro{\symref}|\symref| macros provided
% by the |statements| package~\ctancite{Kohlhase:smms}. Together with the |hyperref|
% package~\cite{RahObe:hmlmh10}, this provide cross-referencing to the definitions of the
% symbols and concepts. As discussed in section~\ref{sec:limitations:crossref}, the
% |\symdef| and |\termdef| declarations must be on top-level in a module, so the
% infrastructure provided in the |modules| package alone cannot be used to locate the
% definitions, so we use the infrastructure for mathematical statements for that.
%
%\begin{exfig}
% \begin{verbatim}
%   \termdef[name=xor]{xdisjunction}{exclusive disjunction}
%   \captitalize\xdisjunction is commutative: $\xor{p}q=\xor{q}p$
% \end{verbatim}
% \vspace*{-3.5ex}
% \caption{Extending Example~\ref{fig:symvariant} with Term References}\label{fig:termref}
% \end{exfig}
%
% \subsection{Modules and Inheritance}\label{sec:modules}
%
% The\DescribeEnv{module}|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}}).  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 the \DescribeMacro{\importmodule}|\importmodule| declarations induce the
% {\atwintoo{semantic}{inheritance}{relation}}. Figure~\ref{exf:importmodule} shows a
% module that imports the semantic macros from three others. In the simplest form,
% |\importmodule{|\meta{mod}|}| will activate the semantic macros and concepts declared by
% |\symdef| and |\termdef| in module \meta{mod} in the current module\footnote{Actually,
% in the current {\TeX} group, therefore \texttt{\textbackslash importmodule} should be
% placed directly after the \texttt{\textbackslash begin\{module\}}.}. To understand the
% mechanics of this, we need to understand a bit of the internals. The |module|
% environment sets up an internal macro pool, to which all the macros defined by the
% |\symdef| and |\termdef| declarations are added; |\importmodule| only activates this
% macro pool. Therefore |\importmodule{|\meta{mod}|}| can only work, if the {\TeX} parser
% --- which linearly goes through the {\sTeX} sources --- already came across the module
% \meta{mod}. In many situations, this is not obtainable; e.g. for ``semantic forward
% references'', where symbols or concepts are previewed or motivated to knowledgeable
% readers before they are formally introduced or for modularizations of documents into
% multiple files. To enable situations like these, the |module| package uses auxiliary
% files called {\textbf{\sTeX module signatures}}. For any file, \meta{file}|.tex|, we
% generate a corresponding \sTeX module signature \meta{file}|.sms| with the |sms| utility
% (see also Limitation~\ref{sec:limitations:sms}), which contains (copies of) all
% |\begin|/|\end{module}|, |\importmodule|, |\symdef|, and |\termdef| invocations in
% \meta{file}|.tex|. The value of an \sTeX module signature is that it can be loaded
% instead its corresponding \sTeX document, if we are only interested in the semantic
% macros. So |\importmodule[|\meta{filepath}|]{|\meta{mod}|}| will load the \sTeX module
% signature \meta{filepath}|.sms| (if it exists and has not been loaded before) and
% activate the semantic macros from module \meta{mod} (which was supposedly defined in
% \meta{filepath}|.tex|). Note that since \meta{filepath}|.sms| contains all
% |\importmodule| statements that \meta{filepath}|.tex| does, an |\importmodule|
% recursively loads all necessary files to supply the semantic macros inherited by the
% current module.
% 
% The |\importmodule| macro has a variant
% \DescribeMacro{importmodulevia}|\importmodulevia| that allows the specification of a
% theory morphism to be applied.  |\importmodulevia{|\meta{thyid}|}{|\meta{assignments}|}|
% specifies the ``source theory'' via its identifier \meta{thyid} and the morphism by
% \meta{assignments}. There are three kinds:
% \begin{compactdesc}
% \item[symbol assignments] via
%   \DescribeMacro{\vassign}|\vassign{|\meta{sym}|}{|\meta{exp}|}|, which defines the
%   symbol \meta{sym} introduced in the current theory by an expression \meta{exp} in the
%   source theory.
% \item[term assignments] via
%   \DescribeMacro{\tassign}|\tassign[||\meta{source-cd}]{|\meta{tname}|}{|\meta{source-tname}|}|,
%   which defines the term with name \meta{tname} in the current via a term with
%   name\meta{source-tname} in the theory \meta{source-cd} whose default value is the
%   source theory.
% \item[term text assignments] via
%   \DescribeMacro{\ttassign}|\tassign{|\meta{tname}|}{|\meta{text}|}|, which defines a
%   term with name \meta{tname} in the current theory via a definitional text.
% \end{compactdesc}
% 
%\begin{exfig}
% \begin{verbatim}
% \begin{module}[id=ring]
% \begin{importmodulevia}{monoid}
%   \vassign{rbase}\magbase
%   \vassign{rtimesOp}\magmaop
%   \vassign{rone}\monunit
% \end{importmodulevia}
% \symdef{rbase}{G}
% \symdef[name=rtimes]{rtimesOp}{\cdot}
% \symdef{rtimes}[2]{\infix\rtimesOp{#1}{#2}}
% \symdef{rone}{1}
% \begin{importmodulevia}{cgroup}
%   \vassign{rplus}\magmaop
%   \vassign{rzero}\monunit
%   \vassign{rinvOp}\cginvOp
% \end{importmodulevia}
% \symdef[name=rplus]{rplusOp}{+}
% \symdef{rplus}[2]{\infix\rplusOp{#1}{#2}}
% \symdef[name=rminus]{rminusOp}{-}
% \symdef{rminus}[1]{\infix\rminusOp{#1}{#2}}
% ...
% \end{module}
% \end{verbatim}
% \caption{A Module for Rings with inheritance from monoids and commutative groups}\label{fig:ring}
% \end{exfig}
%
% The \DescribeMacro{\metalanguage} |metalanguage| macro is a variant of
% \lstinline|importmodule| that imports the meta language, i.e. the language in which the
% meaning of the new symbols is expressed. For mathematics this is often first-order logic
% with some set theory; see~\cite{RabKoh:WSMSML10} for discussion. 
% 
% \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 entropy is aggravated by the fact that modules are very
% self-contained 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 corresponding 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 {\texttt{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.
%
% Sometimes we want to import an existing {\omdoc} theory\footnote{{\omdoc} theories are
%   the counterpart of {\stex} modules.} $\widehat\cT$ into (the {\omdoc} document
% $\widehat\cD$ generated from) a {\stex} document $\cD$. Naturally, we have to provide an
% {\stex} stub module $\cT$ that provides |\symdef| declarations for all symbols we use in
% $\cD$. In this situation, we use\DescribeMacro{\importOMDocmodule}
% |\importOMDocmodule[|\meta{spath}|]{|\meta{OURI}|}{|\meta{name}|}|, where \meta{spath}
% is the file system path to $\cT$ (as in |\importmodule|, this argument must not contain
% the file extension), \meta{OURI} is the URI to the {\omdoc} module (this time with
% extension), and \meta{name} is the name of the theory $\widehat\cT$ and the module in
% $\cT$ (they have to be identical for this to work). Note that since the \meta{spath}
% argument is optional, we can make ``local imports'', where the stub $\cT$ is in $\cD$
% and only contains the |\symdef|s needed there.
%
% 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}
% formatter (it is usually set to something like 15\footnote{If you have sufficient rights
% to change your {\TeX} installation, you can also increase the variable
% {\texttt{max\_in\_open}} in the relevant {\texttt{texmf.cnf}} file. Setting it to 50
% usually suffices}). 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 depth
% 15, then we cannot naively 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) without activating them, so that it would not have to be re-loaded in the
% critical path of the module |foo|. Solving the load depth problem.
% 
% \DescribeMacro{\sinput} In all of the above, we do not want to load an |sms| file, if
% the corresponding file has already been loaded, since the semantic macros are already in
% memory. Therefore the |modules| package supplies a semantic variant of the |\input|
% macro, which records in an internal register that the modules in the file have already
% been loaded. Thus if we consistently use |\sinput| instead of |\input| or |\include| for
% files that contain modules\footnote{files without modules should be treated by the
%   regular {\LaTeX} input mechanism, since they do not need to be registered.}, we can
% prevent double loading of files and therefore gain efficiency. The
% \DescribeMacro{\sinputref} |\sinputref| macro behaves just like |\sinput| in the
% {\LaTeX} workflow, but in the {\latexml} conversion process creates a reference to the
% transformed version of the input file instead.
% 
% Finally, the separation of documents into multiple modules often profits from a symbolic
% management of file paths. To simplify this, the |modules| package supplies the
% \DescribeMacro{\defpath}|\defpath| macro: |\defpath{|\meta{cname}|}{|\meta{path}|}|
% defines a command, so that |\|\meta{csname}|{|\meta{name}|}| expands to
% \meta{path}|/|\meta{name}. So we could have used
% \begin{lstlisting}
% \defpath{OPaths}{../other}
% \importmodule[\OPhats{bar}]{bar}
% \end{lstlisting}
% instead of the second line in Example~\ref{exf:importmodule}. The variant |\OPaths| has
% the big advantage that we can get around the fact that {\TeX/\LaTeX} does not set the
% current directory in |\input|, so that we can use systematically deployed
% |\defpath|-defined path macros to make modules relocatable by defining the path macros
% locally.
% 
% \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 corresponds 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 corresponding {\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.
%
% \subsection{Views}\label{sec:user:views}
% 
% A view is a mapping between modules, such that all model assumptions (axioms) of the
% source module are satisfied in the target module. \ednote{Document and make Examples}
%
% \section{Limitations \& Extensions}\label{sec:limitations}
% 
% In this section we will discuss limitations and possible extensions of the |modules|
% package. Any contributions and extension ideas are welcome; please discuss ideas,
% requests, fixes, etc on the {\sTeX} TRAC~\cite{sTeX:online}.
% 
% \subsection{Perl Utility \texttt{sms}}\label{sec:limitations:sms}
% 
% Currently we have to use an external perl utility |sms| to extract \sTeX module
% signatures from \sTeX files. This considerably adds to the complexity of the \sTeX
% installation and workflow. If we can solve security setting problems that allows us to
% write to \sTeX module signatures outside the current directory, writing them from \sTeX
% may be an avenue of future development see~\cite[issue \#1522]{sTeX:online} for a
% discussion.
% 
% \subsection{Qualified Imports}\label{sec:limitations:qualified-imports}
% 
% In an earlier version of the \texttt{modules} package we used the \texttt{usesqualified}
% for importing macros with a disambiguating prefix (this is used whenever we have
% conflicting names for macros inherited from different modules). This is not accessible
% from the current interface. We need something like a |\importqualified| macro for this;
% see~\cite[issue \#1505]{sTeX:online}. Until this is implemented the infrastructure is
% turned off by default, but we have already introduced the
% \DescribeMacro{qualifiedimports}|qualifiedimports| option for the future.
% 
% \subsection{Error Messages}\label{sec:limitations:errormsg}
% 
% The error messages generated by the |modules| package are still quite bad. For instance
% if |thyA| does note exists we get the cryptic error message 
% \begin{verbatim}
% ! Undefined control sequence.
% \module@defs@thyA ...hy 
%                        \expandafter \mod@newcomma...
% l.490 ...ortmodule{thyA}
% \end{verbatim}
% This should definitely be improved. 
% 
% \subsection{Crossreferencing}\label{sec:limitations:crossref}
% 
% Note that the macros defined by |\symdef| are still subject to the normal {\TeX} scoping
% rules. Thus they have to be at the top level of a module to be visible throughout the
% module as intended. As a consequence, the location of the |\symdef| elements cannot be
% used as targets for crossreferencing, which is currently supplied by the |statement|
% package~\ctancite{Kohlhase:smms}. A way around this limitation would be to import
% the current module from the \sTeX module signature (see Section~\ref{sec:modules}) via
% the |\importmodule| declaration.
% 
% \subsection{No Forward Imports}\label{sec:limitations:forward-imports}
% 
% {\sTeX} allows imports in the same file via |\importmodule{|\meta{mod}|}|, but due to
% the single-pass linear processing model of {\TeX}, \meta{mod} must be the name of a
% module declared {\emph{before}} the current point. So we cannot have forward imports as
% in 
% \begin{verbatim}
% \begin{module}[id=foo]
%   \importmodule{mod}
%   ...
% \end{module}
% ... 
% \begin{module}[id=mod]
%   ... 
% \end{module}
% \end{verbatim}
% a workaround, we can extract the module \meta{mod} into a file {{{mod.tex}}} and replace
% it with |\sinput{mod}|, as in 
% \begin{verbatim}
% \begin{module}[id=foo]
%   \importmodule[mod]{mod}
%   ...
% \end{module}
% ... 
% \sinput{mod}
% \end{verbatim}
% then the |\importmodule| command can read |mod.sms| (created via the |sms| utility)
% without having to wait for the module \meta{mod} to be defined.
% 
% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\newpage\printbibliography}\newpage
%
% \section{The Implementation} 
%
% The |modules| package generates two files: the {\LaTeX} package (all the code between
% {\textlangle\textsf{*package}\textrangle} and {\textsf{\textlangle/package\textrangle}})
% and the {\latexml} bindings (between {\textsf{\textlangle*ltxml\textrangle}} and
% {\textsf{\textlangle/ltxml\textrangle}}). We keep the corresponding code fragments
% together, since the documentation applies to both of them and to prevent them from
% getting out of sync.
%
% \subsection{Package Options}\label{sec:impl:options}
% 
% We declare some switches which will modify the behavior according to the package
% options. Generally, an option |xxx| will just set the appropriate switches to true
% (otherwise they stay false).
%    \begin{macrocode}
%<*package>
\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
\newif\ifmod@show\mod@showfalse
\DeclareOption{showmods}{\mod@showtrue}
\newif\ifmod@qualified\mod@qualifiedfalse
\DeclareOption{qualifiedimports}{\mod@qualifiedtrue}
%    \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 {\texttt{emacs}}
% about the appropriate mode for convenience  
% 
% The next measure is to ensure that the |sref| and |xcomment| packages are loaded (in the
% right version). For {\latexml}, we also initialize the package inclusions.
%    \begin{macrocode}
%<*package>
\RequirePackage{sref}
\RequirePackage{xspace}
\RequirePackage{xcomment}
%</package>
%<*ltxml>
# -*- CPERL -*-
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Global;
use LaTeXML::Package;
%</ltxml>
%    \end{macrocode}
%
% \subsection{Modules and Inheritance}\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>
\addmetakey{module}{cd}
\addmetakey{module}{title}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{module:id}
%   For a module with |[id=|\meta{name}|]|, we have a macro |\module@defs@|\meta{name}
%   that acts as a repository for semantic macros of the current module. I will be called
%   by |\importmodule| to activate them. We will add the internal forms of the semantic
%   macros whenever |\symdef| is invoked. To do this, we will need an unexpended form
%   |\this@module| that expands to |\module@defs@|\meta{name}; we define it first and then
%   initialize |\module@defs@|\meta{name} as empty. Then we do the same for qualified
%   imports as well (if the |qualifiedimports| option was specified). Furthermore, we save
%   the module name in |\mod@id| and the module path in |\|\meta{name}|@cd@file@base|
%   which we add to |\module@defs@|\meta{name}, so that we can use it in the importing
%   module.
%    \begin{macrocode}
%<*package>
\define@key{module}{id}{%
\edef\this@module{\expandafter\noexpand\csname module@defs@#1\endcsname}%
\global\@namedef{module@defs@#1}{}%
\ifmod@qualified
\edef\this@qualified@module{\expandafter\noexpand\csname module@defs@qualified@#1\endcsname}%
\global\@namedef{module@defs@qualified@#1}{}%
\fi
\def\mod@id{#1}%
\expandafter\edef\csname #1@cd@file@base\endcsname{\mod@path}%
\expandafter\g@addto@macro\csname module@defs@#1\expandafter\endcsname\expandafter%
{\expandafter\def\csname #1@cd@file@base\expandafter\endcsname\expandafter{\mod@path}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{module@heading}
%   Then we make a convenience macro for the module heading. This can be customized. 
%    \begin{macrocode}
\newcounter{module}[section]
\newcommand\module@heading{\stepcounter{module}%
\noindent{\textbf{Module} \thesection.\themodule [\mod@id]}%
\sref@label@id{Module \thesection.\themodule [\mod@id]}%
\ifx\module@title\@empty :\quad\else\quad(\module@title)\hfill\\\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{module@footer}
%   Then we make a convenience macro for the module heading. This can be customized. 
%    \begin{macrocode}
\newcommand\module@footer{\noindent{\textbf{EndModule} \thesection.\themodule}}
%    \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}
\newenvironment{module}[1][]%
{\metasetkeys{module}{#1}\ifmod@show\module@heading\fi}
{\ifmod@show\module@footer\fi}
%</package>
%    \end{macrocode}
% for the {\latexml} bindings, we have to do the work all at once. 
%    \begin{macrocode}
%<*ltxml>
DefKeyVal('Module','id','Semiverbatim');
DefKeyVal('Module','cd','Semiverbatim');
DefEnvironment('{module} OptionalKeyVals:Module',
	       "?#excluded()(<omdoc:theory "
             . "?&defined(&KeyVal(#1,'id'))(xml:id='&KeyVal(#1,'id')')(xml:id='#id')>#body</omdoc:theory>)", 
#     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));       
       	#make sure we have an id or give a stub one otherwise:
	if (not $id) {
		#do magic to get a unique id for this theory
		#$whatsit->setProperties(beginItemize('theory'));
		#$id = ToString($whatsit->getProperty('id'));
                # changed: beginItemize returns the hash returned by RefStepCounter.
                # RefStepCounter deactivates any scopes for the current value of the
                # counter which causes the stored prop. of the env. not to be
                # visible anymore.
                $id = LookupValue('stex:theory:id') || 0;
                AssignValue('stex:theory:id', $id+1);
                $id = "I$id";
	}
       $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;

       #activate the module in our current scope
       $STATE->activateScope("module:".$id);

       #Activate parent scope, if present
       my $parentmod = LookupValue('parent_module');
       use_module($parentmod) if $parentmod;
       #Update the current parent module
       AssignValue("parent_of_$id"=>$parentmod,'global');
       AssignValue("parent_module" => $id);
       return; },
     afterDigest => sub {
       #Move a step up on the module ancestry
       AssignValue("parent_module" => LookupValue("parent_of_".LookupValue("parent_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,%ancestors)=@_;
  $module = ToString($module);
  if (defined $ancestors{$module})  {
    Fatal(":module \"$module\" leads to import cycle!");
  }
  $ancestors{$module}=1;
  # Depth-first load definitions from used modules, disregarding cycles
  foreach my $used_module (@{ LookupValue("module_${module}_uses") || []}){
    use_module($used_module,%ancestors);
  }
  # then load definitions for this module
  $STATE->activateScope("module:$module"); }#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\activate@defs}
%   To activate the |\symdef|s from a given module \meta{mod}, we call the macro
%   |\module@defs@|\meta{mod}.
%    \begin{macrocode}
%<*package>
\def\activate@defs#1{\csname module@defs@#1\endcsname}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\export@defs}
%   To export a the |\symdef|s from the current module, we all the macros
%   |\module@defs@|\meta{mod} to |\module@defs@|\meta{mod} (if the current module has a
%   name and it is \meta{mod})
%    \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}{\coolurion/off}
%   \ednote{@DG: this needs to be documented somewhere in section 1}
%    \begin{macrocode}
%<*package>
\def\coolurion{}
\def\coolurioff{}
%</package>
%<*ltxml>
DefMacro('\coolurion',sub {AssignValue('cooluri'=>1);});
DefMacro('\coolurioff',sub {AssignValue('cooluri'=>0);});
%</ltxml>
%    \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 |\symdef|s from module
%   \meta{mod}. It also remembers the file name in |\mod@path|.
%    \begin{macrocode}
%<*package>
\newcommand{\importmodule}[2][]{{\def\mod@path{#1}%
\ifx\mod@path\@empty\else\requiremodules{#1}\fi}%
\activate@defs{#2}\export@defs{#2}}
%</package>
%<*ltxml>
sub omext {
  my ($mod)=@_; my $dest='';
  $mod = ToString($mod);
  if ($mod) {
    #We need a constellation of abs_path invocations
    # to make sure that all symbolic links get resolved
    if ($mod=~/^(\w)+:\/\//) { $dest=$mod; } else {
      my ($d,$f,$t) = pathname_split(abs_path($mod));
      $d = pathname_relative(abs_path($d),abs_path(cwd()));
      $dest=$d."/".$f;
    }
  }
  $dest.=".omdoc" if (ToString($mod) && !LookupValue('cooluri')); 
  return Tokenize($dest);}
sub importmoduleI {
   my($stomach,$whatsit)=@_;
   my $file = ToString($whatsit->getArg(1));
   my $omdocmod = $file.".omdoc" if $file;
   my $module = ToString($whatsit->getArg(2));
   my $containing_module = LookupValue('current_module');
   AssignValue('last_import_module',$module);
   #set the relation between the current module and the one to be imported
   PushValue("module_".$containing_module."_uses"=>$module) if $containing_module;
  #check if we've already loaded this module file or no file path given
  if((!$file) || (LookupValue('file_'.$module.'_loaded'))) {use_module($module);} #if so activate it!
  else {
    #if not:
    my $gullet = $stomach->getGullet;
    #1) mark as loaded
    AssignValue('file_'.$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'), Tokens(Explode($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;}
DefConstructor('\importmodule OptionalSemiverbatim {}',
   "<omdoc:imports from='?#1(&omext(#1))\##2'/>",
   afterDigest=>sub{ importmoduleI(@_)});
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\importmodulevia} 
%   The |importmodulevia| environment just calls |\importmodule|, but to get around the
%   group, we first define a local macro |\@@doit|, which does that and can be called with
%   an |\aftergroup| to escape the environment groupling introduced by
%   |importmodulevia|. For {\latexml}, we have to\ednote{MK@DG: needs implementation}
%    \begin{macrocode}
%<*package>
\newenvironment{importmodulevia}[2][]{\gdef\@@doit{\importmodule[#1]{#2}}%
\ifmod@show\par\noindent importing module #2 via \@@doit\fi}
{\aftergroup\@@doit\ifmod@show end import\fi}
%</package>
%<*ltxml>
DefMacro('\importmodulevia OptionalSemiverbatim {}','\endgroup\importmoduleI[#1]{#2}\begin{importmoduleenv}[#1]{#2}');
DefMacroI('\end{importmodulevia}',undef,'\end{importmoduleenv}');
DefEnvironment('{importmoduleenv} OptionalSemiverbatim {}',
   "<omdoc:imports from='?#1(&omext(#1))\##2'>"
  .  "<omdoc:morphism>#body</omdoc:morphism>"
  ."</omdoc:imports>");
DefConstructor('\importmoduleI OptionalSemiverbatim {}', '',
   afterDigest=>sub{ importmoduleI(@_)});
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{vassign}
%    \begin{macrocode}
%<*package>
\newcommand\vassign[2]{\ifmod@show\ensuremath{#1\mapsto #2}, \fi}
%</package>
%<*ltxml>
DefConstructor('\vassign{}{}',
    "<omdoc:requation>"
   .  "<ltx:Math><ltx:XMath>#1</ltx:XMath></ltx:Math>"
   .  "<ltx:Math><ltx:XMath>#2</ltx:XMath></ltx:Math>"
   ."</omdoc:requation>");
%</ltxml>
%    \end{macrocode}
% \end{environment}
% 
% \begin{environment}{tassign}
%    \begin{macrocode}
%<*package>
\newcommand\tassign[3][]{\ifmod@show #2\ensuremath{\mapsto} #3, \fi}
%</package>
%<*ltxml>
DefConstructor('\tassign[]{}{}',
    "<omdoc:requation>"
   .  "<om:OMOBJ><om:OMS cd='?#1(#1)(#lastImportModule)' name='#2'/></om:OMOBJ>"
   .  "<om:OMOBJ><om:OMS cd='#currentModule' name='#3'/></om:OMOBJ>"
   ."</omdoc:requation>",
   afterDigest=> sub {
     my ($stomach,$whatsit) = @_;
     $whatsit->setProperty('currentModule',LookupValue("current_module"));
     $whatsit->setProperty('lastImportModule',LookupValue("last_import_module"));
   });
%</ltxml>
%    \end{macrocode}
% \end{environment}
% 
% \begin{environment}{ttassign}
%    \begin{macrocode}
%<*package>
\newcommand\ttassign[3][]{\ifmod@show #1\ensuremath{\mapsto} ``#2'', \fi}
%</package>
%<*ltxml>
DefConstructor('\ttassign{}{}',
    "<omdoc:requation>"
   .  "<ltx:Math><ltx:XMath>#1</ltx:XMath></ltx:Math>"
   .  "<ltx:Math><ltx:XMath>#2</ltx:XMath></ltx:Math>"
   ."</omdoc:requation>");
%</ltxml>
%    \end{macrocode}
% \end{environment}
% 
% \begin{macro}{\importOMDocmodule} 
%   for the {\LaTeX} side we can just re-use |\importmodule|, for the {\latexml} side we
%   have a full URI anyways. So things are easy.
%    \begin{macrocode}
%<*package>
\newcommand{\importOMDocmodule}[3][]{\importmodule[#1]{#3}}
%</package>
%<*ltxml>
DefConstructor('\importOMDocmodule OptionalSemiverbatim {}{}',"<omdoc:imports from='#3\##2'/>",
afterDigest=>sub{ 
  #Same as \importmodule, just switch second and third argument.
  my ($stomach,$whatsit) = @_;
  my $path = $whatsit->getArg(1);
  my $ouri = $whatsit->getArg(2);
  my $module = $whatsit->getArg(3);
  $whatsit->setArgs(($path, $module,$ouri));
  importmoduleI($stomach,$whatsit);
  return;
});
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\metalanguage} 
%   |\metalanguage| behaves exactly like |\importmodule| for formatting. For {\latexml},
%   we only add the |type| attribute.
%    \begin{macrocode}
%<*package>
\let\metalanguage=\importmodule
%</package>
%<*ltxml>
DefConstructor('\metalanguage OptionalSemiverbatim {}',
   "<omdoc:imports type='metalanguage' from='?#1(&omext(#1))\##2'/>",
   afterDigest=>sub{ importmoduleI(@_)});
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Semantic Macros}\label{sec:impl:symdef}
% 
% \begin{macro}{\mod@newcommand}
%   We first hack the {\LaTeX} kernel macros to obtain a version of the |\newcommand|
%   macro that does not check for definedness. This is just a copy of the code from
%   |latex.ltx| where I have removed the |\@ifdefinable| check.\footnote{Someone must have
%     done this before, I would be very happy to hear about a package that provides this.}
%    \begin{macrocode}
%<*package>
\def\mod@newcommand{\@star@or@long\mod@new@command}
\def\mod@new@command#1{\@testopt{\@mod@newcommand#1}0}
\def\@mod@newcommand#1[#2]{\kernel@ifnextchar [{\mod@xargdef#1[#2]}{\mod@argdef#1[#2]}}
\long\def\mod@argdef#1[#2]#3{\@yargdef#1\@ne{#2}{#3}}
\long\def\mod@xargdef#1[#2][#3]#4{\expandafter\def\expandafter#1\expandafter{%
\expandafter\@protected@testopt\expandafter #1\csname\string#1\endcsname{#3}}%
\expandafter\@yargdef\csname\string#1\endcsname\tw@{#2}{#4}}
%</package>
%    \end{macrocode}
% \end{macro}
% 
% Now we define the optional KeyVal arguments for the |\symdef| form and the actions that
% are taken when they are encountered.
%
% \begin{macro}{symdef:keys}
%   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}|. The other keys are not used in the
%   {\LaTeX} part.
%    \begin{macrocode}
%<*package>
\newif\if@symdeflocal
\define@key{symdef}{local}[true]{\@symdeflocaltrue}
\define@key{symdef}{name}{}
\define@key{symdef}{assocarg}{}
\define@key{symdef}{bvars}{}
\define@key{symdef}{bvar}{}
\define@key{symdef}{bindargs}{}
%</package>
%    \end{macrocode}
% \end{macro}
% \ednote{MK@MK: we need to document the binder keys above.}
% \begin{macro}{\symdef}
%    The the |\symdef|, and |\@symdef| macros just handle optional arguments.
%    \begin{macrocode}
%<*package>
\def\symdef{\@ifnextchar[{\@symdef}{\@symdef[]}}
\def\@symdef[#1]#2{\@ifnextchar[{\@@symdef[#1]{#2}}{\@@symdef[#1]{#2}[0]}}
%    \end{macrocode}
% next we locally abbreviate |\mod@newcommand| to simplify argument passing.
%    \begin{macrocode}
\def\@mod@nc#1{\mod@newcommand{#1}[1]}
%    \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 set all the keys that have been provided as arguments: |name|, |local|.
%    \begin{macrocode}
\@symdeflocalfalse\setkeys{symdef}{#1}%
%    \end{macrocode}
% First, using |\mod@newcommand| we initialize the intermediate macro
% |\module@|\meta{sym}|@pres@|, the one that can be extended with |\symvariant|
%    \begin{macrocode}
\expandafter\mod@newcommand\csname modules@#2@pres@\endcsname[#3]{#4}%
%    \end{macrocode}
% and then we define the actual semantic macro. Note that this can take an optional
% argument, for which we provide with |\@ifnextchar| and an internal macro |\@|\meta{sym},
% which when invoked with an optional argument \meta{opt} calls
% |\modules@|\meta{sym}|@pres@|\meta{opt}.
%    \begin{macrocode}
\expandafter\def\csname #2\endcsname%
{\@ifnextchar[{\csname modules@#2\endcsname}{\csname modules@#2\endcsname[]}}%
\expandafter\def\csname modules@#2\endcsname[##1]%
{\csname modules@#2@pres@##1\endcsname}%
%    \end{macrocode}
% Finally, we prepare the internal macro to be used in the |\symref| call.
%    \begin{macrocode}
\expandafter\@mod@nc\csname mod@symref@#2\expandafter\endcsname\expandafter%
{\expandafter\mod@termref\expandafter{\mod@id}{#2}{##1}}%
%    \end{macrocode}
% We check if the switch for the local scope is set: if it is we are done, since this
% function has a local scope. Similarly, if we are not inside a module, which we could
% export from.  
%    \begin{macrocode}
\if@symdeflocal\else%
\@ifundefined{mod@id}{}{%
%    \end{macrocode}
% Otherwise, we add three functions to the module's pool of defined macros using
% |\g@addto@macro|. We first add the definition of the intermediate function
% |\modules@|\meta{sym}|@pres@|.
%    \begin{macrocode}
\expandafter\g@addto@macro\this@module%
{\expandafter\mod@newcommand\csname modules@#2@pres@\endcsname[#3]{#4}}%
%    \end{macrocode}
% Then we add add the definition of |\|\meta{sym} in terms of the function |\@|\meta{sym}
% to handle the optional argument.
%    \begin{macrocode}
\expandafter\g@addto@macro\this@module%
{\expandafter\def\csname#2\endcsname%
{\@ifnextchar[{\csname modules@#2\endcsname}{\csname modules@#2\endcsname[]}}}%
%    \end{macrocode}
% Finally, we add add the definition of |\@|\meta{sym}, which calls the intermediate
% function.
%    \begin{macrocode}
\expandafter\g@addto@macro\this@module%
{\expandafter\def\csname modules@#2\endcsname[##1]%
{\csname modules@#2@pres@##1\endcsname}}%
%    \end{macrocode}
% We also add |\mod@symref@|\meta{sym} macro to the macro pool so that the |\symref| macro
% can pick it up.
%    \begin{macrocode}
\expandafter\g@addto@macro\csname  module@defs@\mod@id\expandafter\endcsname\expandafter%
{\expandafter\@mod@nc\csname mod@symref@#2\expandafter\endcsname\expandafter%
{\expandafter\mod@termref\expandafter{\mod@id}{#2}{##1}}}%
%    \end{macrocode}
% Finally, using |\g@addto@macro| we add the two functions to the qualified version of the
% module if the |qualifiedimports| option was set.
%    \begin{macrocode}
\ifmod@qualified%
\expandafter\g@addto@macro\this@qualified@module%
{\expandafter\mod@newcommand\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%
%    \end{macrocode}
% So now we only need to close all brackets and the macro is done. 
%    \begin{macrocode}
}\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}
%<*package>
\define@key{DefMathOp}{name}{\def\defmathop@name{#1}}
\newcommand\DefMathOp[2][]{%
\setkeys{DefMathOp}{#1}%
\symdef[#1]{\defmathop@name}{#2}}
%</package>
%<*ltxml>
DefMacro('\DefMathOp OptionalKeyVals:symdef {}',
 sub {
   my($self,$keyval,$pres)=@_;
   my $name = KeyVal($keyval,'name') if $keyval;
   #Rewrite this token
   my $scopes = $STATE->getActiveScopes;
   DefMathRewrite(xpath=>'descendant-or-self::ltx:XMath',match=>ToString($pres),
        replace=>sub{
          map {$STATE->activateScope($_);} @$scopes;
          $_[0]->absorb(Digest("\\".ToString($name)));
        });
   #Invoke symdef
   (Invocation(T_CS('\symdef'),$keyval,$name,undef,$pres)->unlist);
 });
DefMacro('\symdef OptionalKeyVals:symdef {}[]{}',
      sub {
  my($self,@args)=@_;
  ((Invocation(T_CS('\@symdef'),@args)->unlist),
   (LookupValue('excluding_modules') ? ()
     : (Invocation(T_CS('\@symdef@pres'), @args)->unlist))); });

#Current list of recognized formatter command sequences:
our @PresFormatters = qw (infix prefix postfix assoc mixfixi mixfixa mixfixii mixfixia mixfixai mixfixaii mixfixiii);
DefPrimitive('\@symdef OptionalKeyVals:symdef {}[]{}', sub {
  my($stomach,$keys,$cs,$nargs,$presentation)=@_;
  my($name,$cd,$role,$bvars,$bvar)=$keys 
    && map($_ && $_->toString,map($keys->getValue($_), qw(name cd role
    bvars bvar)));
  $cd = LookupValue('module_cd') unless $cd;
  $name = $cs unless $name;
  #Store for later lookup
  AssignValue("symdef.".ToString($cs).".cd"=>ToString($cd),'global');
  AssignValue("symdef.".ToString($cs).".name"=>ToString($name),'global');
  $nargs = (ref $nargs ? $nargs->toString : $nargs || 0);
  my $module = LookupValue('current_module');
  my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":".$module;
  #The DefConstructorI Factory is responsible for creating the \symbol command sequences as dictated by the \symdef
  DefConstructorI("\\".$cs->toString,convertLaTeXArgs($nargs+1,'default'), sub {
     my ($document,@args) = @_;
     my $icvariant = shift @args;
     my @props = @args;
     #Lookup the presentation from the State, if a variant:
     @args = splice(@props,0,$nargs);
     my %prs = @props;
     my $localpres = $prs{presentation};
     $prs{isbound} = "BINDER" if ($bvars || $bvar);
     my $wrapped;
     my $parent=$document->getNode;
     if(! defined $parent->lookupNamespacePrefix("http://omdoc.org/ns")){ # namespace not already declared?
       $document->getDocument->documentElement->setNamespace("http://omdoc.org/ns","omdoc",0); }
     my $symdef_scope=$parent->exists('ancestor::omdoc:rendering'); #Are we in a \symdef rendering?
     if (($localpres =~/^LaTeXML::Token/) && $symdef_scope) {
       #Note: We should probably ask Bruce whether this maneuver makes sense
       # We jump back to digestion, at a processing stage where it has been already completed
       # Hence need to reinitialize all scopes and make a new group. This is probably expensive to do.
 
       my @toks = $localpres->unlist;
       while(@toks && $toks[0]->equals(T_SPACE)){ shift(@toks); }  # Remove leading space
       my $formatters = join("|",@PresFormatters);
       $formatters = qr/$formatters/;
       $wrapped = (@toks && ($toks[0]->toString =~ /^\\($formatters)$/));
       $localpres = Invocation(T_CS('\@use'),$localpres) unless $wrapped;
       # Plug in the provided arguments, doing a nasty reversion:
       my @sargs = map (Tokens($_->revert),  @args);
       $localpres = Tokens(LaTeXML::Expandable::substituteTokens($localpres,@sargs)) if $nargs>0;
       #Digest:
       my $stomach = $STATE->getStomach;
       $stomach->beginMode('inline-math');
       $STATE->activateScope($scope);
       use_module($module);
       use_module(LookupValue("parent_of_".$module)) if LookupValue("parent_of_".$module);
       $localpres=$stomach->digest($localpres);
       $stomach->endMode('inline-math');
     }
     else { #Some are already digested to Whatsit, usually when dropped from a wrapping constructor
     }
     if ($nargs == 0) {
       if (!$symdef_scope) { #Simple case - discourse flow, only a single XMTok
         #Referencing XMTok when not in \symdefs:
         $document->insertElement('ltx:XMTok',undef,(name=>$cs->toString, meaning=>$name,omcd=>$cd,role => $role,scriptpos=>$prs{'scriptpos'}));
       }
       else {
         if ($symdef_scope && ($localpres =~/^LaTeXML::Whatsit/) && (!$wrapped)) {#1. Simple case: converts to a single token
           $localpres->setProperties((name=>$cs->toString, meaning=>$name,omcd=>$cd,role => $role,scriptpos=>$prs{'scriptpos'}));
         }
         else {
           #Experimental treatment - COMPLEXTOKEN
           #$role=$role||'COMPLEXTOKEN';
           #$document->openElement('ltx:XMApp',role=>'COMPLEXTOKEN');
           #$document->insertElement('ltx:XMTok',undef,(name=>$cs->toString, meaning=>$name, omcd=>$cd, role=>$role, scriptpos=>$prs{'scriptpos'}));
           #$document->openElement('ltx:XMWrap');
           #$document->absorb($localpres);
           #$document->closeElement('ltx:XMWrap');
           #$document->closeElement('ltx:XMApp');
         }
         #We need expanded presentation when invoked in \symdef scope:
 
         #Suppress errors from rendering attributes when absorbing.
         #This is bad style, but we have no way around it due to the digestion acrobatics.
         my $verbosity = $LaTeXML::Global::STATE->lookupValue('VERBOSITY');
         my $errors = $LaTeXML::Global::STATE->getStatus('error');
         $LaTeXML::Global::STATE->assignValue('VERBOSITY',-5);
 
         #Absorb presentation:
         $document->absorb($localpres);
 
         #Return to original verbosity and error state:
         $LaTeXML::Global::STATE->assignValue('VERBOSITY',$verbosity);
         $LaTeXML::Global::STATE->setStatus('error',$errors);
 
         #Strip all/any <rendering><Math><XMath> wrappers:
         #TODO: Ugly LibXML work, possibly do something smarter
         my $parent = $document->getNode;
         my @renderings=$parent->findnodes(".//omdoc:rendering");
         foreach my $render(@renderings) {
           my $content=$render;
           while ($content && $content->localname =~/^rendering|[X]?Math/) {
             $content = $content->firstChild;
           }
           my $sibling = $content->parentNode->lastChild;
           my $localp = $render->parentNode;
           while ((defined $sibling) && (!$sibling->isSameNode($content))) {
             my $clone = $sibling->cloneNode(1);
             $localp->insertAfter($clone,$render);
             $sibling = $sibling->previousSibling;
           }
           $render->replaceNode($content);
         }
       }
     }
     else {#2. Constructors with arguments
       if (!$symdef_scope) { #2.1 Simple case, outside of \symdef declarations:
         #Referencing XMTok when not in \symdefs:
         my %ic = ($icvariant ne 'default') ? (ic=>'variant:'.$icvariant) : ();
         $document->openElement('ltx:XMApp',%ic,scriptpos=>$prs{'scriptpos'},role=>$prs{'isbound'});
         $document->insertElement('ltx:XMTok',undef,(name=>$cs->toString, meaning=>$name, omcd=>$cd, role=>$role, scriptpos=>$prs{'operator_scriptpos'}));
         foreach my $carg (@args) {
           if ($carg =~/^LaTeXML::Token/) {
             my $stomach = $STATE->getStomach;
             $stomach->beginMode('inline-math');
             $carg=$stomach->digest($carg);
             $stomach->endMode('inline-math');
           }
           $document->openElement('ltx:XMArg');
           $document->absorb($carg);
           $document->closeElement('ltx:XMArg');
         }
         $document->closeElement('ltx:XMApp');
       }
       else { #2.2 Complex case, inside a \symdef declaration
         #We need expanded presentation when invoked in \symdef scope:
 
         #Suppress errors from rendering attributes when absorbing.
         #This is bad style, but we have no way around it due to the digestion acrobatics.
         my $verbosity = $LaTeXML::Global::STATE->lookupValue('VERBOSITY');
         my $errors = $LaTeXML::Global::STATE->getStatus('error');
         $LaTeXML::Global::STATE->assignValue('VERBOSITY',-5);
 
         #Absorb presentation:
         $document->absorb($localpres);
 
         #Return to original verbosity and error state:
         $LaTeXML::Global::STATE->assignValue('VERBOSITY',$verbosity);
         $LaTeXML::Global::STATE->setStatus('error',$errors);
 
         #Strip all/any <rendering><Math><XMath> wrappers:
         #TODO: Ugly LibXML work, possibly do something smarter?
         my $parent = $document->getNode;
         if(! defined $parent->lookupNamespacePrefix("http://omdoc.org/ns")){ # namespace not already declared?
           $document->getDocument->documentElement->setNamespace("http://omdoc.org/ns","omdoc",0); }
         my @renderings=$parent->findnodes(".//omdoc:rendering");
         foreach my $render(@renderings) {
           my $content=$render;
           while ($content && $content->localname =~/^rendering|[X]?Math/) {
             $content = $content->firstChild;
           }
           my $sibling = $content->parentNode->lastChild;
           my $localp = $render->parentNode;
           while ((defined $sibling) && (!$sibling->isSameNode($content))) {
             my $clone = $sibling->cloneNode(1);
             $localp->insertAfter($clone,$render);
             $sibling = $sibling->previousSibling;
           }
           $render->replaceNode($content);
         }
       }
     }},
   properties => {name=>$cs->toString, meaning=>$name,omcd=>$cd,role => $role},
   scope=>$scope,
   beforeDigest => sub{
     my ($gullet, $variant) = @_;
     my $icvariant = ToString($variant);
     my $localpres = $presentation;
     if ($icvariant && $icvariant ne 'default') {
       $localpres = LookupValue($cs->toString."$icvariant:pres");
       if (!$localpres) {
         Error("No variant named '$icvariant' found! Falling back to ".
         "default.\n Please consider introducing \\symvariant{".
         $cs->toString."}[$nargs]{$icvariant}{... your presentation ...}");
         $localpres = $presentation;
       }
     }
     my $count = LookupValue(ToString($cs).'_counter') || 0;
     AssignValue(ToString($cs).":pres:$count",$localpres);
     AssignValue(ToString($cs).'_counter',$count+1);
     return;
   },
   afterDigest => sub{
     my ($stomach,$whatsit) = @_;
     my $count = LookupValue(ToString($cs).'_aftercounter') || 0;
     $whatsit->setProperty('presentation',LookupValue(ToString($cs).":pres:$count"));
     AssignValue(ToString($cs).'_aftercounter',$count+1);
   });
   return; });
%</ltxml>%$ 
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\symvariant}
%   |\symvariant{|\meta{sym}|}[|\meta{args}|]{|\meta{var}|}{|\meta{cseq}|}| just extends
%   the internal macro |\modules@|\meta{sym}|@pres@| defined by
%   |\symdef{|\meta{sym}|}[|\meta{args}|]{|\ldots|}| with a variant
%   |\modules@|\meta{sym}|@pres@|\meta{var} which expands to \meta{cseq}. Recall that this
%   is called by the macro |\|\meta{sym}|[|\meta{var}|]| induced by the
%   |\symdef|.\ednote{MK@DG: this needs to
%   be implemented in LaTeXML}
%    \begin{macrocode}
%<*package>
\def\symvariant#1{\@ifnextchar[{\@symvariant{#1}}{\@symvariant{#1}[0]}}
\def\@symvariant#1[#2]#3#4{%
\expandafter\mod@newcommand\csname modules@#1@pres@#3\endcsname[#2]{#4}%
%    \end{macrocode}
% and if we are in a named module, then we need to export the function
% |\modules@|\meta{sym}|@pres@|\meta{opt} just as we have done that in |\symdef|.
%    \begin{macrocode}
\@ifundefined{mod@id}{}{%
\expandafter\g@addto@macro\this@module%
{\expandafter\mod@newcommand\csname modules@#1@pres@#3\endcsname[#2]{#4}}}}%
%</package>
%<*ltxml>
 DefMacro('\symvariant{}[]{}{}', sub {
  my($self,@args)=@_;
  my $prestok = Invocation(T_CS('\@symvariant@pres'), @args);
  pop @args; push @args, $prestok;
  Invocation(T_CS('\@symvariant@construct'),@args)->unlist;
});
 DefMacro('\@symvariant@pres{}[]{}{}', sub {
   my($self,$cs,$nargs,$ic,$presentation)=@_;
   symdef_presentation_pmml($cs,ToString($nargs)||0,$presentation);
 });
 DefConstructor('\@symvariant@construct{}[]{}{}', sub {
  my($document,$cs,$nargs,$icvariant,$presentation)=@_;
  $cs = ToString($cs);
  $nargs = ToString($nargs);
  $icvariant = ToString($icvariant);
  # Save presentation for future reference:
  #Notation created by \symdef
  #Create the rendering at the right place:
  my $cnode = $document->getNode;
  my $root = $document->getDocument->documentElement;
  my $name = LookupValue("symdef.".ToString($cs).".name") || $cs;
  # Fix namespace (the LibXML XPath problems...)
  $root->setNamespace("http://omdoc.org/ns","omdoc",0);
  my ($notation) = $root->findnodes(".//omdoc:notation[\@name='$name' and ".
                                    "preceding-sibling::omdoc:symbol[1]/\@name
                                    = '$name']");
  if (!$notation) {
    #No symdef found, raise error:
    Error("No \\symdef found for \\$cs! Please define symbol prior to introducing variants!");
    return;
  }
  $document->setNode($notation);
  $document->absorb($presentation);
  $notation->lastChild->setAttribute("ic","variant:$icvariant");
  $document->setNode($cnode);
  return;
 },
 beforeDigest => sub {
    my($gullet,$cs,$nargs,$icvariant,$presentation)=@_;
    $cs = ToString($cs);
    $icvariant = ToString($icvariant);
    AssignValue("$cs:$icvariant:pres",Digest($presentation),'module:'.LookupValue('current_module'));
 });
 #mode=>'math'
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\resymdef}
%   This is now deprecated.
%    \begin{macrocode}
%<*package>
\def\resymdef{\@ifnextchar[{\@resymdef}{\@resymdef[]}}
\def\@resymdef[#1]#2{\@ifnextchar[{\@@resymdef[#1]{#2}}{\@@resymdef[#1]{#2}[0]}}
\def\@@resymdef[#1]#2[#3]#4{\PackageError{modules}
  {The \protect\resymdef macro is deprecated,\MessageBreak
    use the \protect\symvariant instead!}}
%</package>
%    \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
%</package>
%<*ltxml>
DefPrimitive('\abbrdef OptionalKeyVals:symdef {}[]{}', sub {
  my($stomach,$keys,$cs,$nargs,$presentation)=@_;
  my $module = LookupValue('current_module');
  my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":$module";
  DefMacroI("\\".$cs->toString,convertLaTeXArgs($nargs,''),$presentation,
	   scope=>$scope);
  return; });
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Symbol and Concept Names}\label{sec:impl:concepts}
%
% \begin{macro}{\mod@path} 
%   the |\mod@path| macro is used to remember the local path, so that the |module|
%   environment can set it for later cross-referencing of the modules. If |\mod@path| is
%   empty, then it signifies the local file.
%    \begin{macrocode}
%<*package>
\def\mod@path{}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\termdef} 
%    \begin{macrocode}
%<*package>
\def\mod@true{true}
\addmetakey[false]{termdef}{local}
\addmetakey{termdef}{name}
\newcommand{\termdef}[3][]{\metasetkeys{termdef}{#1}%
\expandafter\mod@newcommand\csname#2\endcsname[0]{#3\xspace}%
\ifx\termdef@local\mod@true\else%
\@ifundefined{mod@id}{}{\expandafter\g@addto@macro\this@module%
{\expandafter\mod@newcommand\csname#2\endcsname[0]{#3\xspace}}}%
\fi}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\capitalize} 
%    \begin{macrocode}
%<*package>
\def\@captitalize#1{\uppercase{#1}}
\newcommand\capitalize[1]{\expandafter\@captitalize #1}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@termref} 
%   |\mod@termref{|\meta{module}|}{|\meta{name}|}{|\meta{nl}|}| determines whether the
%   macro |\|\meta{module}|@cd@file@base| is defined. If it is, we make it the prefix of a
%   URI reference in the local macro |\@uri|, which we compose to the hyper-reference,
%   otherwise we give a warning.
%    \begin{macrocode}
%<*package>
\def\mod@termref#1#2#3{\def\@test{#3}
\@ifundefined{#1@cd@file@base}
    {\protect\G@refundefinedtrue
      \@latex@warning{\protect\termref with unidentified cd "#1": the cd key must
        reference an active module}
      \def\@label{sref@#2 @target}}
  {\def\@label{sref@#2@#1@target}}%
\expandafter\ifx\csname #1@cd@file@base\endcsname\@empty% local reference
\sref@hlink@ifh{\@label}{\ifx\@test\@empty #2\else #3\fi}\else%
\def\@uri{\csname #1@cd@file@base\endcsname.pdf\#\@label}%
\sref@href@ifh{\@uri}{\ifx\@test\@empty #2\else #3\fi}\fi}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Dealing with Multiple Files}\label{sec:impl:multiple}
%
% Before we can come to the functionality we want to offer, we need some auxiliary
% functions that deal with path names. 
% 
% \subsubsection{Simplifying Path Names}
% 
% The |\mod@simplify| macro is used for simplifying
% path names by removing \meta{xxx}|/..| from a string. eg:
% \meta{aaa}|/|\meta{bbb}|/../|\meta{ddd} goes to \meta{aaa}|/|\meta{ddd} unless
% \meta{bbb} is |..|. This is used to normalize relative path names below.
%
% \begin{macro}{\mod@simplify}
%   The macro |\mod@simplify| recursively runs over the path collecting the result in the
%   internal |\mod@savedprefix| macro.
%    \begin{macrocode}
%<*package>
\def\mod@simplify#1{\expandafter\mod@simpl#1/\relax}
%    \end{macrocode}
% It is based on the |\mod@simpl| macro\ednote{what does the mod@blaaa do?}
%    \begin{macrocode}
\def\mod@simpl#1/#2\relax{\def\@second{#2}%
\ifx\mod@blaaaa\@empty\edef\mod@savedprefix{}\def\mod@blaaaa{aaa}\else\fi%
\ifx\@second\@empty\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@updir{..}
\def\mod@simplhelp#1/#2/#3\relax{\def\@first{#1}\def\@second{#2}\def\@third{#3}%
%\message{mod@simplhelp: first=\@first, second=\@second, third=\@third, result=\mod@savedprefix.}
\ifx\@third\@empty% base case
\ifx\@second\mod@updir\else%

\ifx\mod@second\@empty\edef\mod@savedprefix{\mod@savedprefix#1}%
\else\edef\mod@savedprefix{\mod@savedprefix#1/#2}%
\fi%
\fi%
\else%
\ifx\@first\mod@updir%
\edef\mod@savedprefix{\mod@savedprefix#1/}\mod@simplhelp#2/#3\relax%
\else%
\ifx\@second\mod@updir\mod@simpl#3\relax%
\else\edef\mod@savedprefix{\mod@savedprefix#1/}\mod@simplhelp#2/#3\relax%
\fi%
\fi%
\fi}%
%</package>
%    \end{macrocode}
% \end{macro}
%
% We directly test the simplification: \makeatletter
% \def\mod@simpl@test#1{\def\mod@savedprefix{}\mod@simplify{#1}\mod@savedprefix}
% \begin{center}
% \begin{tabular}{|l|l|l|}\hline
%   source       & result                          & should be \\\hline\hline
% ../../aaa      & \mod@simpl@test{../../aaa}      &  ../../aaa\\\hline
% aaa/bbb        & \mod@simpl@test{aaa/bbb}        & aaa/bbb\\\hline
% aaa/..         & \mod@simpl@test{aaa/..}         & \\\hline
% ../../aaa/bbb  & \mod@simpl@test{../../aaa/bbb}  & ../../aaa/bbb\\\hline
% ../aaa/../bbb  & \mod@simpl@test{../aaa/../bbb}  &  ../bbb\\\hline
% ../aaa/bbb  & \mod@simpl@test{../aaa/bbb}  &  ../aaa/bbb\\\hline
% aaa/bbb/../ddd & \mod@simpl@test{aaa/bbb/../ddd} & aaa/ddd\\\hline
% \end{tabular}
% \end{center}
% \makeatother
%
% \begin{macro}{\defpath}
%    \begin{macrocode}
%<*package>
\newcommand{\defpath}[2]{\expandafter\newcommand\csname #1\endcsname[1]{#2/##1}}
%</package>
%<*ltxml>
DefMacro('\defpath{}{}', sub {
	   my ($gullet,$arg1,$arg2)=@_;
	   $arg1 = ToString($arg1);
	   $arg2 = ToString($arg2);
	   my $paths = LookupValue('defpath')||{};
	   $$paths{"$arg1"}=$arg2;
	   AssignValue('defpath'=>$paths,'global');
	   DefMacro('\\'.$arg1.' Semiverbatim',$arg2."/#1");
	 });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Loading Module Signatures}
%
% We will need a switch\ednote{explain why?}
%    \begin{macrocode}
%<*package>
\newif\ifmodules
%    \end{macrocode}
% and a ``registry'' macro whose expansion represents the list of added macros (or files)
% \begin{macro}{\mod@reg}
%    We initialize the |\mod@reg| macro with the empty string.
%    \begin{macrocode}
\gdef\mod@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 |\mod@reg| macro in the following way:  |string@\mod@reg|.
%    \begin{macrocode}
\def\mod@update#1{\ifx\mod@reg\@empty\xdef\mod@reg{#1}\else\xdef\mod@reg{#1@\mod@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 |\ifmodules| true, otherwise make |\ifmodules| false. The macro |\mod@search|
%   will look at |\ifmodules| and update the registry for |\modulestrue| or do nothing for
%   |\modulesfalse|.
%    \begin{macrocode}
\def\mod@check#1@#2///#3\relax{%
\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\@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\mod@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\mod@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 updates the path prefix |\mod@prefix| with the last word in the path given
%    in its argument. 
%    \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| macro 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{macro}{\mod@updatedpost}
%    This macro updates |\mod@savedprefix| with leading path (all but the last word) in the path given
%    in its argument. 
%    \begin{macrocode}
\def\mod@updatedpost#1{%
\edef\mod@savedprefix{\mod@savedprefix\mod@pathpostfix@check#1/\relax}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@updatedsms}
% Finally: A 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}
% \end{macro}
% 
% \subsubsection{Selective Inclusion}
%
% \begin{macro}{\requiremodules}
%    \begin{macrocode}
%<*package>
\newcommand\requiremodules[1]{%
{\mod@showfalse% save state and ensure silence while reading sms
\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\mod@reg% use to compare, in case the .sms file was loaded before
\mod@search{\mod@savedprefix}% update registry
\ifx\newreg\mod@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('file_'.$module.'_loaded')) {}
  else {
    AssignValue('file_'.$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\mod@reg% use to compare, in case the .sms file was loaded before
\mod@search{\mod@savedprefix}% update registry
\ifx\newreg\mod@reg%\message{This file has been previously introduced}
\else\input{\mod@savedprefix}%
\fi}}
%</package>
%<*ltxml>
DefPrimitive('\sinput Semiverbatim', sub {
  my($stomach,$module)=@_;
  my $GULLET = $stomach->getGullet;
  $module = Digest($module)->toString;
  AssignValue('file_'.$module.'_loaded' => 1, 'global');
  $stomach->bgroup;
  AssignValue('last_module_path', $module);
  $GULLET->unread(Invocation(T_CS('\end@requiredmodule'),Tokens(Explode($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.}
%
%    \begin{macrocode}
%<*package>
\let\sinputref=\sinput
\let\inputref=\input
%</package>
%<*ltxml> 
DefConstructor('\sinputref{}',"<omdoc:oref href='#1.omdoc' class='expandable'/>");
DefConstructor('\inputref{}',"<omdoc:oref href='#1.omdoc' class='expandable'/>");
%</ltxml>
%    \end{macrocode}
% 
% \subsubsection{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,$presentation)=@_;

  my($name,$cd,$role)=$keys
   && map($_ && $_->toString,map($keys->getValue($_), qw(name cd role)));
  $cd = LookupValue('module_cd') unless $cd;
  $name = $cs unless $name;
  AssignValue('module_name'=>$name) if $name;
  $nargs = 0 unless ($nargs);
  my $nargkey = ToString($name).'_args';
  AssignValue($nargkey=>ToString($nargs)) if $nargs;
  $name=ToString($name);
  
  Invocation(T_CS('\@symdef@pres@aux'),
     $cs,
     ($nargs || Tokens(T_OTHER(0))),
     symdef_presentation_pmml($cs,ToString($nargs)||0,$presentation),
     (Tokens(Explode($name))),
     (Tokens(Explode($cd))),
     $keys)->unlist; });#$
%    \end{macrocode}
% Generate the expansion of a symdef's macro using special arguments.
%
% Note that the |symdef_presentation_pmml| subroutine is responsible for preserving the
% rendering structure of the original definition. Hence, we keep a
% collection of all known formatters in the |@PresFormatters| array,
% which should be updated whenever the list of allowed formatters has
% been altered.
%
%    \begin{macrocode}
sub symdef_presentation_pmml {
  my($cs,$nargs,$presentation)=@_;
  my @toks = $presentation->unlist;
  while(@toks && $toks[0]->equals(T_SPACE)){ shift(@toks); }  # Remove leading space
  $presentation = Tokens(@toks);
  # Wrap with \@use, unless already has a recognized formatter.
  my $formatters = join("|",@PresFormatters);
  $formatters = qr/$formatters/;
  $presentation = Invocation(T_CS('\@use'),$presentation)
    unless (@toks && ($toks[0]->toString =~ /^\\($formatters)$/));
  # Low level substitution.
  my @args =
  map(Invocation(T_CS('\@SYMBOL'),T_OTHER("arg:".($_))),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}
sub  getSymmdefProperties {
  my $cd = LookupValue('module_cd');
  my $name = LookupValue('module_name');
  my $nargkey = ToString($name).'_args';
  my $nargs = LookupValue($nargkey);
  $nargs = 0 unless ($nargs);
  my %props = ('cd'=>$cd,'name'=>$name,'nargs'=>$nargs);
  return %props;}
DefConstructor('\@use{}', sub{
  my ($document,$args,%properties) = @_;
  #Notation created at \@symdef@pres@aux
  #Create the rendering:
  $document->openElement('omdoc:rendering');
  $document->openElement('ltx:Math');
  $document->openElement('ltx:XMath');
  if ($args->isMath) {$document->absorb($args);}
  else {  $document->insertElement('ltx:XMText',$args);}
  $document->closeElement('ltx:XMath');
  $document->closeElement('ltx:Math');
  $document->closeElement('omdoc:rendering');
},
properties=>sub { getSymmdefProperties($_[1]);},
               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)=@_;
   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', sub {
  my ($document,$cs,$nargs,$pmml,$name,$cd,$keys)=@_;
  my $assocarg = ToString($keys->getValue('assocarg')) if $keys;
  $assocarg = $assocarg||"0";
  my $bvars = ToString($keys->getValue('bvars')) if $keys;
  $bvars = $bvars||"0";
  my $bvar = ToString($keys->getValue('bvar')) if $keys;
  $bvar = $bvar||"0";
  my $appElement = 'om:OMA'; $appElement = 'om:OMBIND' if ($bvars || $bvar);
  my $root = $document->getDocument->documentElement;
  my $name_str = ToString($name);
  my ($notation) = $root->findnodes(".//omdoc:notation[\@name='$name_str' and ".
                                    "preceding-sibling::omdoc:symbol[1]/\@name
                                    = '$name_str']");
  if (!$notation) {
    $document->insertElement("omdoc:symbol",undef,(name=>$name,"xml:id"=>$name_str.".sym"));
  }
   $document->openElement("omdoc:notation",(name=>$name,cd=>$cd));
   #First, generate prototype:
   $nargs = ToString($nargs)||0;
   $document->openElement('omdoc:prototype');
   $document->openElement($appElement) if $nargs;
   my $cr="fun" if $nargs;
   $document->insertElement('om:OMS',undef,
    (cd=>$cd,
     name=>$name,
     "cr"=>$cr));
   if ($bvar || $bvars) {
     $document->openElement('om:OMBVAR');
     if ($bvar) {
       $document->insertElement('omdoc:expr',undef,(name=>"arg$bvar"));
     } else {
       $document->openElement('omdoc:exprlist',(name=>"args"));
       $document->insertElement('omdoc:expr',undef,(name=>"arg"));
       $document->closeElement('omdoc:exprlist');       
     }
     $document->closeElement('om:OMBVAR');
   }
   for my $id(1..$nargs) {
     next if ($id==$bvars || $id==$bvar);
     if ($id!=$assocarg) {
       my $argname="arg$id";
       $document->insertElement('omdoc:expr',undef,(name=>"$argname"));
     }
     else {
       $document->openElement('omdoc:exprlist',(name=>"args"));
       $document->insertElement('omdoc:expr',undef,(name=>"arg"));
       $document->closeElement('omdoc:exprlist');
     }
   }
   $document->closeElement($appElement) if $nargs;
   $document->closeElement('omdoc:prototype');
   #Next, absorb rendering:
   $document->absorb($pmml);
   $document->closeElement("omdoc:notation");
 }, afterDigest=>sub { my ($stomach, $whatsit) = @_;
  my $keys = $whatsit->getArg(6);
  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}
%</package>
%<*ltxml>
DefConstructor('\requirepackage{} Semiverbatim',"<omdoc:imports from='#2'/>",
       afterDigest=>sub { my ($stomach, $whatsit) = @_;
  my $select = $whatsit->getArg(1);
  RequirePackage($select->toString); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Views}\label{sec:impl:views}
% 
% We first prepare the ground by defining the keys for the |view| environment.
%    \begin{macrocode}
%<*package>
\srefaddidkey{view}
\addmetakey*{view}{title}
\define@key{view}{load}{\requiremodules{#1}}
%    \end{macrocode}
%
% \begin{macro}{\view@heading}
%   Then we make a convenience macro for the view heading. This can be customized. 
%    \begin{macrocode}
\newcounter{view}[section]
\newcommand\view@heading[2]{\stepcounter{view}%
{\textbf{View} \thesection.\theview: from #1 to #2}%
\sref@label@id{View \thesection.\theview}%
\ifx\view@title\@empty :\quad\else\quad(\view@title)\hfill\\\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{view}
% The |view| environment only has an effect if the |showmods| option is set. 
%    \begin{macrocode}
\ifmod@show\newsavebox{\viewbox} 
\newenvironment{view}[3][]{\metasetkeys{view}{#1}\sref@target\stepcounter{view}
\begin{lrbox}{\viewbox}\begin{minipage}{.9\textwidth}
\importmodule{#1}\importmodule{#2}\gdef\view@@heading{\view@heading{#2}{#3}}}
{\end{minipage}\end{lrbox}
\setbox0=\hbox{\begin{minipage}{.9\textwidth}%
\noindent\view@@heading\rm%
\end{minipage}}
\smallskip\noindent\fbox{\vbox{\box0\vspace*{.2em}\usebox\viewbox}}\smallskip}
\else\newxcomment[]{view}\fi%ifmod@show
%</package>
%<*ltxml>
DefKeyVal('view','id','Semiverbatim');
DefEnvironment('{view} OptionalKeyVals:view {}{}',
   "<omdoc:theory-inclusion from='#2' to='#3'>"
  .  "<omdoc:morphism>#body</omdoc:morphism>"
  ."</omdoc:theory-inclusion>");
%</ltxml>
%    \end{macrocode}
% \end{environment}
% 
% \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 issue 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}
% \end{macro}
% 
% \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{Providing IDs for {\omdoc} Elements}\label{sec:impl:ids}
% 
%   To provide default identifiers, we tag all {\omdoc} elements that allow |xml:id|
%   attributes by executing the |numberIt| procedure below.
% 
%    \begin{macrocode}
%<*ltxml>
Tag('omdoc:recurse',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:imports',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:theory',afterOpen=>\&numberIt,afterClose=>\&locateIt);
%</ltxml>
%    \end{macrocode}
%
% \subsection{Experiments}
% In this section we develop experimental functionality. Currently support for complex
% expressions, see
% \url{https://svn.kwarc.info/repos/stex/doc/blue/comlex_semmacros/note.pdf} for details.
%
% \begin{macro}{\csymdef}
% For the {\LaTeX} we use |\symdef| and forget the last argument. The code here is just
% needed for parsing the (non-standard) argument structure. 
%    \begin{macrocode}
%<*package>
\def\csymdef{\@ifnextchar[{\@csymdef}{\@csymdef[]}}
\def\@csymdef[#1]#2{\@ifnextchar[{\@@csymdef[#1]{#2}}{\@@csymdef[#1]{#2}[0]}}
\def\@@csymdef[#1]#2[#3]#4#5{\@@symdef[#1]{#2}[#3]{#4}}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\notationdef}
% For the {\LaTeX} side, we just make |\notationdef| invisible.
%    \begin{macrocode}
%<*package>
\def\notationdef[#1]#2#3{}
%</package>
%<*ltxml>
%</ltxml>
%    \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}
% 
% \Finale
\endinput
%%% 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  iffalse importOMDocmodule
% 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 cr
% LocalWords:  DefConstructor afterDigest setProperties undef tok PARAM thyid
% LocalWords:  getString showfalse showtrue xcomment stex srcref KeyVal omext
% LocalWords:  beginItemize getProperty introdcue afterOpen numberIt Tokenize
% LocalWords:  OptionalSemiverbatim omdocmod PushValue assocarg getStomach prs
% LocalWords:  begingroup beginMode endMode endgroup insertElement resymdef sym
% LocalWords:  updir nargkey PresFormatters mixfixaii formatters argname expr
% LocalWords:  getSymmdefProperties XMath mcdcr exprlist recurse texttt scsys
% LocalWords:  textbackslash newcommand providecommand sc sc mathml openmath nx
% LocalWords:  latexml cmathml activemath twintoo atwin atwintoo mathcal Deyan
% LocalWords:  mathcal fileversion Ginev maketitle  newpage infty ulsmf08 exfig
% LocalWords:  omsemmac lstset basicstyle scriptsize aboveskip belowskip hline
% LocalWords:  morekeywords lstlisting csymbol showviews showviews foo exf cseq
% LocalWords:  qualifiedimports qualifiedimports termdef textbf filepath RabKoh
% LocalWords:  symname varSmoothfunctionsOn ednote abbrdef Sumfromto semmodule
% LocalWords:  vspace hrule vspace arith arbitraryn xbool oplus xdisjunction tw
% LocalWords:  emph captitalize ldots termref termref symref symref ctancite nc
% LocalWords:  smms hyperref RahObe hmlmh10 widehat texmf.cnf requiremodules cs
% LocalWords:  sinput sinputref sinputref defpath defpath defpath cname csname
% LocalWords:  OPhats usepackage importqualified Crossreferencing jobname ltxml
% LocalWords:  jobname printbibliography textsf langle textsf langle textlangle
% LocalWords:  textrangle textlangle newif ifmod qualifiedfalse qualifiedtrue
% LocalWords:  sref xspace expandafter noexpand endcsname namedef setkeys ifx
% LocalWords:  newenvironment parentmod usemodule ifundefined coolurion cooluri
% LocalWords:  coolurioff cwd ouri ifdefinable testopt ifnextchar xargdef bvars
% LocalWords:  argdef yargdef somefunction symdeflocaltrue bvar xpath assoc qr
% LocalWords:  symdeflocalfalse localpres isbound symdefs COMPLEXTOKEN localp
% LocalWords:  findnodes localname carg renewcommand bbb showmeta showmeta exp
% LocalWords:  refundefinedtrue subsubsection blaaa makeatletter makeatother rm
% LocalWords:  ifmodules gdef xdef xdef modulestrue modulesfalse pathpostfix
% LocalWords:  updatedsms newreg xref texorpdfstring srefaddidkey newsavebox
% LocalWords:  viewbox newcounter thesection theview theproblem hfill lrbox
% LocalWords:  stepcounter textwidth hbox noindent smallskip fbox vbox usebox
% LocalWords:  smallskip newxcomment vassign ensuremath mapsto doctex tocdepth
% LocalWords:  setcounter tableofcontents mathbb symvariant importmodulevia
% LocalWords:  importmodulevia compactdesc tassign tassign tname source-tname
% LocalWords:  ttassign metakeys addmetakey themodule metasetkeys aftergroup
% LocalWords:  groupling requation IMPORTCD CURRENTCD bindargs defmathop cnode
% LocalWords:  icvariant aftercounter prestok inputref oref loadfrom loadto
% LocalWords:  csymdef notationdef
