summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/stex/presentation/presentation.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-07-20 22:30:22 +0000
committerKarl Berry <karl@freefriends.org>2010-07-20 22:30:22 +0000
commitcdfe96a3444a4d0664b9702c4ff6fe6622257834 (patch)
tree577232accd4bf41d7480fae7c177ceef147c8fea /Master/texmf-dist/source/latex/stex/presentation/presentation.dtx
parent47e2d96a8faed88dfedd17ca5352227d585a6710 (diff)
stex update once more
git-svn-id: svn://tug.org/texlive/trunk@19548 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/stex/presentation/presentation.dtx')
-rw-r--r--Master/texmf-dist/source/latex/stex/presentation/presentation.dtx1368
1 files changed, 1368 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/stex/presentation/presentation.dtx b/Master/texmf-dist/source/latex/stex/presentation/presentation.dtx
new file mode 100644
index 00000000000..57e2352ede5
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/presentation/presentation.dtx
@@ -0,0 +1,1368 @@
+% \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}[2010/06/25 v1.0 presentation for semantic macros]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,presentation,float,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 1502 2010-07-20 08:17:00Z kohlhase $
+\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/presentation/presentation.dtx $
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{presentation.dtx}\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{557}
+%
+% \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}
+% \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}
+%
+% \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!}
+%
+% \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{Variable Names}\label{sec:inter:vname}
+%
+% In mathematics we often use complex variable names like $x'$, $g_n$, $f^1$,
+% $\widetilde\phi_i^j$ or even $foo$; for presentation-oriented {\LaTeX}, this is not a
+% problem, but if we want to generate content markup, we must show that are complex
+% identifiers (otherwise the variable name $foo$ might be mistaken for the product $f\cdot
+% o\cdot o$). In careful mathematical typesetting, |$sin$| is distinguished from |$\sin$|,
+% but we cannot rely on this effect for variable names.
+%
+% \DescribeMacro{\vname} |\vname| identifies a token sequence as a name, and allows the
+% user to provide an ASCII ({\xml}-compatible) identifier for it. The optional argument is
+% the identifier, and the second one the LaTeX representation. The identifier can also be
+% used with \DescribeMacro{\vname} |\vnref| for referencing. So, if we have used
+% |\vnname[xi]{x_i}|, then we can later use |\vnref{xi}| as a short name for
+% |\vname{x_i}|. Note that in output formats that are capable of generating structure
+% sharing, |\vnref{xi}| would be represented as a cross-reference.
+%
+% Since indexed variable names make a significant special case of complex identifiers, we
+% provides the macros \DescribeMacro{\livar}|\livar| that allows to mark up variables with
+% lower indices. If |\livar| is given an optional first argument, this is taken as a
+% name. Thus |\livar[foo]{x}1| is ``short'' for |\vname[foo]{x_1}|. The macros
+% \DescribeMacro{\livar}|\livar|, serve the analogous purpose for variables with upper
+% indices, and \DescribeMacro{\ulivar}|\ulivar| for upper and lower indices. Finally,
+% \DescribeMacro{\primvar}|\primvar| and \DescribeMacro{\pprimvar}|\pprimvar| do the same
+% for variables with primes and double primes (triple primes are bad style).
+%
+% \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.
+%
+% 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]
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+%</ltxml>
+% \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>
+DefMacro('\prefix[]{}{}','\@prefix[#1]{$\crossrefOp[fun]{#2}$}{$#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]{$\crossrefOp[fun]{#2}$}{$#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}
+%
+% \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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}'
+ . '{$\crossrefOp[fun]{#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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\crossrefOp[fun]{#6}$}'
+ . '{$\crossrefOp[fun]{#7}$}');
+DefConstructor('\@mixfixia 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>#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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ .'{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ .'{$\crossrefOp[fun]{#6}$}'
+ .'{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\crossrefOp[fun]{#6}$}{$#7 $}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\crossrefOp[fun]{#6}$}{$#7 $}'
+ . '{$\crossrefOp[fun]{#8}$}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\crossrefOp[fun]{#6}$}{$#7 $}'
+ . '{$\crossrefOp[fun]{#8}$}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}'
+ . '{$\crossrefOp[fun]{#4}$}{$#5 $}'
+ . '{$\crossrefOp[fun]{#6}$}{$#7 $}'
+ . '{$\crossrefOp[fun]{#8}$}'
+ . '{$\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]{$\crossrefOp[fun]{#2}$}{$#3 $}{$#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]{$\crossrefOp[fun]{#2}$}{$#3 $}{$#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{Variable Names}\label{sec:impl:vname}
+%
+% \begin{macro}{\vname}
+% a name macro; the first optional argument is an identifier \meta{id}, this is standard
+% for {\LaTeX}, but for {\latexml}, we want to generate attributes
+% |xml:id="cvar.|\meta{id}|"| and |name="|\meta{id}|"|. However, if no id was given in
+% we default them to |xml:id="cvar.|\meta{count}|"| and
+% |name="name.cvar.|\meta{count}|"|.
+% \begin{macrocode}
+%<*package>
+\newcommand{\vname}[2][]{#2\def\@opt{#1}\ifx\@opt\@empty\else\expandafter\gdef\csname MOD@name@#1\endcsname{#2}\fi}
+%</package>
+%<*ltxml>
+sub cvar_id {
+ my ($id)=@_;
+ $id=ToString($id);
+ if (!$id) {
+ $id=LookupValue('cvar_id');
+ $id=0 unless $id;
+ $id++;
+ AssignValue('cvar_id',$id,'global');
+ }
+ $id="cvar.$id"; $id;}
+DefConstructor('\vname[]{}',
+ "<ltx:XMWrap role='ID' xml:id='&cvar_id(#1)'>#2</ltx:XMWrap>",
+ requireMath=>1);
+DefConstructor('\crossrefOp[]{}',
+ "?#2(<ltx:XMApp role='CROSSREFOP'>"
+ . "<ltx:XMTok role='CROSSREFOP' cr='?#1(#1)(fun)'/>"
+ . "<ltx:XMWrap>#2</ltx:XMWrap>"
+ ."</ltx:XMApp>)()",
+ requireMath=>1);
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\vnref}
+% \begin{macrocode}
+%<*package>
+\def\vnref#1{\csname MOD@name@#1\endcsname}
+%</package>
+%<*ltxml>
+DefMacro('\vnref{}','\@XMRef{#1}');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+% \ednote{the following macros are just ideas, they need to be implemented and documented}
+% \begin{macro}{\uivar}
+% constructors for variables\ednote{these are document them above}
+% \begin{macrocode}
+%<ltxml>RawTeX('
+%<*package|ltxml>
+\newcommand{\primvar}[2][]{\vname[#1]{#2^\prime}}
+\newcommand{\pprimvar}[2][]{\vname[#1]{#2^{\prime\prime}}}
+\newcommand{\uivar}[3][]{\vname[#1]{{#2}^{#3}}}
+\newcommand{\livar}[3][]{\vname[#1]{{#2}_{#3}}}
+\newcommand{\ulivar}[4][]{\vname[#1]{{#2}^{#3}_{#4}}}
+%</package|ltxml>
+%<ltxml>');
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Finale}
+%
+% Finally, we need to terminate the file with a success mark for perl.
+% \begin{macrocode}
+%<ltxml>1;
+% \end{macrocode}
+% \Finale
+\endinput
+%
+% 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 locator 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
+% 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