summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/stex/modules/modules.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/stex/modules/modules.dtx')
-rw-r--r--Master/texmf-dist/source/latex/stex/modules/modules.dtx2252
1 files changed, 826 insertions, 1426 deletions
diff --git a/Master/texmf-dist/source/latex/stex/modules/modules.dtx b/Master/texmf-dist/source/latex/stex/modules/modules.dtx
index 8f155971333..b65107d2aa6 100644
--- a/Master/texmf-dist/source/latex/stex/modules/modules.dtx
+++ b/Master/texmf-dist/source/latex/stex/modules/modules.dtx
@@ -1,16 +1,16 @@
% \iffalse meta-comment
% An Infrastructure for Semantic Macros and Module Scoping
-% Copyright (C) 2004-2010 Michael Kohlhase, all rights reserved
+% Copyright (C) 2004-2013 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 $
+% The original of this file is in the public repository at
+% http://github.com/KWARC/sTeX/
% \fi
%
% \iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
-%<package>\ProvidesPackage{modules}[2012/01/28 v1.1 Semantic Markup]
+%<package>\ProvidesPackage{modules}[2016/04/07 v1.4 Semantic Markup]
%
%<*driver>
\documentclass{ltxdoc}
@@ -18,14 +18,15 @@
\usepackage{url,array,float,textcomp}
\usepackage[show]{ed}
\usepackage[hyperref=auto,style=alphabetic]{biblatex}
+\addbibresource{kwarcpubs.bib}
+\addbibresource{extpubs.bib}
+\addbibresource{kwarccrossrefs.bib}
+\addbibresource{extcrossrefs.bib}
\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}
+\usepackage{ctangit}
+\usepackage{xspace}
+\usepackage{hyperref}
\makeindex
\floatstyle{boxed}
\newfloat{exfig}{thp}{lop}
@@ -35,7 +36,7 @@
%</driver>
% \fi
%
-% \CheckSum{941}
+% \CheckSum{802}
%
% \changes{v0.9}{2005/06/14}{First Version with Documentation}
% \changes{v0.9a}{2005/07/01}{Completed Documentation}
@@ -53,11 +54,23 @@
% \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.}
+% \changes{v1.1}{2012/06/25}{adding additional keys for the \texttt{\textbackslash symdef}
+% macro and exporting them to OMDoc}
+% \changes{v1.1}{2012/07/06}{exporting requiremodules to the \texttt{aux} file, so that
+% they are preloaded (pre-required) so semantic macros in section titles can work.}
+% \changes{v1.1}{2012/11/09}{Moving LaTeXML bindings into \texttt{modules.sty.ltxml} and
+% disabling generation}
+% \changes{v1.2}{2013/08/25}{No longer loading the aux file at the end of the document}
+% \changes{v1.3}{2013/12/12}{adding MathHub support}
+% \changes{v1.4}{2015/03/31}{Completely revamped importing modules this is much faster now,
+% but can no longer do relative paths.}
+% \changes{v1.4}{2015/04/02}{deprecated \texttt {\textbackslash sinput} and \texttt {\textbackslash sinputref}}
+% \changes{v1.5}{2015/11/02}{Moved MH Versions to a separate \texttt{mathhub} package}
%
% \GetFileInfo{modules.sty}
%
% \MakeShortVerb{\|}
-%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}\xspace}
% \def\xml{\scsys{Xml}}
% \def\mathml{\scsys{MathML}}
% \def\omdoc{\scsys{OMDoc}}
@@ -108,7 +121,7 @@
%
% 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
+% 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
@@ -145,12 +158,20 @@
%
% \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}.
+% The |modules| package takes two options: If we set
+% \DescribeMacro{showmods}|showmods|\ednote{This mechanism does not work yet, since we
+% cannot disable it when importing modules and that leads to unwanted boxes. What we need
+% to do instead is to tweak the sms utility to use an internal version that never shows
+% anything during sms reading.}, 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}. The option
+% \DescribeMacro{noauxreq}|noauxreq| prohibits the registration of |\@requiremodules|
+% commands in the |aux| file. They are necessary for preloading the module signatures so
+% that entries in the table of contents can have semantic macros; but as they sometimes
+% cause trouble the option allows to turn off preloading.
%
% If the \DescribeMacro{showmeta}|showmeta| is set, then the metadata keys are shown
% (see~\cite{Kohlhase:metakeys:ctan} for details and customization options).
@@ -177,10 +198,10 @@
% 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
+% \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.
+% 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
@@ -194,6 +215,9 @@
% good style to use |\symdef| and |\abbrdef|, if only to make switching between local and
% exported semantic macros easier.
%
+% Finally, the key \DescribeMacro{primary}|primary| (no value) can be given for primary
+% symbols.
+%
% \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
@@ -269,6 +293,107 @@
% 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{Testing Semantic Macros}\label{sec:user:testing}
+%
+% One of the problems in managing large module graphs with many semantic macros, so the
+% |module| package gives an infrastructure for unit testing. The first macro is
+% \DescribeMacro{\symtest}|\symtest|, which allows the author of a semantic macro to
+% generate test output (if the |symtest| option is set) see figure~\ref{fig:symtest} for a
+% ``tested semantic macro definition''.
+% \begin{exfig}
+% \begin{verbatim}
+% \symdef[name=setst]{SetSt}[2]{\{#1\,\vert\,#2\}}
+% \symtest[name=setst]{SetSt}{\SetSt{a}{a>0}}
+% \end{verbatim}
+% \vspace*{-2em} generates the output
+% \begin{module}[id=foo]
+% \symdef[name=setst]{SetSt}[2]{\{#1\,\vert\,#2\}}
+% \symtest[name=setst]{SetSt}{\SetSt{a}{a>0}}
+% \end{module}
+% \caption{A Semantic Macro Definition with Test}\label{fig:symtest}
+% \end{exfig}
+% Note that the language in this purely generated, so that it can be adapted (tbd).
+%
+% The \DescribeMacro{\abbrtest}|\abbrtest| macro gives the analogous functionality for
+% |\abbrdef|.
+%
+% \subsection{Axiomatic Assumptions}\label{sec:user:assumptions}
+%
+% In many ways, axioms and assumptions in definitions behave a lot like symbols
+% (see~\cite{RabKoh:WSMSML10} for discussion). Therefore we provide the macro
+% \DescribeMacro{\assdef}|\assdef| that can be used to mark up assumptions. Given a phrase
+% \meta{phrase} in a definition\ednote{only definitions?}, we can use
+% |\assdef{|\meta{name}|}{|\meta{phrase}|}| to give this the symbol name
+% \meta{name}.\ednote{continue}
+%
+% \subsection{Semantic Macros for Variables}\label{sec:user:semvars}
+%
+% Up to now, the semantic macros generated \openmath and \mathml markup where the heads of
+% the semantic macros become constants (the |OMS| and |csymbol| elements in
+% Figure~\ref{fig:omsemmac}). But sometimes we want to have semantic macros for variables,
+% e.g. to associate special notation conventions. For instance, if we want to define
+% mathematical structures from components as in Figure~\ref{fig:monoid}, where the
+% semigroup operation $\circ$ is a variable epistemologically, but is a $n$-ary
+% associative operator -- we are in a semigroup after all. Let us call such variables
+% \textbf{semantic variables} to contrast them from \textbf{semantic constants} generated
+% by |\symdef| and |\symvariant|.
+%
+%\begin{exfig}
+% \textbf{Definition 3.17} Let $\langle G,\circ\rangle$ be a semigroup, then we call
+% $e\in G$ a \textbf{unit}, iff $e\circ x=x\circ e=x$. A semigroup with unit $\langle
+% G,\circ,e\rangle$ is called a \textbf{monoid}.
+% \caption{A Definition of a Structure with ``semantic
+% variables''.}\label{fig:monoid}
+% \end{exfig}
+%
+% Semantic variables differ from semantic constants in two ways:
+% \begin{inparaenum}[\em i\rm)]
+% \item they do not participate
+% in the imports mechanism and
+% \item they generate markup with variables.
+% \end{inparaenum}
+% In the case of
+% Figure~\ref{fig:monoid} we (want to) have the \xml markup in Figure~\ref{fig:omsemvar}.
+% To associate the notation to the variables, we define semantic macros for them, here the
+% macro |\op| for the (semigroup) operation via the \DescribeMacro{\vardef}|\vardef|
+% macro. |\vardef| works exactly like, except
+% \begin{inparaenum}[\em i\rm)]
+% \item semantic variables are local to the current {\TeX} group and
+% \item they generate variable markup in the \xml
+% \end{inparaenum}
+%
+% \begin{exfig}\lstset{basicstyle=\scriptsize,aboveskip=-.5em,belowskip=-1.5em}
+% \begin{tabular}{l|p{9.7cm}}
+% \sTeX & \verb|\vardef{op}[1]{\assoc\circ{#1}}|\\\hline
+% \omdoc &
+% \begin{lstlisting}
+% <notation>
+% <prototype>
+% <OMA>
+% <OMV name="op"/>
+% <expr name="a1"/>
+% <expr name="a2"/>
+% </OMA>
+% </prototype>
+% <rendering>
+% <mrow>
+% <render name="a1"/>
+% <mo>&#x2384;</mo>
+% <render name="a2"/>
+% </mrow>
+% </rendering>
+% </notation>\end{lstlisting}\\\hline
+% \LaTeX & \verb|\op{x,e}| \\\hline
+% PDF/DVI & $x\circ e$\\\hline
+% {\openmath} & \lstset{morekeywords={OMA,OMV}}
+% \begin{lstlisting}
+% <OMA><OMV name="op"/><OMV name="x"/><OMV name="e"/></OMA>\end{lstlisting}\\\hline
+% {\mathml} & \lstset{morekeywords={apply,ci}}
+% \begin{lstlisting}
+% <apply><ci>op</ci><ci>x</ci><ci>e</ci></apply>\end{lstlisting}\\
+% \end{tabular}
+% \caption{Semantic Variables in {\openmath} and {\mathml}}\label{fig:omsemvar}
+% \end{exfig}
%
% \subsection{Symbol and Concept Names}\label{sec:user:termdef}
%
@@ -280,7 +405,7 @@
% 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
+% example, where we use the \DescribeMacro{\capitalize}|\capitalize| 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
@@ -295,7 +420,7 @@
%\begin{exfig}
% \begin{verbatim}
% \termdef[name=xor]{xdisjunction}{exclusive disjunction}
-% \captitalize\xdisjunction is commutative: $\xor{p}q=\xor{q}p$
+% \capitalize\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}
@@ -334,62 +459,15 @@
% |\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
+% macros. So |\importmodule[|load=\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.
+% current module.\ednote{MK: document the other keys of |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
+% 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.
@@ -411,7 +489,7 @@
% 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
+% utility |sms| (see Section~\ref{sec:limitations:sms}) 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.
@@ -427,9 +505,9 @@
%\begin{exfig}
% \begin{verbatim}
% \begin{module}[id=foo]
-% \importmodule[../other/bar]{bar}
-% \importmodule[../mycolleaguesmodules]{baz}
-% \importmodule[../other/bar]{foobar}
+% \importmodule[load=../other/bar]{bar}
+% \importmodule[load=../mycolleaguesmodules]{baz}
+% \importmodule[load=../other/bar]{foobar}
% ...
% \end{module}
% \end{verbatim}
@@ -470,33 +548,35 @@
% 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
+% The \DescribeMacro{\inputref}|\inputref| macro behaves just like |\input| 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{Using Semantic Macros in Narrative Structures}\label{sec:user:using}
%
+% The |\importmodule| macro establishes the inheritance relation, a transitive relation
+% among modules that governs visibility of semantic macros. In particular, it can only be
+% used in modules (and has to be used at the top-level, otherwise it is hindered by
+% {\LaTeX} groups). In many cases, we only want to \emph{use} the semantic macros in an
+% environment (and not re-export them). Indeed, this is the normal situation for most
+% parts of mathematical documents. For that \sTeX provides the
+% \DescribeMacro{\usemodule}|\usemodule| macro, which takes the same arguments as
+% |\importmodule|, but is treated differently in the \sTeX module signatures. A typical
+% situation is shown in Figure~\ref{fig:use-ring}, where we open the module |ring| (see
+% Figure~\ref{fig:ring}) and use its semantic macros (in the |omtext| environment). In
+% earlier versions of \sTeX, we would have to wrap the |omtext| environment in an
+% anonymous |module| environment to prevent re-export.
+%
+%\begin{exfig}
+% \begin{verbatim}
+% \begin{omtext}
+% \usemodule[../algebra/rings.tex]{ring}
+% We $R$ be a ring $(\rbase,\rplus,\rzero,\rminusOp,\rtimes,\rone)$, ...
+% \end{omtext}
+% \end{verbatim}
+% \caption{Using Semantic Macros in Narrative Structures}\label{fig:use-ring}
+% \end{exfig}
+%
% \subsection{Including Externally Defined Semantic Macros }
%
% In some cases, we use an existing {\LaTeX} macro package for typesetting objects that
@@ -516,11 +596,6 @@
% 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|
@@ -573,7 +648,7 @@
% {\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
+% in \ednote{usemodule should work here; revise}
% \begin{verbatim}
% \begin{module}[id=foo]
% \importmodule{mod}
@@ -585,10 +660,10 @@
% \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
+% it with |\sinput{mod}|, as in
% \begin{verbatim}
% \begin{module}[id=foo]
-% \importmodule[mod]{mod}
+% \importmodule[load=mod]{mod}
% ...
% \end{module}
% ...
@@ -612,19 +687,22 @@
%
% 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).
+% (otherwise they stay false). The options we are not using, we pass on to the |sref|
+% package we require next.
% \begin{macrocode}
%<*package>
-\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
+\newif\if@modules@mh@\@modules@mh@false
+\DeclareOption{mh}{\@modules@mh@true}
\newif\ifmod@show\mod@showfalse
\DeclareOption{showmods}{\mod@showtrue}
+\newif\ifaux@req\aux@reqtrue
+\DeclareOption{noauxreq}{\aux@reqfalse}
\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}
+\newif\if@mmt\@mmtfalse
+\DeclareOption{mmt}{\@mmttrue}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{sref}}
\ProcessOptions
-%</package>
% \end{macrocode}
%
% {\latexml} does not support module options yet, so we do not have to do anything here
@@ -634,18 +712,12 @@
% 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}
+\if@modules@mh@\RequirePackage{modules-mh}\fi
+\if@mmt\RequirePackage{mmt}\fi
\RequirePackage{xspace}
-\RequirePackage{xcomment}
-%</package>
-%<*ltxml>
-# -*- CPERL -*-
-package LaTeXML::Package::Pool;
-use strict;
-use LaTeXML::Global;
-use LaTeXML::Package;
-%</ltxml>
+\RequirePackage{mdframed}
+\RequirePackage{pathsuris}
% \end{macrocode}
%
% \subsection{Modules and Inheritance}\label{sec:impl:modules}
@@ -657,10 +729,12 @@ use LaTeXML::Package;
% 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>
+\addmetakey{module}{cd}% no longer used
+\addmetakey{module}{load}% ignored
+\addmetakey*{module}{title}
+\addmetakey*{module}{creators}
+\addmetakey*{module}{contributors}
+\addmetakey*{module}{srccite}
% \end{macrocode}
% \end{macro}
%
@@ -672,325 +746,214 @@ use LaTeXML::Package;
% |\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.
+% the module name in the token register |\mod@id|.
% \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}}}
+ \edef\this@module{%
+ \expandafter\noexpand\csname module@defs@#1\endcsname%
+ }%
+ \csgdef{module@defs@#1}{}%
+ \ifmod@qualified%
+ \edef\this@qualified@module{%
+ \expandafter\noexpand\csname module@defs@#1\endcsname%
+ }%
+ \csgdef{module@defs@qualified@#1}{}%
+ \fi%
+ \def\mod@id{#1}%
+}%
% \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}}
+\newcounter{module}[section]%
+\newrobustcmd\module@heading{%
+ \stepcounter{module}%
+ \ifmod@show%
+ \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%
+ \fi%
+}% mod@show
% \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>
+% Finally, we define the begin module command for the module environment. Much of the
+% work has already been done in the keyval bindings, so this is quite simple. We store
+% the file name (without extension) and extension of the module file in the global
+% macros |\module@|\meta{name}|@path| and |\module@|\meta{name}|@ext|, so that we can
+% use them later. The source of these two macros, |\mod@path| and |\mod@ext|, are
+% defined in |\requiremodules|.
+% \begin{macrocode}
+\newenvironment{module}[1][]{%
+ \begin{@module}[#1]%
+ \ifcsundef{mod@id}{}{% only define if components are!
+ \ifcsundef{mod@path}{}{\csxdef{module@\mod@id @path}{\mod@path}}%
+ \ifcsundef{mod@ext}{}{\csxdef{module@\mod@id @ext}{\mod@ext}}%
+ }%
+ \if@mmt\if@importing\else\mmtheory{\mod@id}{????}\fi\fi%
+ \module@heading% make the headings
+ \ignorespaces}{%
+ \if@mmt\if@importing\else\mmtheoryend\fi\fi%
+ \end{@module}%
+ \ignorespacesafterend%
+}%
+\ifmod@show\surroundwithmdframed{module}\fi%
% \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>
+% \begin{environment}{@module}
+% A variant of the |module| environment that does not create printed representations (in
+% particular no frames)
+% \begin{macrocode}
+\newenvironment{@module}[1][]{\metasetkeys{module}{#1}}{}%
% \end{macrocode}
-% \end{macro}
+% \end{environment}
%
% \begin{macro}{\activate@defs}
% To activate the |\symdef|s from a given module \meta{mod}, we call the macro
-% |\module@defs@|\meta{mod}.
+% |\module@defs@|\meta{mod}. But to make sure that every module is activated only once,
+% we only activate if the macro |\module@defs@|\meta{mod} is undefined, and define it
+% directly afterwards to prohibit further activations.
% \begin{macrocode}
-%<*package>
-\def\activate@defs#1{\csname module@defs@#1\endcsname}
-%</package>
+\def\activate@defs#1{%
+ \ifcsundef{module@#1@activated}{\csname module@defs@#1\endcsname}{}%
+ \@namedef{module@#1@activated}{true}%
+}%
% \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})
+% |\export@defs{|\meta{mod}|}| exports all the |\symdef|s from module \meta{mod} to the
+% current module (if it has the name \meta{currmod}), by adding a call to
+% |\module@defs@|\meta{mod} to the registry |\module@defs@|\meta{currmod}.\ednote{MK: I
+% have the feeling that we may be exporting modules multiple times here, is that a
+% problem?}\ednote{Jinbo: This part of code is extremely easy to generate bugs, cautiously edit this part of code.}\newline
+% Naive understanding of this code: |#1| be will be expanded first, then |\this@module|, then |\active@defs|, then |\g@addto@macro|.
+% \begin{macrocode}
+\def\export@defs#1{%
+ \@ifundefined{mod@id}{}{%
+ \expandafter\expandafter\expandafter\g@addto@macro%
+ \expandafter\this@module\expandafter{\activate@defs{#1}}%
+ }%
+}%
+% \end{macrocode}
+% \end{macro}
+%
+% Now we come to the implementation of |\importmodule|, but before we do, we define
+% conditional and an auxiliary macro:
+% \begin{macro}{\if@importing}
+% |\if@importing| can be used to shut up macros in an import situation.
% \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>
+\newif\if@importing\@importingfalse
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\coolurion/off}
-% \ednote{@DG: this needs to be documented somewhere in section 1}
+% \begin{macro}{\update@used@modules}
+% This updates the register |\used@modules|
% \begin{macrocode}
-%<*package>
-\def\coolurion{}
-\def\coolurioff{}
-%</package>
-%<*ltxml>
-DefMacro('\coolurion',sub {AssignValue('cooluri'=>1);});
-DefMacro('\coolurioff',sub {AssignValue('cooluri'=>0);});
-%</ltxml>
+\newcommand\update@used@modules[1]{%
+ \ifx\used@modules\@empty%
+ \edef\used@modules{#1}%
+ \else%
+ \edef\used@modules{\used@modules,#1}%
+ \fi}
% \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>
+% \meta{mod}. As we will (probably) need to keep a record of the currently imported modules
+% (top-level only), we divide the functionality into a user-visible macro that records
+% modules in the |\used@modules| register and an internal one (|\@importmodule|)
+% that does the actual work.
+% \begin{macrocode}
+\gdef\used@modules{}
+\srefaddidkey{importmodule}
+\addmetakey{importmodule}{load}
+\addmetakey[sms]{importmodule}{ext}
+\addmetakey[false]{importmodule}{conservative}[true]
+\newcommand\importmodule[2][]{%
+ \metasetkeys{importmodule}{#1}%
+ \update@used@modules{#2}%
+ \@importmodule[\importmodule@load]{#2}{\importmodule@ext}{export}%
+ \ignorespacesandpars%
+}%
% \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>
+% \begin{macro}{\@importmodule}
+% |\@importmodule[|\meta{filepath}|]{|\meta{mod}|}{|\meta{ext}|}{|\meta{export?}|}|
+% loads \meta{filepath}|.|\meta{ext} (if it is given) and activates the module
+% \meta{mod}. If \meta{export?} is |export|, then it also re-exports the |\symdef|s from
+% \meta{mod}.
+%
+% First |\@load| will store the base file name with full path, then check if
+% |\module@|\meta{mod}|@path| is defined. If this macro is defined, a module of this
+% name has already been loaded, so we check whether the paths coincide, if they do, all
+% is fine and we do nothing otherwise we give a suitable error. If this macro is
+% undefined we load the path by |\requiremodules|.
+% \begin{macrocode}
+\newcommand\@importmodule[4][]{%
+ {\@importingtrue% to shut up macros while in the group opened here
+ \edef\@load{#1}%
+ \ifx\@load\@empty%
+ \relax%
+ \else%
+ \ifcsundef{module@#2@path}{%
+ \requiremodules{#1}{#3}%
+ }{%
+ \edef\@path{\csname module@#2@path\endcsname}%
+ \IfStrEq\@load\@path{% if the known path is the same as the requested one
+ \relax% do nothing, it has already been loaded, else signal an error
+ }{%
+ \PackageError{modules}
+ {{Module Name Clash\MessageBreak
+ A module with name #2 was already loaded under the path "\@path"\MessageBreak
+ The imported path "\@load" is probably a different module with the\MessageBreak
+ same name; this is dangerous -- not importing}%
+ {Check whether the Module name is correct}}%
+ }%
+ }%
+ \fi}%
+ \activate@defs{#2}% activate the module
+ \edef\@export{#4}\def\@@export{export}%prepare comparison
+ \ifx\@export\@@export\export@defs{#2}\fi% export the module
+ \if@importing\else\if@mmt\mmtinclude{#1?#2}\fi\fi%
+}%
% \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{macro}{\usemodule}
+% |\usemodule| acts like |\importmodule|, except that the |sms| utility does not
+% transfer it to the module signatures and it does not re-export the symdefs.
% \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>
+\newcommand\usemodule[2][]{%
+ \metasetkeys{importmodule}{#1}%
+ \update@used@modules{#2}%
+ \@importmodule[\importmodule@load]{#2}{\importmodule@ext}{noexport}%
+ \ignorespacesandpars%
+}%
% \end{macrocode}
-% \end{environment}
-%
-% \begin{environment}{ttassign}
+% \end{macro}
+%
+% \begin{macro}{\withusedmodules}
+% This variant just imports all the modules in a comma-separated list (usually
+% |\used@modules|)
% \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>
+\newcommand\withusedmodules[2]{{\@for\@I:=#1\do{\activate@defs\@I}{#2}}}%
% \end{macrocode}
-% \end{environment}
-%
+% \end{macro}
+%
% \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.
+% have a full URI anyways. So things are easy.\ednote{MK@DG: this macro is seldom used,
+% maybe I should just switch arguments.}
% \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>
+\newrobustcmd\importOMDocmodule[3][]{\importmodule[#1]{#3}}%
% \end{macrocode}
% \end{macro}
%
@@ -998,14 +961,7 @@ afterDigest=>sub{
% |\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>
+\let\metalanguage=\importmodule%
% \end{macrocode}
% \end{macro}
%
@@ -1013,25 +969,31 @@ DefConstructor('\metalanguage OptionalSemiverbatim {}',
%
% \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.}
+% macro that does not check for definedness.
% \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>
+\let\mod@newcommand=\providerobustcmd%
% \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{environment}{conceptdef}
+% \begin{macrocode}
+\srefaddidkey{conceptdef}%
+\addmetakey*{conceptdef}{title}%
+\addmetakey{conceptdef}{subject}%
+\addmetakey*{conceptdef}{display}%
+\def\conceptdef@type{Symbol}%
+\newrobustcmd\conceptdef[2][]{%
+ \metasetkeys{conceptdef}{#1}%
+ \ifx\conceptdef@display\st@flow\else{\stDMemph{\conceptdef@type} #2:}\fi%
+ \ifx\conceptdef@title\@empty~\else~(\stDMemph{\conceptdef@title})\par\fi%
+}%
+% \end{macrocode}
+% \ednote{MK@DG: maybe we need to add DefKeyVals here?}
+% \end{environment}
+%
% \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
@@ -1042,336 +1004,149 @@ DefConstructor('\metalanguage OptionalSemiverbatim {}',
% |\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>
+\newif\if@symdeflocal%
+\srefaddidkey{symdef}%
+\define@key{symdef}{local}[true]{\@symdeflocaltrue}%
+\define@key{symdef}{primary}[true]{}%
+\define@key{symdef}{assocarg}{}%
+\define@key{symdef}{bvars}{}%
+\define@key{symdef}{bargs}{}%
+\addmetakey{symdef}{name}%
+\addmetakey*{symdef}{title}%
+\addmetakey*{symdef}{description}%
+\addmetakey{symdef}{subject}%
+\addmetakey*{symdef}{display}%
% \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]}}
+\def\symdef{%
+ \@ifnextchar[{\@symdef}{\@symdef[]}%
+}%
+\def\@symdef[#1]#2{%
+ \@ifnextchar[{\@@symdef[#1]{#2}}{\@@symdef[#1]{#2}[0]}%
+}%
% \end{macrocode}
+% \end{macro}
+%
% next we locally abbreviate |\mod@newcommand| to simplify argument passing.
% \begin{macrocode}
-\def\@mod@nc#1{\mod@newcommand{#1}[1]}
+\def\@mod@nc#1{\mod@newcommand{#1}[1]}%
+% \end{macrocode}
+% and we copy a very useful piece of code from
+% \url{http://tex.stackexchange.com/questions/23100/looking-for-an-ignorespacesandpars},
+% it ignores spaces and following implicit paragraphs (double newlines), explicit |\par|s
+% are respected however
+% \begin{macrocode}
+\def\ignorespacesandpars{%
+ \begingroup
+ \catcode13=10
+ \@ifnextchar\relax
+ {\endgroup}%
+ {\endgroup}%
+}
+% \end{macrocode}
+% and more adapted from \url{http://tex.stackexchange.com/questions/179016/ignore-spaces-and-pars-after-an-environment}
+% \begin{macrocode}
+\def\ignorespacesandparsafterend#1\ignorespaces\fi{#1\fi\ignorespacesandpars}
+\def\ignorespacesandpars{
+ \ifhmode\unskip\fi%
+ \@ifnextchar\par%
+ {\expandafter\ignorespacesandpars\@gobble}%
+ {}%
+}
% \end{macrocode}
+%
+% \begin{macro}{\@@symdef}
% 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{%
+\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}%
+ \@symdeflocalfalse%
+ \metasetkeys{symdef}{#1}%
+% \end{macrocode}
+% If the |mmt| option is set and we are not importing, then we write out the constant
+% declaration for this symdef\ednote{eventually we may want to do something about the
+% notations. This would pass \#4 to MMT via a macro that makes the \# (argumentmarkers)
+% active and empty. I am not clear how well this works, so we leave out notations.}
+% \begin{macrocode}
+ \if@mmt\if@importing\else%
+\ifx\symdef@name\@empty\mmtconstdec{#2}\else\mmtconstdec{\symdef@name}\fi%
+\fi\fi%
% \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}%
+ \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}.
+% and then we define the actual semantic macro, which when invoked with an optional
+% argument \meta{opt} calls |\modules@|\meta{sym}|@pres@|\meta{opt} provided by the
+% |\symvariant| macro.
% \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}%
+ \expandafter\mod@newcommand\csname #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}}%
+ \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}{}{%
+ \if@symdeflocal%
+ \else%
+ \ifcsundef{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[]}}}%
+ \expandafter\g@addto@macro\this@module%
+ {\expandafter\mod@newcommand\csname modules@#2@pres@\endcsname[#3]{#4}}%
% \end{macrocode}
-% Finally, we add add the definition of |\@|\meta{sym}, which calls the intermediate
-% function.
+% Then we add add the definition of |\|\meta{sym} which calls the intermediate
+% function and handles the optional argument.
% \begin{macrocode}
-\expandafter\g@addto@macro\this@module%
-{\expandafter\def\csname modules@#2\endcsname[##1]%
-{\csname modules@#2@pres@##1\endcsname}}%
+ \expandafter\g@addto@macro\this@module%
+ {\expandafter\mod@newcommand\csname #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}}}%
+ \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>%$
+ \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#2@qualified\endcsname{\csname modules@#2@pres@qualified\endcsname}}%
+ \fi%
+ }% mod@qualified
+ \fi% symdeflocal
+% \end{macrocode}
+% So now we only need to show the data in the symdef, if the options allow.
+% \begin{macrocode}
+ \ifmod@show%
+ \ifx\symdef@display\st@flow\else{\noindent\stDMemph{\symdef@type} #2:}\fi%
+ \ifx\symdef@title\@empty~\else~(\stDMemph{\symdef@title})\par\fi%
+ \fi%
+ \ignorespacesandpars%
+}% mod@show
+\def\symdef@type{Symbol}%
% \end{macrocode}
% \end{macro}
%
@@ -1381,80 +1156,38 @@ DefPrimitive('\@symdef OptionalKeyVals:symdef {}[]{}', sub {
% |\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}
+% |\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{%
+ \@ifnextchar[{\@symvariant{#1}}{\@symvariant{#1}[0]}%
+ }%
\def\@symvariant#1[#2]#3#4{%
-\expandafter\mod@newcommand\csname modules@#1@pres@#3\endcsname[#2]{#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>
+ \ifcsundef{mod@id}{}{%
+ \expandafter\g@addto@macro\this@module%
+ {\expandafter\mod@newcommand\csname modules@#1@pres@#3\endcsname[#2]{#4}}%
+ }%
+\ignorespacesandpars}%
% \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>
+\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}{use the \protect\symvariant instead!}%
+}%
% \end{macrocode}
% \end{macro}
%
@@ -1462,653 +1195,253 @@ DefPrimitive('\@symdef OptionalKeyVals:symdef {}[]{}', sub {
% 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>
+\let\abbrdef\symdef%
% \end{macrocode}
% \end{macro}
%
-% \subsection{Symbol and Concept Names}\label{sec:impl:concepts}
+% \subsection{Defining Math Operators}\label{sec:impl:defmathop}
%
-% \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{macro}{\DefMathOp}
+% |\DefMathOp[|\meta{key pair}|]{definition}| will take 2 arguments. ||\meta{key pair}|| should be something like |[name=...]|, for example, |[name=equal]|. Though |\setkeys|, |\defmathop@name| will be set. Further definition will be done by |\symdef|.
% \begin{macrocode}
-%<*package>
-\def\mod@path{}
-%</package>
+\define@key{DefMathOp}{name}{%
+ \def\defmathop@name{#1}%
+}%
+\newrobustcmd\DefMathOp[2][]{%
+ \setkeys{DefMathOp}{#1}%
+ \symdef[#1]{\defmathop@name}{#2}%
+}%
% \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}
+% \subsection{Axiomatic Assumptions}\label{sec:impl:assumptions}
%
-% 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{macro}{\assdef}
+% We fake it for now, not clear what we should do on the {\LaTeX} side.
% \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>
+\newcommand\assdef[2][]{#2}
% \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}
+% \subsection{Semantic Macros for Variables}\label{sec:impl:semvars}
%
-% \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{macro}{\vardef}
+% We do the argument parsing like in |\symdef| above, but add the |local| key. All the
+% other changes are in the \latexml binding exclusively.
% \begin{macrocode}
-\def\mod@update#1{\ifx\mod@reg\@empty\xdef\mod@reg{#1}\else\xdef\mod@reg{#1@\mod@reg}\fi}
+\def\vardef{\@ifnextchar[{\@vardef}{\@vardef[]}}%
+\def\@vardef[#1]#2{%
+ \@ifnextchar[{\@@vardef[#1]{#2}}{\@@vardef[#1]{#2}[0]}}
+\def\@@vardef[#1]#2[#3]#4{%
+ \def\@test{#1}%
+ \ifx\@test\@empty%
+ \@@symdef[local]{#2}[#3]{#4}%
+ \else%
+ \symdef[local,#1]{#2}[#3]{#4}%
+ \fi%
+ \ignorespacesandpars}%
% \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}
+% \subsection{Testing Semantic Macros}\label{sec:impl:testing}
+%
+% \begin{macro}{\symtest}
+% Allows to test a |\symdef| in place, this shuts up when being imported.
+% \begin{macrocode}
+\addmetakey{symtest}{name}%
+\addmetakey{symtest}{variant}%
+\newrobustcmd\symtest[3][]{%
+ \if@importing%
+ \else%
+ \metasetkeys{symtest}{#1}%
+ \par\noindent \textbf{Symbol}~%
+ \ifx\symtest@name\@empty\texttt{#2}\else\texttt{\symtest@name}\fi%
+ \ifx\symtest@variant\@empty\else\ (variant \texttt{\symtest@variant})\fi%
+ \ with semantic macro %
+ \texttt{\textbackslash #2\ifx\symtest@variant\@empty\else[\symtest@variant]\fi}%
+ : used e.g. in \ensuremath{#3}%
+ \fi%
+ \ignorespacesandpars%
+}%
% \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}
+%
+% \begin{macro}{\abbrtest}
+% \begin{macrocode}
+\addmetakey{abbrtest}{name}%
+\newrobustcmd\abbrtest[3][]{%
+ \if@importing%
+ \else%
+ \metasetkeys{abbrtest}{#1}%
+ \par\noindent \textbf{Abbreviation}~%
+ \ifx\abbrtest@name\@empty\texttt{#2}\else\texttt{\abbrtest@name}\fi%
+ : used e.g. in \ensuremath{#3}%
+ \fi%
+ \ignorespacesandpars}%
% \end{macrocode}
% \end{macro}
+%
+% \subsection{Symbol and Concept Names}\label{sec:impl:concepts}
%
-% \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{macro}{\termdef}
% \begin{macrocode}
-\def\mod@reguse#1{\modulesfalse\expandafter\mod@check\mod@reg @///#1\relax}
+\def\mod@true{true}%
+\addmetakey[false]{termdef}{local}%
+\addmetakey{termdef}{name}%
+\newrobustcmd\termdef[3][]{%
+ \metasetkeys{termdef}{#1}%
+ \expandafter\mod@newcommand\csname#2\endcsname[0]{#3\xspace}%
+ \ifx\termdef@local\mod@true%
+ \else%
+ \ifcsundef{mod@id}{}{%
+ \expandafter\g@addto@macro\this@module%
+ {\expandafter\mod@newcommand\csname#2\endcsname[0]{#3\xspace}}%
+ }%
+ \fi%
+}%
% \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{macro}{\capitalize}
% \begin{macrocode}
-\def\mod@prefix{}
+\def\@capitalize#1{\uppercase{#1}}%
+\newrobustcmd\capitalize[1]{\expandafter\@capitalize #1}%
% \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}}
+% \begin{macro}{\mod@termref}
+% |\mod@termref{|\meta{module}|}{|\meta{name}|}{|\meta{nl}|}| determines whether the
+% macro |\module@|\meta{module}|@path| 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.\ednote{MK: this should be rethought, in particular the
+% local reference does not work!}
+% \begin{macrocode}
+\def\mod@termref#1#2#3{%
+ \def\@test{#3}%
+ \@ifundefined{module@defs@#1}{%
+ \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}}%
+ \@ifundefined{module@#1@path}% local reference
+ {\sref@hlink@ifh{\@label}{\ifx\@test\@empty #2\else #3\fi}}%
+ {\def\@uri{\csname module@#1@path\endcsname.pdf\#\@label}%
+ \sref@href@ifh{\@uri}{\ifx\@test\@empty #2\else #3\fi}}%
+}%
% \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}
+% \subsection{Dealing with Multiple Files}\label{sec:impl:multiple}
%
-% \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}
+% We use the |pathsuris| package deals with the canonicalization of paths. |\@cpath| will
+% canonicalize a path and store the result into |\@CanPath|. To print a canoncalized path,
+% simply use |\cpath{|\meta{path}|}|.
+%
+% \begin{macro}{\@rinput}
+% |\@rinput{|\meta{path to the current file without extension}|}{|\meta{extension}|}| allows loading
+% modules with relative path. For example, |\@rinput{foo/bar/B}{tex}| will load |foo/bar/B.tex|.
+% \ednote{Jinbo: How to handle |mod@path|?}
+% \begin{macrocode}
+\def\CurrentDir{}%
+\newrobustcmd{\@rinput}[2]{%
+ \@cpath{\CurrentDir#1}%
+ \StrCut[\value{RealAddrNum}]{/\@CanPath}{/}\@TempPath\@Rubbish%
+ \StrCut[1]{\@TempPath/}{/}\@Rubbish\@DirPath%
+ \edef\CurrentDir{\@DirPath}%
+% \edef\mod@path{}% what should I put in here???
+% \edef\mod@ext{}%
+ \input{\@CanPath.#2}%
+ \def\CurrentDir{}%
+}%
+% \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}
+% \subsection{Loading Module Signatures}
%
-% \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>
+% this macro loads the modules in a file and makes sure that no text is deposited (we
+% set the flags |\mod@showfalse| and |\@importingtrue| in the local group). It also
+% remembers the file name and extension in |\mod@path| and |\mod@ext| so that
+% |\begin{module}| can pick them up later.
+% \begin{macrocode}
+\newrobustcmd\requiremodules[2]{%
+ \mod@showfalse%
+ \@importingtrue% save state and ensure silence while reading sms
+ \edef\mod@path{#1}%
+ \edef\mod@ext{#2}% set up path/ext
+ \input{#1.#2}%
+}%
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\sinput}
+% \begin{macro}{\@requiremodules}
+% the internal version of |\requiremodules| for use in the |*.aux| file. We disable it
+% at the end of the document, so that when the |aux| file is read again, nothing is
+% loaded.
% \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>
+\newrobustcmd\@requiremodules[2]{%
+ \if@tempswa\requiremodules{#1}{#2}\fi%
+}%
% \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>#$
+% \begin{macro}{\inputref}
+% |\inputref{|\meta{path to the current file without extension}|}| supports both
+% absolute path and relative path, meanwhile, records the path and the extension (not
+% for relative path). \ednote{MK: maybe do something with a non-standard
+% (i.e. non-\texttt{tex}) extension with an optional argument?}
+% \begin{macrocode}
+\newrobustcmd\inputref[2][]{%
+ \def\@Slash{/}
+ \edef\@load{#2}%
+ \StrChar{\@load}{1}[\@testchar]
+ \ifx\@testchar\@Slash%
+ \edef\mod@path{#2}%
+ \edef\mod@ext{tex}%
+ \input{#2}%
+ \else%
+ \@rinput{#2}{tex}%
+ \fi%
+}%
% \end{macrocode}
-%
+% \end{macro}
%
% \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>
+\def\requirepackage#1#2{\makeatletter\input{#1.sty}\makeatother}%
% \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}
+% \subsection{Deprecated Functionality}\label{sec:impl:deprecated}
%
-% \begin{macro}{\view@heading}
-% Then we make a convenience macro for the view heading. This can be customized.
+% \begin{macro}{\sinput*}
% \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}
+\newrobustcmd\sinput[1]{%
+ \PackageError{modules}%
+ {The \protect\sinput macro is deprecated}{use the \protect\input instead!}%
+}%
+\newrobustcmd\sinputref[1]{%
+ \PackageError{modules}%
+ {The \protect\sinputref macro is deprecated}{use the \protect\inputref instead!}%
+}%
% \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>
+ \@for\module@tmp:=#1\do{\activate@defs\module@tmp\export@defs\module@tmp}%
+}%
% \end{macrocode}
% \end{macro}
%
@@ -2117,25 +1450,18 @@ DefEnvironment('{view} OptionalKeyVals:view {}{}',
% 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>
+ \@for\module@tmp:=#1\do{\activate@defs{qualified@\module@tmp}\export@defs\module@tmp}%
+}%
% \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{macro}{\coolurion/off}
% \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>
+\def\coolurion{\PackageWarning{modules}{coolurion is obsolete, please remove}}%
+\def\coolurioff{\PackageWarning{modules}{coolurioff is obsolete, please remove}}%
% \end{macrocode}
+% \end{macro}
%
% \subsection{Experiments}
% In this section we develop experimental functionality. Currently support for complex
@@ -2146,90 +1472,164 @@ Tag('omdoc:theory',afterOpen=>\&numberIt,afterClose=>\&locateIt);
% 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>
+\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}%
+}%
% \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}
+% The code for avoiding duplicate loading is very very complex and brittle (and does not
+% quite work). Therefore I would like to replace it with something better. It has two
+% parts:
+% \begin{itemize}
+% \item keeping a registry of file paths, and only loading when the file path has not been
+% mentioned in that, and
+% \item dealing with relative paths (for that we have to string together prefixes and pass
+% them one)
+% \end{itemize}
+% For the first problem, there is a very nice and efficient solution using |etoolbox| which
+% I document below. If I decide to do away with relative paths, this would be it.
+%
+% \begin{macro}{\reqmodules}
+% We keep a file path registry |\@register| and only load a module signature, if it is
+% not in there.
+% \begin{macrocode}
+\newrobustcmd\reqmodules[2]{%
+ \ifinlist{#1}{\@register}{}{\listadd\@register{#1}\input{#1.#2}}%
+}%
+% \end{macrocode}
+% \end{macro}
+% for the relative paths, I have to find out the directory prefix and the file name. Here
+% are two helper functions, which work well, but do not survive being called in an
+% |\edef|, which is what we would need. First some preparation: we set up a path parser
+% \begin{macrocode}
+\newcounter{@pl}
+\DeclareListParser*{\forpathlist}{/}
+% \end{macrocode}
%
-% Finally, we need to terminate the file with a success mark for perl.
+% \begin{macro}{\file@name}
+% |\file@name| selects the filename of the file path: |\file@name{/foo/bar/baz.tex}| is
+% |baz.tex|.
% \begin{macrocode}
-%<ltxml>1;
+\def\file@name#1{%
+ \setcounter{@pl}{0}%
+ \forpathlist{\stepcounter{@pl}\listadd\@pathlist}{#1}
+ \def\do##1{%
+ \ifnumequal{\value{@pl}}{1}{##1}{\addtocounter{@pl}{-1}}
+ }%
+ \dolistloop{\@pathlist}%
+}%
% \end{macrocode}
-%
+% \end{macro}
+%
+% \begin{macro}{\file@path}
+% |\file@path| selects the path of the file path |\file@path{/foo/bar/baz.tex}| is
+% |/foo/bar|
+% \begin{macrocode}
+\def\file@path#1{%
+ \setcounter{@pl}{0}%
+ \forpathlist{\stepcounter{@pl}\listadd\@pathlist}{#1}%
+ \def\do##1{%
+ \ifnumequal{\value{@pl}}{1}{}{%
+ \addtocounter{@pl}{-1}%
+ \ifnumequal{\value{@pl}}{1}{##1}{##1/}%
+ }%
+ }%
+ \dolistloop{\@pathlist}%
+}%
+%</package>
+% \end{macrocode}
+% \end{macro}
+% what I would really like to do in this situation is
+% \begin{macro}{\NEWrequiremodules}
+% but this does not work, since the |\file@name| and |\file@path| do not survive the
+% |\edef|.
+% \begin{macrocode}
+\def\@NEWcurrentprefix{}
+\def\NEWrequiremodules#1{%
+ \def\@pref{\file@path{#1}}%
+ \ifx\@pref\@empty%
+ \else%
+ \xdef\@NEWcurrentprefix{\@NEWcurrentprefix/\@pref}%
+ \fi%
+ \edef\@input@me{\@NEWcurrentprefix/\file@name{#1}}%
+ \message{requiring \@input@me}\reqmodule{\@input@me}%
+}%
+% \end{macrocode}
+% \end{macro}
% \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
+% LocalWords: GPL structuresharing STR dtx env envfalse idfalse displayfalse filedate nl
+% LocalWords: usesfalse usesqualified usesqualifiedfalse envtrue idtrue CPERL Rares pres
+% LocalWords: usestrue displaytrue usesqualifiedtrue RequirePackage keyval tmp 2oms04 eg
+% LocalWords: defs foreach LookupValue activateScope DefEnvironment keyvals cd varpres
+% LocalWords: OptionalKeyVals getValue toString AssignValue openElement omdoc uvee vee
+% LocalWords: closeElement beforeDigest useTheoryItemizations afterDigestBegin symtest
+% LocalWords: whatsit setProperty getArg qw symdef iffalse importOMDocmodule symtest ci
+% LocalWords: DefKeyVal Semiverbatim symdeflocal atqualified DefMacro STDERR setst spath
+% LocalWords: args unlist DefPrimitive nargs Stringify eq attr omcd ltx XMTok abbrtest
+% LocalWords: convertLaTeXArgs scriptpos XMApp OMA XMArg simpl abbrtest 2oms04 circ ary
+% LocalWords: blaaaa savedprefix aaa simplhelp tust tist tost reguse spath baz rangle
+% LocalWords: updatedpre ReturnAfterFi updateall updatedpost updatesms bgroup includeref
+% LocalWords: texclude tinclude getGullet requiredmodule tex sms egroup pmml sincluderef
+% LocalWords: toks mixfixi mixfixa mixfixii mixfixia mixfixai mixfixiii arg cr OPaths
+% LocalWords: undef tok PARAM thyid BerFieMas inparaenum omsemvar vardef vardef mhview
+% LocalWords: getString showfalse showtrue xcomment stex srcref KeyVal omext osslepsdl13
+% LocalWords: beginItemize getProperty introdcue afterOpen numberIt Tokenize mathhub
+% LocalWords: OptionalSemiverbatim omdocmod PushValue assocarg getStomach prs HorIacJuc
+% LocalWords: begingroup beginMode endMode endgroup insertElement resymdef sym cscpnrr11
+% LocalWords: updir nargkey PresFormatters mixfixaii formatters argname expr behavior
+% LocalWords: getSymmdefProperties XMath mcdcr exprlist recurse texttt scsys foobar mrow
+% LocalWords: textbackslash newcommand providecommand sc sc mathml openmath nx st@flow
+% LocalWords: latexml cmathml activemath twintoo atwin atwintoo mathcal Deyan viewsketch
+% LocalWords: mathcal fileversion Ginev maketitle newpage infty ulsmf08 exfig endinput
+% LocalWords: omsemmac lstset basicstyle scriptsize aboveskip belowskip hline mh-variant
+% LocalWords: morekeywords lstlisting csymbol showmods foo exf cseq mdframed usemhmodule
+% LocalWords: qualifiedimports qualifiedimports termdef textbf filepath RabKoh mhinput
+% LocalWords: symname varSmoothfunctionsOn ednote abbrdef Sumfromto semmodule mhinputref
+% LocalWords: vspace hrule vspace arith arbitraryn xbool oplus xdisjunction tw mhinput
+% LocalWords: emph capitalize ldots termref termref symref symref ctancite nc mhinputref
+% LocalWords: smms hyperref RahObe hmlmh10 widehat texmf.cnf requiremodules cs 2oms04
+% LocalWords: sinput sinputref sinputref cname csname 2oms04
+% LocalWords: OPhats usepackage importqualified Crossreferencing jobname ltxml etoolbox
+% LocalWords: jobname printbibliography textsf langle textsf langle textlangle listadd
+% LocalWords: textrangle textlangle newif ifmod qualifiedfalse qualifiedtrue usemhmodule
+% LocalWords: sref xspace expandafter noexpand endcsname namedef setkeys ifx mh-variants
+% LocalWords: newenvironment parentmod usemodule ifundefined coolurion cooluri reqmodule
+% LocalWords: coolurioff cwd ouri ifdefinable testopt ifnextchar xargdef bvars 2oms04
+% LocalWords: argdef yargdef somefunction symdeflocaltrue bvar xpath assoc qr reqmodules
+% LocalWords: symdeflocalfalse localpres isbound symdefs COMPLEXTOKEN localp fromrepos
+% LocalWords: findnodes localname carg renewcommand bbb showmeta showmeta exp ifnumequal
+% LocalWords: refundefinedtrue subsubsection blaaa makeatletter makeatother rm ifinlist
+% LocalWords: ifmodules gdef xdef xdef modulestrue modulesfalse pathpostfix abbreviative
+% LocalWords: updatedsms newreg xref texorpdfstring srefaddidkey newsavebox importmodule
+% LocalWords: viewbox newcounter thesection theview theproblem hfill lrbox req torepos
+% LocalWords: stepcounter textwidth hbox noindent smallskip fbox vbox usebox forpathlist
+% LocalWords: smallskip newxcomment vassign ensuremath mapsto doctex tocdepth dolistloop
+% LocalWords: setcounter tableofcontents mathbb symvariant importmodulevia assdef Jinbo
+% LocalWords: importmodulevia compactdesc tassign tassign tname source-tname frompath
+% LocalWords: ttassign metakeys addmetakey themodule metasetkeys aftergroup addtocounter
+% LocalWords: groupling requation IMPORTCD CURRENTCD bindargs defmathop cnode topath
+% LocalWords: icvariant aftercounter prestok inputref oref loadfrom loadto customization
+% LocalWords: csymdef notationdef noauxreq noauxreq rinput ifaux reqtrue bargs assdef
+% LocalWords: reqfalse currmod importmoduleenv conceptdef stDMemph tempswa mhviewsketch
+% LocalWords: auxout omtext surroundwithmdframed ignorespaces NeedsTeXFormat lstinline
+% LocalWords: modularizations conventionalized initialize xstring srccite csgdef csxdef
+% LocalWords: customized newrobustcmd ifcsundef definedness providerobustcmd cpath
+% LocalWords: canonicalization canonicalize canoncalized RealAddrNum itemize
+% LocalWords: NEWrequiremodules