% \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 % https://svn.kwarc.info/repos/kwarc/projects/stex/sty/presentation.dtx % \fi % % \iffalse %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{presentation}[2007/09/03 v0.9e presentation for semantic macros] % %<*driver> \documentclass{ltxdoc} \usepackage{url,array,presentation,float} \usepackage[show]{ed} \usepackage{hyperref} \makeindex \floatstyle{boxed} \newfloat{exfig}{thp}{lop} \floatname{exfig}{Example} \begin{document}\DocInput{presentation.dtx}\end{document} % % \fi % % \CheckSum{373} % % \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} % % \GetFileInfo{presentation.sty} % % \MakeShortVerb{\|} %\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}} % \def\stex{{\raisebox{-.5ex}S\kern-.5ex\TeX}} % \def\sTeX{\stex} % \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{An Infrastructure for Presenting Semantic Macros in {\stex}\thanks{Version {\fileversion} (last revised % {\filedate})}} % \author{Michael Kohlhase\\ % Jacobs University, Bremen\\ % \url{http://kwarc.info/kohlhase}} % \maketitle % % \begin{abstract} % The |presentation| packge 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} % % 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{Mixfix Notations}\label{sec:mixfix} % % For the presentation of ordinary 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. 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}}|. % % Finally, we provide the \DescribeMacro{\infix}|\infix| macro for binary operators that % are written between their arguments (see Figure~\ref{fig:mixfix}). % % \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=0]{\{}{#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} % % These macros |\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!} % The |\mixfixii| macro has variants \DescribeMacro{\mixfixia}|\mixfixia|, % \DescribeMacro{\mixfixai}|\mixfixai|, and \DescribeMacro{\mixfixaa}|\mixfixaa|, which % allow to make one or two arguments in a binary function associative\footnote{If you % really need larger arities with associative arguments, contact the package author!}. 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} % and which will format |\fntype{\alpha,\beta,\gamma}\delta| as % $\alpha\times\beta\times\gamma\to\delta$. % % \subsection{Precedence-Based Bracket Elision}\label{sec:elision} % % With the infrastructure supplied by the |\assoc| macro we could now try to combine % set union and set intersection in one formula. Then, writing % \begin{equation}\label{cupcap} % |\nunion{\ninters{a,b},\ninters{c,d}}| % \end{equation} % would yield $((a\cap b)\cup (c\cap d))$, and not $a\cap b\cup c\cap d$ as we would like, % since $\cap$ binds stronger than $\cup$. Dropping outer brackets in the presentations of % the presentation of the operators will not help in general: it would give the desired % form for (\ref{cupcap}) but $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 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. The most common % is to assign precedences to all operators, and elide brackets, if the % {\index*{precedence}} of the operator is lower than that of the context it is presented % in. In our example above, we would assign $\cap$ a lower precedence than $\cup$ (and % both a lower precedence than the initial precedence). To compute the presentation of % (\ref{capcup}) we start out with the |\ninters|, elide its brackets (since the % precedence $n$ of $\cup$ is lower 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 lower than the context precedence $n$. % % This algorithm, which we call {\bf{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 thoug they could have been % elided by our algorithm. Therefore, the author has to retain full control over % bracketing in a bracket elision architecture (otherwise it would become impossible to % explain the concept of associativity).\ednote{think about how to implement that}. % % \begin{figure}[htb] % \begin{center} % \begin{tabular}{|l|l|l|}\hline % Precedence & Operators & Comment\\\hline\hline % 200 & +,- & unary \\\hline % 200 & $\hat{}$ & exponentiation \\\hline % 400 & $*,\land,\cap$ & multiplicative \\\hline % 500 & $+,-,\lor,\cup$ & additive\\\hline % 600 & / & fraction \\\hline % 700 & $=, \ne, \leq, <, >, \geq$ & relation\\\hline % \end{tabular} % \end{center} % \caption{Common Operator Precedences}\label{fig:precedence} % \end{figure} % % In {\stex} 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 % larger than the current precedence level --- which is set by the appropriate argument % precedence by the dominating operators or the outer 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 1000 and can be % set by {\DescribeMacro{\setDefaultPrecedence}}|\setDefaultPrecedence{|\meta{prec}|}| % where \meta{prec} is an integer. 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 lower than the default precedence of 1000, 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=400]{\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|. Just as above, we can also reset the default brackets % with {\DescribeMacro{\setDefaultLeftBracket}}|\setDefaultLeftBracket{|\meta{lb}|}|and % {\DescribeMacro{\setDefaultRightBracket}}|\setDefaultRightBracket{|\meta{rb}|}| where % \meta{lb} and \meta{rb} expand to the desired brackets. Note that formula parts that % look like brackets usually are not. For instance, we should not define the finite set % constructor via % \begin{verbatim} % \newcommand{\fset}[1]{\assoc[lbrack=\{,rbrack=\}]{,}{#1}} % \end{verbatim} % 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 would be able to make the brackets % disappear. % % \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 alreday 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. % % \DescribeMacro{\elide} To provide this functionality, the |presentation| package % provides the |\elide| macro allows to asociate a text with an integer % {\bf{visibility level}} and group them into {\bf{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$. \DescribeMacro{\setelevel} We specify % this threshold for via the |\setelevel| 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{ty}{500}{_\alpha}}.X$ % \end{verbatim} % \vspace{-2em} % \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 paraemter on the $\mathbf{I}$ cominator 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}{1000}| and % |\setegroup{an}{1000}| will show $\mathbf{I}:=\lambda{X}.X$ eliding all redundant % information. If we have both values at 400, then we will see % $\mathbf{I}^\alpha:=\lambda{X_\alpha}.X$ and only if the threshold for |typ| dips below % 100, 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| macor 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{Hyperlinking}\label{sec:hyperlinking} % %\ednote{describe what we want to do here} % % \subsection{Variable Names} % % \ednote{what is the problem?} % % \DescribeMacro{\vname} |\vname| identifies a token sequence as a name, and provides 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 % |\vnameref| for copy and paste.\ednote{does this really work} % % \StopEventually{\ednotemessage} % % \section{The Implementation}\label{sec:implementation} % % We first make sure that the KeyVal package is loaded (in the right % version). For {\latexml}, we also initialize the package inclusions. % \begin{macrocode} %\RequirePackage{keyval}[1997/11/10] %<*ltxml> # -*- CPERL -*- package LaTeXML::Package::Pool; use strict; use LaTeXML::Package; RequirePackage('keyval'); % % \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{1000} \def\setDefaultPrecedence#1{\def\pres@default@precedence{#1}} \def\pres@initial@precedence{1000} \def\setInitialPrecedence#1{\def\pres@initial@precedence{#1}} \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} \def\setDefaultLeftBracket#1{\def\pres@default@lbrack{#1}} \def\setDefaultRightBracket#1{\def\pres@default@rbrack{#1}} % % \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} %\def\PrecSet#1{\def\pres@default@precedence{#1}} %<*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 |\pres@current@precedence| % \begin{macrocode} %\def\PrecWrite#1{\ifnum\pres@current@precedence>\pres@p\else{#1}\fi} % \end{macrocode} % \end{macro} % % \subsection{Mixfix Operators}\label{sec:impl:mixfix} % % \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}{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}}} % %<*ltxml> DefKeyVal('mi','lbrack','Semiverbatim'); DefKeyVal('mi','rbrack','Semiverbatim'); DefKeyVal('mi','p','Semiverbatim'); DefKeyVal('mi','pi','Semiverbatim'); % % \end{macrocode} % % \begin{macro}{\mixfixi} % \begin{macrocode} %<*package> \newcommand{\mixfixi}[4][]%key, pre, arg, post {\setkeys{mi}{#1}\prep@keys@mi\clearkeys \PrecWrite\pres@lbrack% write bracket if necessary #2{\edef\pres@current@precedence{\pres@pi}#3}#4% \PrecWrite\pres@rbrack} % %<*ltxml> DefConstructor('\mixfixi OptionalKeyVals:mi {}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" ."" ."" . "" . "#2" . "" . "#4" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macro}{\mixfixa} % \begin{macrocode} %<*package> \newcommand{\mixfixa}[5][]%key, pre, arg, post, assocop {\setkeys{mi}{#1}\prep@keys@mi\clearkeys% \PrecWrite\pres@lbrack{#2}{\@assoc\pres@pi{#5}{#3}}{#4}\PrecWrite\pres@rbrack} % %<*ltxml> DefConstructor('\mixfixa OptionalKeyVals:mi {}{}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" . "" ."" ."" . "" . "#2" . "" . "" . "#5" . "" . "" . "" . "#4" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macrocode} %<*package> \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}}% \let\pres@pii@key=\relax} % %<*ltxml> DefKeyVal('mii','lbrack','Semiverbatim'); DefKeyVal('mii','rbrack','Semiverbatim'); DefKeyVal('mii','p','Semiverbatim'); DefKeyVal('mii','pi','Semiverbatim'); DefKeyVal('mii','pii','Semiverbatim'); % % \end{macrocode} % % \begin{macro}{\mixfixii} % \begin{macrocode} %<*package> \newcommand{\mixfixii}[6][]%key, pre, arg1, mid, arg2, post {\setkeys{mii}{#1}\prep@keys@mii\clearkeys% \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} % %<*ltxml> DefConstructor('\mixfixii OptionalKeyVals:mi {}{}{}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" ."" ."" . "" . "#2" . "" . "#4" . "" . "#6" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macro}{\mixfixia} % \begin{macrocode} %<*package> \newcommand{\mixfixia}[7][]%key, pre, arg1, mid, arg2, post, assocop {\setkeys{mii}{#1}\prep@keys@mii\clearkeys% \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} % %<*ltxml> DefConstructor('\mixfixia OptionalKeyVals:mi {}{}{}{}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" . "" . "" ."" ."" . "" . "#2" . "" . "#4" . "" . "" . "#7" . "" . "" . "" . "#6" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macro}{\mixfixai} % \begin{macrocode} %<*package> \newcommand{\mixfixai}[7][]%key, pre, arg1, mid, arg2, post, assocop {\setkeys{mii}{#1}\prep@keys@mii\clearkeys% \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} % %<*ltxml> DefConstructor('\mixfixai OptionalKeyVals:mi {}{}{}{}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" . "" . "" ."" ."" . "" . "#2" . "" . "" . "#7" . "" . "" . "" . "#4" . "" . "#6" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macrocode} %<*package> \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}}} % %<*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'); % % \end{macrocode} % % \begin{macro}{\mixfixiii} % \begin{macrocode} %<*package> \newcommand{\mixfixiii}[8][]%key, pre, arg1, mid1, arg2, mid2, arg3, post {\setkeys{miii}{#1}\prep@keys@miii\clearkeys% \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} % %<*ltxml> DefConstructor('\mixfixiii OptionalKeyVals:mi {}{}{}{}{}{}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" . "" ."" ."" . "" . "#2" . "" . "#4" . "" . "#6" . "" . "#8" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \begin{macro}{\prefix, \postfix} % |\prefix|, |\prefixa|, |\postfix| and |\postfixa|\ednote{need prefixl and postfixl as % well, use counters for precedences here.} are simple special cases of |\mixfixi| and % |\mixfixa|. % \begin{macrocode} %<*package> \newcommand{\prefix}[3][]%key, fn, arg {\setkeys{mi}{#1}\prep@keys@mi\clearkeys #2\PrecWrite\pres@lbrack% write bracket if necessary {\edef\pres@current@precedence{\pres@pi}#3}% \PrecWrite\pres@rbrack} \newcommand{\postfix}[3][]%key, fn, arg {\setkeys{mi}{#1}\prep@keys@mi\clearkeys \PrecWrite\pres@lbrack% write bracket if necessary {\edef\pres@current@precedence{\pres@pi}#3}% \PrecWrite\pres@rbrack{#2}} \newcommand{\prefixa}[4][]{\mixfixa[#1]{#2}{#3}{}{#4}} \newcommand{\postfixa}[4][]{{#1}\mixfixa[#1]{}{#3}{#2}{#4}} % %<*ltxml> DefConstructor('\prefix OptionalKeyVals:mi {}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" ."" ."" . "" . "#2" . "" . "" ."", mode=>'inline_math'); DefConstructor('\postfix OptionalKeyVals:mi {}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" ."" ."" . "" . "" . "#2" . "" ."", mode=>'inline_math'); % % \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} %<*package> \newcommand{\infix}[4][]{\mixfixii[#1]{}{#3}{#2}{#4}{}} % %<*ltxml> DefMacro('\infix []{}{}{}','\mixfixii[#1]{}{#3}{#2}{#4}{}'); % % \end{macrocode} % \end{macro} % % \subsection{Associative Operators}\label{sec:impl:assoc} % % \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 % % \end{macrocode} % \end{macro} % % \begin{macro}{\assoc} % With the internal macro above, associatifivity is easily specified. % \begin{macrocode} %\newcommand{\assoc}[3][]{\mixfixa[#1]{}{#3}{}{#2}} %<*ltxml> DefConstructor('\assoc OptionalKeyVals:mi {}{}', "" . "" . ""##### need to get $cd and $name here. . "" . "" . "" . "" ."" ."" . "" . "" . "" . "#3" . "" . "" . "" . "" ."", mode=>'inline_math'); % % \end{macrocode} % \end{macro} % % \subsection{General Elision}\label{sec:impl:elision} % % \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} %\def\setegroup#1#2{\expandafter\def\csname #1@egroup\endcsname{#2}} %<*ltxml> % % \end{macrocode} % \end{macro} % % \begin{macro}{\setegroup} % 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. % \begin{macrocode} %<*package> \def\elide#1#2#3{\@ifundefined{#1@egroup}% {\def\@elevel{1000} \PackageError{presentation}{undefined egroup #1, assuming value 1000}% {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}{1000}.}}% {\edef\@elevel{\csname #1@egroup\endcsname}}% \ifnum\@elevel>#2\else{#3}\fi} % %<*ltxml> % % \end{macrocode} % \end{macro} % % \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}}}} % %<*ltxml> % % \end{macrocode} % \end{macro} % % \begin{macro}{\setEdefault} % The |\setEdefault| macro just redefines the internal \meta{default}|@edefault| in the % local group % \begin{macrocode} %\def\setEdefault#1#2{\expandafter\def\csname #1@edfault\endcsname{#2}} %<*ltxml> % % \end{macrocode} % \end{macro} % % \begin{macro}{\fromEcontext} % The |\fromEcontext| macro just calls internal \meta{default}|@edefault| macro. % \begin{macrocode} %\def\fromEcontext#1{\csname #1@edefault\endcsname} %<*ltxml> % % \end{macrocode} % \end{macro} % % \subsection{Variable Names} % % \begin{macro}{\vname} % a name macro\ednote{add some documentation here}\ednote{maybe this should go into the % structuresharing package?} % \begin{macrocode} %<*package> \def\MOD@namedef#1{\expandafter\def\csname MOD@name@#1\endcsname} \def\MOD@name[#1]#2{#2\def\@test{#2}\ifx\@test\empty\else\MOD@namedef{#1}{#2}\fi} \def\vname{\@ifnextchar[\MOD@name{\MOD@name[]}} % %<*ltxml> % % \end{macrocode} % \end{macro} % \begin{macro}{\vnameref} % \begin{macrocode} %\def\vnref#1{\csname MOD@name@#1\endcsname} % \end{macrocode} % \end{macro} % % \subsection{Hyperlinking} % % this only works for internal links\ednote{actually not at all!} % \begin{macrocode} %\def\hrcr#1#2{\hyperlink{#1@\mod@id}{#2}} %<*ltxml> % % \end{macrocode} % the following would work for external ones, if we could know the proper extension. % except that we should use |\char????| instead of |\#|, so that it parses % |\def\hrcr#1#2{\href{\hr@baseURL\jobname.\hr@EXT\##1@\mod@id}{#2}}| % where |\hr@baseURL| and |\hr@EXT| are defined in the file itself (they will need to go into % the |SMS| file as well) % % \subsection{Finale} % % Finally, we need to terminate the file with a success mark for perl. % \begin{macrocode} %1; % \end{macrocode} % \Finale \endinput % LocalWords: dtx CPERL RequirePackage keyval lbrack rbrack DefKeyVal omdoc % LocalWords: Semiverbatim DefConstructor OptionalKeyVals pmml ltx XMath mii % LocalWords: inline pii miii piii KeyVal egroup namedef