diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-07 20:49:10 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-07 20:49:10 +0000 |
commit | ddfe3a4eaf95167482e923d4da3de2917a7dbfbb (patch) | |
tree | 0acc1bb60b37392451f5e79e00c33c487c19abcf /Master/texmf-dist/source/latex/stex/modules | |
parent | a04ae5a947a6b06bc717719f6ad63e6de5cb5af6 (diff) |
stex (7apr16)
git-svn-id: svn://tug.org/texlive/trunk@40320 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/stex/modules')
-rw-r--r-- | Master/texmf-dist/source/latex/stex/modules/modules.dtx | 2252 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/stex/modules/modules.ins | 10 |
2 files changed, 831 insertions, 1431 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>⎄</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 diff --git a/Master/texmf-dist/source/latex/stex/modules/modules.ins b/Master/texmf-dist/source/latex/stex/modules/modules.ins index 52aa57ce4b2..cde996b92b8 100644 --- a/Master/texmf-dist/source/latex/stex/modules/modules.ins +++ b/Master/texmf-dist/source/latex/stex/modules/modules.ins @@ -28,11 +28,11 @@ \Msg{* if your TeX distribution uses such a database.} \Msg{*} -\nopreamble\nopostamble -\generate{\file{modules.sty.ltxml}{\from{modules.dtx}{ltxml}}} +% \nopreamble\nopostamble +% \generate{\file{modules.sty.ltxml}{\from{modules.dtx}{ltxml}}} -\Msg{*} -\Msg{* You probably need to move the generated ltxml files into a directory searched by LaTeXML.} -\Msg{*} +% \Msg{*} +% \Msg{* You probably need to move the generated ltxml files into a directory searched by LaTeXML.} +% \Msg{*} \endbatchfile |