% \iffalse meta-comment 
% An Infrastructure for Presenting Semantic Macros in sTeX
% Copyright (C) 2004-2007 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/presentation/presentation.dtx $
% \fi
% 
% \iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{presentation}[2012/01/28 v1.0 presentation for semantic macros]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{url,array,float,amstext,alltt}
\usepackage{modules,presentation,stex-logo}
\usepackage[show]{ed}
\usepackage[hyperref=auto,style=alphabetic]{biblatex}
\bibliography{kwarc}
\usepackage{../ctansvn}
\usepackage{hyperref}
\usepackage[eso-foot,today]{svninfo}
\svnInfo $Id: presentation.dtx 1999 2012-01-28 07:32:11Z kohlhase $
\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/presentation/presentation.dtx $
\makeindex
\floatstyle{boxed}
\newfloat{exfig}{thp}{lop}
\floatname{exfig}{Example}
\def\tracissue#1{\cite{sTeX:online}, \hyperlink{http://trac.kwarc.info/sTeX/ticket/#1}{issue #1}}
\begin{document}\DocInput{presentation.dtx}\end{document}
%</driver>
% \fi
% 
% \CheckSum{598}
%
% \changes{v0.9}{2005/06/14}{First Version with Documentation}
% \changes{v0.9a}{2005/07/01}{Completed Documentation}
% \changes{v0.9b}{2005/08/06}{Complete functionality and Updated Documentation}
% \changes{v0.9c}{2006/01/13}{more packaging}
% \changes{v0.9d}{2006/10/13}{adding mixfix declarations}
% \changes{v0.9d}{2006/10/13}{dealing with precedences in keyword arguments}
% \changes{v0.9e}{2007/09/03}{fixing argument precedences, adding LaTeXML bindings}
% \changes{v0.9f}{2007/12/09}{adding general elision}
% \changes{v0.9g}{2008/06/17}{getting the LaTeXML right}
% \changes{v0.9h}{2009/02/27}{turning the precedence order around to make this compatible
% with the latest OMDoc, change all precedences $n$ to $1000-n$}
% \changes{v0.9h}{2009/07/30}{adding brackets to the generated notation elements}
% \changes{v0.9h}{2010/06/18}{considering done now}
% \changes{v1.0}{2010/12/27}{adding \texttt{\textbackslash funapp}}
% \changes{v1.0}{2011/01/28}{moving \texttt{\textbackslash funapp} and
% \texttt{\textbackslash vname} (and friends) to new package {\texttt{cmath}}}
% \GetFileInfo{presentation.sty}
% 
% \MakeShortVerb{\|}
%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
% \def\xml{\scsys{Xml}}
% \def\mathml{\scsys{MathML}}
% \def\omdoc{\scsys{OMDoc}}
% \def\openmath{\scsys{OpenMath}}
% \def\latexml{\scsys{LaTeXML}}
% \def\perl{\scsys{Perl}}
% \def\cmathml{Content-{\sc MathML}\index{Content {\sc MathML}}\index{MathML@{\sc MathML}!content}}
% \def\activemath{\scsys{ActiveMath}}
% \def\twin#1#2{\index{#1!#2}\index{#2!#1}}
% \def\twintoo#1#2{{#1 #2}\twin{#1}{#2}}
% \def\atwin#1#2#3{\index{#1!#2!#3}\index{#3!#2 (#1)}}
% \def\atwintoo#1#2#3{{#1 #2 #3}\atwin{#1}{#2}{#3}}
% \title{{\texttt{presentation.sty}}: An Infrastructure for Presenting Semantic 
%   Macros in {\stex}\thanks{Version {\fileversion} (last revised {\filedate})}}
%    \author{Michael Kohlhase \& Deyan Ginev\\
%            Jacobs University, Bremen\\
%            \url{http://kwarc.info/kohlhase}}
% \date{\today}
% \maketitle
%
% \begin{abstract}
%   The |presentation| package is a central part of the {\stex} collection, a version of
%   {\TeX/\LaTeX} that allows to markup {\TeX/\LaTeX} documents semantically without
%   leaving the document format, essentially turning {\TeX/\LaTeX} into a document format
%   for mathematical knowledge management (MKM).
% 
%   This package supplies an infrastructure that allows to specify the presentation of
%   semantic macros, including preference-based bracket elision. This allows to markup the
%   functional structure of mathematical formulae without having to lose high-quality
%   human-oriented presentation in {\LaTeX}. Moreover, the notation definitions can be
%   used by MKM systems for added-value services, either directly from the {\sTeX}
%   sources, or after translation.
% \end{abstract}
%
% \newpage\setcounter{tocdepth}{2}\tableofcontents\newpage
%
%\section{Introduction}\label{sec:presentation}
%
% The |presentation| package supplies an infrastructure that allows to specify the
% presentation of semantic macros, including preference-based bracket elision. This allows
% to markup the functional structure of mathematical formulae without having to lose
% high-quality human-oriented presentation in {\LaTeX}. Moreover, the notation definitions
% can be used by MKM systems for added-value services, either directly from the {\sTeX}
% sources, or after translation.
%
% {\stex} is a version of {\TeX/\LaTeX} that allows to markup {\TeX/\LaTeX} documents
% semantically without leaving the document format, essentially turning {\TeX/\LaTeX} into
% a document format for mathematical knowledge management (MKM).
%
% The setup for semantic macros described in the {\stex} |modules| package works well for
% simple mathematical functions: we make use of the macro application syntax in {\TeX} to
% express function application. For a simple function called ``foo'', we would just
% declare |\symdef{foo}[1]{foo(#1)}| and have the concise and intuitive syntax |\foo{x}|
% for $foo(x)$. But mathematical notation is much more varied and interesting than just
% this.
%
% \section{The User Interface}\label{sec:user}
% 
% In this package we will follow the {\sTeX} approach and assume that there are four basic
% types of mathematical expressions: symbols, variables, applications and
% binders. Presentation of the variables is relatively straightforward, so we will not
% concern ourselves with that. The application of functions in mathematics is mostly
% presented in the form $f(a_1,\ldots,a_n)$, where $f$ is the function and the $a_i$ are
% the arguments. However, many commonly-used functions from this presentational scheme:
% for instance binomial coefficients: $\bigl({n\atop k}\bigr)$, pairs: $\langle
% a,b\rangle$, sets: $\{x\in S\,\vert\, x^2\ne0\}$, or even simple addition: $3+5+7$. Note
% that in all these cases, the presentation is determined by the (functional) head of the
% expression, so we will bind the presentational infrastructure to the operator.
% 
% \subsection{Prefix \& Postfix Notations}\label{sec:prepostfix}
% 
% The default notation for an object that is obtained by applying a function $f$ to
% arguments $a_1$ to $a_n$ is $f(a_1,\ldots,a_n)$. The \DescribeMacro{\prefix}|\prefix|
% macro allows to specify a prefix presentation for a function (the usual presentation in
% mathematics). Note that it is better to specify |\symdef{uminus}[1]{\prefix{-}{#1}}|
% than just |\symdef{uminus}[1]{-#1}|, since we can specify the bracketing behavior in the
% former (see Section~\ref{sec:elision}).
% 
% The \DescribeMacro{\postfix}|\postfix| macro is similar, only that the function is
% presented after the argument as for e.g. the factorial function: $5!$ stands for the
% result of applying the factorial function to the number 5. Note that the function is
% still the first argument to the |\postfix| macro: we would specify the presentation for
% the factorial function with |\symdef{factorial}[1]{\postfix{!}{#1}}|.
% 
% |\prefix| and |\postfix| have $n$-ary variants \DescribeMacro{\prefixa}|\prefixa| and
% \DescribeMacro{\postfixa}|\postfixa| that take an arbitrary number of arguments
% (mathematically; syntactically grouped into one {\TeX} argument). These take an extra
% separator argument.\ednote{think of a good example!}
% 
% Note that in \stex the |\prefix| and |\postfix| macros should primarily be used in
% |\symdef| declarations. For marking up applications of symbolic functions in text we
% should use the |\symdef|-defined semantic macros direct. For applications of function
% variables we have two options:
% \begin{compactenum}[\em i)]
% \item direct prefix markup of the form |f(x)|, where we have declared the symbol |f| to
%   be a function via the |function| key of the enclosing environment --- e.g. |omtext|
%   (see~\cite{Kohlhase:smmtf*:svn}).
% \item using the \DescribeMacro{\funapp}|\funapp| macro as in |\funapp{f}{x}|, which
%   leads to the same effect and is more general (e.g. for complex function variables,
%   such as $f_1^\prime$). Note that the default prefix rendering of the function is
%   sufficient here, since we can otherwise make use of a user-defined application
%   operator.
% \end{compactenum}
% 
% \subsection{Mixfix Notations}\label{sec:mixfix}
% 
% For the presentation of more complex operators, we will follow the approach used by the
% Isabelle theorem prover. There, the presentation of an $n$-ary function (i.e. one that
% takes $n$ arguments) is specified as
% \meta{pre}\meta{arg$_0$}\meta{mid$_1$}$\cdots$\meta{mid$_n$}\meta{arg$_n$}\meta{post},
% where the \meta{arg$_i$} are the arguments and \meta{pre}, \meta{post}, and the
% \meta{mid$_i$} are presentational material. For instance, in infix operators like the
% binary subset operator, \meta{pre} and $\meta{post}$ are empty, and \meta{mid$_1$} is
% $\subseteq$. For the ternary conditional operator in a programming language, we might
% have the presentation pattern
% |if|\meta{arg$_1$}|then|\meta{arg$_2$}|else|\meta{arg$_3$}|fi| that utilizes all
% presentation positions. 
%
% \DescribeMacro{\mixfix*}The |presentation| package provides mixfix declaration macros
% |\mixfixi|, |\mixfixii|, and |\mixfixiii| for unary, binary, and ternary functions. This
% covers most of the cases, larger arities would need a different argument
% pattern.\footnote{If you really need larger arities, contact the author!} The call
% pattern of these macros is just the presentation pattern above. In general, the mixfix
% declaration of arity $i$ has $2n+1$ arguments, where the even-numbered ones are for the
% arguments of the functions and the odd-numbered ones are for presentation material.  For
% instance, to define a semantic macro for the subset relation and the conditional, we
% would use the markup in Figure~\ref{fig:mixfix}.
% \begin{exfig}
% \begin{verbatim}
% \symdef{sseteq}[2]{\mixfixii{}{#1}{\subseteq}{#2}{}}
% \symdef{sseteq}[2]{\infix\subseteq{#1}{#2}}
% \symdef{ite}[2]{\mixfixiii{{\tt{if}}\;}{#1}
%                           {\;{\tt{then}}\;}{#2}
%                           {\;{\tt{else}}\;}{#3}{\;{\tt{fi}}}}
% \end{verbatim}
% \vspace*{-1.5em}
% \begin{center}
%   \begin{tabular}{|l|l|}\hline
%     source & presentation \\\hline
%     |\sseteq{S}T| & $(S\subseteq T)$\\\hline
%     |\ite{x<0}{-x}x| & ${\tt{if}}\,x<0\,{\tt{then}}\,-x\,{\tt{else}}\,x\,{\tt{fi}}$\\\hline
%   \end{tabular}
% \end{center}
% \caption{Declaration of mixfix operators}\label{fig:mixfix}
% \end{exfig}
% 
% For certain common cases, the |presentation| package provides shortcuts for the mixfix
% declarations. For instance, we provide the \DescribeMacro{\infix}|\infix| macro for
% binary operators that are written between their arguments (see Figure~\ref{fig:mixfix}).\ednote{really?}
%
% \subsection{\texorpdfstring{$n$}{n}-ary Associative Operators}\label{sec:assoc}
%
% Take for instance the operator for set union: formally, it is a binary function on
% sets that is associative (i.e. $(S_1\cup S_2)\cup S_3=S_1\cup (S_2\cup S_3)$), therefore
% the brackets are often elided, and we write $S_1\cup S_2\cup S_3$ instead (once we have
% proven associativity). Some authors even go so far to introduce set union as a $n$-ary
% operator, i.e. a function that takes an arbitrary (positive) number of arguments. We will
% call such operators {\bf{$n$-ary
%     associative}\atwin{n-ary}{associative}{operator}}. 
%
% Specifying the presentation\ednote{introduce the notion of presentation above} of
% $n$-ary associative operators in |\symdef| forms is not straightforward, so we provide
% some infrastructure for that. As we cannot predict the number of arguments for $n$-ary
% operators, we have to give them all at once, if we want to maintain our use of {\TeX}
% macro application to specify function application. So a semantic macro for an $n$-ary
% operator will be applied as |\nunion{|\meta{$a_1$}|,|\ldots|,|\meta{$a_n$}|}|, where the
% sequence of $n$ logical arguments \meta{$a_i$} are supplied as one {\TeX} argument which
% contains a comma-separated list. We provide variants of the mixfix declarations
% presented in section~\ref{sec:mixfix} which deal with associative arguments. For
% instance, the variant \DescribeMacro{\mixfixa}|\mixfixa| allows to specify $n$-ary
% associative operators.
% |\mixfixa{|\meta{pre}|}{|\meta{arg}|}{|\meta{post}|}{|\meta{op}|}| specifies a
% presentation, where \meta{arg} is the associative argument and \meta{op} is the
% corresponding operator that is mapped over the argument list; as above, {\meta{pre}},
% \meta{post}, are prefix and postfix presentational material. For instance, the finite
% set constructor could be constructed as
% \begin{verbatim}
% \newcommand{\fset}[1]{\mixfixa[p=1000]{\{}{#1}{\}}{,}}
% \end{verbatim}
% 
% The \DescribeMacro{\assoc}|\assoc| macro is a convenient abbreviation of a |\mixfixa|
% that can be used in cases, where \meta{pre} and \meta{post} are empty (i.e. in the
% majority of cases). It takes two arguments: the presentation of a binary operator, and a
% comma-separated list of arguments, it replaces the commas in the second argument with
% the operator in the first one. For instance |\assoc\cup{S_1,S_2,S_3}| will be formatted
% to $S_1\cup S_2\cup S_3$. Thus we can use |\def\nunion#1{\assoc\cup{#1}}| or even
% |\def\nunion{\assoc\cup}|, to define the $n$-ary operator for set union in {\TeX}. For
% the definition of a semantic macro in {\stex}, we use the second form, since we are more
% conscious of the right number of arguments and would declare
% |\symdef{nunion}[1]{\assoc\cup{#1}}|.\ednote{think about big operators for ACI
%   functions}
%
% The |\mixfixii| macro has variants \DescribeMacro{\mixfixia}|\mixfixia| and
% \DescribeMacro{\mixfixai}|\mixfixai| which allow to make one or two arguments in a
% binary function associative. A use case for the second macro is an nary function type
% operator |\fntype|, which can be defined via
% \begin{verbatim}
% \def\fntype#1#2{\mixfixai{}{#1}\rightarrow{#2}{}\times}
% \end{verbatim}
% \def\fntype#1#2{\mixfixai{}{#1}\rightarrow{#2}{}\times}
% and which will format |\fntype{\alpha,\beta,\gamma}\delta| as
% $\fntype{\alpha,\beta,\gamma}\delta$
% 
% Finally, the |\mixfixiii| macro has the variants |\mixfixaii|, |\mixfixiai|, and
% |\mixfixiia| as above\footnote{If you really need larger arities with associative
%   arguments, contact the package author!}. For instance we can use the first variant for
% a typing judgment using
% \begin{verbatim}
% \def\typej#1#2#3{\mixfixaii{}{#1}{\vdash_{\Sigma}}{#2}\colon{#3}{}{,}}
% \end{verbatim}
% \def\typej#1#2#3{\mixfixaii{}{#1}{\vdash_{\Sigma}}{#2}\colon{#3}{}{,}}
% which formats |\typej{\Gamma,[x:\alpha],[y:\beta]}{f(x,y)}{\beta}| as 
% \[\typej{\Gamma,[x:\alpha],[y:\beta]}{f(x,y)}{\beta}.\]
% 
% \subsection{Precedence-Based Bracket Elision}\label{sec:elision}
%
% In the infrastructure discussed above, we have completely ignored the fact that we use
% brackets to disambiguate the formula structure. The general baseline rule here is that
% we enclose any presented subformula with (round) brackets to mark it as a logical unit.
% If we applied this to the following formula that combines set union and set intersection
% \begin{equation}\label{cupcap}
% |\nunion{\ninters{a,b},\ninters{c,d}}|
% \end{equation}
% this would yield $((a\cap b)\cup (c\cap d))$, and not $a\cap b\cup c\cap d$ as we are
% used to. In mathematics, brackets are elided, whenever the author anticipates that the
% reader can understand the formula without them, and would be overwhelmed with them. To
% achieve this, there are set of common conventions that govern bracket elision ---
% ``$\cap$ binds stronger than $\cup$'' in (\ref{cupcap}). The most common is to assign
% precedences to all operators, and elide brackets, if the {\index*{precedence}} of the
% operator is larger than that of the context it is presented in (or equivalently: we only
% write brackets, if the operator precedence is smaller or equal to the context
% precedence). Note that this is more selective that simply dropping outer brackets which
% would yield $a\cap b\cup c\cap d$ for (\ref{capcup}), where we would have liked $(a\cup
% b)\cap(c\cup d)$
% \begin{equation}\label{capcup}
% |\ninters{\nunion{a,b},\nunion{c,d}}|
% \end{equation}
% In our example above, we would assign $\cap$ a larger precedence than $\cup$ (and both a
% larger precedence than the initial precedence to avoid outer brackets). To compute the
% presentation of (\ref{capcup}) we start out with the |\ninters|, elide its brackets
% (since the precedence $n$ of $\cup$ is larger than the initial precedence $i$), and set
% the context precedence for the arguments to $n$. When we present the arguments, we
% present the brackets, since the precedence of |nunion| is larger than the context
% precedence $n$.
%
% This algorithm --- which we call {\textbf{precedence-based bracket elision}} --- goes a
% long way towards approximating mathematical practice. Note that full bracket elision in
% mathematical practice is a reader-oriented process, it cannot be fully mechanical,
% e.g. in $(a\cap b\cap c\cap d\cap e\cap f\cap g)\cup h$ we better put the brackets
% around the septary intersection to help the reader even though they could have been
% elided by our algorithm. Therefore, the author has to retain full control\ednote{think
% about how to implement that. We need a way to override precedences locally} over
% bracketing in a bracket elision architecture. Otherwise it would become impossible to
% explain the concept of associativity in $(a\circ b)\circ c =a\circ(b\circ c)$, where we
% need the brackets for this one time on an otherwise associative operation $\circ$.
%
% \begin{figure}[htb]
% \begin{center}
%   \begin{tabular}{|l|l|l|}\hline
%     Precedence & Operators                  & Comment\\\hline\hline
%     800    & +,-                        & unary \\\hline
%     800    & $\hat{}$                   & exponentiation \\\hline
%     600    & $*,\land,\cap$             & multiplicative \\\hline
%     500    & $+,-,\lor,\cup$            & additive\\\hline
%     400    & /                          & fraction \\\hline
%     300    & $=, \ne, \leq, <, >, \geq$ & relation\\\hline
%   \end{tabular}
% \end{center}\vspace*{-1em}
% \caption{Common Operator Precedences}\label{fig:precedence}
% \end{figure}
%
% Furthermore, we supply an optional keyval arguments to the mixfix declarations and their
% abbreviations that allow to specify precedences: The key \DescribeMacro{p}|p| key is
% used to specify the {\bf{operator precedence}}, and the keys
% \DescribeMacro{pi}\DescribeMacro{pii}\DescribeMacro{piii}|p|\meta{i} can be used to
% specify the {\bf{argument precedence}s}. The latter will set the precedence level while
% processing the arguments, while the operator precedence invokes brackets, if it is
% smaller than the current precedence level --- which is set by the appropriate argument
% precedence by the dominating operators or the outer precedence. The values of the
% precedence keys can be integers or \DescribeMacro{\iprec}|\iprec| for the infinitely
% large precedence or \DescribeMacro{\niprec}|\niprec| for the infinitely small
% precedence.
%
% If none of the precedences is specified, then the defaults are assumed. The operator
% precedence is set to the default operator precedence, which defaults to 0. The argument
% precedences default to the operator precedence.
%
% Figure~\ref{fig:precedence} gives an overview over commonly used precedences. Note that
% most operators have precedences higher than the default precedence of 0, otherwise the
% brackets would not be elided.  For our examples above, we would define
% \begin{verbatim}
% \newcommand{\nunion}[1]{\assoc[p=500]{\cup}{#1}}
% \newcommand{\ninters}[1]{\assoc[p=600]{\cap}{#1}}
% \end{verbatim}
% to get the desired behavior. 
%
% Note that the presentation macros uses round brackets for grouping by default. We can
% specify other brackets via two more keywords: \DescribeMacro{lbrack}|lbrack| and
% \DescribeMacro{rbrack}|rbrack|. 
%
% Note that formula parts that look like brackets usually are not. For instance, we should
% not define the finite set constructor via
% \begin{equation}\label{wrongset}
% |\newcommand{\fset}[1]{\assoc[lbrack=\{,rbrack=\}]{,}{#1}}|
% \end{equation}
% where the curly braces are used as brackets, but as presented in section~\ref{sec:assoc}
% even though both would format |\fset{a,b,c}| as $\{a,b,c\}$. In the encoding here, an
% operator with suitably high operator precedence (it is the best practice u)would be able
% to make the brackets disappear. Thus the correct version of (\ref{wrongset}) is
% \begin{equation}\label{goodset}
% |\newcommand{\fset}[1]{\mixfixa[p=\iprec,pi=0]{\{}{#1}{\}}{,}}|
% \end{equation}
% Note that |\prefix| and |\postfix| and their variants declared in
% section~\ref{sec:prepostfix} have brackets that do not participate (actively) in the
% precedence-based elision: function application brackets are not subject to elision. But
% the operator precedence |p| is still taken into account for outer brackets. The argument
% precedence |pi| has negative infinity as a default to avoid spurious brackets for
% arguments.
% 
% \subsection{Flexible Elision}\label{sec:flexible-elision}
% 
% There are several situations in which it is desirable to display only some parts of the
% presentation:
% \begin{itemize}
% \item We have already seen the case of redundant brackets above
% \item Arguments that are strictly necessary are omitted to simplify the notation, and the
%   reader is trusted to fill them in from the context.
% \item Arguments are omitted because they have default values. For example $\log_{10}x$
%   is often written as $\log x$.
% \item Arguments whose values can be inferred from the other arguments are usually
%   omitted. For example, matrix multiplication formally takes five arguments, namely the
%   dimensions of the multiplied matrices and the matrices themselves, but only the latter
%   two are displayed.
% \end{itemize}
%
% Typically, these elisions are confusing for readers who are getting acquainted with a
% topic, but become more and more helpful as the reader advances.  For experienced readers
% more is elided to focus on relevant material, for beginners representations are more
% explicit. In the process of writing a mathematical document for traditional (print)
% media, an author has to decide on the intended audience and design the level of elision
% (which need not be constant over the document though). With electronic media we have new
% possibilities: we can make elisions flexible. The author still chooses the elision level
% for the initial presentation, but the reader can adapt it to her level of competence and
% comfort, making details more or less explicit.
% 
% To provide this functionality, the |presentation| package provides the
% \DescribeMacro{\elide}|\elide| macro allows to associate a text with an integer
% {\textbf{visibility level}} and group them into {\textbf{elision groups}}. High levels
% mean high elidability.
%
% Elision can take various forms in print and digital media. In static media like
% traditional print on paper or the PostScript format, we have to fix the elision level,
% and can decide at presentation time which elidable tokens will be printed and which will
% not. In this case, the presentation algorithm will take visibility thresholds $T_g$ for
% every elidability group $g$ as a user parameter and then elide (i.e. not print) all
% tokens in visibility group $g$ with level $l>T_g$. We specify this threshold for via the
% \DescribeMacro{\setegroup}|\setegroup| macro. For instance in the example below, we have
% a two type annotations |par| for type parameters and |typ| for type annotations
% themselves.
% 
% \begin{exfig}[ht]
% \begin{verbatim}  
% $\mathbf{I}\elide{par}{500}{^\alpha}\elide{typ}{100}{_{\alpha\to\alpha}}
%     :=\lambda{X\elide{typ}{500}{_\alpha}}.X$
% \end{verbatim}\vspace*{-2em}
% \caption{Elision with Elision Groups}\label{ex:elision}
% \end{exfig}
%
% The visibility levels in the example encode how redundant the author thinks the elided
% parts of the formula are: low values show high redundancy. In our example the intuition
% is that the type parameter on the $\mathbf{I}$ combinator and the type annotation on the
% bound variable $X$ in the $\lambda$ expression are of the same obviousness to the
% reader. So in a document that contains |\setegroup{typ}{0}| and |\setegroup{par}{0}|
% Figure~\ref{ex:elision} will show $\mathbf{I}:=\lambda{X}.X$ eliding all redundant
% information. If we have both values at 600, then we will see
% $\mathbf{I}^\alpha:=\lambda{X_\alpha}.X$ and only if the threshold for |typ| rises above
% 900, then we see the full information:
% $\mathbf{I}^\alpha_{\alpha\to\alpha}:=\lambda{X_\alpha}.X$.
% 
% In an output format that is capable of interactively changing its appearance, e.g.
% dynamic XHTML+MathML (i.e. XHTML with embedded Presentation {\mathml} formulas, which
% can be manipulated via JavaScript in browsers), an application can export the
% information about elision groups and levels to the target format, and can then
% dynamically change the visibility thresholds by user interaction. Here the visibility
% threshold would also be used, but here it only determines the default rendering; a user
% can then fine-tune the document dynamically to reveal elided material to support
% understanding or to elide more to increase conciseness.
%
% The price the author has to pay for this enhanced user experience is that she has to
% specify elided parts of a formula that would have been left out in conventional
% {\LaTeX}. Some of this can be alleviated by good coding practices. Let us consider the
% log base case. This is elided in mathematics, since the reader is expected to pick it up
% from context. Using semantic macros, we can mimic this behavior: defining two semantic
% macros: |\logC| which picks up the log base from the context via the |\logbase| macro
% and |\logB| which takes it as a (first) argument.
%
% \begin{verbatim}
% \provideEdefault{logbase}{10}
% \symdef{logB}[2]{\prefix{\mathrm{log}\elide{base}{100}{_{#1}}}{#2}}
% \abbrdef{logC}[1]{\logB{\fromEcontext{logbase}}{#1}}
% \end{verbatim}
%
% \DescribeMacro{\provideEdefault} Here we use the |\provideEdefault| macro to initialize
% a {\LaTeX} token register for the |logbase| default, which we can pick up from the
% elision context using \DescribeMacro{\fromEcontext}|\fromEcontext| in the definition of
% |\logC|. Thus |\logC{x}| would render as $\mathrm{log}_{10}(x)$ with a threshold of 50
% for |base| and as $\mathrm{log}_2$, if the local {\TeX} group e.g. given by the
% |assertion| environment contains a
% \DescribeMacro{setEdefault}|\setEdefault{logbase}{2}|.
% 
% \subsection{Other Layout Primitives}\label{sec:inter:primitives}
% 
% Not all mathematical layouts are producible with mixfix notations. A prime example are
% grid layouts which are marked up  using the |array| element in {\TeX/\LaTeX}, e.g. for
% definition by cases as the (somewhat contrived) definition of the absolute value
% function in the upper part of Figure~\ref{fig:piece}. We will now motivate the need of
% special layout primitives with this example.
% \begin{exfig}
% \begin{module}[id=foo]
% \symdef{piece}[2]{\arrayline{\arraycell{#1}}{\text{if}\;#2}}
% \symdef{otherwise}[1]{\arrayline{\arraycell{#1}}{\text{else}}}
% \symdef{piecewise}[1]{\left\{\begin{array}{rl}#1\end{array}\right.}
% \qquad\begin{minipage}[c]{5cm}
% $\vert x\vert\colon=\piecewise{\piece{x}{x>0}\piece{-x}{x<0}\otherwise{0}}$
% \end{minipage}
% \qquad 
% \begin{minipage}[c]{7cm}
% \begin{verbatim}
% |x|\colon=\left\{
% \begin{array}{rl}
%  x & x>0\\
% -x & x<0\\
%  0 & \text{else}
% \end{array}
% \right.
% \end{verbatim}
% \end{minipage}
% \end{module}
% \hrule
% \begin{verbatim}
% \symdef{piece}[2]{\arrayline{\arraycell{#1}}{\text{if}\;#2}}
% \symdef{otherwise}[1]{\arrayline{\arraycell{#1}}{\text{else}}}
% \symdef{piecewise}[1]{\left\{\begin{array}{rl}#1\end{array}\right.}
% $|x|\colon=\piecewise{\piece{x}{x>0}\piece{-x}{x<0}\otherwise{0}}$
% \end{verbatim}
% \vspace*{-1.5em}
% \caption{A piecewise definition of the absolute value function}\label{fig:piece}
% \end{exfig}
% But this does not work for content markup via semantic macros~\cite{KohAmb:smmssl:ctan},
% which wants to group formula parts by function. For definition by cases, we may want to
% follow the OpenMath |piece1| content dictionary~\cite{CD:piece1:on}, which groups
% ``piecewise'' definitions into a constructor |piecewise|, whose children are a list of
% |piece| constructors optionally followed by an |otherwise|. If we want to mimic this by
% semantic macros in \stex (these are defined via |\symdef|; see~\cite{KohAmb:smmssl:ctan}
% for details), we would naturally define |\piecewise| by wrapping an |array| environment
% (see the last line in Figure~\ref{fig:piece}). Then we would naturally be tempted to
% define |\piece| via |\symdef{piece}[2]{#1&\text{if}\;{#2}\\}| and |\otherwise| via
% |\symdef{otherwise}[1]{#1&\text{else}}|. But this does not support the generation of
% separate notation definitions for |\piece| and |\otherwise|: here \latexml has to
% generate presentational information outside of the |array| context that provides the |&|
% and |\\| command sequences\footnote{Note that this is not a problem when we only run
% |latex| if we assume that \texttt{\textbackslash piece} and \texttt{\textbackslash
% otherwise} are only used in arguments of \texttt{\textbackslash piecewise}.}. Therefore
% the |presentation| package provides the macros |\arrayline| and |\arraycell| that
% refactor this functionality.
% 
% \DescribeMacro{\arrayline}|\arrayline{|\meta{cells}|}{|\meta{cell}|}| is
% {\LaTeX}-equivalent to \meta{cells}|&|\meta{cell}|\\| and can thus be used to create
% array lines with one or more array cells: \meta{cell} is the last array cell, and the
% previous ones are each marked up as
% \DescribeMacro{\arraycell}|\arraycell{|\meta{cell}|}|, where \meta{cell} is the cell
% content. In last lines of Figure~\ref{fig:piece} we have used them to create the array
% lines for |\piece| and |\otherwise|. Note that the array cell specifications in
% |\arrayline| must coincide with the array specification in the main constructor (here
% |rl| in |\piecewise|).
% 
% \section{Limitations}\label{sec:limitations}
% 
% In this section we document known limitations. If you want to help alleviate them,
% please feel free to contact the package author. Some of them are currently discussed in
% the \sTeX TRAC~\cite{sTeX:online}. 
% \begin{compactenum}
% \item none reported yet
% \end{compactenum}
% 
% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}
%
% \section{The Implementation}\label{sec:implementation}
%
% The |presentation| package generates to files: the {\LaTeX} package (all the code
% between {\textsf{$\langle$*package$\rangle$}} and {\textsf{$\langle$/package$\rangle$}}) and the
% {\latexml} bindings (between {\textsf{$\langle$*ltxml$\rangle$}} and
%     {\textsf{$\langle$/ltxml$\rangle$}}). We keep the corresponding code fragments together,
% since the documentation applies to both of them and to prevent them from getting out of
% sync.
%
% For {\latexml}, we initialize the package inclusions.
%    \begin{macrocode}
%<*ltxml>
# -*- CPERL -*-
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Package;
%</ltxml>
%    \end{macrocode}
%
% \subsection{Package Options}\label{sec:impl:options}
%
% We declare some switches which will modify the behavior according to the package
% options. Generally, an option |xxx| will just set the appropriate switches to true
% (otherwise they stay false).\ednote{we have no options at the moment}
%
%    \begin{macrocode}
%<*package>
\ProcessOptions
%</package>
%    \end{macrocode}
%
% We first make sure that the KeyVal package is loaded (in the right
% version). For {\latexml}, we also initialize the package inclusions.
%    \begin{macrocode}
%<package>\RequirePackage{keyval}[1997/11/10]
%    \end{macrocode}
% We will first specify the default precedences and brackets, together with the macros
% that allow to set them. 
%    \begin{macrocode}
%<*package>
\def\pres@default@precedence{0}
\def\pres@infty{1000000}
\def\iprec{\pres@infty}
\def\niprec{-\pres@infty}
\def\pres@initial@precedence{0}
\def\pres@current@precedence{\pres@initial@precedence}
\def\pres@default@lbrack{(}\def\pres@lbrack{\pres@default@lbrack}
\def\pres@default@rbrack{)}\def\pres@rbrack{\pres@default@rbrack}
%</package>
%<*ltxml>
DefMacro('\iprec','1000000');
DefMacro('\niprec','-1000000');
%</ltxml>
%    \end{macrocode}
%
% \subsection{The System Commands}\label{sec:impl:syscommands}
%
% \begin{macro}{\PrecSet}
% |\PrecSet| will set the default precedence.\ednote{need to implement this in {\latexml}?}
%    \begin{macrocode}
%<*package>
\def\PrecSet#1{\def\pres@default@precedence{#1}}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PrecWrite}
% |\PrecWrite| will write a bracket, if the precedence mandates it, i.e. if |\pres@p| is
% greater than the current precedence specified by |\pres@current@precedence|
%    \begin{macrocode}
%<*package>
\def\PrecWrite#1{\ifnum\pres@p>\pres@current@precedence\else{#1}\fi}
%</package>
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Prefix \& Postfix Notations}\label{sec:impl:prepostfix}
% 
% We first define the keys for the keyval arguments for |\prefix| and |\postfix|.
% 
%    \begin{macrocode}
%<*package>
\def\prepost@clearkeys{\def\pres@p@key{\pres@default@precedence}\def\pres@pi@key{\niprec}
\def\pres@lbrack{\pres@default@lbrack}\def\pres@rbrack{\pres@default@rbrack}}
\define@key{prepost}{lbrack}{\def\pres@lbrack{#1}}
\define@key{prepost}{rbrack}{\def\pres@lbrack{#1}}
\define@key{prepost}{p}{\def\pres@p@key{#1}}
\define@key{prepost}{pi}{\def\pres@pi@key{#1}}
%</package>
%    \end{macrocode}
%
% \begin{macro}{\prefix}
%   In prefix we always write the brackets.
%    \begin{macrocode}
%<*package>
\newcommand{\prefix}[3][]%key, fn, arg
{\prepost@clearkeys\setkeys{prepost}{#1}
{#2}\pres@lbrack{\edef\pres@current@precedence{\pres@pi@key}#3}\pres@rbrack}
%</package>
%<*ltxml>
DefConstructor('\crossrefOp[]{}',
       "?#2(<ltx:XMApp role='CROSSREFOP'>"
              .  "<ltx:XMTok role='CROSSREFOP' cr='?#1(#1)(fun)'/>"
              .  "<ltx:XMWrap>#2</ltx:XMWrap>"
              ."</ltx:XMApp>)()",
   requireMath=>1);
 
DefMacro('\prefix[]{}{}','\@prefix[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}');
DefConstructor('\@prefix OptionalKeyVals:mi {}{}',
                "<omdoc:rendering "
               .  "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
               .  "argprec='&argument_precedence(#1)'>"
               .  "<m:mrow>"
	       .    "#2"
               .    "<m:mrow>"
               .      "<m:mo fence='true'>(</m:mo>"
               .      "#3" 
               .      "<m:mo fence='true'>)</m:mo>"
               .    "</m:mrow>"
               .  "</m:mrow>"
               ."</omdoc:rendering>",
      afterDigest=>sub {
        #Default argument precedence is -\infty
        my $keyval = $_[1]->getArg(1);
        $keyval->setValue('pi',-1000000) unless ($keyval && defined($keyval->getValue('pi')));
        applyPrecedencePreferences(@_);
      },
      properties=>sub { getSymmdefProperties($_[1]); });
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\postfix}
%    \begin{macrocode}
%<*package>
\newcommand{\postfix}[3][]%key, fn, arg
{\prepost@clearkeys\setkeys{prepost}{#1}
\pres@lbrack{\edef\pres@current@precedence{\pres@pi@key}#3}\pres@rbrack{#2}}
%</package>
%<*ltxml>
DefMacro('\postfix []{}{}','\@postfix[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}');
DefConstructor('\@postfix OptionalKeyVals:mi {}{}',
              "<omdoc:rendering "
               . "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
               ."argprec='&argument_precedence(#1)'>"
               .  "<m:mrow>"
               .    "<m:mrow>"
               .      "<m:mo fence='true'>(</m:mo>"
               .      "#3" 
               .      "<m:mo fence='true'>)</m:mo>"
               .    "</m:mrow>"
               .    "#2"
               .  "</m:mrow>"
               ."</omdoc:rendering>",
       afterDigest=>sub {
         #Default argument precedence is -\infty
         my $keyval = $_[1]->getArg(1);
         $keyval->setValue('pi',-1000000) unless ($keyval && defined($keyval->getValue('pi')));
         applyPrecedencePreferences(@_);
       },
       properties=>sub { getSymmdefProperties($_[1]); });
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\funapp}
% Finally the |\funapp| macro is very simple:
%    \begin{macrocode}
%<*package>
\newcommand{\funapp}[2]{\prefix{#1}{#2}}
%</package>
%<*ltxml>
DefConstructor('\funapp{}{}','<ltx:XMApp>#1#2</ltx:XMApp>');
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Mixfix Operators}\label{sec:impl:mixfix}
% 
% We need to enable notation definitions of the operators that have
% argument- and precedence-aware renderings. To this end, we
% circumvent {\latexml}'s limitations induced by its internal
% processing stages, by pulling most of the argument rendering
% functionality to the XSLT which produces the final {\omdoc} result.
%
% In the {\latexml} bindings, the internal structure of the mixfix
% operators is generically preserved, via the |symdef_presentation_pmml| subroutine
% in the Modules package. Nevertheless, in the current module we add the promised syntactic
% enhancements to each element of the mixfix family. Also, we use the
% |argument_precedence| subroutine to store the precedences given by
% the 'pi', 'pii', etc. keys as a temporary |argprec|
% attribute of the rendering, to be abolished during the final {\omdoc} generation. 
% This setup is finally utilized by the XSLT stylesheet which combines
% the operator structure with the preserved precedences to produce the
% proper form of the argument render elements.
%
%    \begin{macrocode}
%<*package>
\def\clearkeys{\let\pres@p@key=\relax
\let\pres@pi@key=\relax%
\let\pres@pi@key=\relax%
\let\pres@pii@key=\relax%
\let\pres@piii@key=\relax}
\define@key{mi}{nobrackets}[yes]{\def\pres@p@key{\pres@infty}%
\def\pres@pi@key{-\pres@infty}}
\define@key{mi}{lbrack}{\def\pres@lbrack@key{#1}}
\define@key{mi}{rbrack}{\def\pres@lbrack@key{#1}}
\define@key{mi}{p}{\def\pres@p@key{#1}}
\define@key{mi}{pi}{\def\pres@pi@key{#1}}
\def\prep@keys@mi%
{\edef\pres@lbrack{\@ifundefined{pres@lbrack@key}\pres@default@lbrack\pres@lbrack@key}
\edef\pres@rbrack{\@ifundefined{pres@rbrack@key}\pres@default@rbrack\pres@rbrack@key}
\edef\pres@p{\@ifundefined{pres@p@key}\pres@default@precedence\pres@p@key}
\edef\pres@pi{\@ifundefined{pres@pi@key}\pres@p\pres@pi@key}}
%</package>
%<*ltxml>
our $max_arguments = 10;  #Currently max 10 arguments to \symdef.
DefKeyVal('mi','lbrack','Semiverbatim');
DefKeyVal('mi','rbrack','Semiverbatim');
DefKeyVal('mi','p','Semiverbatim');
DefKeyVal('mi','pi','Semiverbatim');
DefKeyVal('mi','pii','Semiverbatim'); #Why are we using this at mixfixai ?
DefKeyVal('mi','cd','Semiverbatim');
DefKeyVal('mi','name','Semiverbatim');
DefKeyVal('mi','nobrackets','Semiverbatim');
sub argument_precedence {
  my ($keyval) = @_;
  my $attr = 'pi';
  my @precs = ();
  foreach (1..$max_arguments) {
    if (defined KeyVal($keyval,$attr)) {
      push @precs, ToString(KeyVal($keyval,$attr))
    } else {
      push @precs, ""; 
    }
    $attr = $attr.'i';
  }
  return join(" ",@precs)." ";
}
sub applyPrecedencePreferences {
 my ($stomach,$whatsit) = @_;
 my @args = $whatsit->getArgs;
 my $keyvals = shift @args;
 return unless (defined $keyvals);
 my %kvhash = %{$keyvals->getKeyVals};
 #Default p (operator precedence) if not set:
 my $default_precedence = LookupValue('default_precedence');
 $keyvals->setValue('p',$default_precedence) unless defined($keyvals->getValue('p'));
 return unless (exists $kvhash{'nobrackets'});
 $keyvals->setValue('p',1000000);
 $keyvals->setValue('pi',-1000000); 
 $keyvals->setValue('pii',-1000000);
 $keyvals->setValue('piii',-1000000);
 return;
}#$
%</ltxml>
%    \end{macrocode}
%
% \begin{macro}{\mixfixi}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixi}[4][]%key, pre, arg, post
{\clearkeys\setkeys{mi}{#1}\prep@keys@mi%
\PrecWrite\pres@lbrack%
#2{\edef\pres@current@precedence{\pres@pi}#3}#4%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixi[]{}{}{}',
         '\@mixfixi[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .             '{\ensuremath{\crossrefOp[fun]{#4}}}');
DefConstructor('\@mixfixi OptionalKeyVals:mi {}{}{}',
        "<omdoc:rendering"
       .   "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')')"
       .   " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\@assoc}
%   We are using functionality from the {\LaTeX} core packages here to iterate over the
%   arguments.
%    \begin{macrocode}
%<*package>
\def\@assoc#1#2#3{% precedence, function, argv
\let\@tmpop=\relax% do not print the function the first time round
\@for\@I:=#3\do{\@tmpop% print the function
% write the i-th argument with locally updated precedence
{\edef\pres@current@precedence{#1}\@I}%
\let\@tmpop=#2}}%update the function
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mixfixa}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixa}[5][]%key, pre, arg, post, assocop
{\clearkeys\setkeys{mi}{#1}\prep@keys@mi%
\PrecWrite\pres@lbrack{#2}{\@assoc\pres@pi{#5}{#3}}{#4}\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixa[]{}{}{}{}',
         '\@mixfixa[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .              '{\ensuremath{\crossrefOp[fun]{#4}}}'
        .              '{\ensuremath{\crossrefOp[fun]{\ensuremath{#5 }}}}');
DefConstructor('\@mixfixa OptionalKeyVals:mi {}{}{}{}',
        "<omdoc:rendering "
       .   "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')')>"
       .   "<m:mrow>"
       .     "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .     "#2"
       .     "<omdoc:iterate name='args' "
       .         "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .       "<omdoc:separator>#5</omdoc:separator>"
       .       "<omdoc:render name='arg' "
       .         "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .     "</omdoc:iterate>"
       .     "#4"
       .     "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .   "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
%    \begin{macrocode}
%<*package>
\define@key{mii}{nobrackets}[yes]{\def\pres@p@key{\pres@infty}%
\def\pres@pi@key{-\pres@infty}\def\pres@pii@key{-\pres@infty}}
\define@key{mii}{lbrack}{\def\pres@lbrack@key{#1}}
\define@key{mii}{rbrack}{\def\pres@lbrack@key{#1}}
\define@key{mii}{p}{\def\pres@p@key{#1}}
\define@key{mii}{pi}{\def\pres@pi@key{#1}}
\define@key{mii}{pii}{\def\pres@pii@key{#1}}
\def\prep@keys@mii{\prep@keys@mi%
\edef\pres@pii{\@ifundefined{pres@pii@key}\pres@p\pres@pii@key}}
%</package>
%<*ltxml>
DefKeyVal('mii','lbrack','Semiverbatim');
DefKeyVal('mii','rbrack','Semiverbatim');
DefKeyVal('mii','p','Semiverbatim');
DefKeyVal('mii','pi','Semiverbatim');
DefKeyVal('mii','pii','Semiverbatim');
DefKeyVal('mii','cd','Semiverbatim');
DefKeyVal('mii','name','Semiverbatim');
DefKeyVal('mii','nobrackets','Semiverbatim');
%</ltxml>
%    \end{macrocode}
%
% \begin{macro}{\mixfixii}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixii}[6][]%key, pre, arg1, mid, arg2, post
{\clearkeys\setkeys{mii}{#1}\prep@keys@mii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\edef\pres@current@precedence{\pres@pi}#3}%
#4{\edef\pres@current@precedence{\pres@pii}#5}#6%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixii[]{}{}{}{}{}',
         '\@mixfixii[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .              '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
        .              '{\ensuremath{\crossrefOp[fun]{#6}}}');
DefConstructor('\@mixfixii OptionalKeyVals:mi {}{}{}{}{}',
        "<omdoc:rendering "
       .    "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
       .    "argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4 #5 #6"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mixfixia}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixia}[7][]%key, pre, arg1, mid, arg2, post, assocop
{\clearkeys\setkeys{mii}{#1}\prep@keys@mii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\edef\pres@current@precedence{\pres@pi}#3}%
#4{\@assoc\pres@pii{#7}{#5}}#6%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixia[]{}{}{}{}{}{}',
         '\@mixfixia[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .              '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
        .              '{\ensuremath{\crossrefOp[fun]{#6}}}'
        .              '{\ensuremath{\crossrefOp[fun]{#7}}}');
DefConstructor('\@mixfixia OptionalKeyVals:mii {}{}{}{}{}{}',
        "<omdoc:rendering "
       .    "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
       .    " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4"
       .    "<omdoc:iterate name='args' "
       .        "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .      "<omdoc:separator>#7</omdoc:separator>"
       .      "<omdoc:render name='arg' "
       .        "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .    "</omdoc:iterate>"
       .    "#6"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mixfixai}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixai}[7][]%key, pre, arg1, mid, arg2, post, assocop
{\clearkeys\setkeys{mii}{#1}\prep@keys@mii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\@assoc\pres@pi{#7}{#3}}%
#4{\edef\pres@current@precedence{\pres@pii}#5}#6%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixai[]{}{}{}{}{}{}',
         '\@mixfixai[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .'{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
        .'{\ensuremath{\crossrefOp[fun]{#6}}}'
        .'{\ensuremath{\crossrefOp[fun]{#7}}}');
DefConstructor('\@mixfixai OptionalKeyVals:mi {}{}{}{}{}{}',
              "<omdoc:rendering " 
            .     "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
            .     " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
               .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2"
       .    "<omdoc:iterate name='args' "
       .      "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .      "<omdoc:separator>#7</omdoc:separator>"
       .      "<omdoc:render name='arg' "
       .         "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .    "</omdoc:iterate>"
       .    "#4 #5 #6"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
%    \begin{macrocode}
%<*package>
\define@key{miii}{nobrackets}[yes]{\def\pres@p@key{\pres@infty}%
\def\pres@pi@key{-\pres@infty}
\def\pres@pii@key{-\pres@infty}
\def\pres@pii@key{-\pres@infty}}
\define@key{miii}{lbrack}{\def\pres@lbrack@key{#1}}
\define@key{miii}{rbrack}{\def\pres@lbrack@key{#1}}
\define@key{miii}{p}{\def\pres@p@key{#1}}
\define@key{miii}{pi}{\def\pres@pi@key{#1}}
\define@key{miii}{pii}{\def\pres@pii@key{#1}}
\define@key{miii}{piii}{\def\pres@piii@key{#1}}
\def\prep@keys@miii{\prep@keys@mii%
\edef\pres@piii{\@ifundefined{pres@piii@key}{\pres@p}{\pres@piii@key}}}
%</package>
%<*ltxml>
DefKeyVal('miii','lbrack','Semiverbatim');
DefKeyVal('miii','rbrack','Semiverbatim');
DefKeyVal('miii','p','Semiverbatim');
DefKeyVal('miii','pi','Semiverbatim');
DefKeyVal('miii','pii','Semiverbatim');
DefKeyVal('miii','piii','Semiverbatim');
DefKeyVal('miii','cd','Semiverbatim');
DefKeyVal('miii','name','Semiverbatim');
DefKeyVal('miii','nobrackets','Semiverbatim');
%</ltxml>
%    \end{macrocode}
%
% \begin{macro}{\mixfixiii}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixiii}[8][]%key, pre, arg1, mid1, arg2, mid2, arg3, post
{\clearkeys\setkeys{miii}{#1}\prep@keys@miii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\edef\pres@current@precedence{\pres@pi}#3}%
#4{\edef\pres@current@precedence{\pres@pii}#5}%
#6{\edef\pres@current@precedence{\pres@pii}#7}#8%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixiii[]{}{}{}{}{}{}{}',
         '\@mixfixiii[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
       .                '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
       .                '{\ensuremath{\crossrefOp[fun]{#6}}}{\ensuremath{#7 }}'
       .                '{\ensuremath{\crossrefOp[fun]{#8}}}');
DefConstructor('\@mixfixiii OptionalKeyVals:mi {}{}{}{}{}{}{}',
              "<omdoc:rendering "
            .    "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
            .    " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4 #5 #6 #7 #8"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\mixfixaii}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixaii}[9][]%key, pre, arg1, mid1, arg2, mid2, arg3, post, sep
{\clearkeys\setkeys{miii}{#1}\prep@keys@miii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\@assoc\pres@pi{#9}{#3}}%
#4{\edef\pres@current@precedence{\pres@pii}#5}%
#6{\edef\pres@current@precedence{\pres@pii}#7}#8%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixaii[]{}{}{}{}{}{}{}{}',
         '\@mixfixaii[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
         .              '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
         .              '{\ensuremath{\crossrefOp[fun]{#6}}}{\ensuremath{#7 }}'
         .              '{\ensuremath{\crossrefOp[fun]{#8}}}'
         .              '{\ensuremath{\crossrefOp[fun]{#9}}}');
DefConstructor('\@mixfixaii OptionalKeyVals:mi {}{}{}{}{}{}{}{}',
        "<omdoc:rendering "
       .    "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
       .    " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2"
       .    "<omdoc:iterate name='args' "
       .        "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .      "<omdoc:separator>#9</omdoc:separator>"
       .      "<omdoc:render name='arg' "
       .         "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .    "</omdoc:iterate>"
       .    "#4 #5 #6 #7 #8"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\mixfixiai}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixiai}[9][]%key, pre, arg1, mid1, arg2, mid2, arg3, post, assocop
{\clearkeys\setkeys{miii}{#1}\prep@keys@miii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\edef\pres@current@precedence{\pres@pi}#3}%
#4{\@assoc\pres@pi{#9}{#5}}%
#6{\edef\pres@current@precedence{\pres@pii}#7}#8%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixiai[]{}{}{}{}{}{}{}{}',
         '\@mixfixiai[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#6}}}{\ensuremath{#7 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#8}}}'
        .                '{\ensuremath{\crossrefOp[fun]{#9}}}');
DefConstructor('\@mixfixiai OptionalKeyVals:mi {}{}{}{}{}{}{}',
        "<omdoc:rendering "
       .    "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
       .    " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4"
       .    "<omdoc:iterate name='args' "
       .       "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .      "<omdoc:separator>#9</omdoc:separator>"
       .      "<omdoc:render name='arg' "
       .          "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .    "</omdoc:iterate>"
       .    "#6 #7 #8"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\mixfixiia}
%    \begin{macrocode}
%<*package>
\newcommand{\mixfixiia}[9][]%key, pre, arg1, mid1, arg2, mid2, arg3, post,assocop
{\clearkeys\setkeys{miii}{#1}\prep@keys@miii%
\PrecWrite\pres@lbrack% write bracket if necessary
#2{\edef\pres@current@precedence{\pres@pi}#3}%
#4{\edef\pres@current@precedence{\pres@pii}#5}%
#6{\@assoc\pres@pi{#9}{#7}}#8%
\PrecWrite\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\mixfixiia[]{}{}{}{}{}{}{}{}',
         '\@mixfixiia[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#4}}}{\ensuremath{#5 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#6}}}{\ensuremath{#7 }}'
        .                '{\ensuremath{\crossrefOp[fun]{#8}}}'
        .                '{\ensuremath{\crossrefOp[fun]{#9}}}');
DefConstructor('\@mixfixiia OptionalKeyVals:mi {}{}{}{}{}{}{}',
        "<omdoc:rendering "
       .  "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
       .      " argprec='&argument_precedence(#1)'>"
       .  "<m:mrow>"
       .    "<m:mo egroup='fence' fence='true'>(</m:mo>"
       .    "#2 #3 #4 #5 #6"
       .    "<omdoc:iterate name='args' "
       .        "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
       .      "<omdoc:separator>#9</omdoc:separator>"
       .      "<omdoc:render name='arg' "
       .          "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
       .    "</omdoc:iterate>"
       .    "#8"
       .    "<m:mo egroup='fence' fence='true'>)</m:mo>"
       .  "</m:mrow>"
       ."</omdoc:rendering>",
       afterDigest=>sub { applyPrecedencePreferences(@_);},
       properties=>sub { getSymmdefProperties($_[1]); });#$
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\prefixa}
%   In prefix we always write the brackets.
%    \begin{macrocode}
%<*package>
\newcommand{\prefixa}[4][]%keys, fn, arg, sep
{\prepost@clearkeys\setkeys{prepost}{#1}
{#2}\pres@lbrack{\@assoc\pres@pi@key{#3}{#4}}\pres@rbrack}
%</package>
%<*ltxml>
DefMacro('\prefixa[]{}{}{}','\@prefixa[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}{\ensuremath{#4 }}');
DefConstructor('\@prefixa OptionalKeyVals:mi {}{}{}',
                "<omdoc:rendering "
               .  "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
               .  "argprec='&argument_precedence(#1)'>"
               .  "<m:mrow>"
	       .    "#2"
               .    "<m:mrow>"
               .      "<m:mo fence='true'>(</m:mo>"
               .      "<omdoc:iterate name='args' "
               .          "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
               .        "<omdoc:separator>#4</omdoc:separator>"
               .        "<omdoc:render name='arg' "
               .            "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
               .      "</omdoc:iterate>"
              .      "<m:mo fence='true'>)</m:mo>"
               .    "</m:mrow>"
               .  "</m:mrow>"
               ."</omdoc:rendering>",
      afterDigest=>sub {
        #Default argument precedence is -\infty
        my $keyval = $_[1]->getArg(1);
        $keyval->setValue('pi',-1000000) unless ($keyval && defined($keyval->getValue('pi')));
        applyPrecedencePreferences(@_);
      },
      properties=>sub { getSymmdefProperties($_[1]); });
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\postfixa}
%    \begin{macrocode}
%<*package>
\newcommand{\postfixa}[4][]%keys, fn, arg, sep
{\prepost@clearkeys\setkeys{prepost}{#1}
\pres@lbrack{\@assoc\pres@pi@key{#3}{#4}}\pres@rbrack{#2}}
%</package>
%<*ltxml>
DefMacro('\postfixa []{}{}{}','\@postfixa[#1]{\ensuremath{\crossrefOp[fun]{#2}}}{\ensuremath{#3 }}{\ensuremath{#4 }}');
DefConstructor('\@postfixa OptionalKeyVals:mi {}{}{}',
              "<omdoc:rendering "
               . "?&defined(&KeyVal(#1,'p'))(precedence='&KeyVal(#1,'p')') "
               ."argprec='&argument_precedence(#1)'>"
               .  "<m:mrow>"
               .    "<m:mrow>"
               .      "<m:mo fence='true'>(</m:mo>"
               .      "<omdoc:iterate name='args' "
               .          "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')>"
               .        "<omdoc:separator>#4</omdoc:separator>"
               .        "<omdoc:render name='arg' "
               .          "?&defined(&KeyVal(#1,'pi'))(precedence='&KeyVal(#1,'pi')')/>"
               .      "</omdoc:iterate>"
              .      "<m:mo fence='true'>)</m:mo>"
               .    "</m:mrow>"
               .    "#2"
               .  "</m:mrow>"
               ."</omdoc:rendering>",
       afterDigest=>sub {
         #Default argument precedence is -\infty
         my $keyval = $_[1]->getArg(1);
         $keyval->setValue('pi',-1000000) unless ($keyval && defined($keyval->getValue('pi')));
         applyPrecedencePreferences(@_);
       },
       properties=>sub { getSymmdefProperties($_[1]); });
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\infix}
%   |\infix|\ednote{need infixl as well, use counters for precedences here.} is a simple
%   special case of |\mixfixii|.
%    \begin{macrocode}
%<ltxml>RawTeX('
%<*package|ltxml>
\newcommand{\infix}[4][]{\mixfixii[#1]{}{#3}{#2}{#4}{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\assoc}
%    \begin{macrocode}
\newcommand{\assoc}[3][]{\mixfixa[#1]{}{#3}{}{#2}}
%</package|ltxml>
%<ltxml>');
%    \end{macrocode}
% \end{macro}
%
% \subsection{General Elision}\label{sec:impl:elision}
%
% \ednote{all of these still need to be tested and implemented in LaTeXML.}
% \begin{macro}{\setegroup}
%   The elision macros are quite simple, a group |foo| is internally represented by a
%   macro |foo@egroup|, which we set by a |\gdef|.
%    \begin{macrocode}
%<*package>
\def\setegroup#1#2{\expandafter\def\csname #1@egroup\endcsname{#2}}
%</package>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\elide}
%   Then the elision command is picks up on this (flags an error) if the internal macro
%   does not exist and prints the third argument, if the elision value threshold is above
%   the elision group threshold in the paper.\ednote{do we need to turn this around as
%     well?} We test the implementation with Figure~\ref{ex:elision-test}.
%    \begin{macrocode}
%<*package>
\def\elide#1#2#3{\@ifundefined{#1@egroup}%
{\def\@elevel{0}
\PackageError{presentation}{undefined egroup #1, assuming value 0}%
{When calling \protect\elide{#1}... the elision group #1 has be have\MessageBreak
been set by \protect\setegroup before, e.g. by \protect\setegroup{an}{0}.}}%
{\edef\@elevel{\csname #1@egroup\endcsname}}%
\ifnum\@elevel>#2\else{#3}\fi}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{figure}[ht]\centering
% \begin{tabular}{|l|l|l|l|}\hline
%   {\texttt{par}} &  {\texttt{typ}} & result & expected \\\hline\hline 
%    0 & 0 & \setegroup{par}{0}\setegroup{typ}{0}
%            $\mathbf{I}\elide{par}{500}{^\alpha}\elide{typ}{100}{_{\alpha\to\alpha}}
%             :=\lambda{X\elide{typ}{500}{_\alpha}}.X$
%    & $\mathbf{I}:=\lambda{X}.X$\\\hline
%    600 & 600 & \setegroup{par}{600}\setegroup{typ}{600}
%            $\mathbf{I}\elide{par}{500}{^\alpha}\elide{typ}{100}{_{\alpha\to\alpha}}
%             :=\lambda{X\elide{typ}{500}{_\alpha}}.X$
%    & $\mathbf{I}^\alpha:=\lambda{X_\alpha}.X$\\\hline
%    600 & 1000 & \setegroup{par}{600}\setegroup{typ}{1000}
%            $\mathbf{I}\elide{par}{500}{^\alpha}\elide{typ}{100}{_{\alpha\to\alpha}}
%             :=\lambda{X\elide{typ}{500}{_\alpha}}.X$
%    & $\mathbf{I}^\alpha_{\alpha\to\alpha}:=\lambda{X_\alpha}.X$\\\hline
%  \end{tabular}
%  \caption{Testing Elision with the example in Figure~\protect\ref{ex:elision}}\label{ex:elision-test}
% \end{figure}
%
% \begin{macro}{\provideEdefault}
%   The |\provideEdefault| macro sets up the context for an elision default by locally
%   defining the internal macro \meta{default}|@edefault| and (if necessary) exporting it
%   from the module. 
%    \begin{macrocode}
%<*package>
\def\provideEdefault#1#2{\expandafter\def\csname#1@edefault\endcsname{#2}
\@ifundefined{this@module}{}%
{\expandafter\g@addto@macro\this@module{\expandafter\def\csname#1@edefault\endcsname{#2}}}}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\setEdefault}
%   The |\setEdefault| macro just redefines the internal \meta{default}|@edefault| in the
%   local group
%    \begin{macrocode}
%<*package>
\def\setEdefault#1#2{\expandafter\def\csname #1@edfault\endcsname{#2}}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\fromEcontext}
%   The |\fromEcontext| macro just calls internal \meta{default}|@edefault| macro.
%    \begin{macrocode}
%<*package>
\def\fromEcontext#1{\csname #1@edefault\endcsname}
%</package>
%<*ltxml>
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Other Layout Primitives}\label{sec:impl:primitives}
% 
% The |\arrayline| and |\arraycell| macros are simple refactorings of the |array|
% functionality on the {\LaTeX} side\ednote{@Deyan, implement and describe them on the
% latexml side}
% 
% \begin{macro}{\arrayline}
%    \begin{macrocode}
%<package>\newcommand{\arrayline}[2]{#1#2\\}
%<*ltxml>
DefConstructor('\arrayline{}{}','<ltx:XMRow>#1<ltx:XMCell>#2</ltx:XMCell></ltx:XMRow>');
%</ltxml>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\arraycell}
%    \begin{macrocode}
%<package>\newcommand{\arraycell}[1]{#1&}
%<*ltxml>
DefConstructor('\arraycell{}','<ltx:XMCell>#1</ltx:XMCell>');
%</ltxml>
%    \end{macrocode}
% \end{macro}
%
% \subsection{Finale}
%
% Finally, we need to terminate the file with a success mark for perl.
%    \begin{macrocode}
%<ltxml>1;
%    \end{macrocode}
% \Finale
\endinput
%
% LocalWords:  dtx CPERL RequirePackage keyval lbrack rbrack DefKeyVal omdoc cd
% LocalWords:  Semiverbatim DefConstructor OptionalKeyVals pmml ltx XMath mii
% LocalWords:  pii miii piii KeyVal egroup namedef attr precs foreach ToString
% LocalWords:  DefMacro stex srcref argprec mrow getSymmdefProperties
% LocalWords:  args arg LaTeX cvar iffalse scsys sc sc mathml openmath latexml
% LocalWords:  cmathml activemath twintoo atwin atwintoo texttt fileversion foo
% LocalWords:  Deyan Ginev maketitle setcounter tocdepth tableofcontents symdef
% LocalWords:  newpage ldots bigl bigr langle ary cdots subseteq mixfixi exfig
% LocalWords:  mixfixii mixfixiii vspace hline sseteq ite tt tt tt tt uminus rb
% LocalWords:  texorpdfstring assoc ednote nunion mixfixa mixfixa postfixa leq
% LocalWords:  postfixa mixfixia mixfixia mixfixai mixfixai fntype rightarrow
% LocalWords:  mixfixaii mixfixiai mixfixiia typej vdash cupcap ninters ninters
% LocalWords:  capcup geq prec fset textbf textbf setegroup setegroup mathbf fn
% LocalWords:  provideEdefault provideEdefault fromEcontext fromEcontext mathrm
% LocalWords:  setEdefault setEdefault widetilde cdot vname vname vnref vnname
% LocalWords:  ulivar ulivar primvar primvar pprimvar pprimvar textsf textsf rl
% LocalWords:  printbibliography ltxml infty ifnum clearkeys nobrackets whatsit
% LocalWords:  ifundefined keyvals kvhash newcommand setkeys crossrefOp argv
% LocalWords:  tmpop i-th assocop textbackslash infixl gdef expandafter csname
% LocalWords:  endcsname edefault edfault ifx prepostfix circ circ circ circ
% LocalWords:  iprec iprec niprec niprec wrongset goodset prepost prepkeys
% LocalWords:  arrayline arraycell qquad hrule
