summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/stex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-07-19 23:16:46 +0000
committerKarl Berry <karl@freefriends.org>2010-07-19 23:16:46 +0000
commit277ca449c86a187fe858defdcd6aa1830d3b2d0d (patch)
treea804dd4e397504655fc225e6f582554780c4115d /Master/texmf-dist/source/latex/stex
parentd515f1120311798486a522c56170bd519d9c6a7a (diff)
reinstate stex via new .tds.zip
git-svn-id: svn://tug.org/texlive/trunk@19538 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/stex')
-rw-r--r--Master/texmf-dist/source/latex/stex/assignment/assignment.dtx426
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/Makefile5
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/Modparse.pm189
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/README151
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/TexId.pm464
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/allgen30
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/bms340
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/checksum68
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/convert-paths56
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/filedate42
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/gen-symdef-table.pl85
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/idcheck29
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/msplit140
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/old/Makefile28
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/old/defcon.l91
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/old/idcheck.l130
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/old/modstr.l137
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/old/symdef46
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/rf63
-rw-r--r--Master/texmf-dist/source/latex/stex/bin/rng2dot/ModelRNC.pm770
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/rng2dot/rng2dot37
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/sgraph173
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/sms135
-rwxr-xr-xMaster/texmf-dist/source/latex/stex/bin/termin279
-rw-r--r--Master/texmf-dist/source/latex/stex/cmathml/cmathml.dtx2493
-rw-r--r--Master/texmf-dist/source/latex/stex/cnx/cnx.dtx1176
-rw-r--r--Master/texmf-dist/source/latex/stex/mikoslides.dtx503
-rw-r--r--Master/texmf-dist/source/latex/stex/problem/problem.dtx540
-rw-r--r--Master/texmf-dist/source/latex/stex/xsl/ltxml2cnx.xsl43
-rw-r--r--Master/texmf-dist/source/latex/stex/xsl/omdocpost.xsl441
-rw-r--r--Master/texmf-dist/source/latex/stex/xsl/owl2post.xsl62
31 files changed, 9172 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/stex/assignment/assignment.dtx b/Master/texmf-dist/source/latex/stex/assignment/assignment.dtx
new file mode 100644
index 00000000000..bed15998630
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/assignment/assignment.dtx
@@ -0,0 +1,426 @@
+% \iffalse meta-comment
+% An Infrastructure for marking up Assignments
+% $URL: https://svn.kwarc.info/repos/stex-content/sty/assignment/assignment.dtx $
+% $Rev: 2871 $; last modified by $Author: kohlhase $
+% $Date: 2010-05-29 07:43:20 +0200 (Sat, 29 May 2010) $
+% Copyright (c) 2007 Michael Kohlhase, all rights reserved
+% this file is released under the
+% LaTeX Project Public License (LPPL)
+% \fi
+%
+% \iffalse
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{assignment}[2010/06/25 v0.9a assignment documents]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,float}
+\usepackage[show]{ed}
+\usepackage{hyperref}
+\usepackage{assignment}
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{assignment.dtx}\end{document}
+%</driver>
+% \fi
+% \changes{v0.9}{2006/09/18}{First Version with Documentation}
+%
+% \GetFileInfo{assignment.sty}
+%
+% \MakeShortVerb{\|}
+%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\latexml{\scsys{LaTeXML}}
+%
+% \title{An Infrastructure for formatting Assignments\thanks{Version {\fileversion} (last revised
+% {\filedate})}}
+% \author{Michael Kohlhase\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% The |assignment| packge allows individual course assignment sheets and compond
+% assignment documents using problem files marked up with the |problem| package.
+% \end{abstract}
+% \setcounter{tocdepth}{2}\tableofcontents\newpage
+%
+%\section{Introduction}\label{sec:intro}
+%
+% The |assignment| package supplies an infrastructure that allows to format nice-looking
+% assignment sheets by simply including problems from problem files marked up with the
+% |problem| package. It is designed to be compatible with |problems.sty|, and inherits
+% some of the functionality.
+%
+% \section{The User Interface}
+%
+% \subsection{Assignments}
+% \DescribeEnv{assignment} This package supplies the |assignment| environment that groups
+% problems into assignment sheets. It takes an optional KeyVal argument with the keys
+% \DescribeMacro{number}|number| (for the assignment number; if none is given, 1 is
+% assumed as the default or --- in multi-assignment documents --- the ordinal of the
+% |assignment| environment), \DescribeMacro{title}|title| (for the assignment title; this
+% is referenced in the title of the assignment sheet), \DescribeMacro{type}|type| (for the
+% assignment type; e.g. ``quiz'', or ``homework''), \DescribeMacro{given}|given| (for the
+% date the assignment was given), and \DescribeMacro{due}|due| (for the date the
+% assignment is due).
+%
+% \DescribeMacro{\CourseTitle} |\Coursetitle{|\meta{title}|}| can be used to specify the
+% title of the course. It is usually specified in the driver file.
+%
+% \DescribeMacro{\AssignmentType} Similarly, |\AssignmentType{|\meta{type}|}| can be used
+% to specify the default assignment type.
+%
+% The |assignment| package takes the options \DescribeMacro{solutions}|solutions|,
+% \DescribeMacro{notes}|notes|, \DescribeMacro{hints}|hints|, \DescribeMacro{pts}|pts|,
+% \DescribeMacro{min}|min|, and \DescribeMacro{boxed}|boxed| that are just passed on to
+% the |problems| package (cf. its documentation for a description of the intended
+% behavior).
+%
+% \subsection{Typesetting Exams}
+%
+% Furthermore, the |assignment| package takes the option
+% \DescribeMacro{multiple}|multiple| that allows to combine multiple assigment sheets into
+% a compound document (the assignment sheets are treated as section, there is a table of
+% contents, etc.).
+%
+% Finally, there is the option \DescribeMacro{test}|test| that modifies the behavior to
+% facilitate formatting tests. Only in |test| mode, the macros |\testspace|,
+% |\testnewpage|, and |\testemptypage| have an effect: they generate space for the
+% students to solve the given problems. Thus they can be left in the {\LaTeX} source.
+%
+% \DescribeMacro{\testspace}|\testspace| takes an argument that expands to a dimension,
+% and leaves vertical space accordingly. \DescribeMacro{\testnewpage}|\testnewpage| makes
+% a new page in |test| mode, and \DescribeMacro{\testemptypage}|\testemptypage| generates
+% an empty page with the cautionary message that this page was intentionally left empty.
+%
+% Finally, the \DescribeMacro{\testheading}|\testheading| takes a keyword argument where
+% the keys |duation| specifies a string that specifies the duration of the test, |min|
+% specifies the equivalent in number of minutes, and |reqpts| the points that are required
+% for a perfect grade.
+% \begin{exfig}[ht]
+% \makeatletter
+% \@problem{1.1}{4}{10}
+% \@problem{2.1}{4}{8}
+% \@problem{2.2}{6}{10}
+% \@problem{2.3}{6}{10}
+% \@problem{3.1}{4}{8}
+% \@problem{3.2}{4}{8}
+% \@problem{3.3}{2}{4}
+% \makeatother
+% \begin{verbatim}
+% \testheading{duration=one hour,min=60,reqpts=27}
+% \end{verbatim}
+% \vspace*{-3ex}\hrule\vspace*{.5ex} formats to\vspace*{1ex} \hrule\par\noindent\vspace*{2ex}
+% \testheading{duration=one hour,min=60,reqpts=27}
+% \caption{A generated test heading.}\label{fig:testheading}
+% \end{exfig}
+%
+% \subsection{Including Assignments}
+%
+% The \DescribeMacro{\includeassignment}|\includeassignment| macro can be used to include
+% an assignment from another file. It takes an optional KeyVal argument and a second
+% argument which is a path to the file containing the problem (the macro assumes that
+% there is only one |assignment| environment in the included file). The keys
+% \DescribeMacro{number}|number|, \DescribeMacro{title}|title|,
+% \DescribeMacro{type}|type|,\DescribeMacro{given}|given|, and \DescribeMacro{due}|due|
+% are just as for the |assignment| environment and (if given) overwrite the ones specified
+% in the |assignment| environment in the included file.
+%
+% \StopEventually{\newpage\PrintChanges}
+% \newpage
+%
+% \section{The Implementation}
+%
+% \subsection{Package Options}
+%
+% The first step is to declare (a few) package options that handle whether certain
+% information is printed or not. Some come with their own conditionals that are set by the
+% options, the rest is just passed on to the |problems| package.
+%
+% \begin{macrocode}
+%<*package>
+\newif\iftest\testfalse
+\newif\ifsolutions\solutionsfalse
+\DeclareOption{test}{\testtrue\solutionsfalse}
+\newif\ifmultiple\multiplefalse
+\DeclareOption{multiple}{\multipletrue}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{problem}}
+\ProcessOptions
+%</package>
+% \end{macrocode}
+% Then we make sure that the necessary packages are loaded (in the right versions).
+% \begin{macrocode}
+%<*package>
+\RequirePackage{keyval}[1997/11/10]
+\RequirePackage{problem}
+%</package>
+% \end{macrocode}
+%
+% Here comes the equivalent header information for {\latexml}, we also initialize the
+% package inclusions. Since {\latexml} does not handle options yet, we have nothing to
+% do.
+% \begin{macrocode}
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+RequirePackage('problem');
+%</ltxml>
+% \end{macrocode}
+%
+% Then we register the namespace of the requirements ontology
+% \begin{macrocode}
+%<*ltxml>
+RegisterNamespace('assig'=>"http://omdoc.org/ontology/assignments#");
+RegisterDocumentNamespace('assig'=>"http://omdoc.org/ontology/assignments#");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Assignments}
+%
+% We will prepare the keyval support for the |assignment| environment.
+%
+% \begin{macrocode}
+%<*package>
+\omdaddkey{assig}{number}
+\omdaddkey{assig}{title}
+\omdaddkey{assig}{type}
+\omdaddkey{assig}{given}
+\omdaddkey{assig}{due}
+%</package>
+% \end{macrocode}
+%
+% The next macro just sets the internal token register to the intended string.
+%
+% \begin{macrocode}
+%<*package>
+\def\AssignmentType#1{\gdef\assig@default@type{#1}}
+\def\assig@default@type{Assignment}
+%</package>
+%<*ltxml>
+%</ltxml>
+% \end{macrocode}
+%
+% The next three macros are intermediate functions that handle the case gracefully, where
+% the respective token registers are undefined.
+%
+% \begin{macrocode}
+%<*package>
+\def\Assig@Type{\ifx\assig@type\@empty\assig@default@type\else\assig@type\fi}
+\def\Assig@Title{\ifx\assig@title\@empty\else\assig@title~\fi}
+% \end{macrocode}
+%
+% The |\given@due| macro prints information about the given and due status of the
+% assignment. Its arguments specify the brackets.
+%
+% \begin{macrocode}
+\def\given@due#1#2{%
+\ifx\assig@given\@empty\else\ifx\assig@due\@empty\else{#1}\fi\fi%
+\ifx\assig@given\@empty\else{Given {\assig@given}}\fi%
+\ifx\assig@given\@empty\else\ifx\assig@due\@empty\else{, }\fi\fi%
+\ifx\assig@due\@empty\else{Due {\assig@due}}\fi%
+\ifx\assig@given\@empty\else{\ifx\assig@due\@empty\else{#2}\fi}\fi}
+%</package>
+% \end{macrocode}
+%
+% With them, we can define the central |assignment| environment. This has two forms
+% (separated by |\ifmultiple|) in one we make a title block for an assignment sheet, and
+% in the other we make a section heading and add it to the table of
+% contents.
+%
+% \begin{environment}{assignment}
+% \begin{macrocode}
+%<*package>
+\newenvironment{assignment}[1][]% keyval args
+{\omdsetkeys{assig}{#1}% collect the keys and correct them from the outside
+\@ifundefined{incl@assig@title}{}{\def\assig@title{\incl@assig@title}}
+\@ifundefined{incl@assig@type}{}{\def\assig@type{\incl@assig@type}}
+\@ifundefined{incl@assig@num}{}{\def\assig@num{\incl@assig@num}}
+\@ifundefined{incl@assig@due}{}{\def\assig@due{\incl@assig@due}}
+\@ifundefined{incl@assig@given}{}{\def\assig@given{\incl@assig@given}}
+\@ifundefined{assig@num}{\stepcounter{section}}%
+{\setcounter{section}{\assig@num}\setcounter{problem}{0}}
+\ifmultiple%
+\section*{\Assig@Type~\arabic{section}:~\Assig@Title\given@due{\\(})}
+ \addcontentsline{toc}{section}{\Assig@Type~{\arabic{section}}:~\Assig@Title}
+\else
+\begin{center}
+\Large\Course@Title\\
+{\bf{\Assig@Type}~{\arabic{section}}:~\Assig@Title\strut\\\large{\given@due()}}
+\end{center}
+\fi%ifmultiple
+}{}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*ltxml>
+DefEnvironment('{assignment} OptionalKeyVals:assig',
+ "<omdoc:omgroup ?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')() "
+ . "assig:dummy='for the namespace'"
+ . "?#locator(stex:srcref='#locator')()>"
+ . "<omdoc:metadata ?#locator(stex:srcref='#locator')()>"
+ . "<dc:title ?#locator(stex:srcref='#locator')()>"
+ . "Assignment ?&KeyVal(#1,'num')(&KeyVal(#1,'num').)()"
+ . "?&KeyVal(#1,'title')((&KeyVal(#1,'title')))"
+ . "</dc:title>"
+ . "?&KeyVal(#1,'given')(<omdoc:meta property='assig:given'>&KeyVal(#1,'given')</omdoc:meta>)()"
+ . "?&KeyVal(#1,'due')(<omdoc:meta property='assig:due'>&KeyVal(#1,'due')</omdoc:meta>)()"
+ . "?&KeyVal(#1,'pts')(<omdoc:meta property='assig:pts'>&KeyVal(#1,'pts')</omdoc:meta>)()"
+ . "</omdoc:metadata>"
+ . "#body"
+ ."</omdoc:omgroup>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Including Assignments}
+%
+% The next command is essentially a glorified |\include| statement, it just sets some
+% internal macros first that overwrite the local points,
+%
+% \begin{macrocode}
+%<*package>
+\define@key{incl@assig}{number}{\def\incl@assig@num{#1}}
+\define@key{incl@assig}{title}{\def\incl@assig@title{#1}}
+\define@key{incl@assig}{type}{\def\incl@assig@type{#1}}
+\define@key{incl@assig}{given}{\def\incl@assig@given{#1}}
+\define@key{incl@assig}{due}{\def\incl@assig@due{#1}}
+\newcommand{\includeassignment}[2][]{\bgroup\setkeys{incl@assig}{#1}\include{#2}\egroup}
+%</package>
+%<*ltxml>
+DefMacro('\includeassignment [] {}','\input{#2}');
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\def\CourseTitle#1{\gdef\Course@Title{#1}}
+%</package>
+%<*ltxml>
+DefConstructor('\CourseTitle{}','');
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Typesetting Exams}
+%
+% \begin{macrocode}
+%<*package>
+\omdaddkey{testheading}{min}
+\omdaddkey{testheading}{duration}
+\omdaddkey{testheading}{reqpts}
+\def\testheading#1{\omdsetkeys{testheading}{#1}
+{\noindent\large NAME: \\[1ex] MATRICULATION NUMBER:\\[2ex]
+ {\textbf{You have
+\ifx\test@heading@duration\@empty\testheading@min minutes\else\testheading@duration\fi
+(sharp) for the test}};\\ Write the solutions to the sheet.}\par\noindent
+
+\newcount\check@time\check@time=\testheading@min
+\advance\check@time by -\theassignment@totalmin
+The scheduled time for solving this exam is {\theassignment@totalmin} minutes,
+leaving you {\the\check@time} minutes for revising your exam.
+
+\newcount\bonus@pts\bonus@pts=\theassignment@totalpts
+\advance\bonus@pts by -\testheading@reqpts
+You can reach {\theassignment@totalpts} points if you solve all problems. You will only need
+{\testheading@reqpts} points for a perfect score, i.e.\ {\the\bonus@pts} points are
+bonus points. \vfill
+\begin{center}
+ {\Large\em
+% You have ample time, so take it slow and avoid rushing to mistakes!\\[2ex]
+ Different problems test different skills and knowledge, so do not get stuck on
+ one problem.}\vfill\par\correction@table
+\end{center}\newpage}
+%</package>
+%<*ltxml>
+DefConstructor('\testheading{}','');
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\def\testspace#1{\iftest\vspace*{#1}\fi}
+\def\testnewpage{\iftest\newpage\fi}
+\def\testemptypage{\iftest\begin{center}This page was intentionally left
+ blank for extra space\end{center}\vfill\eject\else\fi}
+%</package>
+%<*ltxml>
+DefConstructor('\testspace{}','');
+DefConstructor('\testnewpage','');
+DefConstructor('\testemptypage','');
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macro}{\@problem}
+% This macro acts on a problem's record in the |*.aux| file. Here we redefine it to
+% generate the correction table.
+% \begin{macrocode}
+%<*package>
+\def\@problem#1#2#3{\stepcounter{assignment@probs}
+\def\@test{#2}\ifx\@test\@empty\else\addtocounter{assignment@totalpts}{#2}\fi
+\def\@test{#3}\ifx\@test\@empty\else\addtocounter{assignment@totalmin}{#3}\fi
+\xdef\correction@probs{\correction@probs & #1}%
+\xdef\correction@pts{\correction@pts & #2}
+\xdef\correction@reached{\correction@reached &}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\correction@table}
+% This macro generates the correction table
+% \begin{macrocode}
+%<*package>
+\newcounter{assignment@probs}
+\newcounter{assignment@totalpts}
+\newcounter{assignment@totalmin}
+\def\correction@probs{prob.}%
+\def\correction@pts{total}%
+\def\correction@reached{reached}%
+\stepcounter{assignment@probs}
+\def\correction@table{\begin{tabular}{|l|*{\theassignment@probs}{c|}|p{3cm}|}\hline%
+&\multicolumn{\theassignment@probs}{c||}%
+{\footnotesize To be used for grading, do not write here} &\\\hline
+\correction@probs & Sum & grade\\\hline
+\correction@pts &\theassignment@totalpts & \strut\hspace{3cm}\strut\\\hline
+\correction@reached & & \\[.7cm]\hline
+\end{tabular}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Leftovers}
+%
+% at some point, we may want to reactivate the logos font, then we use
+% \begin{verbatim}
+% here we define the logos that characterize the assignment
+% \font\bierfont=../assignments/bierglas
+% \font\denkerfont=../assignments/denker
+% \font\uhrfont=../assignments/uhr
+% \font\warnschildfont=../assignments/achtung
+%
+% \def\bierglas{{\bierfont\char65}}
+% \def\denker{{\denkerfont\char65}}
+% \def\uhr{{\uhrfont\char65}}
+% \def\warnschild{{\warnschildfont\char 65}}
+% \def\hardA{\warnschild}
+% \def\longA{\uhr}
+% \def\thinkA{\denker}
+% \def\discussA{\bierglas}
+% \end{verbatim}
+%
+% Finally, we need to terminate the file with a success mark for perl.
+% \begin{macrocode}
+%<ltxml>1;
+% \end{macrocode}
+% \Finale
+\endinput
+% \iffalse
+% LocalWords: GPL structuresharing STR
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
diff --git a/Master/texmf-dist/source/latex/stex/bin/Makefile b/Master/texmf-dist/source/latex/stex/bin/Makefile
new file mode 100644
index 00000000000..c603315a964
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/Makefile
@@ -0,0 +1,5 @@
+all:
+
+clean:
+ rm -f *~
+
diff --git a/Master/texmf-dist/source/latex/stex/bin/Modparse.pm b/Master/texmf-dist/source/latex/stex/bin/Modparse.pm
new file mode 100644
index 00000000000..3c4cc8c9dd4
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/Modparse.pm
@@ -0,0 +1,189 @@
+#######################################################################################
+# A module for loading .tex files and feeding the data to the various applications. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/Modparse.pm$ #
+# $Date: 2005-09-26 12:44:28 -0500 (Mon, 26 Sep 2005) $ $Rev: 4243 $ #
+#######################################################################################
+
+package Modparse;
+
+use File::Basename;
+use File::Path;
+
+# if both snippath and snippathList are specified,
+# snippathList is ignored !
+
+# if a default snippath definition file is found
+# (snippath.def) it is used if no snippath is given
+# as argument;
+sub new {
+ my ($class, %options) = @_;
+
+ $options{recursion} = 1 unless defined $options{recursion};
+ $options{requireStatus} = 'include|exclude' unless defined $options{requireStatus};
+ $options{loadInputs} = 1 unless defined $options{loadInputs};
+ $options{onlyModuleLines} = 0 unless defined $options{onlyModuleLines};
+
+ if ( !(%{$options{snippath}}) && (-e "snippath.def") ) {
+ open(SNIPPATHDEF, 'snippath.def');
+ my @snlist = <SNIPPATHDEF>;
+ close(SNIPPATHDEF);
+ for (my $i = 0 ; $i <= $#snlist; $i++) { chomp($snlist[$i]); }
+ %{$options{snippath}} = @snlist; }
+ @{$options{snippathList}} = keys(%{$options{snippath}})
+ if ($options{snippath} && %{$options{snippath}});
+ $options{debug} = 0;
+
+ bless(\%options, $class); }
+
+sub execute{
+ my ($self, $file) = @_;
+
+ local *run_event = sub {
+ my ($event, $arg) = @_;
+ if ($self->{$event}) { $self->{$event}($arg); }
+ };
+
+ local *go = sub {
+ my ($location, %param) = @_;
+ my ($tex, $path, @tex_data) = $self->readLocation($location);
+ return unless @tex_data;
+ my $NL = $#tex_data+1;
+
+ $param{filename} = $tex;
+ $param{depth}++;
+ $param{filecount}++;
+ my $i = 0;
+
+ $param{nextline} = sub { $tex_data[++$i]; };
+ $param{prevline} = sub { $tex_data[--$i]; };
+ $param{rewriteline}= sub { $tex_data[$i] = $_[0]; };
+
+ print "Processing $tex...\n" if $self->{verbose};
+ run_event('onBeginFile', \%param);
+
+ while ($i<$NL){
+ $param{original} = $tex_data[$i];
+ $_ = $tex_data[$i]; chomp; /([^%]*)((%.*)?)/;
+ ($param{tex}, $param{comment}) = ($1, $2); $_ = $1;
+ s/\s+//g; $param{simple_tex} = $_;
+
+ if (/\\begin\{module\}(\[([^\]]*)\])?/) {
+ if ($param{in_module}) {
+ push(@{$param{module_stack}}, [$param{module_id}, $param{module_arg}]); }
+ $param{in_module} = 1;
+ $param{module_args} = $1 ? $2 : undef;
+ $param{module_id} = ($param{module_args} &&
+ $param{module_args} =~ /id=([^\],]+)/) ? $1 : undef;
+ $param{module_nesting}++;
+ run_event('onBeginModule', \%param); }
+
+ if (/\\end\{module\}/) {
+ run_event('onEndModule', \%param);
+ if ($#{$param{module_stack}} >= 0) {
+ ($param{module_id}, $param{module_args}) = @{pop(@{$param{module_stack}})};
+ } else {
+ $param{in_module} = 0;
+ ($param{module_id}, $param{module_args}) = (undef, undef); }
+ $param{module_nesting}--;
+ }
+
+ foreach my $srch_snippath(@{$self->{snippathList}}){
+ $self->{snippath}{$srch_snippath} = $1
+ if (/\\def\\$srch_snippath\#1\{([^\#]+)\#1\}$/); }
+
+ if (/\\((requiremodules(\[($self->{requireStatus})\])?)|input|include)\{([^\}]+)\}/){
+ my $req_filename = $5; my $req_spath = ''; my $command = $1;
+ my $is_require = ($command =~ /requiremodules/) ? 1 : 0;
+ if ($is_require || $self->{loadInputs}) {
+ foreach my $srch_snippath(@{$self->{snippathList}}){
+ if ($req_filename =~ /\\$srch_snippath\{(.+)/){
+ ($req_spath, $req_filename) = ($self->{snippath}{$srch_snippath}, $1);
+ last; }}
+ run_event('onRecurse', \%param);
+ if ($self->{recursion} || !$is_require) {
+ go($self->makeLocation($req_filename, $path, $req_spath), %param); }
+ }
+ }
+ run_event('onEveryLine', \%param) if ($param{in_module} || !$self->{onlyModuleLines});
+
+ last if (/\\end\{document\}/ && $self->{stopAtEnd});
+ $i++;
+ }
+ run_event('onEndFile', \%param);
+ $param{depth}--; return;
+ };
+
+ my %param = (pack=>$self, perm=>$self->{_AUX_DATA}, depth=>0, filecount=>0,
+ in_module=>0, module_nesting=>0);
+ run_event('onBegin', \%param);
+ go($self->makeLocation($file), %param);
+ run_event('onEnd', \%param);
+ return;
+}
+
+
+# add a [.tex] extension to the filename
+sub add_ext{
+ my ($self, $fn, $ext) = @_;
+ $ext = '.tex' unless $ext;
+ $fn.=$ext if $fn !~ /\Q$ext\E$/;
+ $fn; }
+
+# as long as the extension is .tex, drop it
+sub drop_ext{
+ my ($self, $filename) = @_;
+ while ($filename =~ /\.tex$/){
+ while ($filename !~ /\.$/ ) { chop($filename); }
+ chop($filename); }
+ $filename; }
+
+sub new_ext{
+ my ($self, $filename, $ext) = @_;
+ $self->add_ext($self->drop_ext($filename), $ext); }
+
+# location = pointer to array of strings
+# first element is filename; next are possible paths
+sub makeLocation{ my $self = shift; return \@_; }
+
+# read a location into an array of strings
+# aslo return filename and path to it (just in
+# case some changes were made to it, like adding
+# extension and/or relative paths)
+sub readLocation{
+ my ($self, $location) = @_;
+
+ my ($filename, @paths) = @{$location};
+ # try to add proper extension;
+ my $filename_ext = $self->new_ext($filename) unless -e $filename;
+ $filename = $filename_ext if $filename_ext && -e $filename_ext;
+
+ # try search paths
+ if (! -e $filename){
+ my $all_p = '';
+ foreach my $p(@paths){
+ $all_p .= $p;
+ $filename = $all_p.$filename and last if -e $all_p.$filename;
+ $filename = $p.$filename and last if -e $p.$filename;
+ if ($filename_ext){
+ $filename = $all_p.$filename_ext and last if -e $all_p.$filename_ext;
+ $filename = $p.$filename_ext and last if -e $p.$filename_ext; }
+ }}
+ # don't do the same work too many times
+ foreach my $file(@{$self->{loadedFiles}})
+ { return undef if $file eq $filename; }
+
+ push(@{$self->{loadedFiles}}, $filename);
+ open(FIN, $filename) or die "Cannot open '$filename'\n";
+ my @data = <FIN>;
+ close(FIN);
+
+ # find path of current file
+ my $path = dirname($filename);
+ $path.='/' if ($path ne '');
+
+ return ($filename, $path, @data);
+}
+
+1;
diff --git a/Master/texmf-dist/source/latex/stex/bin/README b/Master/texmf-dist/source/latex/stex/bin/README
new file mode 100644
index 00000000000..6af84e42bab
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/README
@@ -0,0 +1,151 @@
+msplit
+"Module Split"
+
+Usage:
+ msplit <input filename> [options]
+
+Options:
+ --output <filename> filename of new main .tex file; default stdout
+ --path <path> path where to write the module files;
+ --header <filename> filename of header file to be included in all new .tex files
+ --verbose verbose on
+ --stop stop when \end{document} is found, not at EOF
+ --help show help screen
+
+
+NOTE: All options '--xoption' can be replaced by '-x' as long as there is only one option starting with 'x'
+
+This program splits the .tex file given at input into:
+ one main .tex file, that includes
+ more .tex files, each containing one module
+
+The name of the new main .tex file is specified by output option. The path to the inputted
+files can be specified by path. The name of one generated input file is "name of the
+module it contains".tex Running on one already split file will just make a copy. Example
+usage: ./msplit slides.tex -o sl.tex -p ./modules -s
+
+Interpretation: "Split the file slides.tex; wite the new main file as sl.tex and the
+inputted files should be placed in ./modules; if path does not exist, it is automatically
+created; stop when (uncommented) \end{document} is found."
+
+
+
+rf
+"Reuse Factor"
+
+Usage:
+ rf [options]
+
+Options:
+ --input <filename> .tex input file. stdin by default
+ --stop stop when \end{document} is found, not at EOF
+ --verbose verbose on
+ --help show help screen
+
+
+This program computes the reuse factor for the .tex document given at input. This number
+represents the ratio of latex processed lines of code to actual lines contained in file
+given at input. This number will always be 1 for files that have no \input or \include.
+
+Example usage:
+./rf -v -i slides.tex
+Interpretation: "Compute the reuse factor of slides.tex and show all processed files(verbose mode)."
+
+
+
+sgraph
+"Slides graph [representation]"
+
+Usage:
+ sgraph [options]
+
+Options:
+ --input <filename> .tex input file; stdin by default
+ --output <filename> output file; out.dot by default
+ --format <ps|png|jpg|...> output format; .ps by default; for available formats, see dot --help
+ --nodot do not generate .dot file, just target format
+ --root <string> the 'root' of the graph. (name of course)
+ --theory <string> generate a subgraph for the theory
+ --sliderange <begin:end> only look at the given slide range; (2:16 for example)
+ --stop stop reading data when \end{document} is found, not at EOF
+ --verbose verbose on
+ --help show help screen
+
+This program generates a .dot file readable by graphviz, containing a graph of the module
+usage in the .tex file given at input, optionally looking at a specific theory and/or
+slide range; it also adds a dummy 'root' for the graph, so one can see where everything
+starts. It then converts the .dot file to a given format (.ps by default) using graphviz
+and optionally deletes the intermediary .dot file.
+
+Example usage:
+./sgraph -i slides.tex -o graph -f ps -n -t TCN --sliderange 20:10000 -r GenCS -v
+
+Interpretation: "Generate the graph of slides.tex in .ps format, write it in graph.ps, do
+not keep the .dot file; include only the part needed for the theory 'TCN' and in the slide
+range 20 to 10000; use as root for the graph the string 'GenCS' and show all processed
+files."
+
+
+sms
+??
+
+Usage:
+ sms [options]
+
+Options:
+ --input <filename> .tex file to split; default stdin
+ --verbose verbose on
+ --stop stop when \end{document} is found, not at EOF
+ --help show help screen
+
+Generate .sms file from .tex file given at input; .sms files contain only the modules and
+the macros defined within, no other text.
+
+Example usage:
+./sms -i slides.tex -s
+
+Interpretation: "Generate the slides.sms file for slides.tex; Stop when \end{document} is found."
+
+
+
+
+bms
+"Build Module Structure"
+
+Usage:
+ bms [options]
+
+Options:
+ --input <filename> .tex file to read from
+ --graph <filename> if mentioned, produce the suggested module structure as
+ a graphviz digraph (.dot file)
+ --path <pathname> if mentioned, produce same input file/s (including
+ dependencies) in specified path with suggested
+ module structure.
+ --output <filename> the new name of the main .tex file in specified path
+ --root <string> if mentioned, a father module is included, so that all
+ other modules descend from it. generally the course name
+ --stop stop when \end{document} is found; default is to go on
+ --definitions show a list of all definitions
+ --verbose verbose on
+ --help show help screen
+
+
+This program has the purpose of computing a default module structure, such that a module
+uses another module if and only if it needs that module and does not need another
+descendant of it. First, the prgram reads all necessary data from the input .tex file,
+computes the minimal strictly required module usage structure, and writes it as a graphviz
+digraph, and/or writes a copy of the input .tex file (and maybe inputted files by the .tex
+file) with the new module structure in the given path. All paths are created if not
+existing.
+
+Example usage:
+./bms -i slides.tex -s -g - | dot -Tps > out.ps; ggv out.ps
+./bms -i slides.tex -g out.dot -p ./new
+
+Interpretation: "Build default module structure for slides.tex and write it to out.dot;
+also use the obtained module structure and copy the input file to given path with changed
+module usage."
+
+rng2dot
+Convert Relax NG Compact form to Graphviz dot file
diff --git a/Master/texmf-dist/source/latex/stex/bin/TexId.pm b/Master/texmf-dist/source/latex/stex/bin/TexId.pm
new file mode 100644
index 00000000000..d0f28ccbce5
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/TexId.pm
@@ -0,0 +1,464 @@
+# package for handling .tex IDs
+
+package TexId;
+
+use File::Basename;
+use strict;
+
+# error messages markers
+
+use constant ERR => '[X]'; # error can't be fixed
+
+################### 'public' members ###################
+
+sub new{
+ my ($class, %options) = @_;
+ my $self = {};
+
+ @{$self->{ENVIRONMENTS}} = qw(module note omtext example
+ definition problem proof
+ solution program); # the environments to look at
+
+ @{$self->{ENV_PREFIXES}} = qw(mod not txt ex def prob pf sol prg); # the prefixes for environments
+
+
+ @{$self->{ENV_DEF}} = qw(id); # environment arguments that define new environments
+ @{$self->{ENV_USAGE}} = qw(use uses for from); # environment arguments that
+ # specify usage of other environments
+
+ # options for the class
+ %{$self->{OPTIONS}} = %options;
+
+ # in case \snippath{} is encountered, prepend this to the filename
+ $self->{OPTIONS}{snippath} = 'snippets/' unless defined $self->{OPTIONS}{snippath};
+
+
+ # show progress while reading data
+ $self->{OPTIONS}{progress} = 1 unless defined $self->{OPTIONS}{progress};
+
+ bless ($self, $class);
+}
+
+# check/set list of environments to look at
+sub environments{
+ my ($self, $new_environments, $new_prefixes) = @_;
+ if (defined $new_environments and defined $new_prefixes){
+ @{$self->{ENVIRONMENTS}} = split(/,/, $new_environments);
+ @{$self->{ENV_PREFIXES}} = split(/,/, $new_prefixes);
+ die "Invalid argument combination (both arguments must have same number of elements)"
+ if $#{$self->ENVIRONMENTS} != $#{$self->ENV_PREFIXES};
+ }
+ else {
+ return (join(',', @{$self->{ENVIRONMENTS}}), join(',', @{$self->{ENV_PREFIXES}}));
+ }
+}
+
+# define/read environment definition arguments
+sub env_def{
+ my ($self, $new_env_def) = @_;
+ if (defined $new_env_def){
+ @{$self->{ENV_DEF}} = split(/,/, $new_env_def);
+ }
+ else {
+ return join(',', @{$self->{ENV_DEF}});
+ }
+}
+
+# define/read the environment usage arguments
+sub env_usage{
+ my ($self, $new_env_usage) = @_;
+ if (defined $new_env_usage){
+ @{$self->{ENV_USAGE}} = split(/,/, $new_env_usage);
+ }
+ else {
+ return join(',', @{$self->{ENV_USAGE}});
+ }
+}
+
+# define/read the snippets path
+sub snippath{
+ my ($self, $new_snippath) = @_;
+ if (defined $new_snippath){
+ $new_snippath.='/' if ($new_snippath !~ /\/$/);
+ $self->{OPTIONS}{snippath} = $new_snippath;
+ }
+ else {
+ return $self->{OPTIONS}{snippath};
+ }
+}
+
+
+# check all the definitions and module usages
+# in all files referenced by base file
+sub parse{
+
+ my ($self, $basefile) = @_;
+
+ # recursive local function to go through each file
+ local *run_parse = sub
+ {
+ my ($filename) = @_;
+
+ # read current .tex file
+ print STDERR "Loading $filename...\n" if ($self->{OPTIONS}{progress} == 1);
+ $filename = $self->load_file_data($filename);
+ my @text = @{$self->{FILEDATA}};
+ my $line_no = 0;
+
+ # go through every line of the read file
+ # depends on: \requiremodules, \snippath
+ # ignores \end{document}
+
+ foreach (@text){
+ # delete newline character, comments and redundant white space
+
+ $line_no++;
+ /([^%]*)((%.*)?)/;
+ $_ = $1;
+ s/\s+//g;
+
+ # see if an environment that has some arguments is defined
+ my ($possible_env, $env_args) = (undef, undef);
+ ($possible_env, $env_args) = ($1, $2) if (/\\begin\{([^\}]+)\}\[([^\]]+)\]/);
+
+ # if it is, search it through the list of environments we want to look at
+ if (defined $possible_env){
+ foreach my $environment(@{$self->{ENVIRONMENTS}}){
+ next unless ($environment eq $possible_env);
+
+ # if we found an anvironment we want to look at,
+ # go through the list of arguments
+ $env_args = $self->swap_exterior_char(',', ';', $env_args);
+ foreach (split(/;/, $env_args)){
+ # we want arguments of type name=value
+ next unless /([^=]+)=(.+)/;
+ my ($arg_name, $arg_value) = ($1, $2);
+
+ # see if the argument defines an environment
+ foreach my $current_env_arg(@{$self->{ENV_DEF}}){
+ next unless ($arg_name eq $current_env_arg);
+ my @to_add = split(/,/, $arg_value);
+ push(@{$self->{'DEF'}->{$environment}}, @to_add);
+ foreach my $added_element(@to_add){
+ $self->{'DEF'}->{LOCATION}{$added_element}.=$line_no.':'.$filename."\n";
+ }
+ last;
+ }
+
+ # see if the argument uses an environment
+ foreach my $current_env_arg(@{$self->{ENV_USAGE}}){
+ next unless ($arg_name eq $current_env_arg);
+ my @to_add = split(/,/, $arg_value);
+ push(@{$self->{'USE'}->{$environment}}, @to_add);
+ foreach my $added_element(@to_add){
+ $self->{'USE'}->{LOCATION}{$added_element}.=$line_no.':'.$filename."\n";
+ }
+ last;
+ }
+ }
+ last;
+ }
+ }
+ # reference to another file
+ if (/\\requiremodules(\[(include|exclude)\])?\{([^\}]+)\}/){
+ if (defined $2 && $2 eq 'include'){
+ $_ = $3;
+ $_ = $self->{OPTIONS}{snippath}.$1 if (/\\snippath\{(.+)/);
+ $_ = $self->{path}.$_;
+ run_parse($_);
+ }
+ }
+
+ # see definition of snippath
+ $self->snippath($1) if (/\\def\\snippath\#1\{([^\#]+)\#1\}$/);
+ }
+ };
+
+ run_parse($basefile);
+
+}
+
+# this is the first checking step to be done
+sub check_uniq{
+
+ my ($self) = @_;
+
+ my $error = 0;
+
+ # sort environment definitions and see whether they are uniquely defined
+ foreach my $environment(@{$self->{ENVIRONMENTS}}){
+ next unless defined $self->{'USE'}->{$environment};
+
+ my @list1 = sort @{$self->{'DEF'}->{$environment}};
+ my @list2 = $self->uniq(@list1);
+ @{$self->{'DEF'}->{$environment}} = @list2;
+
+ # some environments are defined multiple times
+ if ($#list1 != $#list2){
+ my $j = 0;
+ for (my $i = 0; $i<=$#list2; $i++){
+ my $start_j = $j;
+ while ($j<=$#list1 && $list1[$j] eq $list2[$i]){
+ $j++;
+ }
+ if ($j - $start_j != 1){
+ print STDERR ERR, " Environment '$list2[$i]' is defined multiple times ",
+ "within same environment type: \n";
+ print STDERR $self->{'DEF'}->{LOCATION}{$list2[$i]}, "\n";
+ $error = 1;
+ }
+ }
+ }
+ }
+
+ # see that all environment references are unique (and sort them)
+ foreach my $environment(@{$self->{ENVIRONMENTS}}){
+ next unless defined $self->{'USE'}->{$environment};
+ @{$self->{'USE'}->{$environment}} = sort $self->uniq(@{$self->{'USE'}->{$environment}});
+ }
+
+ return $error;
+}
+
+sub check_prefix{
+
+ my ($self) = @_;
+
+ my $count = $#{$self->{ENVIRONMENTS}}+1;
+
+ for (my $i = 0; $i < $count; $i++){
+ my $environment = ${$self->{ENVIRONMENTS}}[$i];
+ my $envprefix = ${$self->{ENV_PREFIXES}}[$i];
+ next unless defined $self->{'DEF'}->{$environment};
+
+ foreach my $elem (@{$self->{'DEF'}->{$environment}}){
+
+ my $proper = undef;
+ if ($elem =~ /^([^:]+):(.+)/){
+ $proper = $envprefix.':'.$2 if $1 ne $envprefix;
+ } else {
+ $proper = $envprefix.':'.$elem;
+ }
+
+ if (defined $proper){
+ print STDERR ERR, " $environment '$elem' has no prefix ($envprefix). Add it? [ <y>, n ]";
+ my $answer = <STDIN>;
+ chomp($answer);
+ if ($answer eq 'y' or $answer eq ''){
+ $self->add_change('DEF', $elem, $proper);
+ }
+ }
+ }
+ }
+}
+
+
+sub check_defs{
+ my ($self) = @_;
+
+ my $error = 0;
+
+ # combine all definitions
+ my @defs;
+ map {push(@defs, @{$self->{'DEF'}->{$_}}) if defined @{$self->{'DEF'}->{$_}}} @{$self->{ENVIRONMENTS}};
+ @defs = sort @defs;
+
+ # combine all used environments
+ my @uses;
+ map {push(@uses, @{$self->{'USE'}->{$_}}) if defined @{$self->{'USE'}->{$_}}} @{$self->{ENVIRONMENTS}};
+ @uses = sort @uses;
+
+
+ # for all environments
+
+ foreach my $used_env(@uses){
+ # if used environment is not defined
+ if ($self->find_elem($used_env, @defs) < 0){
+ # maybe it is a typo
+ print STDERR ERR, " '$used_env' was not found. Replace options:\n";
+ foreach my $definition(@defs){
+ print STDERR "\t$definition\n" if $self->edit_dist($used_env,$definition)<4;
+ $error = 1;
+ }
+ }
+ }
+
+ return $error;
+}
+
+
+sub add_change{
+ my ($self, $location, $from, $to) = @_;
+ if ($self->{$location}->{LOCATION}{$from} =~ /([^:]+):([^\n]+)\n/){
+ push(@{$self->{CHANGE}->{$2}}, ($1, $from, $to));
+ }
+}
+
+# write the stored changes
+sub apply_changes{
+ my ($self) = @_;
+ while (my ($filename, $changes) = each %{$self->{CHANGE}}){
+ $filename = $self->load_file_data($filename);
+ my $count = int(($#{$changes}+1)/3);
+ for (my $i = 0; $i<$count ; $i++){
+ my ($line, $from, $to) = (${$changes}[$i*3]-1,
+ ${$changes}[$i*3+1], ${$changes}[$i*3+2]);
+ ${$self->{FILEDATA}}[$line] =~ s/\Q$from/$to/;
+ }
+ print STDERR "Writing $filename\n" if ($self->{OPTIONS}{progress} == 1);
+ $self->write_file_data($filename);
+ }
+}
+
+sub load_file_data{
+ my ($self, $filename) = @_;
+
+ # try to give proper file extension if file is not found
+ $filename = $self->add_ext($self->drop_ext($filename)) unless -e $filename;
+
+ open(FIN, $filename) or die "Cannot open $filename\n";
+ @{$self->{FILEDATA}} = <FIN>;
+ close(FIN);
+
+ $self->{path} = dirname($filename).'/' unless defined $self->{path};
+
+ return $filename;
+}
+
+sub write_file_data{
+ my ($self, $filename) = @_;
+
+ open(FOUT, ">$filename") or die "Cannot write $filename\n";
+ print FOUT @{$self->{FILEDATA}};
+ close(FOUT);
+}
+
+
+################### 'protected' members ###################
+
+sub def_env_list{
+ my ($self, $env_name) = @_;
+ return @{$self->{'DEF'}->{$env_name}};
+}
+
+sub use_env_list{
+ my ($self, $env_name) = @_;
+ return @{$self->{'USE'}->{$env_name}};
+}
+
+
+################### 'private' members ###################
+
+sub drop_ext{
+ my ($self, $filename) = @_;
+ while ($filename =~ /\.tex$/){
+ while ($filename !~ /\.$/ ) { chop($filename); }
+ chop($filename);
+ }
+ return $filename;
+}
+
+sub add_ext{
+ my ($self, $filename) = @_;
+ $filename.='.tex' if $filename !~ /\.tex$/;
+ return $filename;
+}
+
+# look at $word, and swap all occurances of $char_find with
+# $new_char if they are not in a {...} environment
+
+sub swap_exterior_char{
+ my ($self, $char_find, $new_char, $word) = @_;
+ my @new_word = ();
+ my $exterior = 0;
+ foreach (split('', $word)){
+ if ($_ eq '{'){
+ $exterior++;
+ next;
+ }
+
+ if ($_ eq '}'){
+ $exterior--;
+ next;
+ }
+
+ if ($exterior == 0 && $_ eq $char_find){
+ push(@new_word, $new_char);
+ }
+ else{
+ push(@new_word, $_);
+ }
+ }
+ return join('',@new_word);
+}
+
+# return unique elements from a list
+sub uniq{
+ my ($self, @list) = @_;
+ my %seen = ();
+ my @uniqu = grep { ! $seen{$_} ++ } @list;
+ return @uniqu;
+}
+
+
+# binary search
+sub find_elem{
+ my ($self, $elem, @list) = @_;
+
+ local *search_elem = sub
+ {
+ my ($a, $b) = @_;
+ my $m = int(($a + $b)/2);
+ return $m if $list[$m] eq $elem;
+ return -1 if ($a >= $b);
+ return ($list[$m] le $elem)?search_elem($m+1,$b):search_elem($a,$m-1);
+ };
+
+ return search_elem(0, $#list);
+}
+
+# edit distance between two strings
+# insertions, deletions, replacement, transposition
+sub edit_dist{
+ my ($self, $s1, $s2) = @_;
+ my $m = length($s1);
+ my $n = length($s2);
+ my @w1 = split(//, $s1);
+ my @w2 = split(//, $s2);
+
+ # add dummy char so we can have nicer indeces
+ unshift(@w1, '*');
+ unshift(@w2, '*');
+
+ # distances matrix
+ my @d;
+
+ # initialize
+ $d[0][0] = 0;
+ for (my $i = 1; $i <= $m ; $i++) { $d[$i][0] = $i;}
+ for (my $i = 1; $i <= $n ; $i++) { $d[0][$i] = $i;}
+
+ # compute
+ for (my $i = 1; $i <= $m ; $i++){
+ for (my $j = 1; $j <= $n ; $j++){
+ my @possibilities = ($d[$i-1][$j-1] + ($w1[$i] ne $w2[$j]),
+ $d[$i-1][$j] + 1, $d[$i][$j-1] + 1);
+
+ push(@possibilities, $d[$i-2][$j-2] + 1)
+ if ($i>1 && $j>1 && $w1[$i] eq $w2[$j-1] && $w1[$i-1] eq $w2[$j]);
+
+ $d[$i][$j] = $self->minimum(@possibilities);
+ }
+ }
+ return $d[$m][$n];
+}
+
+sub minimum{
+ my ($self, @list) = @_;
+ my $result = shift(@list);
+ map {$result = $_ if $result ge $_} @list;
+ return $result;
+}
+
+
+1;
diff --git a/Master/texmf-dist/source/latex/stex/bin/allgen b/Master/texmf-dist/source/latex/stex/bin/allgen
new file mode 100755
index 00000000000..4728d89ee56
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/allgen
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+if [[ -z $STEX_CONTENT_HOME ]]
+then
+ echo "STEX_CONTENT_HOME is not set; please set it in your ~/.bashrc"
+ exit 1
+fi
+
+LIB="$STEX_CONTENT_HOME/slides/lib"
+cat <<'EOF'
+% this file is automatically generated by allgen
+% Note: This hack is needed to make mikoslides and problems work together.
+\PassOptionsToPackage{solutions,notes,pts,min}{problems}
+EOF
+
+sed -e '/\\begin{document}/ i\
+\\usepackage{problems}
+' $LIB/pre.tex | \
+ grep -v '^\\def\\snippets'
+
+cat <<'EOF'
+EOF
+
+for file in *.tex
+do
+ prefix=${file%.tex} # file name without .tex suffix
+ [[ $prefix != "all" ]] && echo -e "\\subsection{${prefix//_/\\\\_}} \n \\input{$prefix}" # in subsection replace "_" by "\_"
+done
+
+cat $LIB/post.tex
diff --git a/Master/texmf-dist/source/latex/stex/bin/bms b/Master/texmf-dist/source/latex/stex/bin/bms
new file mode 100755
index 00000000000..52f1002c0d9
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/bms
@@ -0,0 +1,340 @@
+#!/usr/bin/perl -w
+
+#######################################################################################
+# A tool for building a default module usage structure. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/bms$ #
+# $Date: 2005-10-04 10:47:41 -0500 (Tue, 04 Oct 2005) $ $Rev: 4371 $ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use File::Path;
+use Pod::Usage;
+use Modparse;
+
+
+##########################################
+# Command Line processing
+##########################################
+
+my $input="-", my $graph_output='', my $graph_root='',
+my $verbose=0, my $stop_at_end=0;
+my $show_definitions=0, my $show_modules = 0;
+my %arg_snippath; my @snippathList;
+
+$main::path_new='';
+$main::new_name='';
+
+GetOptions("path=s" => \%arg_snippath,
+ "defpath=s" => \@snippathList,
+ "graph=s" => \$graph_output,
+ "opath=s" => \$main::path_new,
+ "output=s" => \$main::new_name,
+ "root=s" => \$graph_root,
+ "definitions" => sub {$show_definitions = 1;},
+ "modules" => sub {$show_modules = 1;},
+ "stop" => sub {$stop_at_end = 1;},
+ "verbose" => sub {$verbose = 1;},
+ "help" => sub {pod2usage(2);});
+
+$input = $ARGV[0] if ($#ARGV>=0);
+
+##########################################
+# .tex data reading
+##########################################
+
+$main::no_name_modules = 0;
+%main::definition_module = ();
+@main::definitions_list = ();
+
+%main::module_definitions = ();
+%main::used_modules = ();
+@main::modules_list = ();
+
+my $mp = Modparse->new(snippathList=>\@snippathList,
+ snippath=>\%arg_snippath,
+ stopAtEnd=>$stop_at_end,
+ verbose=>$verbose,
+ requireStatus=>'exclude',
+ onlyModuleLines=>1,
+ onBeginModule=>sub {
+ if (!defined $_[0]->{module_id}) {
+ $_[0]->{module_id} = "MOD".$main::no_name_modules;
+ $main::no_name_modules++; }
+ $_[0]->{defines} = '';
+ },
+ onEveryLine=>sub {
+ if ($_[0]->{simple_tex} =~ /\\(sym|abbr|ell)def\{\\([^\}]+)\}/) {
+ my $data = $2;
+ $_[0]->{defines} .= "$data;";
+ $main::definition_module{$data} = $_[0]->{module_id};
+ push(@main::definitions_list, $data);
+ } elsif ($_[0]->{simple_tex} =~ /\\STRlabel\{([^\}]*)\}/){
+ my $data = "L:$1";
+ $_[0]->{defines} .= "$data;";
+ $main::definition_module{$data} = $_[0]->{module_id};
+ push(@main::definitions_list, $data);
+ }
+ $_[0]->{module_content} .= $_[0]->{simple_tex};
+ },
+ onEndModule=>sub {
+ chop($_[0]->{defines}) if $_[0]->{defines};
+ $main::module_definitions{$_[0]->{module_id}} = $_[0]->{defines};
+ push(@main::modules_list, $_[0]->{module_id});
+ my $module_refs = '';
+ foreach my $def(@main::definitions_list){
+ next if $main::definition_module{$def} eq $_[0]->{module_id};
+ next unless $module_refs !~ /$main::definition_module{$def}/;
+ if ($def =~ /^L\:(.*)/){
+ $module_refs .= "$main::definition_module{$def};"
+ if ($_[0]->{module_content} =~ /\\STRcopy\{$1\}/);
+ } else {
+ $module_refs .= "$main::definition_module{$def};"
+ if ($_[0]->{module_content} =~ /\\$def/);
+ }
+ }
+ chop($module_refs) if $module_refs;
+ $main::used_modules{$_[0]->{module_id}} = $module_refs;
+ });
+
+##################################################################
+# Internal routines for BMS
+##################################################################
+
+%main::bms = ();
+
+# add a dummy module that uses nothig, such that any other module uses at least something
+sub addroot {
+ foreach my $module(@main::modules_list){
+ next if $main::used_modules{$module};
+ $main::used_modules{$module} = $graph_root;
+ }
+ push(@main::modules_list, $graph_root);
+ $main::module_definitions{$graph_root}='';
+ $main::used_modules{$graph_root}='';
+}
+# end addroot
+
+sub included {
+ my ($a1_ref, $a2_ref) = @_;
+ my $ok;
+ foreach my $elem (@$a1_ref){
+ $ok = 0;
+ foreach (@$a2_ref){
+ if ($elem eq $_){
+ $ok=1;
+ last; }}
+ return 0 unless $ok;}
+ return 1;
+}
+
+# find if a module uses another module
+sub can_go{
+ my ($src,$dest) = @_;
+ return 1 if $src eq $dest;
+ foreach (split(/;/, $main::bms{$src})){
+ return 1 if can_go($_,$dest);
+ }
+ return 0;
+}
+# end can_go
+
+# find the actual module structure
+sub find_bms{
+ my @added_modules, my @can_add, my @to_look, my @next_step;
+
+ %main::bms=();
+ @to_look = @main::modules_list;
+ @added_modules = ();
+
+ while($#main::modules_list != $#added_modules){
+
+ @can_add=(); @next_step=();
+
+ foreach my $module(@to_look){
+ my @temp = split(/;/, $main::used_modules{$module});
+ included(\@temp,\@added_modules)?push(@can_add,$module):push(@next_step,$module);
+ }
+ @to_look = @next_step;
+
+ foreach my $module(@can_add){
+
+ my @uses = split(/;/,$main::used_modules{$module});
+ my $change = 1;
+ while ($change){
+ $change = 0;
+ foreach my $f1(@uses){
+ foreach my $f2(@uses){
+ next if $f1 eq $f2;
+ if (can_go($f1,$f2)){ # i.e. f2 used by f1 => can remove f2
+ my @new_uses;
+ foreach (@uses){
+ push(@new_uses,$_) unless ($_ eq $f2);
+ }
+ @uses = @new_uses;
+ $change = 1;
+ last;
+ }
+ }
+ last if $change;
+ }
+ }
+ $main::bms{$module} = join(";",@uses);
+ push(@added_modules,$module);
+ }
+ }
+}
+# end find_bms
+
+# print the content of %bms in a .dot file; note: may change %bms by adding dummy root
+sub printgraph {
+ my $out = shift;
+
+ addroot if $graph_root;
+
+ open(FOUT,">$out") or die "Can't write $out\n";
+ print FOUT "digraph MS {\n";
+ while (my ($module, $uses) = each %main::bms){
+ $uses =~ s/-/_/g;
+ $module =~ s/-/_/g;
+ if ($uses){
+ if ($uses =~ /;/){
+ print FOUT "$module -> {$uses};\n";
+ } else {
+ print FOUT "$module -> $uses;\n";
+ }
+ } else {
+ print FOUT "$module [shape=box color=red];\n";
+ }
+ }
+ print FOUT "}\n";
+ close(FOUT);
+}
+# end printgraph
+
+# print the list of definitions
+sub printdefinitions{
+ while (my ($module,$def) = each %main::module_definitions){
+ print "$module:\n" if $def;
+ foreach (split(/;/,$def)){
+ print "\t$_\n";
+ }
+ }}
+# end printdefinitions
+
+#print the list of modules
+sub printmodules{
+ while (my ($module,$uses) = each %main::used_modules){
+ print "'$module' uses:\n $uses\n\n\n";
+ }}
+#end printmodules
+
+
+# wite the new .tex file, with found module usage, in given path
+sub writenew {
+ my ($filename) = @_;
+ $main::no_name_modules = 0;
+ my $wmp = Modparse->new(snippathList=>\@snippathList,
+ snippath=>\%arg_snippath,
+ stopAtEnd=>$stop_at_end,
+ verbose=>$verbose,
+ requireStatus=>'exclude',
+ onlyModuleLines=>0,
+ onBeginFile=> sub {
+ $_[0]->{'new_content'.$_[0]->{depth}} = '';
+ },
+ onBeginModule=>sub {
+ if (!defined $_[0]->{module_id}) {
+ $_[0]->{module_id} = "MOD".$main::no_name_modules;
+ $main::no_name_modules++; }
+ my $new_uses = $main::bms{$_[0]->{module_id}};
+ if (defined $new_uses) {
+ $new_uses =~ s/;/,/g;
+ $new_uses="{$new_uses}" if $new_uses =~ /,/;
+ my $arg = $_[0]->{module_args};
+ my @new_arg=();
+ my $done = 0;
+ while ($arg =~ /^([\w-]+)=(([\w-]+)|(\{[\w,-]+\}))/){
+ if ($1 eq 'uses'){
+ push(@new_arg,"$1=$new_uses")if $new_uses;
+ $done = 1;
+ } else {
+ push(@new_arg,"$1=$2");
+ }
+ $arg=substr($arg,length($1)+length($2)+1);
+ $arg=substr($arg,1) if ($arg =~ /^,/);
+ }
+ if ($new_uses) {
+ push(@new_arg,"uses=$new_uses") unless $done; }
+ $_[0]->{original} = "\\begin{module}\[".join(',',@new_arg)."\] ". $_[0]->{comment}. "\n";
+ }
+ },
+ onEveryLine=>sub {
+ $_[0]->{'new_content'.$_[0]->{depth}} .= $_[0]->{original};
+ },
+ onEndFile=> sub {
+ my $filename = ($main::path_new).'/'.$_[0]->{filename};
+ my $path = $filename;
+ while ($path !~ m!\/$!) { chop($path); }
+ mkpath($path);
+ $filename = $path.'/'.$main::new_name if ($main::new_name && $_[0]->{depth} == 1);
+ print "Writing $filename\n" if $_[0]->{pack}->{verbose};
+ open(FS, ">$filename") or die "Cannot write $filename\n";
+ print FS $_[0]->{'new_content'.$_[0]->{depth}};
+ close(FS);
+ });
+
+ $wmp->execute($filename);
+}
+
+
+#############################################################
+# Start program
+#############################################################
+
+$mp->execute($input);
+
+printdefinitions if $show_definitions;
+printmodules if $show_modules;
+
+if ($graph_output || $main::path_new){
+ find_bms;
+ writenew($input) if $main::path_new;
+ printgraph($graph_output) if $graph_output;
+}
+
+__END__
+
+
+=head1 SYNOPSIS
+
+bms <input filename> [options]
+
+Options:
+
+ --path XXX specify the value of \XXX (some snippath) in case it is
+ = somePath not defined in the processed .tex file
+ --defpath XXX specify which \XXX (snippath definitions) to look for
+ --graph <filename> if mentioned, produce the suggested module structure as
+ a graphviz digraph. (.dot file)
+ --opath <pathname> if mentioned, produce same input file/s (including
+ dependencies) in specified path with suggested
+ module structure.
+ --output <name> the new name of the main .tex file in specified path.
+ --root <name> if mentioned, a father module is included, so that all
+ other modules descend from it. generally the course name.
+ --stop stop when \end{document} is found; default is to go on.
+ --definitions show a list of all definitions.
+ --modules show a list of all modules.
+ --verbose verbose on.
+ --help this screen.
+
+
+ This program has the purpose of computing a default module structure, according
+to actual necessities.
+ Example:
+ ./bms -i slides.tex -g out.dot
+ ./bms -i slides.tex -s -g - | dot -Tps > out.ps; ggv out.ps
diff --git a/Master/texmf-dist/source/latex/stex/bin/checksum b/Master/texmf-dist/source/latex/stex/bin/checksum
new file mode 100755
index 00000000000..7e521deaa7c
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/checksum
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+#######################################################################################
+# A tool for updating .dtx files with a correspodning checksum counter #
+# Copyright (c) 2010, Deyan Ginev, released under the Gnu General Public License (GPL)#
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: https://svn.kwarc.info/repos/stex/trunk/bin/checksum$ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use Modparse;
+use Pod::Usage;
+use Cwd qw(abs_path);
+
+####### start of program #######
+my $mode = "update"; #Default is update
+my $action = { "update" => \&update, "disable" => \&disable, "enable"=>\&enable };
+GetOptions("disable" => sub { $mode="disable"; },
+ "enable" => sub { $mode="enable"; },
+ "update" => sub { $mode="update"; });
+
+
+my ($path) = @ARGV;
+$path = abs_path($path);
+my ($volume,$dir,$file) = File::Spec->splitpath( $path );
+my @lines = `cd $dir; pdflatex "\\nonstopmode\\input{$file}"` if ($mode eq "update");
+my ($checksum) = map {$_=~/^\* The checksum should be (\d+)!/; $1;} grep ($_ =~ /^\* The checksum should be (\d+)!/,@lines) if @lines;
+
+open(IN,"<$path") or die "Cannot open DTX source: $path\n";
+@lines = ();
+while (<IN>) {
+ push @lines, &{$$action{$mode}}($_,$checksum);
+}
+close(IN);
+open(OUT,">$path") or die "Cannot write to DTX target: $path\n";
+print OUT join("",@lines);
+close(OUT);
+######### Subroutines ############
+sub update {
+ my $checksum=$_[1]||"1";
+ $_[0]=~s/\\CheckSum\{\d*\}/\\CheckSum{$checksum}/;
+ $_[0];
+}
+
+sub disable {
+ $_[0]=~s/\\CheckSum\{(\d*)\}/\\iffalse\\CheckSum\{$1}\\fi/ unless $_[0]=~/\\iffalse\\CheckSum\{(\d*)\}\\fi/;
+ $_[0];
+}
+
+sub enable {
+ $_[0]=~s/\\iffalse\\CheckSum\{(\d*)\}\\fi/\\CheckSum{$1}/;
+ $_[0];
+}
+
+
+__END__
+
+
+=head1 SYNOPSIS
+
+checksum <input filename> --update|enable|disable
+
+Purpose:
+ Update, enable or disable the \CheckSum macro for a given .dtx source
+
+Example:
+ checksum omd.dtx --update
diff --git a/Master/texmf-dist/source/latex/stex/bin/convert-paths b/Master/texmf-dist/source/latex/stex/bin/convert-paths
new file mode 100755
index 00000000000..55ee72a2370
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/convert-paths
@@ -0,0 +1,56 @@
+#!/usr/bin/perl -w
+#
+# A script that converts paths in sTeX files from the old \Foosnipppath{bar}
+# to \snippets{foo/bar}, according to the definition of those path macros in
+# paths.sty.
+#
+# Syntax: convert-paths path/to/paths.sty FILES
+#
+# © 2008 Christoph Lange, KWARC, Jacobs University
+
+use File::Copy;
+
+my %map;
+
+my $SNIPPATHRE = '\\\\[[:alnum:]]+(?i:snip|pic)path';
+
+if (open(P, shift(@ARGV))) {
+ print STDERR "Mapping:\n";
+ while (<P>) {
+ if (/^\\def($SNIPPATHRE)#1\{(\\KWARCslides\{[^#]+)#1\}/o) {
+ printf STDERR "\t%s -> %s\n", $1, $2;
+ $map{$1} = $2;
+ }
+ }
+ close(P);
+}
+else {
+ die "Could not open paths.sty";
+}
+
+print STDERR "Processing files:\n";
+while ($#ARGV >= 0) {
+ my $filename = shift(@ARGV);
+ print STDERR "\t$filename\n";
+ copy($filename, "$filename~") || print STDERR "\t\tWARN: could not create backup\n";
+ if (open(T, $filename)) {
+ # slurp the file into a string
+ local $/;
+ $data = <T>;
+ $data =~ s/($SNIPPATHRE)\{([^}]+)\}/
+ $map{$1} ? "$map{$1}$2\}"
+ : ((print STDERR "\t\tWARN: could not replace $1\n"), "$1\{$2}")
+ /oxge;
+ close T;
+ if (open(T, ">$filename")) {
+ print T $data;
+ close T;
+ }
+ else {
+ print STDERR "\t\tWARN: could not save replacement\n";
+ }
+ }
+ else {
+ print STDERR "\t\tWARN: could not open file\n";
+ }
+}
diff --git a/Master/texmf-dist/source/latex/stex/bin/filedate b/Master/texmf-dist/source/latex/stex/bin/filedate
new file mode 100755
index 00000000000..8149b5e57bd
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/filedate
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+#######################################################################################
+# A tool for updating .dtx files with a given package date. #
+# Copyright (c) 2010, Deyan Ginev, released under the Gnu General Public License (GPL)#
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: https://svn.kwarc.info/repos/stex/trunk/bin/filedate$ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use Modparse;
+use Pod::Usage;
+use Cwd qw(abs_path);
+
+my ($file,$date) = @ARGV;
+$file = abs_path($file);
+open(IN,"<$file");
+my @lines = ();
+while (<IN>) {
+ if ($_ =~ /\\Provides(Package|Class)/) {
+ $_ =~ s/\[(.*?)\s/\[$date /;
+ }
+ push @lines, $_;
+}
+close(IN);
+open(OUT,">$file");
+print OUT join("",@lines);
+close(OUT);
+
+__END__
+
+
+=head1 SYNOPSIS
+
+filedate <input filename> <newdate>
+
+Purpose:
+ Update the dates for a \ProvidePackage invocation in a given .dtx source
+
+Example:
+ filedate omdoc.dtx "2010/06/24"
diff --git a/Master/texmf-dist/source/latex/stex/bin/gen-symdef-table.pl b/Master/texmf-dist/source/latex/stex/bin/gen-symdef-table.pl
new file mode 100755
index 00000000000..cd6da0dc06a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/gen-symdef-table.pl
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+use Cwd;
+
+die 'Set your environment variable "KWARC_HOME" and try again.' if !($ENV{KWARC_HOME});
+
+open(PATH_STY,"$ENV{KWARC_HOME}/projects/stex/sty/paths.sty") || die "can't open path.sty";
+while ($line=<PATH_STY>) {
+ $line =~ m/\\def\\(\w*).*\/([\w-]*)\/#1/;
+ $macros{$2}=$1; # dir -> macro
+}
+close(PATH_STY);
+
+print <<PRE_TEX;
+\\documentclass[notes]{mikoslides}
+\\usepackage{amssymb}
+\\usepackage{latexml,stex,program}
+\\usepackage{ded,calbf,myindex}
+\\usepackage{tikz,multicol}
+\\usepackage{paths}
+\\usepackage[show]{ed}
+\\def\\bsp{\\sl\\color{green}}
+\\def\\hrcr#1#2{#2}
+
+\\begin{document}
+PRE_TEX
+
+chdir("$ENV{KWARC_HOME}/teaching/snippets/");
+
+foreach $dir (<*/>) {
+ $dir = substr($dir,0,-1);
+ if (@ARGV){ # take all dirs listet in @ARGV
+ next if !(grep(/$dir/,@ARGV))
+ } else { # take all dirs but those listed here
+ # next if $dir lt "b"; #test break
+ # next if $dir gt "comb"; #test break
+ next if grep(/$dir/,qw(PIC activemath admin eLearning lib kwarc mathweb mbase old.assignments omdoc openmath physml quantumcomputing sTex search semweb setthy spl1 term-indexing trs varia xml)); #skip these
+ next if grep(/$dir/,qw(ai codeml fa graphs-trees kr mws nlfrags pl0 pl1 prolog regexp)); #broken dirs
+ }
+ print "\\begin{omgroup}{$dir}\n";
+ foreach $file (<${dir}/en/*.sms>) {
+ $file =~ m/([^\/]*).sms/;
+ $prefix = $1;
+ next if grep(/$prefix/,qw(all admin));
+ print "\\begin{omgroup}{$prefix}\n";
+ print "\\requiremodules[exclude]{\\$macros{$dir}\{en/$prefix}\}\n";
+ open (FILE,"./$file") || die "can't open $file";
+ while ($line=<FILE>) {
+ $line =~ s/%.*//;
+ if ($line =~ m/begin{module}/) { # many "begin{module}" in one line yields invalid stex!!!
+ $uses = ($line =~ m/id=([\w-]*)/) ? "[uses=$1]" : "";
+ print "\\begin{module}$uses\n"; # symbols after inner modules yields stex errors!!!
+ print "\\begin{verbatim}\n";
+ print "\\requiremodules[exclude]{\\$macros{$dir}\{en/$prefix}\}\n";
+ print "\\begin{module}$uses\n";
+ print "\\end{verbatim}\n";
+# print "\\begin{multicols}{2}\n";
+ }
+ if ($line =~ m/\\symdef{([^}]*)}(?:\[(\d)\])?({\\assoc\[)?/) {
+ $symb = $1;
+ $arity = $2;
+ $isAssoc = $3 ne "";
+ $defArity = $isAssoc ? 4 : $arity;
+ $exampleArity = $arity eq "" ? 0 : $defArity;
+ $arityOrAssoc = $isAssoc ? "assoc" : $arity;
+ $dummy_args = join("",map {"{$_}"} (qw(a b c d e f g h m)[0..$exampleArity-1]));
+ $dummy_args = "{a,b,c,d}" if $isAssoc;
+ $escaped_dummy_args = $dummy_args;
+ $escaped_dummy_args =~ s/{/\\{/g;
+ $escaped_dummy_args =~ s/}/\\}/g;
+# print "{\\tt{$symb\[$arityOrAssoc\]}} $escaped_dummy_args\\hfill";
+ print "{\\tt{$symb$escaped_dummy_args}} \\hfill ";
+ print "\$\\$symb$dummy_args\$\\\\\n";
+ }
+ if ($line =~ m/end{module}/) { # several "end{mdoule}" allowed!!!
+# print "\\end{multicols}\n";
+ print $line;
+ }
+ }
+ close(FILE);
+ print "\\end{omgroup}\n";
+ }
+ print "\\end{omgroup}\n";
+}
+
+print "\\end{document}";
diff --git a/Master/texmf-dist/source/latex/stex/bin/idcheck b/Master/texmf-dist/source/latex/stex/bin/idcheck
new file mode 100755
index 00000000000..d832ac7788e
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/idcheck
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+use strict;
+
+use Getopt::Long;
+use File::Path;
+use Pod::Usage;
+use TexId;
+
+
+
+my $tex = TexId->new(progress => 1);
+
+
+
+$tex->load_file_data('../GenCS/notes.tex');
+
+my ($a, $b) = $tex->environments();
+print $b, "\n";
+
+print $tex->snippath(), "\n";
+
+$tex->parse('../GenCS/notes.tex');
+#print join(', ', $tex->use_env_list('omtext')), "\n";
+
+#print $tex->edit_dist('anaIU', 'aanUI'), "\n";
+
+$tex->check_uniq;
+$tex->check_prefix;
+$tex->apply_changes;
diff --git a/Master/texmf-dist/source/latex/stex/bin/msplit b/Master/texmf-dist/source/latex/stex/bin/msplit
new file mode 100755
index 00000000000..cf178ce9b5f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/msplit
@@ -0,0 +1,140 @@
+#!/usr/bin/perl -w
+##############################################################################################
+# Program: msplit (a utility for splitting STeX documents along module boundaries)
+##############################################################################################
+# $URL: svn://kwarc.faculty.iu-bremen.de/kohlhase/kwarc/projects/content/bin/msplit$
+# $Rev: 3722 $; last modified by $Author: $
+# $Date: 2005-07-27 03:22:19 +0200 (Wed, 27 Jul 2005) $
+# Copyright (c) 2005 Ioan Sucan
+##############################################################################################
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License [http://www.gnu.org/copyleft/gpl.html]
+# for more details.
+##############################################################################################
+use strict;
+use Getopt::Long;
+use File::Path;
+use Pod::Usage;
+
+my $input='-', my $output='-', my $path='', my $verbose=0, my $stop_at_end=0;
+my $flag = "include";
+my $header='', my @hdr_data;
+
+sub texf {
+ my $fn = shift;
+ $fn.='.tex' if $fn !~ /\.tex$/;
+ return $fn; }
+
+sub write_file_data{
+ my $filename = shift;
+ open(FS,$filename) or die "Cannot write $filename\n";
+ print FS @_;
+ close(FS); }
+
+# remove the last component in a path
+sub justpath{
+ my $arg = shift;
+ return '' if ($arg !~ m!\/!);
+ while ($arg !~ m!\/$!) {chop($arg);}
+ return $arg; }
+# end justpath
+
+
+sub go {
+ my ($input, $output) = @_;
+ my $path = justpath($output);
+
+ my @module_file=();
+ my @out_data=();
+
+ print "Splitting $input...\n" if $verbose;
+ `mv $output $output~` if (-e $output);
+ $input="$input~" if ($input eq $output);
+
+ open(FIN,$input) or die "Can't open $input\n";
+ my $in_module=0; my $path_name;
+ foreach (<FIN>){
+ chomp;
+ /([^%]*)((%.*)?)/;
+ ($_,my $comment)=($1,$2);
+ if (/\\begin\s*\{module\}/){
+ $_ =~ s/\s//g;
+ /id=([\w-]*)/;
+ my $module_name = $1;
+ $path_name = "$path$module_name.tex";
+ print "$path_name\n" if $verbose;
+ `mv $path_name $path_name~` if (-e $path_name);
+ push(@module_file,@hdr_data) if $header;
+ push(@module_file,"\n$_$comment\n");
+ push(@out_data,"\\requiremodules[$flag]{$module_name}\n");
+ $in_module=1;
+ next; }
+ if (/\\end\s*\{module\}/){
+ $_ =~ s/\s//g;
+ push(@module_file,"$_$comment\n");
+ mkpath(justpath($path_name));
+ write_file_data(">$path_name",@module_file);
+ $in_module=0;
+ next; }
+ if ($stop_at_end && /\\end\s*\{document\}/){
+ $_ =~ s/\s//g;
+ push(@out_data,"$_$comment\n");
+ last; }
+ $_="$_$comment\n";
+ if ($in_module) {push(@module_file,$_);}
+ else {push(@out_data,$_); }}
+ close(FIN);
+ mkpath($path) if $path;
+ write_file_data(">$output",@out_data); }
+
+GetOptions("output=s" => \$output,
+ "path=s" => \$path,
+ "header=s" => \$header,
+ "exclude" => sub { $flag = "exclude"; },
+ "verbose" => sub { $verbose=1; },
+ "stop" => sub { $stop_at_end=1; },
+ "help" => sub { pod2usage(2)});
+
+$input = $ARGV[0] if ($#ARGV>=0);
+die "Input file does not exist\n" if (! defined $input || ! -e $input);
+$output = $input if (! defined $output);
+
+if ($header && -e $header) {
+ open(HDR,$header);
+ @hdr_data = <HDR>;
+ close(HDR); }
+
+$path.='/' if $path && $path !~ m!\/$!;
+go($input,$path.$output);
+print "Done.\n" if $verbose;
+
+__END__
+
+
+=head1 SYNOPSIS
+
+msplit <inputfile> [options]
+
+Options:
+
+ --output filename of new main .tex file; default: same as input
+ --path path where to generate the new documents; '.' by default
+ --header file to be copied at beginning of all new module files
+ --exclude modules exluded by default; if not mentioned, modules
+ are included by default
+ --verbose verbose on
+ --stop stop when \end{document} is found; default is to go on
+ --help this screen
+
+
+
+ This program splits a .tex file into more files, each containing a module.
+ Example usage:
+ ./msplit slides.tex -o sl.tex -p ./modules -s
diff --git a/Master/texmf-dist/source/latex/stex/bin/old/Makefile b/Master/texmf-dist/source/latex/stex/bin/old/Makefile
new file mode 100644
index 00000000000..d2ae41c6401
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/old/Makefile
@@ -0,0 +1,28 @@
+all: src exec
+
+src: idcheck.l defcon.l modstr.l
+ flex -ft idcheck.l > idcheck.yy.c
+ flex -ft defcon.l > defcon.yy.c
+ flex -f+t modstr.l > modstr.yy.cc
+
+idcheck: idcheck.l
+ flex -f $<
+ gcc lex.yy.c -lfl -o idcheck
+
+defcon: defcon.l
+ flex -f $<
+ gcc lex.yy.c -lfl -o defcon
+
+modstr: modstr.l
+ flex -f+ $<
+ g++ lex.yy.cc -lfl -o modstr
+
+exec: idcheck.yy.c defcon.yy.c modstr.yy.cc
+ gcc idcheck.yy.c -lfl -o idcheck
+ gcc defcon.yy.c -lfl -o defcon
+ g++ modstr.yy.cc -lfl -o modstr
+
+clean:
+ rm -f *.yy.c *.yy.cc *~
+
+distclean: clean
diff --git a/Master/texmf-dist/source/latex/stex/bin/old/defcon.l b/Master/texmf-dist/source/latex/stex/bin/old/defcon.l
new file mode 100644
index 00000000000..ad758086145
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/old/defcon.l
@@ -0,0 +1,91 @@
+%{
+
+#include <string.h>
+
+char ltxml[100];
+char fext[6] = ".ltxml";
+
+char symstr[200];
+char ltxmlstr[200];
+
+int i,t,c,tmp,q;
+FILE *lt;
+
+%}
+
+ID [a-zA-Z0-9._:\|-]*
+NR [0-9]*
+
+%s idenv env sym
+
+%%
+
+"\\begin{module}"(" ")*"[" BEGIN(idenv);
+<idenv>"]" BEGIN(INITIAL);
+
+<idenv>"id="{ID} {
+ for (i=3; i<yyleng; i++) ltxml[i-3]=yytext[i];
+ t=yyleng-3;
+ tmp=strlen(fext);
+ for (i=0; i<tmp; i++) ltxml[t+i]=fext[i];
+ t=t+tmp;
+ ltxml[t]=0;
+ if (!q) printf("File %s\n",ltxml);
+ lt = fopen(ltxml,"w");
+ BEGIN(env);
+}
+
+<env>"symdef{\\"{ID}"}"(.)* {
+i=7;
+while (yytext[i]!='}'){
+ symstr[i-7]=yytext[i];
+ i++;
+}
+symstr[i-7]=0;
+BEGIN(sym);
+}
+
+<sym>"latexmldef{"(.)* {
+i=11;
+while (i<yyleng){
+ ltxmlstr[i-11]=yytext[i];
+ i++;
+}
+ltxmlstr[i-12]=0;
+fprintf(lt,"DefConstructor('\%s{}...{}','%s')\n",symstr,ltxmlstr);
+BEGIN(env);
+}
+
+<env,sym>"\\end{module}" {
+fclose(lt);
+BEGIN(INITIAL);
+}
+
+\n c++;
+. c++;
+
+%%
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ if (argc==1) {
+ printf("arguments expected: [-q] filename(s)\n");
+ } else {
+ q=0;
+ i=1;
+ if (argv[1][0]=='-'){
+ i++;
+ if (argv[1][1]=='q') q=1;
+ }
+ while (i<argc){
+ if (!q) printf("Processing %s...\n",argv[i]);
+ yyin = fopen(argv[i], "r");
+ c=0;
+ yylex();
+ fclose(yyin);
+ i++;
+ }
+ }
+}
diff --git a/Master/texmf-dist/source/latex/stex/bin/old/idcheck.l b/Master/texmf-dist/source/latex/stex/bin/old/idcheck.l
new file mode 100644
index 00000000000..9b1603527d2
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/old/idcheck.l
@@ -0,0 +1,130 @@
+%{
+#include <string.h>
+int ur,ok,a,lin,i,j,c,n,m,d,s,q,fe,f,for_ok,curr_lin;
+typedef char idstr[50];
+idstr l[5000], r[5000];
+%}
+
+ID [a-zA-Z0-9._:\|-]*
+WS [\n\t ]*
+
+%s env inenv fid foc
+
+%%
+
+"\\begin"{WS}"{"("proof"|"example")"}"{WS}"[" {
+fe=1;
+for_ok=0;
+curr_lin=lin;
+BEGIN(env); // stuff that "for" keyval is recommended for
+}
+
+"\\begin"{WS}"{"("proof"|"example")"}" if (f) printf("Missing 'for' at line %d\n",lin);
+
+("\\begin"{WS}"{"("definition"|"assertion"|"proof"|"omtext"|"example"|"step"|"pfcase"|"module")"}"{WS}"[")|("\\justification"{WS}"[") {
+fe=0;
+BEGIN(env);
+}
+
+<env>"]" {
+if (fe && !for_ok && f) printf("Missing 'for' at line %d\n",curr_lin);
+BEGIN(INITIAL);
+}
+
+<env>"id"{WS}"="{WS} BEGIN(fid);
+
+<fid>{ID} {
+for (i=0; i<yyleng; i++) l[n][i]=yytext[i];
+l[n][yyleng]=0;
+if (s) printf("%s\n",l[n]);
+n++;
+BEGIN(env);
+}
+
+<env>("for"){WS}"="{WS} {
+for_ok=1;
+BEGIN(foc);
+}
+<env>("continues"|"for"|"uses"|"premises"){WS}"="{WS} BEGIN(foc);
+
+<foc>{ID} {
+for (j=0; j<yyleng; j++) r[m][j]=yytext[j];
+r[m][yyleng]=0;
+m++;
+BEGIN(env);
+}
+
+<env>("premises"|"uses"){WS}"="{WS}"{" BEGIN(inenv);
+
+<inenv>{ID} {
+strncpy(r[m],yytext,yyleng);
+r[m][yyleng]=0;
+m++;
+}
+
+<inenv>"}" BEGIN(env);
+
+\n {c++;lin++;}
+. c++;
+
+%%
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ if (argc==1) {
+ printf("Usage: idcheck [-q | -s | -f] filename(s)\n");
+ printf("Option -s shows all detected IDs. \n");
+ printf("Option -f shows line numbers for examples and proofs\n that have 'for' keyval missing. \n");
+ printf("Option -q for quiet mode.\n");
+ } else{
+ s=0; q=0;
+ a=1;
+ if (argv[1][0]=='-') {
+ a++;
+ for (j=1; j<strlen(argv[1]); j++)
+ if (argv[1][j]=='s') s=1; else
+ if (argv[1][j]=='q') q=1; else
+ if (argv[1][j]=='f') f=1;
+ }
+ d=0;
+ while (a<argc){
+ if (!q) printf("Parsing %s...\n",argv[a]);
+ yyin = fopen(argv[a] , "r");
+ c = 0;
+ lin = 1;
+ n = 0;
+ m = 0;
+ yylex();
+ fclose(yyin);
+ if (!q) printf("%d characters skipped. Found %d IDs. \n",c,n);
+ if (!q) printf("Checking for duplicates...\n");
+ for (i=0; i<n; i++)
+ for (j=i+1; j<n; j++)
+ if (strcmp(l[i],l[j])==0) {
+ printf("ID=%s is a duplicate in %s\n",l[i],argv[a]);
+ d++;
+ }
+ if (!q) printf("Found %d duplicates.\n",d);
+ if (!q) printf("Checking references... (found %d)\n",m);
+ ur=0;
+ for (i=0;i<m; i++){
+ ok=0;
+ for (j=0; j<n; j++)
+ if (strcmp(r[i],l[j])==0){
+ ok=1;
+ break;
+ }
+ if (!ok) {
+ printf("Unmatched reference for ID=%s\n",r[i]);
+ ur++;
+ }
+ }
+ if (!q) printf("Found %d unmatched references.\n",ur);
+ a++;
+ }
+ return d+ur;
+ }
+ return 1;
+}
diff --git a/Master/texmf-dist/source/latex/stex/bin/old/modstr.l b/Master/texmf-dist/source/latex/stex/bin/old/modstr.l
new file mode 100644
index 00000000000..ae0101147c5
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/old/modstr.l
@@ -0,0 +1,137 @@
+%{
+#include <iostream>
+#include <string>
+#include <map>
+#include <vector>
+using namespace std;
+
+
+const int indent = 4;
+const char start_char = '*';
+
+typedef struct {
+ vector<string> defs,list;
+ int father;
+} nodetype;
+
+map<string,nodetype> g;
+
+string vertex, data;
+int d, miss, skip;
+
+int max(int, int);
+
+%}
+
+ID [a-zA-Z0-9._:\|-]*
+SEP [,;]*
+WS [\n\t ]*
+M [^}]*
+
+%x in_module found_vertex in_module_cont mdef
+%x found_one_child found_more_children
+
+%%
+
+<INITIAL>"\\begin"{WS}"{module}"{WS}"[" BEGIN(in_module);
+
+<in_module>"id"{WS}"=" BEGIN(found_vertex);
+<found_vertex>{ID} {
+vertex = YYText();
+g[vertex].father=0;
+if (miss) cout << endl << "<-------- Module '" << vertex
+ << "' -------->" << endl << endl;
+BEGIN(in_module);
+}
+<in_module>"uses"{WS}"=" BEGIN(found_one_child);
+<found_one_child>"{" BEGIN(found_more_children);
+<found_more_children>"}" BEGIN(in_module);
+<found_one_child>{ID} {
+data=YYText();
+if (g[data].list.empty())
+ g[vertex].father=g[data].father+1;
+else
+ g[vertex].father=max(g[data].father+1,g[vertex].father);
+g[data].list.push_back(vertex);
+BEGIN(in_module);
+}
+<found_more_children>{ID} {
+data=YYText();
+if (g[data].list.empty())
+ g[vertex].father=g[data].father+1;
+else
+ g[vertex].father=max(g[data].father+1,g[vertex].father);
+g[data].list.push_back(vertex);
+}
+
+<found_one_child,found_more_children,found_vertex>{SEP}|{WS}
+
+<in_module>"]" BEGIN(in_module_cont);
+
+<in_module,in_module_cont>(.|\n)
+
+<in_module_cont>"\\"("symdef"|"abbrdef"|"elldef"|"aliasdef"){WS}"{"{WS} BEGIN(mdef);
+<mdef>{M} {
+data = YYText();
+g[vertex].defs.push_back(data);
+}
+<mdef>"}" BEGIN(in_module_cont);
+<in_module_cont>"\\end"{WS}"{module}" BEGIN(INITIAL);
+
+<INITIAL>(.|\n) if (miss) cout << YYText();
+
+<*>{WS}(%)(.)*(\n)*
+
+%%
+
+void spc(int n){
+ for(int i=0; i<n; i++) cout << " ";
+}
+
+int max(int a, int b){
+ return a>b?a:b;
+}
+
+void go(map<string, nodetype > ::iterator node, int depth){
+if (skip && node->second.father!=depth) return;
+spc(d);
+cout << start_char << " " << node->first << "{";
+int tmp = node->second.defs.size()-1;
+for (int j=0; j<=tmp; j++){
+ cout << node->second.defs[j];
+ if (j!=tmp) cout << ",";
+}
+cout << "}" << endl;
+d+=indent;
+for (int i=0; i<node->second.list.size(); i++)
+ go(g.find(node->second.list[i]),depth+1);
+d-=indent;
+}
+
+int main(int argc, char** argv){
+miss=0;
+skip=0;
+if (argc==2)
+ if (argv[1][0]=='-')
+ for (int z=1; argv[1][z]!=0; z++)
+ if (argv[1][z]=='m') miss=1; else
+ if (argv[1][z]=='s') skip=1; else
+ if (argv[1][z]=='h') {
+ cout << " Usage: modstr [-s|m|h]\n Input: stdin\n Output: stdout\n";
+ cout << " Options: -s Show module usage only at the deepest level\n";
+ cout << " -m Show text not within a module\n";
+ cout << " -h This help screen\n";
+ return 0;
+ }
+if (miss) cout << "Text NOT within a module:\n" << endl;
+FlexLexer* lex = new yyFlexLexer;
+lex->yylex();
+d=0;
+map<string, nodetype > ::iterator start = g.begin();
+map<string, nodetype > ::iterator stop = g.end();
+cout << endl;
+for(;stop!=start;start++)
+ if (!start->second.father) go(start,0);
+cout << endl;
+return 0;
+}
diff --git a/Master/texmf-dist/source/latex/stex/bin/old/symdef b/Master/texmf-dist/source/latex/stex/bin/old/symdef
new file mode 100755
index 00000000000..b5c789a1c72
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/old/symdef
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Getopt::Long;
+use Pod::Usage;
+
+my $output = "-";
+my $input = "-";
+
+GetOptions("output=s",\$output);
+
+$input = $ARGV[0] if @ARGV;
+
+open(FIN,$input) or die "Can't open input file.";
+open(FOUT,">$output");
+
+my $line;
+
+while ($line=<FIN>){
+ if ($line !~ m/symdef/ && $line !~ m/elldef/ && $line !~ m/abbrdef/){
+ print FOUT $line;
+ next;
+ }
+ if ($line =~ m/\}\[\d,/){
+ print FOUT $line;
+ next;
+ }
+
+ if ($line =~ m/\\(sym|abbr|ell)def\{\\([^\}]+)\}\[(\d)\]([^\n\%]+)(.*)/){
+ print FOUT "\\$1def{\\$2}[$3,name=$2]$4$5\n";
+ } else {
+ if ($line =~ m/\\(sym|ell|abbr)def\{\\([^\}]+)\}([^\n\%]+)(.*)/){
+ print FOUT "\\$1def{\\$2}[0,name=$2]$3$4\n";
+ }
+ }
+}
+
+close(FIN);
+close(FOUT);
+
+
+__END__
+
+=head1 SYNOPSIS
+
+symdef [--output=outputfile] [texfile]
diff --git a/Master/texmf-dist/source/latex/stex/bin/rf b/Master/texmf-dist/source/latex/stex/bin/rf
new file mode 100755
index 00000000000..7de36042620
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/rf
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w
+
+#######################################################################################
+# A tool for computing the module reuse factor for TEX files. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/rf$ #
+# $Date: 2005-06-29 23:08:10 +0200 (Wed, 29 Jun 2005) $ $Rev: 3147 $ #
+#######################################################################################
+
+use strict;
+use Getopt::Long;
+use Modparse;
+use Pod::Usage;
+
+my $input = "-", my $verbose=0, my $stop_at_end=0;
+my %arg_snippath; my @snippathList;
+
+GetOptions("path=s" => \%arg_snippath,
+ "defpath=s" => \@snippathList,
+ "verbose" => sub { $verbose=1; },
+ "stop" => sub { $stop_at_end=1; },
+ "help" => sub { pod2usage(2)});
+
+$input = $ARGV[0] if ($#ARGV>=0);
+
+$main::lc1 = 0; $main::lc2 = 0;
+my $mp = Modparse->new(snippathList=>\@snippathList,
+ snippath=>\%arg_snippath,
+ stopAtEnd=>$stop_at_end,
+ verbose=>$verbose,
+ onEveryLine=>sub {
+ $main::lc1++;
+ $main::lc2++ if $_[0]->{depth}==1; });
+
+$mp->execute($input);
+my $f = ($main::lc2>0)?$main::lc1/$main::lc2:0;
+print "Reuse factor: $f\n";
+
+__END__
+
+
+=head1 SYNOPSIS
+
+rf <input filename> [options]
+
+ This program computes the reuse factor for a .tex document
+
+ Options:
+ --path XXX specify the value of \XXX (some snippath) in case it is
+ = somePath not defined in the processed .tex file
+ --defpath XXX specify which \XXX (snippath definitions) to look for
+ --stop stop when \end{document} is found; default is to go on
+ --verbose verbose on
+ --help this screen
+
+
+ Example usage:
+ ./rf slides.tex -d snippath -v
+
+ Interpretation:
+ compute the reuse factor for the file slides.tex, look for definitions
+ of \snippath, in verbose mode
diff --git a/Master/texmf-dist/source/latex/stex/bin/rng2dot/ModelRNC.pm b/Master/texmf-dist/source/latex/stex/bin/rng2dot/ModelRNC.pm
new file mode 100644
index 00000000000..53673e37dc8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/rng2dot/ModelRNC.pm
@@ -0,0 +1,770 @@
+# anything that starts with # is removed until \n (considered as a comment)
+# except in literals;
+#
+# NCName is limited to a-zA-Z0-9.-_
+#
+# no proper support for except nameClass
+# no support for exceptPatterns
+
+package ModelRNC;
+
+use strict;
+use File::Basename;
+
+my $DOCUMENT = '_Document_';
+
+sub new{
+ my ($class) = @_;
+ my $self = {};
+ $self->{literalCount} = 0;
+ bless($self, $class);
+}
+
+# this is the main method of the package
+# it should be called right after new
+sub process{
+ my ($self, $filename) = @_;
+ $self->readfile($filename);
+ $self->clean_rnc;
+ $self->read_topLevel;
+ $self->build_info;
+ # free some memory
+ $self->{DATA} = ''; $self->{FILEPATH} = ''; $self->{GRAPH} = '';
+}
+
+sub Error{
+ my ($self, $msg) = @_;
+ print "'$self->{DATA}'\n";
+ die $msg."\n";
+}
+
+# read a file into $storage;
+# or $self->{DATA} if $storage not given
+sub readfile{
+ my ($self, $filename, $storage) = @_;
+
+ # NOTE: this is not exactly perfect
+ if ($self->{FILEPATH}){
+ $filename = $self->{FILEPATH}.$filename unless -e $filename; }
+ my $basepath = dirname($filename);
+ $basepath .= '/' if ($basepath && $basepath !~ m|/$|);
+ $self->{FILEPATH} = $basepath;
+
+ open(FIN, $filename) or $self->Error("Cout not open '$filename'");
+ my @data = <FIN>;
+ close(FIN);
+
+ # for use in namespace set selection
+ push(@{$self->{LOADEDFILES}}, $filename);
+
+ if (defined $storage){ $$storage = join('',@data); }
+ else { $self->{DATA} = join('',@data); }
+}
+
+# remove lines after ##
+sub remove_annotations{
+ my ($self, $data) = @_;
+ $data = \$self->{DATA} unless $data;
+ do {} while ($$data =~ s/\[[^\]\[]*\]//g);
+ $$data =~ s/\#\#[^\n]*//g;
+}
+
+# remove all lines that start with # except
+# the ones that start with ##
+sub remove_comments{
+ my ($self, $data) =@_;
+ $data = \$self->{DATA} unless $data;
+ $$data =~ s/\#[^\#\n][^\n]*//g;
+ $$data =~ s/\#\n/\n/g;
+}
+
+sub scan_literals{
+ my ($self, $data) = @_;
+ my @litseg; my $seg = 0;
+ $data = \$self->{DATA} unless $data;
+ while ($$data =~ s/\"\"\"((\"{0,2}[^\"])*)\"\"\"/_LITSEG$seg/) { $litseg[$seg++] = $1; }
+ while ($$data =~ s/\'\'\'((\'{0,2}[^\'])*)\'\'\'/_LITSEG$seg/) { $litseg[$seg++] = $1; }
+ while ($$data =~ s/\"([^\"\n]*)\"/_LITSEG$seg/) { $litseg[$seg++] = $1; }
+ while ($$data =~ s/\'([^\'\n]*)\'/_LITSEG$seg/) { $litseg[$seg++] = $1; }
+
+ while ($$data =~ s/_LITSEG(\d+)\s*~\s*_LITSEG(\d+)/_LITSEG$seg/)
+ { $litseg[$seg++] = $litseg[$1].$litseg[$2]; }
+
+ while ($$data =~ s/_LITSEG(\d+)/!LIT$self->{literalCount}/)
+ { $self->{literals}[$self->{literalCount}++] = $litseg[$1]; }
+}
+
+# remove \x{N} sections
+sub special_chars{
+ my ($self, $data) = @_;
+ $data = \$self->{DATA} unless $data;
+ while ($$data =~ m/\\x\{([a-fA-F0-9x]+)\}/g){
+ my $lng = length($&); my $p = pos($$data) - $lng;
+ substr($$data, $p, $lng) = chr(hex($1));
+ pos($$data) = $p + 1;
+ }
+}
+
+# remove redundant data from loaded file
+sub clean_rnc{
+ my ($self, $data) = @_;
+ $data = \$self->{DATA} unless $data;
+ $self->scan_literals($data);
+ $self->special_chars($data);
+ $self->remove_annotations($data);
+ $self->remove_comments($data);
+ # add a newline, just in case the last word is a keyword
+ # and for nice printing;
+ $$data.="\n";
+}
+
+# in the processing of the data, the data is destroyed
+# provide two methods for resolving that
+sub backup{
+ my ($self) = @_;
+ $self->{BACKUP_DATA} = $self->{DATA};
+}
+
+sub restore{
+ my ($self) = @_;
+ $self->{DATA} = $self->{BACKUP_DATA} if defined $self->{BACKUP_DATA};
+}
+
+# set or retrieve stored data
+sub data{
+ my ($self, $newdata) = @_;
+ if (defined $newdata){ $self->{DATA} = $newdata; }
+ else { return $self->{DATA}; }
+}
+
+# put back some extracted string from DATA
+sub put_back{
+ my ($self, $back) = @_;
+ substr($self->{DATA}, 0, 0) = $back;
+}
+
+# try to match a keyword; return 1 on success; 0 on failure
+# NOTE: this implies that the used keywords should be followed by
+# some non alphanumeric or space character
+sub read_keyword{
+ my ($self, $keyword) = @_;
+ return 0 if ($self->{DATA} !~ /^\s*\Q$keyword\E\s*[^a-zA-Z0-9_\-\.]/);
+ substr($self->{DATA}, 0, length($&)-1) = '';
+ return 1;
+}
+
+# same as read_keyword, except it dies not expect a non-word character
+# after the word it searches
+sub read_controlword{
+ my ($self, $controlword) = @_;
+ return 0 if ($self->{DATA} !~ /^\s*\Q$controlword\E\s*/);
+ substr($self->{DATA},0,length($&)) = '';
+ return 1;
+}
+
+# expect a keyword; if the word is found, it is extracted
+# otherwise, the program dies (the grammar is incorrect)
+sub expect_keyword{
+ my ($self, $keyword) = @_;
+ $self->Error("Expected keyword '$keyword' was not found")
+ if ($self->{DATA} !~ /^\s*\Q$keyword\E\s*/);
+ substr($self->{DATA}, 0, length($&)) = '';
+}
+
+
+# Does not include Extender and CombiningChar
+# (as in XML Namespaces: http://www.w3.org/TR/REC-xml/)
+sub read_NCName{
+ my ($self, $terminators) = @_;
+ my $termin_exists = 1;
+ if (defined $terminators) { $terminators = "[$terminators]"; }
+ else { $terminators = ''; $termin_exists = 0; }
+ if ($self->{DATA} =~ /^\s*([_a-zA-Z][_a-zA-Z0-9\.\-]*)\s*$terminators/){
+ substr($self->{DATA}, 0, length($&)-$termin_exists) = '';
+ return $1;
+ }
+ return undef;
+}
+
+# try to match an identifierOrKeyword; return it in case
+# of success; return undef in case of failure;
+sub read_identifierOrKeyword{
+ my ($self, $terminators) = @_;
+ $self->read_controlword('\\');
+ return $self->read_NCName($terminators);
+}
+
+# see if the argument is in the set of defined keyword of RelaxNG
+sub isRNCKeyword{
+ my ($word) = @_;
+ return ($word =~ /^\s*(attribute|default|datatypes|div|element|empty|external|grammar|include|inherit|list|mixed|namespace|notAllowed|parent|start|string|text|token)\s*$/);
+}
+
+# read an identifier; return undef if no identifier can be read
+sub read_identifier{
+ my ($self, $terminators) = @_;
+ my $quote = $self->read_controlword('\\');
+ my $ident = $self->read_NCName($terminators);
+ if (!$quote && $ident && isRNCKeyword($ident)){
+ $self->put_back($ident);
+ return undef;
+ }
+ return $ident;
+}
+
+# read a literal in any form given;
+# segments are taken into account
+sub read_literal{
+ my ($self) = @_;
+ if ($self->{DATA} =~ /^\s*!LIT(\d+)\s*/){
+ substr($self->{DATA}, 0, length($&)) = '';
+ return $self->{literals}[$1];
+ }
+ return undef;
+}
+
+# read a namespace URI literal
+sub read_namespaceURILiteral{
+ my ($self, $inherited_namespace) = @_;
+ return $inherited_namespace if $self->read_keyword('inherit');
+ return $self->read_literal;
+}
+
+# read any URI literal
+sub read_anyURILiteral{
+ my ($self) = @_;
+ $self->read_literal; }
+
+sub getNS{
+ my ($self, $nspref) = @_;
+ $self->{${$self->{LOADEDFILES}}[$#{$self->{LOADEDFILES}}]}->{NAMESPACE}{$nspref}; }
+
+sub setNS{
+ my ($self, $nspref, $nsval) = @_;
+ $self->{${$self->{LOADEDFILES}}[$#{$self->{LOADEDFILES}}]}->{NAMESPACE}{$nspref} = $nsval; }
+
+# read all declarations, until none can be read
+sub read_decl{
+ my ($self, $inherited_namespace) = @_;
+ $inherited_namespace = '' unless defined $inherited_namespace;
+ $self->setNS('default',$inherited_namespace) unless $self->getNS('default');
+ my $found = 1;
+ while ($found){
+ if ($self->read_keyword('namespace')){
+ my $namespace_name = $self->read_identifierOrKeyword('=');
+ $self->Error('Undefined namespace name') unless $namespace_name;
+ $self->expect_keyword('=');
+ my $namespace_value =
+ $self->read_namespaceURILiteral($inherited_namespace);
+ $self->Error('Undefined namespace URI')
+ unless defined $namespace_value;
+ $self->setNS($namespace_name, $namespace_value);
+ }
+ elsif ($self->read_keyword('default') &&
+ $self->read_keyword('namespace')){
+ my $namespace_name = undef;
+ if (!$self->read_controlword('=')){
+ $namespace_name = $self->read_identifierOrKeyword('=');
+ $self->Error('Undefined namespace name')
+ unless $namespace_name;
+ $self->expect_keyword('=');
+ }
+ my $namespace_value =
+ $self->read_namespaceURILiteral($inherited_namespace);
+ $self->Error('Undefined namespace URI')
+ unless defined $namespace_value;
+ $self->setNS('default', $namespace_value);
+ $self->setNS($namespace_name, $namespace_value)
+ if $namespace_name;
+ }
+ elsif ($self->read_keyword('datatypes')){
+ my $datatype_name = $self->read_identifierOrKeyword('=');
+ $self->Error('Undefined datatype name') unless $datatype_name;
+ $self->expect_keyword('=');
+ my $datatype_value = $self->read_literal;
+ $self->Error('Undefined datatype value')
+ unless defined $datatype_value;
+ }
+ else { $found = 0; }
+ }
+}
+
+# ignore an annotation definition;
+# (assumes annotation content does not exist)
+# (it has been removed by clean_rnc)
+sub ignore_annotation{
+ my ($self) = @_;
+ $self->read_CName; }
+
+# read a name (CName) of the form NCName:NCName
+sub read_CName{
+ my ($self, $terminators) = @_;
+ $terminators = '\s' unless defined $terminators;
+ my $name = $self->read_NCName(':');
+ if ($name){
+ $self->expect_keyword(':');
+ my $part2 = $self->read_NCName($terminators);
+ $self->Error('Incomplete CName definition') unless $part2;
+ $name .= ":$part2";
+ }
+ return $name;
+}
+
+# read a datatype name
+sub read_datatypeName{
+ my ($self, $terminators) = @_;
+ $terminators = '\s' unless defined $terminators;
+ if ($self->{DATA} =~ /^\s*string\s*[$terminators]/){
+ substr($self->{DATA},0,length($&)-1) = '';
+ return 'string';
+ }
+ elsif ($self->{DATA} =~ /^\s*token\s*[$terminators]/){
+ substr($self->{DATA},0,length($&)-1) = '';
+ return 'token';
+ } else {
+ return $self->read_CName($terminators);
+ }
+}
+
+# read a datatype value
+sub read_datatypeValue{
+ my ($self) = @_;
+ return $self->read_literal;
+}
+
+# return the set of names an element or an attribute can have
+# this does not work well on complicated name classes
+sub read_nameClassEx{
+ my ($self, $terminators) = @_;
+
+ my @result;
+
+ if ($self->read_controlword('(')){
+ @result = $self->read_nameClassEx($terminators.'\)');
+ $self->expect_keyword(')');
+ } else {
+
+ #anyName
+ if ($self->read_controlword('*')){
+ push(@result, '*');
+ if ($self->read_controlword('-')){
+ print STDERR "Warning: USE OF EXCEPT NAMECLASS NOT IMPLEMENTED\n";
+ push(@result, $self->read_nameClassEx($terminators));
+ }
+ }
+ # nsName or name(CName)
+ elsif (my $part1 = $self->read_NCName(':')){
+ $self->expect_keyword(':');
+ if ($self->read_controlword('*')){
+ push(@result, "$part1:*");
+ if ($self->read_controlword('-')){
+ print STDERR
+ "Warning: USE OF EXCEPT NAMECLASS NOT IMPLEMENTED\n";
+ push(@result, '-',
+ $self->read_nameClassEx($terminators));
+ }
+ } else {
+ push(@result, $part1.':'.$self->read_NCName($terminators.'\|'));
+ }
+ }
+ # name(identifierOrKeyword)
+ else {
+ my $name = $self->read_identifierOrKeyword($terminators.'\|');
+ $self->Error('Incomplete name class given') unless $name;
+ push(@result, $name);
+ }
+ }
+
+ $self->Error('No name class provided') unless @result;
+
+ # see if we have more possible names:
+ push(@result, $self->read_nameClassEx($terminators))
+ if ($self->read_controlword('|'));
+
+ return @result;
+}
+
+sub read_nameClass{
+ my ($self, $terminators, @parents) = @_;
+ $terminators = '\s' unless defined $terminators;
+ my @result = $self->read_nameClassEx($terminators);
+ my @finalRes;
+
+ if (@parents && @result){
+
+ my @nsList, my %saw = ();
+ foreach (@parents){
+ if (/\{(.*)\}:.+/){
+ next if $saw{$1};
+ push(@nsList, $1); $saw{$1} = 1; }
+ else {
+ next if $saw{'default'};
+ push(@nsList, $self->getNS('default')); $saw{'default'} = 1; }
+ }
+
+ foreach my $res(@result){
+ if ($res =~ /(.+):(.+)/){
+ push(@finalRes, $self->ns_prepend($2, $1)); }
+ else {
+ map(push(@finalRes, "{$_}:$res"), @nsList); }
+ }
+ } else {
+ map(push(@finalRes, (/(.+):(.+)/)?
+ $self->ns_prepend($2, $1):$self->ns_prepend($_)), @result);
+ }
+ return @finalRes;
+}
+
+
+# read a parameter declaration, if one exists
+sub read_param{
+ my ($self) = @_;
+ my $id = $self->read_identifierOrKeyword('=');
+ return (undef, undef) unless $id;
+ $self->expect_keyword('=');
+ my $val = $self->read_literal;
+ $self->Error('No parameter value specified') unless defined $val;
+ return ($id, $val);
+}
+
+sub begin_read_newfile{
+ my ($self) = @_;
+ my $file = $self->read_anyURILiteral;
+ my $inherit = 'default';
+ if ($self->read_keyword('inherit')){
+ $self->expect_keyword('=');
+ $inherit = $self->read_identifierOrKeyword; }
+ $inherit = $self->getNS($inherit);
+ my $newdata = '';
+ $self->readfile($file, \$newdata);
+ $self->clean_rnc(\$newdata);
+ $self->put_back($newdata.'#');
+ $self->read_decl($inherit); }
+
+sub end_read_newfile{
+ my ($self) = @_;
+ pop(@{$self->{LOADEDFILES}});
+ $self->expect_keyword('#'); }
+
+# read a pattern
+sub read_pattern{
+ my ($self, $grammarPath, $grammarIdent, @parentElements) = @_;
+ my $found = 1; my $grammarCount = 0;
+ my $DEF = $grammarPath.':'.$grammarIdent;
+
+ if ($self->read_keyword('element')){
+ my @elementNames = $self->read_nameClass('{', @parentElements);
+ $self->Error('Unspecified element name') unless @elementNames;
+ map(push(@{$self->{GRAPH}->{$DEF}->{$_}{ELEMENTS}},
+ @elementNames), @parentElements);
+ $self->expect_keyword('{');
+ $self->read_pattern($grammarPath, $grammarIdent, @elementNames);
+ $self->expect_keyword('}');
+ }
+ elsif ($self->read_keyword('attribute')){
+ my @attributeNames = $self->read_nameClass('{');
+ $self->Error('Unspecified attribute name') unless @attributeNames;
+ map(push(@{$self->{GRAPH}->{$DEF}->{$_}{ATTRIBUTES}},
+ @attributeNames), @parentElements);
+ $self->expect_keyword('{');
+ $self->read_pattern($grammarPath, $grammarIdent, @parentElements);
+ $self->expect_keyword('}');
+ }
+ elsif ($self->read_keyword('list') || $self->read_keyword('mixed')){
+ $self->expect_keyword('{');
+ $self->read_pattern($grammarPath, $grammarIdent, @parentElements);
+ $self->expect_keyword('}');
+ }
+ elsif ($self->read_controlword('(')){
+ $self->read_pattern($grammarPath, $grammarIdent, @parentElements);
+ $self->expect_keyword(')');
+ }
+ elsif (my $datatypeValue =
+ $self->read_datatypeValue){
+ # do nothing
+ }
+ elsif (my $datatypeName =
+ $self->read_datatypeName('\s\{\}\-!')){
+ my $datatypeValue = $self->read_datatypeValue;
+
+ # read parameters; ignore them for now
+ if ($self->read_controlword('{')){
+ my ($ident, $val);
+ do{
+ ($ident, $val) = $self->read_param;
+ } while ($ident && $val);
+ $self->expect_keyword('}');
+ }
+ # read possible exceptPattern
+ if ($self->read_controlword('-')){
+ print STDERR "Warning: USE OF EXCEPT PATTERN NOT IMPLEMENTED\n";
+ $self->Error('exceptPattern expected but not found')
+ unless $self->read_pattern($grammarPath, $grammarIdent,
+ @parentElements);
+ }
+ }
+ elsif ($self->read_keyword('external')){
+ $self->begin_read_newfile;
+ $self->read_pattern($grammarPath, $grammarIdent, @parentElements);
+ $self->end_read_newfile;
+ }
+ elsif ($self->read_keyword('grammar')){
+ my $ident = $DEF.$grammarCount++;
+ $self->expect_keyword('{');
+ $self->read_grammarContent($ident, @parentElements);
+ $ident .= ':start';
+ map(push(@{$self->{GRAPH}->{$DEF}->{$_}{REFS}},
+ $ident), @parentElements);
+ $self->expect_keyword('}');
+ }
+ elsif ($self->read_keyword('parent')){
+ my $ident = $self->read_identifier;
+ if ($grammarPath =~ /^([.]+:)[^:]+$/){
+ $ident = $1.$ident;
+ map(push(@{$self->{GRAPH}->{$DEF}->{$_}{REFS}},
+ $ident), @parentElements);
+ }
+ }
+ elsif ($self->read_keyword('empty') || $self->read_keyword('text')
+ || $self->read_keyword('notAllowed')){
+ # do nothing
+ }
+ elsif (my $ident = $self->read_identifier){
+ # check if we did not enter a grammar by mistake:
+ my $asg = $self->read_assignMethod(1);
+ if ($ident && $asg){
+ $self->put_back($ident.$asg);
+ } else {
+ $ident = $grammarPath.':'.$ident;
+ map(push(@{$self->{GRAPH}->{$DEF}->{$_}{REFS}},
+ $ident), @parentElements);
+ }
+
+ } else { $found = 0; }
+
+ if ($self->read_controlword('?') || $self->read_controlword('*')
+ || $self->read_controlword('+')){
+ # ignore
+ }
+
+ if ($self->read_controlword(',') || $self->read_controlword('|')
+ || $self->read_controlword('&')){
+ Error('Pattern expected') unless
+ $self->read_pattern($grammarPath, $grammarIdent, @parentElements);
+ }
+
+ return $found;
+}
+
+sub read_assignMethod{
+ my ($self, $asString) = @_;
+ if ($asString){
+ return '&=' if ($self->read_controlword('&='));
+ return '|=' if ($self->read_controlword('|='));
+ return '=' if ($self->read_controlword('='));
+ return undef;
+ }
+ return 3 if ($self->read_controlword('&='));
+ return 2 if ($self->read_controlword('|='));
+ return 1 if ($self->read_controlword('='));
+ return 0;
+}
+
+# read a grammar pattern
+sub read_grammarPattern{
+ my ($self, $DEF, @parentElements) = @_;
+ if ($self->read_keyword('grammar')){
+ $self->expect_keyword('{');
+ $self->read_grammarContent($DEF, @parentElements);
+ $self->expect_keyword('}'); }
+ else{
+ $self->read_grammarContent($DEF, @parentElements);}
+}
+
+# read all possible grammar contents
+sub read_grammarContent{
+ my ($self, $DEF, @parentElements) = @_;
+ my ($div, $found) = (0, 1);
+
+ while ($found){
+ if ($self->read_keyword('div')){
+ $div++;
+ $self->expect_keyword('{');
+ $self->read_grammarContent($DEF.':_G'.$div, @parentElements);
+ $self->expect_keyword('}');
+ }
+ elsif ($self->read_keyword('include')){
+ $self->begin_read_newfile;
+ $self->read_grammarPattern($DEF, @parentElements);
+ $self->end_read_newfile;
+ if ($self->read_controlword('{')){
+ $self->read_grammarContent($DEF, @parentElements);
+ $self->expect_keyword('}'); }
+ }
+ elsif ($self->read_keyword('start')){
+ my $asg = $self->read_assignMethod;
+ $self->Error('Invalid assign method') unless $asg;
+ @{$self->{GRAPH}->{$DEF.':start'}->{PARENTS}} = @parentElements;
+ $self->read_pattern($DEF, 'start', @parentElements);
+ }
+ elsif (my $ident = $self->read_identifier('=\|\&')){
+ my $asg = $self->read_assignMethod;
+ $self->Error('Invalid assign method') unless $asg;
+ my $ref = $DEF.':'.$ident;
+ %{$self->{GRAPH}->{$ref}} = () if $asg == 1;
+ @{$self->{GRAPH}->{$ref}->{PARENTS}} = @parentElements;
+ $self->read_pattern($DEF, $ident, @parentElements);
+ }
+ elsif ($self->ignore_annotation) {}
+ else { $found = 0; }
+ }
+}
+
+sub ns_prepend{
+ my ($self, $tag, $ns_pref) = @_;
+ my $ns = $ns_pref?$self->getNS($ns_pref):undef;
+ $ns = $self->getNS('default') unless $ns;
+ return "{$ns}:$tag";
+}
+
+# this should match the whole file
+sub read_topLevel{
+ my ($self) = @_;
+ $self->read_decl;
+ $self->read_pattern($DOCUMENT, 'start', $DOCUMENT);
+
+ my ($after, $before) = (0, 1);
+ while ($before != $after){
+ $before = length($self->{DATA});
+ $self->read_grammarContent($DOCUMENT, $DOCUMENT);
+ $after = length($self->{DATA});
+ }
+ $self->{DATA} = trim($self->{DATA});
+ $self->Error('Unable to completely process data')
+ unless $self->{DATA} eq '';
+}
+
+# remove leading and trailing white space
+sub trim{
+ my ($arg) = @_;
+ $arg =~ s/^\s+//;
+ $arg =~ s/\s+$//;
+ return $arg;
+}
+
+sub build_info{
+ my ($self) = @_;
+
+ my %seen = ();
+ local *go = sub {
+ my ($reference, $node) = @_;
+
+ my $ident = $reference.'#'.$node;
+ return if defined $seen{$ident};
+ $seen{$ident} = 1;
+
+ map($self->{ATTR}->{$node}{$_} = 1,
+ @{$self->{GRAPH}->{$reference}->{$node}{ATTRIBUTES}})
+ if defined $self->{GRAPH}->{$reference}->{$node}{ATTRIBUTES};
+
+ my @sons;
+ map(push(@sons, ($reference, $_)),
+ @{$self->{GRAPH}->{$reference}->{$node}{ELEMENTS}})
+ if defined $self->{GRAPH}->{$reference}->{$node}{ELEMENTS};
+
+ if (defined $self->{GRAPH}->{$reference}->{$node}{REFS}){
+ my @refs = @{$self->{GRAPH}->{$reference}->{$node}{REFS}};
+ foreach my $ref(@refs){
+ next unless $self->{GRAPH}->{$ref}->{PARENTS};
+ foreach my $son(@{$self->{GRAPH}->{$ref}->{PARENTS}}){
+ map(push(@sons, ($ref, $_)),
+ @{$self->{GRAPH}->{$ref}->{$son}{ELEMENTS}})
+ if defined $self->{GRAPH}->{$ref}->{$son}{ELEMENTS};
+ push(@refs, @{$self->{GRAPH}->{$ref}->{$son}{REFS}})
+ if defined $self->{GRAPH}->{$ref}->{$son}{REFS};
+ # if a reference has attributes defined,
+ # they will appear as attributes to $DOCUMENT
+ # if the reference is not defined within some element
+ map($self->{ATTR}->{$node}{$_} = 1,
+ @{$self->{GRAPH}->{$ref}->{$son}{ATTRIBUTES}})
+ if ($self->{GRAPH}->{$ref}->{$son}{ATTRIBUTES} &&
+ ($son eq $DOCUMENT));
+ }
+ }
+ }
+ my $sonCount = ($#sons+1)/2;
+ for (my $i = 0; $i < $sonCount; $i++){
+ my ($ref, $son) = ($sons[2*$i], $sons[2*$i+1]);
+ go($sons[2*$i], $sons[2*$i+1]);
+ $self->{NODES}->{$node}{$son} = 1;
+ }
+ };
+
+ go($DOCUMENT.':start', $DOCUMENT);
+
+ %seen = ();
+ local *gnodes = sub {
+ my ($node) = @_;
+ return if $seen{$node};
+ $seen{$node} = 1;
+ foreach my $son(keys %{$self->{NODES}->{$node}}){
+ map($self->{GNODES}->{$node}{$_} = $son,
+ keys %{$self->{NODES}->{$son}});
+ gnodes($son); }
+ };
+
+ gnodes($DOCUMENT);
+ @{$self->{TAGLIST}} = keys %seen;
+}
+
+sub getTagList {
+ my ($self) = @_;
+ return @{$self->{TAGLIST}};
+}
+
+sub tagChildren {
+ my ($self, $tag) = @_;
+ keys %{$self->{NODES}->{$tag}}; }
+
+# given a tag and a childtag, return whether
+# tag can contain childtag
+sub canContain()
+{
+ my ($self, $tag, $childtag) = @_;
+ return ($self->{NODES}->{$tag}{$childtag} ||
+ $self->{NODES}->{$tag}{'*'})?1:0;
+}
+
+# there can be more results: list ?
+# there can be no result, but a class of results.. like a nsName
+# choose representative?
+sub canContainIndirect()
+{
+ my ($self, $tag, $childtag) = @_;
+ return $self->{GNODES}->{$tag}{$childtag} if
+ $self->{GNODES}->{$tag}{$childtag};
+
+ if ($self->{NODES}->{$tag}{'*'}){
+ foreach (@{$self->{TAGLIST}}){
+ return $_ if $self->{NODES}->{$_}{$childtag};
+ }
+ }
+}
+
+# given a tag and an attribute return whether
+# the tag can have that attribute
+sub canHaveAttribute()
+{
+ my ($self, $tag, $attr) = @_;
+ return ($self->{ATTR}->{$tag}{$attr} ||
+ $self->{ATTR}->{$tag}{'*'})?1:0;
+}
+
+sub canContainSomehow()
+{
+ my ($self, $tag, $childtag) = @_;
+ return ($self->canContain($tag, $childtag) ||
+ $self->canContainIndirect($tag, $childtag));
+}
+
+1;
diff --git a/Master/texmf-dist/source/latex/stex/bin/rng2dot/rng2dot b/Master/texmf-dist/source/latex/stex/bin/rng2dot/rng2dot
new file mode 100755
index 00000000000..588b8827c63
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/rng2dot/rng2dot
@@ -0,0 +1,37 @@
+#!/usr/bin/perl -w
+
+use ModelRNC;
+
+die "No input file\n" unless $ARGV[0];
+my $opt = $ARGV[1] || '';
+
+my $rnc = ModelRNC->new();
+$rnc->process($ARGV[0]);
+print STDERR 'Unable to properly parse ('.$rnc->data.")\n" if $rnc->data;
+
+my %seen = ();
+sub make_graph {
+ my ($node) = @_;
+ my @children = $rnc->tagChildren($node);
+ my $pnode = $node;
+ $pnode =~ s/^\{[^\}]*\}://; $pnode =~ s/\-|\+|\*|\s/_/g;
+ my @pchildren = @children;
+ for (my $i = 0 ; $i < @pchildren; $i++) {
+ $pchildren[$i] =~ s/^\{[^\}]*\}://;
+ $pchildren[$i] =~ s/\-|\+|\*|\s/_/g; }
+ if ($opt eq 'txt') {
+ print "$pnode: ".join(', ', @pchildren)."\n\n"; }
+ else {
+ for (my $i = 0 ; $i < @pchildren; $i++) {
+ print "$pnode -> ".$pchildren[$i].";\n"; }}
+ return 0 if $seen{$node};
+ $seen{$node} = 1;
+ foreach my $child(@children) {
+ make_graph($child); }
+ 1; }
+
+print "digraph RNC {\n" unless $opt eq 'txt';
+make_graph('_Document_');
+print "}\n" unless $opt eq 'txt';
+
+__END__
diff --git a/Master/texmf-dist/source/latex/stex/bin/sgraph b/Master/texmf-dist/source/latex/stex/bin/sgraph
new file mode 100755
index 00000000000..c4e709db476
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/sgraph
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+#######################################################################################
+# A tool for creating graphs of module usage patterns based on graphviz. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/sgraph$ #
+# $Date: 2005-10-04 19:31:43 +0200 (Tue, 04 Oct 2005) $ $Rev: 4376 $ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use Modparse;
+use Pod::Usage;
+
+my $input = "-", my $output = "out", my $format = "ps";
+my $root, my $stop_at_end=0, my $use_grouping = 0;
+my $rmdot = 0, my $verbose=0, my $theory = '', my $srange = '';
+my %arg_snippath; my @snippathList;
+
+sub group_name{
+ my ($st) = @_;
+ if ($st =~ /^(.*[\/\\])?([^\/\\]+)\.[^\.\/\\]*$/) { $st = $2; }
+ elsif ($st =~ /^(.*[\/\\])?([^\.\/\\]+)$/) { $st = $2; }
+ $st =~ s/-/_/g;
+ return $st; }
+
+GetOptions("output=s" => \$output,
+ "format=s" => \$format,
+ "nodot" => sub {$rmdot = 1;},
+ "root=s" => \$root,
+ "theory=s" => \$theory,
+ "sliderange=s" => \$srange,
+ "path=s" => \%arg_snippath,
+ "defpath=s" => \@snippathList,
+ "verbose" => sub {$verbose = 1;},
+ "grouping" => sub {$use_grouping = 1},
+ "stop" => sub {$stop_at_end = 1},
+ "help" => sub {pod2usage(2)});
+
+$output = $1 if ($output =~ m/([^.]+)\..*/);
+$input = $ARGV[0] if ($#ARGV>=0);
+$root = group_name($input) unless $root;
+
+
+my %data = (); my %group = ();
+my $mp = Modparse->new(snippathList=>\@snippathList,
+ snippath=>\%arg_snippath,
+ stopAtEnd=>$stop_at_end,
+ verbose=>$verbose,
+ onBegin=>sub { $_[0]->{perm}->{slide} = 0; $_[0]->{perm}->{linecount} = 0;
+ if ($srange =~ /(\d+)\:(\d+)/){
+ ($_[0]->{perm}->{sbegin}, $_[0]->{perm}->{send}) = ($1, $2);
+ $_[0]->{perm}->{in_sliderange} = ($_[0]->{perm}->{sbegin}<1);
+ } else { $_[0]->{perm}->{in_sliderange} = 1; }},
+ onBeginFile=>sub { $_[0]->{grp} = group_name($_[0]->{filename}); },
+ onBeginModule=>sub {
+ if ($_[0]->{perm}->{in_sliderange} && (my $id = $_[0]->{module_id})){
+ $id =~ s/[:-]/_/g;
+ my $uses = '';
+ if ($_[0]->{module_args} =~ /uses=(([\w-]+)|(\{[\w,-]+\}))/){
+ $uses = $1;
+ $uses =~ s/,/;/g; $uses =~ s/[:-]/_/g; }
+ $data{$id}=$uses;
+ $group{$id}=$_[0]->{perm}->{grp};
+ }},
+ onEveryLine=>sub {
+ $_[0]->{perm}->{linecount}++;
+ print ". " if ($_[0]->{pack}->{verbose} && ($_[0]->{perm}->{linecount} % 1000==0));
+ $_[0]->{perm}->{slide}++ if $_[0]->{simple_tex} =~ /\\begin\{slide\}/;
+ $_[0]->{perm}->{in_sliderange}=($_[0]->{perm}->{slide}<=$_[0]->{perm}->{send} &&
+ $_[0]->{perm}->{slide}>=$_[0]->{perm}->{sbegin})
+ if ($_[0]->{perm}->{sbegin} && $_[0]->{perm}->{send});
+ });
+
+print "\nGenerating graph...\n" if $verbose;
+
+$mp->execute($input);
+
+my @queue=();
+
+if ($theory){
+ $theory =~ s/-/_/g;
+ if ($data{$theory}){
+ my $start = 0, my $end = 1, my %already_in;
+ $queue[0] = $theory;
+ $already_in{$theory} = 1;
+ while ($start<$end){
+ my $idx, my $usesx;
+ $idx = $queue[$start];
+ $usesx = $data{$queue[$start]};
+ $start++;
+ if ($usesx){
+ $usesx =~ s/\{//;
+ $usesx =~ s/\}//;
+ foreach (split(/;/,$usesx)){
+ next if $already_in{$_};
+ $queue[$end] = $_;
+ $already_in{$_} = 1;
+ $end++;
+ }
+ }
+ }
+ }
+} else{
+ @queue = keys %data;
+}
+
+open(FOUT,">$output.dot") or die "Can't open output file\n";
+print FOUT "digraph TEX {\n";
+print FOUT "$root [shape=box];\n";
+
+if ($use_grouping){
+ my %subgraph = ();
+ foreach (@queue){
+ $subgraph{$group{$_}}.="$_;";
+ }
+ foreach my $subgr (keys %subgraph){
+ print FOUT "subgraph cluster_$subgr {\n";
+ print FOUT "color = blue;\n";
+ print FOUT "label = $subgr;\n";
+ print FOUT "$subgraph{$subgr}\n";
+ print FOUT "}\n";
+ }
+}
+
+my $lk = 0;
+for my $idx (@queue){
+ my $usesx = $data{$idx};
+ $lk=$lk+($usesx =~ tr/;//)+1;
+ if ($usesx){
+ print FOUT "$idx -> $usesx;\n";
+ } else {
+ print FOUT "$idx -> $root;\n";
+ }
+}
+
+print "Number of links: $lk\n" if $verbose;
+
+
+print FOUT "}\n";
+close(FOUT);
+
+`dot -T$format -o $output.$format $output.dot`;
+unlink "$output.dot" if ($rmdot==1);
+
+print "Done.\n" if $verbose;
+
+__END__
+
+=head1 SYNOPSIS
+
+sgraph <filename> [options]
+
+ <filename> .tex input file; stdin by default
+
+ Options:
+ --output output file; out.dot by default
+ --format output format; .ps by default; for available formats, see dot --help
+ --nodot do not generate .dot file, just target format
+ --root the 'root' of the graph. (name of course)
+ --theory generate a subgraph for the theory
+ --sliderange only look at the given slide range; (2:16 for example)
+ --path XXX specify the value of \XXX (some snippath) in case it is
+ = somePath not defined in the processed .tex file
+ --defpath XXX specify which \XXX (snippath definitions) to look for
+ --stop stop reading data when \end{document} is found, not at EOF
+ --grouping group modules within sections.
+ --verbose verbose on
+ --help this screen
+
+Example:
+./sgraph slides.tex -o graph -f ps -n -t TCN --sliderange 20:10000 -r GenCS -v
diff --git a/Master/texmf-dist/source/latex/stex/bin/sms b/Master/texmf-dist/source/latex/stex/bin/sms
new file mode 100755
index 00000000000..4599f3e2763
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/sms
@@ -0,0 +1,135 @@
+#!/usr/bin/perl -w
+#######################################################################################
+# A tool for creating STeX Module Signatures (SMS) files. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/sms$ #
+# $Date: 2006-10-22 20:01:47 +0200 (Sun, 22 Oct 2006) $ $Rev: 10669 $ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use Modparse;
+use Pod::Usage;
+
+my $input = "-", my $verbose=0, my $stop_at_end=0;
+my %arg_snippath; my @snippathList;
+
+# match {,} brackets that are not comments or special characters
+sub match{
+ my $data = shift;
+ my $b = 0, my $i = 0, my $ignore = 0 ;
+ foreach (split('',$data)){
+ $i++;
+ if ($ignore == 1){
+ $ignore = 0;
+ next;
+ }
+ if ($ignore == 2){
+ next if $_ ne "\n";
+ $ignore = 0;
+ next;
+ }
+ if ($_ eq "\\"){
+ $ignore = 1;
+ next;
+ }
+ if ($_ eq '%'){
+ $ignore = 2;
+ next;
+ }
+ $b++ if $_ eq '{';
+ $b-- if $_ eq '}';
+ return (substr($data,0,$i),substr($data,$i,length($data)-$i+1)) if !$b;
+ }
+ return ('',$data);
+}
+
+
+####### start of program #######
+
+GetOptions("verbose" => sub { $verbose=1; },
+ "stop" => sub { $stop_at_end=1; },
+ "path=s" => \%arg_snippath,
+ "defpath=s" => \@snippathList,
+ "help" => sub { pod2usage(2)});
+
+$input = $ARGV[0] if ($#ARGV>=0);
+
+my $mp = Modparse->new(snippathList=>\@snippathList,
+ snippath=>\%arg_snippath,
+ stopAtEnd=>$stop_at_end,
+ verbose=>$verbose,
+ recursion=>0,
+ onBeginFile=>sub { @{$_[0]->{'sms'.$_[0]->{depth}}}=(); },
+ onBeginModule=>sub { push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original});
+ @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/; },
+ onEndModule=>sub { push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original});
+ @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/ },
+ onRecurse=>sub {
+ my $recurse = $_[0]->{original};
+ $recurse =~ s/include/exclude/g;
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $recurse); },
+ onEndFile=>sub {
+ my $file = $_[0]->{pack}->new_ext($_[0]->{filename},'.sms');
+ open(FOUT, ">$file") or die "Cannot write $file\n";
+ print FOUT @{$_[0]->{'sms'.$_[0]->{depth}}};
+ close(FOUT);
+ `touch $file` unless @{$_[0]->{'sms'.$_[0]->{depth}}};
+ print "Wrote $file\n" if $verbose; },
+ onEveryLine=>sub {
+ my @lines = @{$_[0]->{'sms'.$_[0]->{depth}}};
+ if ($_[0]->{in_module}){
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
+ if ($_[0]->{simple_tex} =~ /\\(sym|abbr|ell)def\{([^\}]+)\}/ ||
+ $_[0]->{simple_tex} =~ /\\symdef\[([^\]]+)\]/);
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
+ if ($_[0]->{simple_tex} =~ /\\importmodule/);
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
+ if ($_[0]->{simple_tex} =~ /\\importOMDocmodule/);
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
+ if ($_[0]->{simple_tex} =~ /\\requiremodules/);
+ push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
+ if ($_[0]->{simple_tex} =~ /\\requirepackage/);
+ if ((/\\STRlabel\{([^\}]+)\}(\{.*)/) || (/\\STRsemantics\[([^\]]+)\](\{.*)/)){
+ my ($label, $line) = ($1, "$2 $_[0]->{comment}");
+ my ($matched, $rest) = (undef, undef);
+ while (1) {
+ ($matched, $rest) = match($line);
+ last if $matched;
+ $line.=$_[0]->{nextline}(); }
+ $_[0]->{rewriteline}($rest) if $rest;
+ $line = "\\STRlabeldef{$label}$matched"; chomp($line);
+ map(push(@{$_[0]->{'sms'.$_[0]->{depth}}},"$_\n"),split("\n",$line));
+ }
+ @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/
+ if (@lines < @{$_[0]->{'sms'.$_[0]->{depth}}});
+ }} );
+
+$mp->execute($input);
+
+print "Done.\n" if $verbose;
+
+
+__END__
+
+
+=head1 SYNOPSIS
+
+sms <input filename> [options]
+
+Options:
+
+ --verbose verbose on
+ --stop stop when \end{document} is found; default is to go on
+ --path XXX=somePath specify the value of \XXX (some snippath) in case it is
+ not defined in the processed .tex file
+ --defpath XXX specify which \XXX (snippath definitions) to look for
+ --help this screen
+
+Purpose:
+ Generate .sms files (STeX Module Signatures) from .tex files
+
+Example:
+ sms slides.tex -v
diff --git a/Master/texmf-dist/source/latex/stex/bin/termin b/Master/texmf-dist/source/latex/stex/bin/termin
new file mode 100755
index 00000000000..0589be09c2f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/bin/termin
@@ -0,0 +1,279 @@
+#!/usr/bin/perl -w
+
+#######################################################################################
+# A tool for automatized replacement of plain words with their \termin macros. #
+# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) #
+# see http://www.gnu.org/copyleft/gpl.html #
+# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/termin$ #
+# $Date: 2005-10-04 17:47:41 +0200 (Tue, 04 Oct 2005) $ $Rev: 4371 $ #
+#######################################################################################
+
+use strict;
+
+use Getopt::Long;
+use Term::ANSIColor;
+use Pod::Usage;
+
+my $verbose = 0;
+my $wordDefs={}, my $twinDefs={}, my $atwinDefs={};
+
+use constant twin => 'T';
+use constant word => 'W';
+use constant atwin => 'A';
+
+my $before_chars = 128;
+my $after_chars = 128;
+
+sub loadDefs{
+ my ($tex_file) = @_;
+
+ # read file
+ open(FIN, $tex_file) or die "Cannot read $tex_file\n";
+ my @contentLines = <FIN>;
+ close(FIN);
+
+ my $content = join('',@contentLines);
+ $content =~ s/\s+//g;
+ $content =~ s/%[^\n]*\n//g;
+ pos($content) = 0;
+
+ my %modules = ();
+ while ($content =~ m/\\begin\{module\}\[([^\]]+)\]/g){
+ next unless $1 =~ /id=([^\],]+)/;
+ $modules{pos($content)} = $1;
+ }
+ my @posList = keys %modules;
+ my $modIndex, my $current_module;
+
+ # see definiens of form \definiens[bar]{foobar}
+ # word 'foobar', concept 'bar', within module 'foo'
+ pos($content) = 0; $modIndex = 0; $current_module = $modules{$posList[0]};
+ while ($content =~ m/\\definiens\[([^\]\-]+)\]\{([^\}]+)\}/g){
+ my $p = pos($content);
+ while ($modIndex < $#posList && $p > $posList[$modIndex+1]) {
+ $modIndex++; $current_module = $modules{$posList[$modIndex]}; }
+ push(@{$wordDefs->{modules}}, $current_module);
+ push(@{$wordDefs->{concepts}}, $1);
+ push(@{$wordDefs->{words}}, $2);
+ print word, " ==> $current_module: $1: $2\n" if $verbose>=2;
+ }
+
+ # see definiens of form \definiens[aaa-bbb]{\twin{ccc}{ddd}}
+ # words 'ccc ddd', concept 'aaa-bbb', within module 'foo'
+ pos($content) = 0; $modIndex = 0; $current_module = $modules{$posList[0]};
+ while ($content =~ m/\\definiens\[([^\-\]]+)\-([^\]]+)\]\{\\twin\{([^\}]+)\}\{([^\}]+)\}\}/g){
+ my $p = pos($content);
+ while ($modIndex < $#posList && $p > $posList[$modIndex+1]) {
+ $modIndex++; $current_module = $modules{$posList[$modIndex]}; }
+ push(@{$twinDefs->{modules}}, $current_module);
+ push(@{$twinDefs->{concepts}}, "$1-$2");
+ push(@{$twinDefs->{words}}, $3);
+ push(@{$twinDefs->{twins}}, $4);
+ print twin, " ==> $current_module: $1-$2: $3 $4\n" if $verbose>=2;
+ }
+
+ # \twindef{aaa}{bbb}
+ pos($content) = 0; $modIndex = 0; $current_module = $modules{$posList[0]};
+ while ($content =~ m/\\twindef\{([^\}]+)\}\{([^\}]+)\}/g){
+ my $p = pos($content);
+ while ($modIndex < $#posList && $p > $posList[$modIndex+1]) {
+ $modIndex++; $current_module = $modules{$posList[$modIndex]}; }
+ push(@{$twinDefs->{modules}}, $current_module);
+ push(@{$twinDefs->{concepts}}, "$1-$2");
+ push(@{$twinDefs->{words}}, $1);
+ push(@{$twinDefs->{twins}}, $2);
+ print twin, " ==> $current_module: $1-$2: $1 $2\n" if $verbose>=2;
+ }
+
+ # see definiens of form \definiens[aaa-bbb-ccc]{\twin{ddd}{eee}{fff}}
+ # words 'ddd eee fff', concept 'aaa-bbb-ccc', within module 'foo'
+ pos($content) = 0; $modIndex = 0; $current_module = $modules{$posList[0]};
+ while ($content =~ m/\\definiens\[([^\-\]]+)\-([^\-\]]+)\-([^\]]+)\]\{\\atwin\{([^\}]+)\}\{([^\}]+)\}\{([^\}]+)\}\}/g){
+ my $p = pos($content);
+ while ($modIndex < $#posList && $p > $posList[$modIndex+1]) {
+ $modIndex++; $current_module = $modules{$posList[$modIndex]}; }
+ push(@{$atwinDefs->{modules}}, $current_module);
+ push(@{$atwinDefs->{concepts}}, "$1-$2-$3");
+ push(@{$atwinDefs->{words}}, $4);
+ push(@{$atwinDefs->{twins}}, $5);
+ push(@{$atwinDefs->{adjs}}, $6);
+ print atwin, " ==> $current_module: $1-$2-$3: $4 $5 $6\n" if $verbose>=2;
+ }
+
+ # \atwindef{aaa}{bbb}{ccc}
+ pos($content) = 0; $modIndex = 0; $current_module = $modules{$posList[0]};
+ while ($content =~ m/\\atwindef\{([^\}]+)\}\{([^\}]+)\}\{([^\}]+)\}/g){
+ my $p = pos($content);
+ while ($modIndex < $#posList && $p > $posList[$modIndex+1]) {
+ $modIndex++; $current_module = $modules{$posList[$modIndex]}; }
+ push(@{$atwinDefs->{modules}}, $current_module);
+ push(@{$atwinDefs->{concepts}}, "$1-$2-$3");
+ push(@{$atwinDefs->{words}}, $1);
+ push(@{$atwinDefs->{twins}}, $2);
+ push(@{$atwinDefs->{adjs}}, $3);
+ print atwin, " ==> $current_module: $1-$2-$3: $1 $2 $3\n" if $verbose>=2;
+ }
+
+}
+
+sub max{
+ my ($max, @values) = @_;
+ foreach (@values) { $max = $_ if $_ gt $max;}
+ return $max;
+}
+
+sub nospace{
+ my ($str) = @_;
+ $str =~ s/\s+/ /g;
+ $str =~ s/^\s//;
+ $str =~ s/\s$//;
+ return $str;
+}
+
+sub replaceDefs{
+ my ($in_tex_file, $out_tex_file) = @_;
+
+ open(FIN, $in_tex_file) or die "Cannot read $in_tex_file\n";
+ my @content_lines = <FIN>;
+ close(FIN);
+
+ my $content = join('',@content_lines);
+ my $lcont = length($content);
+
+ local *go_word = sub {
+
+ my ($word, $new_word1_ex, $new_word2_ex) = @_;
+ $new_word2_ex = $new_word1_ex unless defined $new_word2_ex;
+
+ while ($content =~ m/([^\{\s]?)(\s*$word\s*)[^\}\s]?/gi){
+ my $p = pos($content);
+ my $ahead_len = length($1); my $matched_word = $2;
+ my $wlen = length($matched_word);
+ my $trail_len = length($&) - $wlen - $ahead_len;
+
+ if (($ahead_len != 0 || $trail_len != 0) ||
+ ($ahead_len == 0 && $trail_len == 0 && ($p == $wlen || $p == $lcont))){
+ my $start_pos = max(0, $p - $wlen - $trail_len - $before_chars);
+ my $new_word1 = $new_word1_ex; my $new_word2 = $new_word2_ex;
+
+ my $word_count = 0;
+ while ($matched_word =~ /\s*([^\s]+)\s*/g){
+ my $replace = $1;
+ $new_word1 =~ s/W%$word_count/$replace/g;
+ $new_word2 =~ s/W%$word_count/$replace/g;
+ $word_count++;
+ }
+
+ print "\nAnnotate '";
+ print color 'bold blue'; print nospace($matched_word); print color 'reset';
+ print "' with \n Y = '"; print color 'red bold'; print $new_word2;
+ print color 'reset'; print "'\n y = '"; print color 'red bold';
+ print $new_word1; print color 'reset'; print "'\n in: \n<<< ";
+ print color 'green';
+ print substr($content, $start_pos, $before_chars);
+ print color 'bold blue';
+ print substr($content, $start_pos + $before_chars, $wlen);
+ print color 'reset green';
+ print substr($content, $start_pos + $before_chars + $wlen, $after_chars);
+ print color 'reset';
+ print " >>> ?\n";
+ print "Options: <Y, y, [n]> ";
+
+ my $answer = <STDIN>;
+ chomp($answer);
+
+ if ($answer eq 'y'){
+ substr($content, $p - $wlen - $trail_len, $wlen) = $new_word1;
+ $lcont = length($content);
+ pos($content) = $p + length($new_word1) - $wlen;
+ print "PROGRESS: Matched text was replaced with '$new_word1'\n" if $verbose;
+ } elsif ($answer eq 'Y'){
+ substr($content, $p - $wlen - $trail_len, $wlen) = $new_word2;
+ $lcont = length($content);
+ pos($content) = $p + length($new_word2) - $wlen;
+ print "PROGRESS: Matched text was replaced with '$new_word2'\n" if $verbose;
+ }
+
+ }
+ pos($content) = $p - $trail_len;
+ }
+ };
+
+ my $we = "(s|(ing))?"; # word endings
+ if (defined $wordDefs->{words}){
+ my $wordDefsCount = $#{$wordDefs->{words}} + 1;
+ for (my $j = 0 ; $j < $wordDefsCount; $j++){
+ my $word = "${$wordDefs->{words}}[$j]$we";
+ my $new_word = " {\\termin[cd=${$wordDefs->{modules}}[$j],name=${$wordDefs->{concepts}}[$j]]".
+ "{W%0} ";
+ go_word($word, $new_word);
+ }
+ }
+
+ if (defined $twinDefs->{words}){
+ my $twinDefsCount = $#{$twinDefs->{words}} + 1;
+ for (my $j = 0 ; $j < $twinDefsCount; $j++){
+ my $word = "${$twinDefs->{words}}[$j]$we\\s+${$twinDefs->{twins}}[$j]$we";
+ my $new_word1 = " {\\termin[cd=${$twinDefs->{modules}}[$j],name=${$twinDefs->{concepts}}[$j]]".
+ "{W%0 W%1}} ";
+ my $new_word2 = " {\\termin[cd=${$twinDefs->{modules}}[$j],name=${$twinDefs->{concepts}}[$j]]".
+ "{\\twin{W%0}{W%1}}} ";
+ go_word($word, $new_word1, $new_word2);
+ }
+ }
+
+ if (defined $atwinDefs->{words}){
+ my $atwinDefsCount = $#{$atwinDefs->{words}} + 1;
+ for (my $j = 0 ; $j < $atwinDefsCount; $j++){
+ my $word = "${$atwinDefs->{words}}[$j]$we\\s+${$atwinDefs->{twins}}[$j]$we\\s+${$atwinDefs->{adjs}}[$j]$we";
+ my $new_word1 = " {\\termin[cd=${$atwinDefs->{modules}}[$j],name=${$atwinDefs->{concepts}}[$j]]".
+ "{W%0 W%1 W%2}} ";
+ my $new_word2 = " {\\termin[cd=${$atwinDefs->{modules}}[$j],name=${$atwinDefs->{concepts}}[$j]]".
+ "{\\atwin{W%0}{W%1}{W%2}}} ";
+ go_word($word, $new_word1, $new_word2);
+ }
+ }
+
+ open(FOUT, ">$out_tex_file") or die "Cannot write $out_tex_file\n";
+ print FOUT $content;
+ close(FOUT);
+
+}
+
+my @background, my @main, my @output;
+
+GetOptions("verbose" => sub {$verbose++;},
+ "background=s" => \@background,
+ "main=s" => \@main,
+ "output=s" => \@output,
+ "help" => sub { pod2usage(2)});
+
+foreach (@background) { loadDefs($_); }
+
+for (my $i = 0 ; $i <= $#main; $i++) {
+ replaceDefs($main[$i], $output[$i] || $main[$i]);
+}
+
+
+__END__
+
+=head1 SYNOPSIS
+
+termin [options]
+
+Options:
+
+ --verbose verbose on
+ --background background file to read \termin{} definitions from
+ --main main file to process
+ --output output file; the modified content of the main file will
+ be written here
+ --help this screen
+
+Purpose:
+ Read the \termin definitions from a background file and update a specific main file;
+ output will be written to the specified the output file.
+ Note: multiple background/main/output files may be specified.
+
+Example:
+ termin --background a.tex --background b.tex --main slides.tex --output new_slides.tex
diff --git a/Master/texmf-dist/source/latex/stex/cmathml/cmathml.dtx b/Master/texmf-dist/source/latex/stex/cmathml/cmathml.dtx
new file mode 100644
index 00000000000..dfd1c52bd18
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/cmathml/cmathml.dtx
@@ -0,0 +1,2493 @@
+% \iffalse meta-comment
+% Semantic Macros for Content MathML in LaTeX
+% Copyright (c) 2006 Michael Kohlhase, all rights reserved
+% this file is released under the
+% Gnu Library Public Licences (LGPL)
+%
+% The development version of this file can be found at
+% $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/cmathml/cmathml.dtx $
+% \fi
+%
+% \iffalse
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{cmathml}[2010/06/25 v1.0 CMathML Bindings]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,float,amsfonts,a4wide}
+\usepackage{stex-logo,cmathml,cmathmlx,presentation}
+\usepackage[show]{ed}
+\usepackage[hyperref=auto,style=alphabetic]{biblatex}
+\bibliography{kwarc}
+\usepackage{../ctansvn}
+\usepackage{hyperref}
+\usepackage[eso-foot,today]{svninfo}
+\svnInfo $Id: cmathml.dtx 1483 2010-07-19 07:11:16Z kohlhase $
+\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/cmathml/cmathml.dtx $
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{cmathml.dtx}\end{document}
+%</driver>
+% \fi
+%
+%\CheckSum{1}
+%
+% \changes{v0.1}{2006/01/10}{Initial Version}
+% \changes{v0.2}{2006/01/16}{Added big operators}
+% \changes{v1.0}{2010/06/18}{Declared complete}
+%
+% \GetFileInfo{cmathml.sty}
+%
+% \MakeShortVerb{\|}
+%
+% \def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \newenvironment{pcmtab}[1][5cm]{\begin{center}\begin{tabular}{|l|l|p{#1}|l|}\hline%
+% macro & args & Example & Result\\\hline\hline}%
+% {\end{tabular}\end{center}}
+% \newenvironment{cmtab}{\begin{center}\begin{tabular}{|l|l|l|l|}\hline%
+% macro & args & Example & Result\\\hline\hline}%
+% {\end{tabular}\end{center}}
+%
+% \def\snippet#1{\hbox{\ttfamily{#1}}}
+% \def\xml{{\scsys{Xml}}}
+% \def\xslt{{\scsys{xslt}}}
+% \def\element#1{{\ttfamily{#1}}}
+% \def\mathml{{\scshape{MathML}}\index{MathML}}
+% \def\latexml{\hbox{{\LaTeX}ML}\index{LaTexML}}
+% \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{cmathml.sty}}: A {\TeX/\LaTeX}-based Syntax for Content
+% {\mathml}\thanks{Version {\fileversion} (last revised {\filedate})}}
+% \author{Michael Kohlhase\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% The |cmathml| package is 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 provides a collection of semantic macros for content {\mathml} and their
+% {\latexml} bindings. These macros form the basis of a naive translation from
+% semantically preloaded {\LaTeX} formulae into the content {\mathml} formulae via the
+% {\latexml} system.
+% \end{abstract}
+%
+% \newpage\tableofcontents\newpage
+%
+%\section{Introduction}\label{sec:intro}
+%
+% This document describes the collection of semantic macros for content {\mathml} and
+% their {\latexml} bindings. These macros can be used to mark up mathematical formulae,
+% exposing their functional/logical structure. This structure can be used by MKM systems
+% for added-value services, either directly from the {\sTeX} sources, or after
+% translation. Even though it is part of the {\stex} collection, it can be used
+% independently. Note that this documentation of the package presupposes the discussion of
+% the {\stex} collection to be self-contained.
+%
+% \subsection{Encoding Content {\mathml} in {\TeX/\LaTeX}}\label{sec:encoding}
+%
+% The |cmathml| packge presented here addresses part of transformation problem: representing
+% mathematical formulae in the {\LaTeX} workflow, so that content {\mathml} representations
+% can be derived from them. The underlying problem is that run-of-the-mill {\TeX/\LaTeX}
+% only specifies the presentation (i.e. what formulae look like) and not their content
+% (their functional structure). Unfortunately, there are no good methods (yet) to infer the
+% latter from the former, but there are ways to get presentation from content.
+%
+% The solution to this problem is to dump the extra work on the author (after all she knows
+% what she is talking about) and give them the chance to specify the intended structure. The
+% markup infrastructure supplied by the |cmathml| package lets the author do this without
+% changing the visual appearance, so that the {\LaTeX} workflow is not disrupted.
+%
+% To use these |cmathml| macros in a {\LaTeX} document, you will have to include the
+% |cmathml| package using |\usepackage{cmathml}| somewhere in the document preamble. Then
+% you can use the macros
+% \begin{verbatim}
+% $\Ceq{\Cexp{\Ctimes{\Cimaginaryi,\Cpi}},\Cuminus{\Ccn{1}}}$
+% \end{verbatim}
+% which will result in $e^{i\pi}=-1$ when the document is formatted in {\LaTeX}. If the
+% document is converted to {\xml} using the {\latexml} conversion tool, then the result
+% will be content {\mathml} representation:
+%
+%\begin{exfig}
+% \begin{verbatim}
+% <math xmlns="http://www.w3.org/1998/Math/MathML">
+% <apply>
+% <eq/>
+% <apply>
+% <exp/>
+% <apply><times><imaginaryi/><pi/></times></apply>
+% </apply>
+% <apply><minus/><cn>1</cn></apply>
+% </apply>
+% </math>
+% \end{verbatim}\vspace*{-.6cm}
+% \caption{Content {\mathml} Form of $e^{i\pi}=-1$}\label{fig:cmathml-eip}
+% \end{exfig}
+%
+% \subsection{Changing the {\TeX/\LaTeX} Presentation}\label{sec:changing}
+%
+% It is possible to change the default presentation (i.e. the result under {\LaTeX}
+% formatting): The semantic macros only function as interface control sequences, which
+% call an internal macro that does the actual presentation. Thus we simply have to
+% redefine the internal macro to change the presentation. This is possible locally or
+% globally in the following way:
+% \begin{verbatim}
+% \makeatletter
+% \gdef\CMathML@exp#1{exp(#1)}
+% \def\CMathML@pi{\varpi}
+% \makeatother
+% \end{verbatim}
+%
+% The first line is needed to lift the {\LaTeX} redefinition protection for internal
+% macros (those that contain the $\snippet{\@}$ character), and the last line restores it
+% for the rest of the document. The second line has a {\em{global}} (i.e. the presentation
+% will be changed from this point on to the end of the document.) redefinition of the
+% presentation of the exponential function in the {\LaTeX} output. The third line has a
+% {\em{local}} redefinition of the presentation (i.e. in the local group induced by
+% {\LaTeX}'s $\snippet{begin}/\snippet{end}$ grouping or by {\TeX}'s grouping induced by
+% curly braces). Note that the argument structure has to be respected by the presentation
+% redefinitions. Given the redefinitions above, our equation above would come out as
+% $exp(i\varpi)=-1$.
+%
+% \subsection{The Future: Heuristic Parsing}\label{sec:future}
+%
+% The current implementation of content {\mathml} transformation from {\LaTeX} to
+% {\mathml} lays a heavy burden on the content author: the {\LaTeX} source must be
+% semantically preloaded --- the structure of the formulae must be fully annotated. In our
+% example above, we had to write {|\Ceq{A,B}|} instead of the more conventional (and more
+% legible) {|A=B|}.\ednote{come up with a good mixed example}
+%
+% The reason for this is that this keeps the transformation to content {\mathml} very
+% simple, predictable and robust at the expense of authoring convenience. The
+% implementation described in this module should be considered as a first step and
+% fallback solution only. Future versions of the $\latexml$ tool will feature more
+% intelligent solutions for determining the implicit structure of more conventional
+% mathematical notations (and {\LaTeX} representations), so that writing content {\mathml}
+% via {\LaTeX} will become less tedious.
+%
+% However, such more advanced techniques usually rely on linguistic, structural, and
+% semantic information about the mathematical objects and their preferred
+% representations. They tend to be less predictable to casual users and may lead to
+% semantically unexpected results.\ednote{talk about sTeX and extensibility in
+% MathML/OpenMath/OMDoc}
+%
+% \newpage
+% \section{The User Interface}\label{sec:modules}
+%
+% We will now tabulate the semantic macros for the Content {\mathml} elements. We have
+% divided them into modules based on the sectional structure of the {\mathml}2
+% recommendation ($2^{nd}$ edition). Before we go into the specific elements one-by-one,
+% we will discuss some general properties of the |cmatml| macros and their {\latexml}
+% bindings.
+%
+% \subsection{Generalities of the Encoding}\label{sec:generalities}
+%
+% The semantic macros provided by the |cmatml| package differ mainly in the way they treat
+% their arguments. The simplest case are those for constants~\ref{sec:constants} that do
+% not take any. Others take one, two, three, or even four arguments, which have to be
+% {\TeX} tokens or have to be wrapped in curly braces. For operators that are associative
+% {\twin{associative}{operator}} like addition the argument sequence is provided as a
+% single {\TeX} argument (wrapped in curly braces) that contains a comma-separated
+% sequence of arguments (wrapped in curly braces where necessary).
+%
+% \DescribeMacro{\Capply} The current setup of the |cmathml| infrastructure minimizes the
+% need of specifying the {\mathml} {\element{apply}} element, since the macros are all in
+% applied form: As we have seen in the example in the Introduction~\ref{sec:intro}, a
+% macro call like {|\Cexp{A}|} corresponds to the application of the exponential function
+% to some object, so the necessary {\element{apply}} elements in the {\mathml}
+% representation are implicit in the {\LaTeX} formulation and are thus added by the
+% transformation. Of course this only works, if the function is a content {\mathml}
+% element. Often, in mathematics we will have situations, where the function is a variable
+% (or ``arbitrary but fixed'') function. Then the formula $f(x)$ represented as |$f(x)$|
+% in {\TeX} could (and sometimes will) be misunderstood by the Math parser as $f\cdot x$,
+% i.e. a product of the number $f$ with the number $x$, where $x$ has brackets for some
+% reason. In this case, we can disambiguate by using |\Capply{f}x|, which will also format
+% as $f(x)$.\ednote{what about $n$-ary functions?}
+%
+% By the same token, we do not need to represent the qualifier elements
+% {\element{condition}} and {\element{domainofapplication}}\footnote{We do not support the
+% {\element{fn}} element as it is deprecated in {\mathml}2 and the {\element{declare}}
+% and {\element{sep}} elements, since their semantic status is unclear (to the author,
+% if you feel it is needed, please gripe to me).}, for
+% {\twintoo{binding}{operator}s}. They are are folded into the special forms of the
+% semantic macros for the binding operators below (the ones with the {|Cond|} and {|DA|}
+% endings):
+%
+% For operators that are {\index*{associative}}, {\index*{commutative}}, and
+% {\index*{idempotent}} ({\index*{ACI}} i.e. {\index*{bracketing}},
+% order\twin{argument}{order}, and {\index*{multiplicity}} of arguments does not matter)
+% {\mathml} supplies the a special form of application as a binding operator (often called
+% the corresponding ``{\twintoo{big}{operator}})'', which ranges over a whole set of
+% arguments. For instance for the ACI operator $\cup$ for set union has the ``big''
+% operator for unions over collections of sets e.g. used in the power set
+% $\bigcup_{S\subseteq T}S$ of a set $T$. In some cases, the ``big'' operators are
+% provided independently by {\mathml}, e.g. the ACI addition operator has the sum operator
+% as a corresponding ``big operator'': $\sum_{x\in\Cnaturalnumbers}{x^i}$ is the sum of
+% the powers of $x$ for all natural numbers. Where they are not, we will supply extra
+% macros in the |cmathml| package, e.g. the |\CUnion| macro as the big operator for
+% |\Cunion|.
+%
+% Finally, some of the binding operators have multiple content models flagged by the
+% existence of various modifier elements. In these cases, we have provided different
+% semantic macros for the different cases.
+%
+% \subsection{The Token Elements}\label{sec:tokens}
+%
+% The {\mathml} token elements are very simple containers that wrap some presentation
+% {\mathml} text. The {\element{csymbol}} element is the extension element in
+% {\mathml}. It's content is the presentation of symbol, and it has a |definitionURL|
+% attribute that allows to specify a URI that specifies the semantics of the symbol. This
+% URL can be specified in an optional argument to the |\Ccsymbol| macro, in accordance
+% with usual mathematical practice, the |definitionURL| is not presented.
+% \DescribeMacro{\Ccn}\DescribeMacro{\Cci}\DescribeMacro{\Ccsymbol}
+% \begin{cmtab}
+% |\Ccn| & token & |\Ccn{t}| & $\Ccn{t}$\\\hline
+% |\Cci| & token & |\Cci{t}| & $\Cci{t}$\\\hline
+% |\Ccsymbol| & token, URI & |\Ccsymbol[http://w3.org]{t}|
+% & $\Ccsymbol[http://w3.org]{t}$\\\hline
+% \end{cmtab}
+% Like the |\Ccsymbol| macro, all other macros in the |camthml| package take an optional
+% argument\footnote{This may change into a KeyVaL argument in future versions of the
+% |cmathml| package.} for the |definitionURL| attribute in the corresponding {\mathml}
+% element.
+%
+%\newpage
+% \subsection{The Basic Content Elements}\label{sec:basic}
+%
+% The basic elements comprise various pieces of the {\mathml} infrastructure. Most of the
+% semantic macros in this section are relatively uneventful.
+%
+% \DescribeMacro{\Cinverse}\DescribeMacro{\Ccompose}\DescribeMacro{\Cident}
+% \DescribeMacro{\Cdomain}\DescribeMacro{\Ccodomain}\DescribeMacro{\Cimage}
+% \begin{cmtab}
+% |\Cinverse| & 1 & |\Cinverse{f}| & $\Cinverse{f}$\\\hline
+% |\Ccompose| & 1 & |\Ccompose{f,g,h}| & $\Ccompose{f,g,h}$\\\hline
+% |\Cident| & 0 & |\Cident| & $\Cident$\\\hline
+% |\Cdomain| & 1 & |\Cdomain{f}| & $\Cdomain{f}$\\\hline
+% |\Ccodomain| & 1 & |\Ccodomain{f}| & $\Ccodomain{f}$\\\hline
+% |\Cimage| & 1 & |\Cimage{f}| & $\Cimage{f}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Clambda}\DescribeMacro{\ClambdaDA}\DescribeMacro{\Crestrict} For the
+% {\element{lambda}} element, we only have the {\element{domainofapplication}} element, so
+% that we have three forms a $\lambda$-construct can have. The first one is the simple one
+% where the first element is a bound variable. The second one restricts the applicability
+% of the bound variable via a {\element{domainofapplication}} element, while the third one
+% does not have a bound variable, so it is just a function restriction
+% operator.\ednote{need ClambdaCond}
+%
+% \begin{cmtab}
+% |\Clambda| & 2 & |\Clambda{x,y}{A}| & $\Clambda{x,y}{A}$\\\hline
+% |\ClambdaDA| & 3 & |\ClambdaDA{x}{C}{A}| & $\ClambdaDA{x,y}{C}{A}$\\\hline
+% |\Crestrict| & 2 & |\Crestrict{f}{S}| & $\Crestrict{f}{S}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{ccinterval}\DescribeMacro{cointerval}
+% \DescribeMacro{ocinterval}\DescribeMacro{oointerval}
+% The {\element{interval}} constructor actually represents four types of intervals in
+% {\mathml}. Therefore we have four semantic macros, one for each combination of open and
+% closed endings:
+% \begin{cmtab}
+% |\Cccinterval| & 2 & |\Cccinterval{1}{2}| & $\Cccinterval{1}{2}$\\\hline
+% |\Ccointerval| & 2 & |\Ccointerval{1}{2}| & $\Ccointerval{1}{2}$\\\hline
+% |\Cocinterval| & 2 & |\Cocinterval{1}{2}| & $\Cocinterval{1}{2}$\\\hline
+% |\Coointerval| & 2 & |\Coointerval{1}{2}| & $\Coointerval{1}{2}$\\\hline
+% \end{cmtab}
+%
+%\DescribeMacro{\Cpiecewise}\DescribeMacro{\Cpiece}\DescribeMacro{\Cotherwise}
+% The final set of semantic macros are concerned with piecewise definition of functions.
+% \begin{cmtab}
+% |\Cpiecewise| & 1 & see below & see below\\\hline
+% |\Cpiece| & 2 & |\Cpiece{A}{B}| & $\begin{array}{ll}\Cpiece{A}{B}\end{array}$\\\hline
+% |\Cotherwise| & 1 & |\Cotherwise{B}| & $\begin{array}{ll}\Cotherwise{1}\end{array}$\\\hline
+% \end{cmtab}
+%
+% For instance, we could define the abstract value function on the reals with the following
+% markup
+%
+% \begin{center}
+% \begin{tabular}{|l|l|}\hline
+% Semantic Markup & Formatted\\\hline
+% \begin{minipage}{8cm}\footnotesize
+% \begin{verbatim}
+% \Ceq{\Cabs{x},
+% \Cpiecewise{\Cpiece{\Cuminus{x}}{\Clt{x,0}}
+% \Cpiece{0}{\Ceq{x,0}}
+% \Cotherwise{x}}}
+% \end{verbatim}
+% \end{minipage} &
+% $\Ceq{\Cabs{x},\Cpiecewise{\Cpiece{\Cuminus{x}}{\Clt{x,0}}
+% \Cpiece{0}{\Ceq{x,0}}
+% \Cotherwise{x}}}$
+% \\\hline
+% \end{tabular}
+% \end{center}
+%
+% \newpage
+% \subsection{Elements for Arithmetic, Algebra, and Logic}\label{sec:arith}
+%
+% This section introduces the infrastructure for the basic arithmetic operators. The first
+% set is very simple
+%
+% \DescribeMacro{\Cquotient}\DescribeMacro{\Cfactorial}\DescribeMacro{\Cdivide}
+% \DescribeMacro{\Cminus}\DescribeMacro{\Cplus}\DescribeMacro{\Cpower}
+% \DescribeMacro{\Crem}\DescribeMacro{\Ctimes}\DescribeMacro{\Croot}
+% \begin{cmtab}
+% |\Cquotient| & 2 & |\Cquotient{1}{2}| & $\Cquotient{1}{2}$\\\hline
+% |\Cfactorial| & 1 & |\Cfactorial{7}| & $\Cfactorial{7}$\\\hline
+% |\Cdivide| & 2 & |\Cdivide{1}{2}| & $\Cdivide{1}{2}$\\\hline
+% |\Cminus| & 2 & |\Cminus{1}{2}| & $\Cminus{1}{2}$\\\hline
+% |\Cplus| & 1 & |\Cplus{1}| & $\Cplus{1}$\\\hline
+% |\Cpower| & 2 & |\Cpower{x}{2}| & $\Cpower{x}{2}$\\\hline
+% |\Crem| & 2 & |\Crem{7}{2}| & $\Crem{7}{2}$\\\hline
+% |\Ctimes| & 1 & |\Ctimes{1,2,3,4}| & $\Ctimes{1,2,3,4}$\\\hline
+% |\Croot| & 2 & |\Croot{3}{2}| & $\Croot{3}{2}$\\\hline
+% \end{cmtab}
+%
+% The second batch below is slightly more complicated, since they take a set of
+% arguments. In the |cmathml| package, we treat them like {\index*{associative}}
+% operators, i.e. they act on a single argument that contains a sequence of
+% comma-separated arguments\ednote{implement this in the latexml side}
+%
+% \DescribeMacro{\Cmax}\DescribeMacro{\Cmin}\DescribeMacro{\Cgcd}\DescribeMacro{\Clcm}
+% \begin{cmtab}
+% |\Cmax| & 1 & |\Cmax{1,3,6}| & $\Cmax{1,3,6}$\\\hline
+% |\Cmin| & 1 & |\Cmin{1,4,5}| & $\Cmin{1,4,7}$\\\hline
+% |\Cgcd| & 1 & |\Cgcd{7,3,5}| & $\Cgcd{7,3,5}$\\\hline
+% |\Clcm| & 1 & |\Clcm{3,5,4}| & $\Clcm{3,5,4}$\\\hline
+% \end{cmtab}
+%
+% The operators for the logical connectives are associative as well\ednote{maybe add some
+% precedences here.}. Here, conjunction, (exclusive) disjunction are $n$-ary associative
+% operators, therefore their semantic macro only has one {\TeX} argument which contains a
+% comma-separated list of subformulae.
+% \DescribeMacro{\Cand}\DescribeMacro{\Cor}\DescribeMacro{\Cxor}\DescribeMacro{\Cnot}
+% \DescribeMacro{\Cimplies}
+% \begin{cmtab}
+% |\Cand| & 1 & |\Cand{A,B,C}| & $\Cand{A,B,C}$\\\hline
+% |\Cor| & 1 & |\Cor{A,B,C}| & $\Cor{A,B,C}$\\\hline
+% |\Cxor| & 1 & |\Cxor{A,B,C}| & $\Cxor{A,B,C}$\\\hline
+% |\Cnot| & 1 & |\Cnot{A}| & $\Cnot{A}$\\\hline
+% |\Cimplies| & 2 & |\Cimplies{A}{B}| & $\Cimplies{A}{B}$\\\hline
+% \end{cmtab}
+%
+% The following are the corresponding big operators, where appropriate.
+% \DescribeMacro{\CAndDA}\DescribeMacro{\CAndCond}
+% \DescribeMacro{\COrDA}\DescribeMacro{\COrCond}
+% \DescribeMacro{\CXorDA}\DescribeMacro{\CXorCond}
+% \begin{cmtab}
+% |\CAndDA| & 2 & |\CAndDA\Cnaturalnumbers\phi| & $\CAndDA\Cnaturalnumbers\phi$\\\hline
+% |\CAndCond| & 3 & |\CAndCond{x}{\Cgt{x}5}{\psi(x)}|
+% & $\CAndCond{x}{\Cgt{x}5}{\psi(x)}$\\\hline
+% |\COrDA| & 2 & |\COrDA\Cnaturalnumbers\phi| & $\COrDa\Cnaturalnumbers\phi$\\\hline
+% |\COrCond| & 3 & |\COrCond{x}{\Cgt{x}5}{\psi(x)}|
+% & $\COrCond{x}{\Cgt{x}5}{\psi(x)}$\\\hline
+% |\CXorDA| & 2 & |\CXorDA\Cnaturalnumbers\phi| & $\CXorDA\Cnaturalnumbers\phi$\\\hline
+% |\CXorCond| & 3 & |\CXorCond{x}{\Cgt{x}5}{\psi(x)}|
+% & $\CXorCond{x}{\Cgt{x}5}{\psi(x)}$\\\hline
+% \end{cmtab}
+%
+% The semantic macros for the quantifiers come in two forms: with- and without a condition
+% qualifier. In a restricted quantification of the form $\forall x,C:A$, the bound variable
+% $x$ ranges over all values, such that $C$ holds ($x$ will usually occur in the condition
+% $C$). In an unrestricted quantification of the form $\forall x:A$, the bound variable
+% ranges over all possible values for $x$.
+% \DescribeMacro{\Cforall}\DescribeMacro{\CforallCond}
+% \DescribeMacro{\Cexists}\DescribeMacro{\CexistsCond}
+% \begin{cmtab}
+% |\Cforall| & 2 & |\Cforall{x,y}{A}| & $\Cforall{x,y}{A}$\\\hline
+% |\CforallCond| & 3 & |\CforallCond{x}{C}{A}| & $\CforallCond{x}{C}{A}$\\\hline
+% |\Cexists| & 2 & |\Cexists{x,y}{A}| & $\Cexists{x,y}{A}$\\\hline
+% |\CexistsCond| & 3 & |\CexistsCond{x}{C}{A}| & $\CexistsCond{x}{C}{A}$\\\hline
+% \end{cmtab}
+%
+% The rest of the operators are very simple in structure.
+% \DescribeMacro{\Cabs}\DescribeMacro{\Cconjugate}\DescribeMacro{\Carg}
+% \DescribeMacro{\Creal}\DescribeMacro{\Cimaginary}\DescribeMacro{\Cfloor}
+% \DescribeMacro{\Cceiling}
+% \begin{cmtab}
+% |\Cabs| & 1 & |\Cabs{x}| & $\Cabs{x}$\\\hline
+% |\Cconjugate| & 1 & |\Cconjugate{x}| & $\Cconjugate{x}$\\\hline
+% |\Carg| & 1 & |\Carg{x}| & $\Carg{x}$\\\hline
+% |\Creal| & 1 & |\Creal{x}| & $\Creal{x}$\\\hline
+% |\Cimaginary| & 1 & |\Cimaginary{x}| & $\Cimaginary{x}$\\\hline
+% |\Cfloor| & 1 & |\Cfloor{1.3}| & $\Cfloor{1.3}$\\\hline
+% |\Cceiling| & 1 & |\Cceiling{x}| & $\Cceiling{x}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Relations}\label{sec:rels}
+%
+% The relation symbols in {\mathml} are mostly $n$-ary associative operators (taking a
+% comma-separated list as an argument).
+%
+% \DescribeMacro{\Ceq}\DescribeMacro{\Cneq}\DescribeMacro{\Cgt}\DescribeMacro{\Clt}
+% \DescribeMacro{\Cgeq}\DescribeMacro{\Cleq}\DescribeMacro{\Cequivalent}
+% \DescribeMacro{\Capprox}\DescribeMacro{\Cfactorof}
+% \begin{cmtab}
+% |\Ceq| & 1 & |\CeqA,B,C| & $\Ceq{A,B,C}$\\\hline
+% |\Cneq| & 2 & |\Cneq{1}{2}| & $\Cneq{1}{2}$\\\hline
+% |\Cgt| & 1 & |\Cgt{A,B,C}| & $\Cgt{A,B,C}$\\\hline
+% |\Clt| & 1 & |\Clt{A,B,C}| & $\Clt{A,B,C}$\\\hline
+% |\Cgeq| & 1 & |\Cgeq{A,B,C}| & $\Cgeq{A,B,C}$\\\hline
+% |\Cleq| & 1 & |\Cleq{A,B,C}| & $\Cleq{A,B,C}$\\\hline
+% |\Cequivalent| & 1 & |\Cequivalent{A,B,C}| & $\Cequivalent{A,B,C}$\\\hline
+% |\Capprox| & 2 & |\Capprox{1}{2}| & $\Capprox{1}{1.1}$\\\hline
+% |\Cfactorof| & 2 & |\Cfactorof{7}{21}| & $\Cfactorof{7}{21}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Elements for Calculus and Vector Calculus}\label{sec:calculus-vector-calculus}
+%
+% The elements for calculus and vector calculus have the most varied forms.
+%
+% The integrals come in four forms: the first one is just an indefinite integral over a
+% function, the second one specifies the bound variables, upper and lower limits. The
+% third one specifies a set instead of an interval, and finally the last specifies a
+% bound variable that ranges over a set specified by a condition.
+%
+% \DescribeMacro{\Cint}\DescribeMacro{\CintLimits}\DescribeMacro{\CintDA}\DescribeMacro{\CintCond}
+% \begin{cmtab}
+% |\Cint| & 1 & |\Cint{f}| & $\Cint{f}$\\\hline
+% |\CintLimits| & 4 & |\CintLimits{x}{0}{\Cinfinit}{f(x)}|
+% & $\CintLimits{x}{0}{\infty}{f(x)}$\\\hline
+% |\CintDA| & 2 & |\CintDA{\Creals}{f}|
+% & $\CintDA{\mathbb{R}}{f}$\\\hline
+% |\CintCond| & 3 & |\CintCond{x}{\Cin{x}{D}}{f(x)}|
+% & $\CintCond{x}{x\in D}{f(x)}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Cdiff}\DescribeMacro{\Cddiff} The differentiation operators are used in
+% the usual way: simple differentiation is represented by the |\Cdiff| macro which takes
+% the function to be differentiated as an argument, differentiation with the $d$-notation
+% is possible by the |\Cddiff|, which takes the bound variable\ednote{really only one?} as
+% the first argument and the function expression (in the bound variable) as a second
+% argument.
+%
+% \DescribeMacro{\Cpartialdiff} Partial Differentiation is specified by the
+% |\Cpartialdiff| macro. It takes the overall degree as the first argument (to leave it
+% out, just pass the empty argument). The second argument is the list of bound variables
+% (with their degrees; see below), and the last the function expression (in these bound
+% variables). \DescribeMacro{\Cdegree} To specify the respective degrees of
+% differentiation on the variables, we use the |\Cdegree| macro, which takes two arguments
+% (but no optional argument), the first one is the degree (a natural number) and the
+% second one takes the variable. Note that the overall degree has to be the sum of the
+% degrees of the bound variables.
+%
+% \begin{pcmtab}[6cm]
+% |\Cdiff| & 1 & |\Cdiff{f}| & $\Cdiff{f}$\\\hline
+% |\Cddiff| & 2 & |\Cddiff{x}{f}| & $\Cddiff{x}{f}$\\\hline
+% |\Cpartialdiff| & 3 & |\Cpartialdiff{3}{x,y,z}{f(x,y)}|
+% & $\Cpartialdiff{3}{x,y,z}{f(x,y)}$\\\hline
+% |\Cpartialdiff| & 3 & |\Cpartialdiff{7}| |{\Cdegree{2}{x},\Cdegree{4}{y},z}| |{f(x,y)}|
+% & $\Cpartialdiff{7}{\Cdegree{2}{x},\Cdegree{4}{y},z}{f(x,y)}$\\\hline
+% \end{pcmtab}
+%
+% \DescribeMacro{\Climit}\DescribeMacro{\ClimitCond} For content {\mathml}, there are two
+% kinds of limit expressions: The simple one is specified by the |\Climit| macro, which
+% takes three arguments: the bound variable, the target, and the limit expression. If we
+% want to place additional conditions on the limit construction, then we use the
+% |\ClimitCond| macro, which takes three arguments as well, the first one is a sequence of
+% bound variables, the second one is the condition, and the third one is again the limit
+% expression.
+%
+% \DescribeMacro{\Ctendsto}\DescribeMacro{\CtendstoAbove}\DescribeMacro{\CtendstoBelow} If
+% we want to speak qualitatively about limit processes (e.g. in the condition of a
+% |\ClimitCond| expression), then can use the {\mathml} {\element{tendsto}} element, which
+% is represented by the |\Ctendsto| macro, wich takes two expressions arguments. In
+% {\mathml}, the {\element{tendsto}} element can be further specialized by an attribute to
+% indicate the direction from which a limit is approached. In the |cmathml| package, we
+% supply two additional (specialized) macros for that: |\CtendstoAbove| and
+% |\CtendstoBelow|.
+% \begin{cmtab}
+% |\Climit| & 3 & |\Climit{x}{0}{\Csin{x}}| & $\Climit{x}{0}{\Csin{x}}$\\\hline
+% |\ClimitCond| & 3 & |\ClimitCond{x}{\Ctendsto{x}{0}}{\Ccos{x}}|
+% & $\ClimitCond{x}{\Ctendsto{x}{0}}{\Ccos{x}}$\\\hline
+% |\Ctendsto| & 2 & |\Ctendsto{f(x)}{2}| & $\Ctendsto{f(x)}{2}$\\\hline
+% |\CtendstoAbove| & 2 & |\CtendstoAbove{x}{1}| & $\CtendstoAbove{x}{1}$\\\hline
+% |\CtendstoBelow| & 2 & |\CtendstoBelow{x}{2}| & $\CtendstoBelow{x}{2}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Cdivergence}\DescribeMacro{\Cgrad}\DescribeMacro{\Ccurl}
+% \DescribeMacro{\Claplacian}
+% \begin{cmtab}
+% |\Cdivergence| & 1 & |\Cdivergence{A}| & $\Cdivergence{A}$\\\hline
+% |\Cgrad| & 1 & |\Cgrad{\Phi}| & $\Cgrad{\Phi}$\\\hline
+% |\Ccurl| & 1 & |\Ccurl{\Xi}| & $\Ccurl{\Xi}$\\\hline
+% |\Claplacian| & 1 & |\Claplacian{A}| & $\Claplacian{A}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Sets and their Operations}\label{sec:sets}
+%
+% \DescribeMacro{\Cset}\DescribeMacro{\Clist}
+% \DescribeMacro{\CsetDA}\DescribeMacro{\CsetRes}\DescribeMacro{\CsetCond}
+% The |\Cset| macros is used as the simple finite set constructor, it takes one argument
+% that is a comma-separated sequence of members of the set. |\CsetRes| allows to specify a
+% set by restricting a set of variables, and |\CsetCond| is the general form of the set
+% construction.\ednote{need to do this for lists as well? Probably}
+% \begin{cmtab}
+% |\Cset| & 1 & |\Cset{1,2,3}| & $\Cset{1,2,3}$\\\hline
+% |\CsetRes| & 2 & |\CsetRes{x}{\Cgt{x}5}|
+% & $\CsetRes{x}{\Cgt{x}5}$\\\hline
+% |\CsetCond| & 3 & |\CsetCond{x}{\Cgt{x}5}{\Cpower{x}3}|
+% & $\CsetCond{x}{\Cgt{x}5}{\Cpower{x}3}$\\\hline
+% |\CsetDA| & 3 & |\CsetDA{x}{\Cgt{x}5}{S_x}}|
+% & $\CsetDA{x}{\Cgt{x}5}{S_x}$\\\hline
+% |\Clist| & 1 & |\Clist{3,2,1}| & $\Clist{3,2,1}$\\\hline
+%\end{cmtab}
+%
+%\DescribeMacro{\Cunion}\DescribeMacro{\Cintersect}\DescribeMacro{\Ccartesianproduct}
+% \DescribeMacro{\Csetdiff}\DescribeMacro{\Ccard}\DescribeMacro{\Cin}\DescribeMacro{\Cnotin}
+% \begin{cmtab}
+% |\Cunion| & 1 & |\Cunion{S,T,L}| & $\Cunion{S,T,L}$\\\hline
+% |\Cintersect| & 1 & |\Cintersect{S,T,L}| & $\Cintersect{S,T,L}$\\\hline
+% |\Ccartesianproduct| & 1 & |\Ccartesianproduct{A,B,C}| & $\Ccartesianproduct{A,B,C}$\\\hline
+% |\Csetdiff| & 2 & |\Csetdiff{S}{L}| & $\Csetdiff{S}{L}$\\\hline
+% |\Ccard| & 1 & |\Ccard{\Cnaturalnumbers}| & $\Ccard{\mathbb{N}}$\\\hline
+% |\Cin| & 2 & |\Cin{a}{S}| & $\Cin{a}{S}$\\\hline
+% |\Cnotin| & 2 & |\Cnotin{b}{S}| & $\Cnotin{b}{S}$\\\hline
+%\end{cmtab}
+%
+% The following are the corresponding big operators for the first three binary ACI
+% functions. \DescribeMacro{\CUnionDA}\DescribeMacro{\CUnionCond}
+% \DescribeMacro{\CIntersectDA}\DescribeMacro{\CIntersectCond}
+% \DescribeMacro{\CCartesianproductDA}\DescribeMacro{\CCartesianproductCond}
+% \begin{cmtab}
+% |\CUnionDA| & 2 & |\CUnionDA\Cnaturalnumbers{S_i}|
+% & $\CUnionDA\Cnaturalnumbers{S_i}$\\\hline
+% |\CUnionCond| & 3 & |\CUnionCond{x}{\Cgt{x}5}{S_x}}|
+% & $\CUnionCond{x}{\Cgt{x}5}{S_x}$\\\hline
+% |\CIntersectDA| & 2 & |\CIntersectDA\Cnaturalnumbers{S_i}|
+% & $\CIntersectDa\Cnaturalnumbers{S_i}$\\\hline
+% |\CIntersectCond| & 3 & |\CIntersectCond{x}{\Cgt{x}5}{S_x}|
+% & $\CIntersectCond{x}{\Cgt{x}5}{S_x}$\\\hline
+% |\CCartesianproductDA| & 2 & |\CCartesianproductDA\Cnaturalnumbers{S_i}|
+% & $\CCartesianproductDA\Cnaturalnumbers{S_i}$\\\hline
+% |\CCartesianproductCond| & 3 & |\CCartesianproductCond{x}{\Cgt{x}5}{S_x}|
+% & $\CCartesianproductCond{x}{\Cgt{x}5}{S_x}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Csubset}\DescribeMacro{\Cprsubset}
+% \DescribeMacro{\Cnotsubset}\DescribeMacro{\Cnotprsubset} For the set containment
+% relations, we are in a somewhat peculiar situation: content {\mathml} only supplies the
+% subset side of the reations and leaves out the superset relations. Of course they are
+% not strictly needed, since they can be expressed in terms of the subset relation with
+% reversed argument order. But for the |cmathml| package, the macros have a presentational
+% side (for the {\LaTeX} workflow) and a content side (for the {\latexml} converter)
+% therefore we will need macros for both relations.
+%
+% \begin{cmtab}
+% |\Csubset| & 1 & |\Csubset{S,T,K}| & $\Csubset{S,T,K}$\\\hline
+% |\Cprsubset| & 1 & |\Cprsubset{S,T,K}| & $\Cprsubset{S,T,K}$\\\hline
+% |\Cnotsubset| & 2 & |\Cnotsubset{S}{K}| & $\Cnotsubset{S}{K}$\\\hline
+% |\Cnotprsubset| & 2 & |\Cnotprsubset{S}{L}| & $\Cnotprsubset{S}{L}$\\\hline
+% \end{cmtab}
+% \DescribeMacro{\Csupset}\DescribeMacro{\Cprsupset}
+% \DescribeMacro{\Cnotsupset}\DescribeMacro{\Cnotprsupset}
+% The following set of macros are presented in {\LaTeX} as their name suggests, but upon
+% transformation will generate content markup with the {\mathml} elements (i.e. in terms
+% of the subset relation).
+%
+% \begin{cmtab}
+% |\Csupset| & 1 & |\Csupset{S,T,K}| & $\Csupset{S,T,K}$\\\hline
+% |\Cprsupset| & 1 & |\Cprsupset{S,T,K}| & $\Cprsupset{S,T,K}$\\\hline
+% |\Cnotsupset| & 2 & |\Cnotsupset{S}{K}| & $\Cnotsupset{S}{K}$\\\hline
+% |\Cnotprsupset| & 2 & |\Cnotprsupset{S}{L}| & $\Cnotprsupset{S}{L}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Sequences and Series}\label{sec:sequences}
+%
+% \DescribeMacro{\CsumLimits}\DescribeMacro{\CsumCond}\DescribeMacro{\CsumDA}
+% \DescribeMacro{\CprodLimist}\DescribeMacro{\CprodCond}\DescribeMacro{\CprodDA}
+% \begin{cmtab}
+% |\CsumLimits| & 4 & |\CsumLimits{i}{0}{50}{x^i}| & $\CsumLimits{i}{0}{50}{x^i}$\\\hline
+% |\CsumCond| & 3 & |\CsumCond{i}{\Cintegers}{i}| & $\CsumCond{i}{\mathbb{Z}}{i}$\\\hline
+% |\CsumDA| & 2 & |\CsumDA{\Cintegers}{f}| & $\CsumDA{\mathbb{Z}}{f}$\\\hline
+% |\CprodLimits| & 4 & |\CprodLimits{i}{0}{20}{x^i}| & $\CprodLimits{i}{0}{20}{x^i}$\\\hline
+% |\CprodCond| & 3 & |\CprodCond{i}{\Cintegers}{i}| & $\CprodCond{i}{\mathbb{Z}}{i}$\\\hline
+% |\CprodDA| & 2 & |\CprodDA{\Cintegers}{f}| & $\CprodDA{\mathbb{Z}}{f}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Elementary Classical Functions}\label{sec:specfun}
+%
+% \DescribeMacro{\Csin}\DescribeMacro{\Ccos}\DescribeMacro{\Ctan}
+% \DescribeMacro{\Csec}\DescribeMacro{\Ccsc}\DescribeMacro{\Ccot}
+% \begin{cmtab}
+% |\Csin| & 1 & |\Csin{x}| & $\Csin{x}$\\\hline
+% |\Ccos| & 1 & |\Ccos{x}| & $\Ccos{x}$\\\hline
+% |\Ctan| & 1 & |\Ctan{x}| & $\Ctan{x}$\\\hline
+% |\Csec| & 1 & |\Csec{x}| & $\Csec{x}$\\\hline
+% |\Ccsc| & 1 & |\Ccsc{x}| & $\Ccsc{x}$\\\hline
+% |\Ccot| & 1 & |\Ccot{x}| & $\Ccot{x}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Csinh}\DescribeMacro{\Ccosh}\DescribeMacro{\Ctanh}
+% \DescribeMacro{\Csech}\DescribeMacro{\Ccsch}\DescribeMacro{\Ccoth}
+% \begin{cmtab}
+% |\Csinh| & 1 & |\Csinh{x}| & $\Csinh{x}$\\\hline
+% |\Ccosh| & 1 & |\Ccosh{x}| & $\Ccosh{x}$\\\hline
+% |\Ctanh| & 1 & |\Ctanh{x}| & $\Ctanh{x}$\\\hline
+% |\Csech| & 1 & |\Csech{x}| & $\Csech{x}$\\\hline
+% |\Ccsch| & 1 & |\Ccsch{x}| & $\Ccsch{x}$\\\hline
+% |\Ccoth| & 1 & |\Ccoth{x}| & $\Ccoth{x}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Carcsin}\DescribeMacro{\Carccos}\DescribeMacro{\Carctan}
+% \DescribeMacro{\Carcsec}\DescribeMacro{\Carccsc}\DescribeMacro{\Carccot}
+% \begin{cmtab}
+% |\Carcsin| & 1 & |\Carcsin{x}| & $\Carcsin{x}$\\\hline
+% |\Carccos| & 1 & |\Carccos{x}| & $\Carccos{x}$\\\hline
+% |\Carctan| & 1 & |\Carctan{x}| & $\Carctan{x}$\\\hline
+% |\Carccosh| & 1 & |\Carccosh{x}| & $\Carccosh{x}$\\\hline
+% |\Carccot| & 1 & |\Carccot{x}| & $\Carccot{x}$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Carcsinh}\DescribeMacro{\Carccosh}\DescribeMacro{\Carctanh}
+% \DescribeMacro{\Carcsech}\DescribeMacro{\Carccsch}\DescribeMacro{\Carccoth}
+% \begin{cmtab}
+% |\Carccoth| & 1 & |\Carccoth{x}| & $\Carccoth{x}$\\\hline
+% |\Carccsc| & 1 & |\Carccsc{x}| & $\Carccsc{x}$\\\hline
+% |\Carcsinh| & 1 & |\Carcsinh{x}| & $\Carcsinh{x}$\\\hline
+% |\Carctanh| & 1 & |\Carctanh{x}| & $\Carctanh{x}$\\\hline
+% |\Cexp| & 1 & |\Cexp{x}| & $\Cexp{x}$\\\hline
+% |\Cln| & 1 & |\Cln{x}| & $\Cln{x}$\\\hline
+% |\Clog| & 2 & |\Clog{5}{x}| & $\Clog{5}{x}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Statistics}\label{sec:statistics}
+%
+% The only semantic macro that is non-standard in this module is the one for the
+% {\element{moment}} and {\element{momentabout}} elements in {\mathml}. They are combined
+% into the semantic macro {|CmomentA|}; its first argument is the degree, its
+% second one the point in the distribution, the moment is taken about, and the third is
+% the distribution.
+%
+% \DescribeMacro{\Cmean}\DescribeMacro{\Csdev}\DescribeMacro{\Cvar}\DescribeMacro{\Cmedian}
+% \DescribeMacro{\Cmode}\DescribeMacro{\Cmoment}\DescribeMacro{\CmomentA}
+% \begin{cmtab}
+% |\Cmean| & 1 & |\Cmean{X}| & $\Cmean{X}$\\\hline
+% |\Csdev| & 1 & |\Csdev{X}| & $\Csdev{X}$\\\hline
+% |\Cvar| & 1 & |\Cvar{X}| & $\Cvar{X}$\\\hline
+% |\Cmedian| & 1 & |\Cmedian{X}| & $\Cmedian{X}$\\\hline
+% |\Cmode| & 1 & |\Cmode{X}| & $\Cmode{X}$\\\hline
+% |\Cmoment| & 3 & |\Cmoment{3}{X}| & $\Cmoment{3}{X}$\\\hline
+% |\CmomentA| & 3 & |\CmomentA{3}{p}{X}| & $\CmomentA{3}{p}{X}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Linear Algebra}\label{sec:linalg}
+%
+% In these semantic macros, only the matrix constructor is unusual; instead of
+% constructing a matrix from {\element{matrixrow}} elements like {\mathml} does, the macro
+% follows the {\TeX/\LaTeX} tradition allows to give a matrix as an array. The first
+% argument of the macro is the column specification (it will only be used for presentation
+% purposes), and the second one the rows.
+%
+% \DescribeMacro{\Cvector}\DescribeMacro{\Cmatrix}\DescribeMacro{\Cdeterminant}
+% \DescribeMacro{\Ctranspose}\DescribeMacro{\Cselector}
+% \DescribeMacro{\Cvectorproduct}\DescribeMacro{\Cscalarproduct}\DescribeMacro{\Couterproduct}
+% \begin{cmtab}
+% |\Cvector| & 1 & |\Cvector{1,2,3}| & $\Cvector{1,2,3}$\\\hline
+% |\Cmatrix| & 2 & |\Cmatrix{ll}{1 & 2\\ 3 & 4}| & $\Cmatrix{ll}{1 & 2\\3 & 4}$\\\hline
+% |\Cdeterminant| & 1 & |\Cdeterminant{A}| & $\Cdeterminant{A}$\\\hline
+% |\Ctranspose| & 1 & |\Ctranspose{A}| & $\Ctranspose{A}$\\\hline
+% |\Cselector| & 2 & |\Cselector{A}{2}| & $\Cselector{A}{2}$\\\hline
+% |\Cvectproduct| & 2 & |\Cvectproduct{\phi}{\psi}| & $\Cvectproduct{\phi}{\psi}$\\\hline
+% |\Cscalarproduct| & 2 & |\Cscalarproduct{\phi}{\psi}| & $\Cscalarproduct{\phi}{\psi}$\\\hline
+% |\Couterproduct| & 2 & |\Couterproduct{\phi}{\psi}| & $\Couterproduct{\phi}{\psi}$\\\hline
+% \end{cmtab}
+%
+% \subsection{Constant and Symbol Elements}\label{sec:constants}
+%
+% The semantic macros for the {\mathml} constant and symbol elements are very simple, they
+% do not take any arguments, and their name is just the {\mathml} element name prefixed by
+% a capital C.
+%
+% \DescribeMacro{\Cintegers}\DescribeMacro{\Creals}\DescribeMacro{\Crationals}
+% \DescribeMacro{\Ccomplexes}\DescribeMacro{\Cprimes}
+% \begin{cmtab}
+% |\Cintegers| & & |\Cintegers| & $\Cintegers$\\\hline
+% |\Creals| & & |\Creals| & $\Creals$\\\hline
+% |\Crationals| & & |\Crationals| & $\Crationals$\\\hline
+% |\Cnaturalnumbers| & & |\Cnaturalnumbers| & $\Cnaturalnumbers$\\\hline
+% |\Ccomplexes| & & |\Ccomplexes| & $\Ccomplexes$\\\hline
+% |\Cprimes| & & |\Cprimes| & $\Cprimes$\\\hline
+% \end{cmtab}
+%
+% \DescribeMacro{\Cexponentiale}\DescribeMacro{\Cimaginaryi}
+% \DescribeMacro{\Ctrue}\DescribeMacro{\Cfalse} \DescribeMacro{\Cemptyset}
+% \DescribeMacro{\Cpi}\DescribeMacro{\Ceulergamma}\DescribeMacro{\Cinfinit}
+% \begin{cmtab}
+% |\Cexponemtiale| & & |\Cexponemtiale| & $\Cexponemtiale$\\\hline
+% |\Cimaginaryi| & & |\Cimaginaryi| & $\Cimaginaryi$\\\hline
+% |\Cnotanumber| & & |\Cnotanumber| & $\Cnotanumber$\\\hline
+% |\Ctrue| & & |\Ctrue| & $\Ctrue$\\\hline
+% |\Cfalse| & & |\Cfalse| & $\Cfalse$\\\hline
+% |\Cemptyset| & & |\Cemptyset| & $\Cemptyset$\\\hline
+% |\Cpi| & & |\Cpi| & $\Cpi$\\\hline
+% |\Ceulergamma| & & |\Ceulergamma| & $\Ceulergamma$\\\hline
+% |\Cinfinit| & & |\Cinfinit| & $\Cinfinit$\\\hline
+% \end{cmtab}
+%
+% \subsection{Extensions}\label{sec:cmathmlx}
+% Content MathML does not (even though it claims to cover M-14 Math) symbols for all the
+% common mathematical notions. The |cmathmlx| attempts to collect these and provide
+% {\TeX/\LaTeX} and {\latexml} bindings.
+%
+%\DescribeMacro{\Ccomplement}
+% \begin{cmtab}
+% |\Ccomplement| & 1 & |\Ccomplement{\Cnaturalnumbers}| & $\Ccomplement{\mathbb{N}}$\\\hline
+%\end{cmtab}
+%
+% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\newpage
+%
+% \section{The Implementation}\label{sec:impl}
+%
+% In this file we document both the implementation of the |cmathml| package, as well as
+% the corresponding {\latexml} bindings. This keeps similar items close to each other,
+% even though they eventually go into differing files and helps promote consistency. We
+% specify which code fragment goes into which file by the {\xml}-like grouping commands:
+% The code between {\textsf{$\langle$*sty$\rangle$}} and {\textsf{$\langle$/sty$\rangle$}}
+% goes into the package file |cmathml.sty|, and the code between
+% {\textsf{$\langle$*ltxml$\rangle$}} and {\textsf{$\langle$/ltxml$\rangle$}} goes into
+% |cmathml.ltxml|
+%
+% \subsection{Initialization and auxiliary functions}\label{sec:impl:init}
+%
+% We first make sure that the {\sTeX} |presentation| package is loaded.
+% \begin{macrocode}
+%<*sty|styx>
+\RequirePackage{presentation}
+%</sty|styx>
+% \end{macrocode}
+%
+% Before we start im plementing the {\mathml} macros, we will need to set up the packages
+% for perl in the {\latexml} bindings file.
+% \begin{macrocode}
+%<*ltxml|ltxmlx>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+use LaTeXML::Document;
+RequirePackage('LaTeX');
+%</ltxml|ltxmlx>
+% \end{macrocode}
+%
+% The next step is to itroduce two auxiliary functions, they are needed to work with
+% $n$-ary function elements. The first one removes arbitrary tokens from a list, and the
+% specializes that to commas. In particular |remove_tokens_from_list($List, $pattern, $math)|
+% returns a new |List| (or |MathList| if |$math| is true)
+% with all the tokens in |$List| except the ones which follow
+% the pattern |$pattern|.
+%
+% \begin{macrocode}
+%<*ltxml>
+sub remove_tokens_from_list {
+ my ($list, $pattern, $math) = @_;
+ if (ref $list) {
+ my @toks = $list->unlist;
+ @toks = grep($_->toString !~ /$pattern/, @toks);
+ ($math ? (LaTeXML::MathList->new(@toks)) : (LaTeXML::List)->new(@toks)); }
+ else { undef; } }
+
+sub remove_math_commas {
+ my ($whatsit, $argno) = @_;
+ my @args = $whatsit ? $whatsit->getArgs() : undef;
+ $argno--;
+ if ($args[$argno]) {
+ $args[$argno] = remove_tokens_from_list($args[$argno], ',', 1);
+ $whatsit->setArgs(@args);
+ }
+ return;
+}
+%</ltxml>
+% \end{macrocode}
+%
+% The structural macros are rather simple:
+%
+% \begin{macrocode}
+%<*sty>
+\newcommand{\Capply}[3][]{#2(#3)}
+%</sty>
+%<*ltxml>
+DefConstructor('\Capply [] {} {}',
+ "<ltx:XMApp ?#1(definitionURL='#1')()>#2 #3</ltx:XMApp>");
+%</ltxml>
+% after this, the implementation will always have the same form. We will first
+% implement a block of {\LaTeX} macros via a |\newcommand| and then specify the
+% corresponding {\latexml} bindings for them.
+%
+% \subsection{The Token Elements}\label{impl:tokens}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@cn#1{#1}
+\newcommand{\Ccn}[2][]{\CMathML@cn{#2}}
+\def\CMathML@ci#1{#1}
+\newcommand{\Cci}[2][]{\CMathML@ci{#2}}
+\def\CMathML@csymbol#1{#1}
+\newcommand{\Ccsymbol}[2][]{\CMathML@csymbol{#2}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Ccn [] {}',"#2");
+DefConstructor('\Cci [] {}',"#2");
+DefConstructor('\Ccsymbol [] {}',
+ "<ltx:XMTok role='CSYMBOL' meaning='#2' ?#1(definitionURL='#1')()/>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{The Basic Elements}\label{impl:basic}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@ccinterval#1#2{[#1,#2]}
+\newcommand{\Cccinterval}[3][]{\CMathML@ccinterval{#2}{#3}}
+\def\CMathML@cointerval#1#2{[#1,#2)}
+\newcommand{\Ccointerval}[3][]{\CMathML@cointerval{#2}{#3}}
+\def\CMathML@ocinterval#1#2{(#1,#2]}
+\newcommand{\Cocinterval}[3][]{\CMathML@ocinterval{#2}{#3}}
+\def\CMathML@oointerval#1#2{(#1,#2)}
+\newcommand{\Coointerval}[3][]{\CMathML@oointerval{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cccinterval [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='ccinterval' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg></ltx:XMApp>");
+DefConstructor('\Ccointerval [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='cointerval' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg></ltx:XMApp>");
+DefConstructor('\Cocinterval [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='ocinterval' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg></ltx:XMApp>");
+DefConstructor('\Coointerval [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='oointerval' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg></ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\newcommand{\Cinverse}[2][]{#2^{-1}}
+% what about separator
+%</sty>
+%<*ltxml>
+DefConstructor('\Cinverse [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='inverse' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@lambda#1#2{\lambda({#1},{#2})}
+\newcommand{\Clambda}[3][]{\CMathML@lambda{#2}{#3}}
+\def\CMathML@lambdaDA#1#2#3{\lambda({#1}\colon{#2},#3)}
+\newcommand{\ClambdaDA}[4][]{\CMathML@lambdaDA{#2}{#3}{#4}}
+\def\CMathML@restrict#1#2{\left.#1\right|_{#2}}
+\newcommand{\Crestrict}[3][]{\CMathML@restrict{#2}{#3}}
+%</sty>
+%\ednote{need do deal with multiple variables!}
+%<*ltxml>
+DefConstructor('\Clambda [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='lambda' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\ClambdaDA [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='lambda' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Crestrict [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='restrict' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@composeOp{\circ}
+ \newcommand{\CcomposeOp}{\CMathML@composeOp}
+\def\CMathML@compose#1{\assoc[p=500,pi=500]{\CMathML@composeOp}{#1}}
+\newcommand{\Ccompose}[2][]{\CMathML@compose{#2}}
+\def\CMathML@ident#1{\mathrm{id}}
+\newcommand{\Cident}[1][]{\CMathML@ident{#1}}
+\def\CMathML@domain#1{\mbox{dom}(#1)}
+\newcommand{\Cdomain}[2][]{\CMathML@domain{#2}}
+\def\CMathML@codomain#1{\mbox{codom}(#1)}
+\newcommand{\Ccodomain}[2][]{\CMathML@codomain{#2}}
+\def\CMathML@image#1{{\mathbf{Im}}(#1)}
+\newcommand{\Cimage}[2][]{\CMathML@image{#2}}
+\def\CMathML@piecewise#1{\left\{\begin{array}{ll}#1\end{array}\right.}
+\newcommand{\Cpiecewise}[2][]{\CMathML@piecewise{#2}}
+\def\CMathML@piece#1#2{#1&{\mathrm{if}}\;{#2}\\}
+\newcommand{\Cpiece}[3][]{\CMathML@piece{#2}{#3}}
+\def\CMathML@otherwise#1{#1&else\\}
+\newcommand{\Cotherwise}[2][]{\CMathML@otherwise{#2}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CcomposeOp []',
+ "<ltx:XMTok meaning='compose' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ccompose [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='MULOP' meaning='compose' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\Cident []',
+ "<ltx:XMTok meaning='ident' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cdomain [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='domain' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccodomain [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='codomain' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cimage [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='image' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cpiecewise [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='piecewise' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cpiece [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='piece' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cotherwise [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='otherwise' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Elements for Arithmetic, Algebra, and Logic}\label{impl:arith}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@quotient#1#2{\frac{#1}{#2}}
+\newcommand{\Cquotient}[3][]{\CMathML@quotient{#2}{#3}}
+ \def\CMathML@factorialOp{!}
+ \newcommand{\CfactorialOp}{\CMathML@factorialOp}
+\def\CMathML@factorial#1{#1{\CMathML@factorialOp}}
+\newcommand{\Cfactorial}[2][]{\CMathML@factorial{#2}}
+ \def\CMathML@divideOp{\div}
+ \newcommand{\CdivideOp}{\CMathML@divideOp}
+\def\CMathML@divide#1#2{\infix[p=400]{\CMathML@divideOp}{#1}{#2}}
+\newcommand{\Cdivide}[3][]{\CMathML@divide{#2}{#3}}
+ \def\CMathML@maxOp{\mathrm{max}}
+ \newcommand{\CmaxOp}{\CMathML@maxOp}
+\def\CMathML@max#1{{\CMathML@maxOp}(#1)}
+\newcommand{\Cmax}[2][]{\CMathML@max{#2}}
+ \def\CMathML@minOp{\mathrm{min}}
+ \newcommand{\CminOp}{\CMathML@minOp}
+\def\CMathML@min#1{{\CMathML@minOp}(#1)}
+\newcommand{\Cmin}[2][]{\CMathML@min{#2}}
+ \def\CMathML@minusOp{-}
+ \newcommand{\CminusOp}{\CMathML@minusOp}
+\def\CMathML@minus#1#2{\infix[p=500]{\CMathML@minusOp}{#1}{#2}}
+\newcommand{\Cminus}[3][]{\CMathML@minus{#2}{#3}}
+\def\CMathML@uminus#1{\prefix[p=200]{\CMathML@minusOp}{#1}}
+\newcommand{\Cuminus}[2][]{\CMathML@uminus{#2}}
+ \def\CMathML@plusOp{+}
+ \newcommand{\CplusOp}{\CMathML@plusOp}
+\def\CMathML@plus#1{\assoc[p=500]{\CMathML@plusOp}{#1}}
+\newcommand{\Cplus}[2][]{\CMathML@plus{#2}}
+\def\CMathML@power#1#2{\infix[p=200]{^}{#1}{#2}}
+\newcommand{\Cpower}[3][]{\CMathML@power{#2}{#3}}
+ \def\CMathML@remOp{\bmod}
+ \newcommand{\CremOp}{\CMathML@remOp}
+\def\CMathML@rem#1#2{#1 \CMathML@remOp #2}
+\newcommand{\Crem}[3][]{\CMathML@rem{#2}{#3}}
+ \def\CMathML@timesOp{\cdot}
+ \newcommand{\CtimesOp}{\CMathML@timesOp}
+\def\CMathML@times#1{\assoc[p=400]{\CMathML@timesOp}{#1}}
+\newcommand{\Ctimes}[2][]{\CMathML@times{#2}}
+ \def\CMathML@rootOp{\sqrt}
+ \newcommand{\CrootOp}{\CMathML@rootOp{}}
+\def\CMathML@root#1#2{\CMathML@rootOp[#1]{#2}}
+\newcommand{\Croot}[3][]{\CMathML@root{#2}{#3}}
+\def\CMathML@gcd#1{\gcd(#1)}
+\newcommand{\Cgcd}[2][]{\CMathML@gcd{#2}}
+ \def\CMathML@andOp{\wedge}
+ \newcommand{\CandOp}{\CMathML@andOp}
+\def\CMathML@and#1{\assoc[p=400]{\CMathML@andOp}{#1}}
+\newcommand{\Cand}[2][]{\CMathML@and{#2}}
+ \def\CMathML@orOp{\vee}
+ \newcommand{\CorOp}{\CMathML@orOp}
+\def\CMathML@or#1{\assoc[p=500]{\CMathML@orOp}{#1}}
+\newcommand{\Cor}[2][]{\CMathML@or{#2}}
+ \def\CMathML@xorOp{\oplus}
+ \newcommand{\CxorOp}{\CMathML@xorOp}
+\def\CMathML@xor#1{\assoc[p=400]{\CMathML@xorOp}{#1}}
+\newcommand{\Cxor}[2][]{\CMathML@xor{#2}}
+ \def\CMathML@notOp{\neg}
+ \newcommand{\CnotOp}{\CMathML@notOp}
+\def\CMathML@not#1{\CMathML@notOp{#1}}
+\newcommand{\Cnot}[2][]{\CMathML@not{#2}}
+ \def\CMathML@impliesOp{\Longrightarrow}
+ \newcommand{\CimpliesOp}{\CMathML@impliesOp}
+\def\CMathML@implies#1#2{#1\CMathML@impliesOp{#2}}
+\newcommand{\Cimplies}[3][]{\CMathML@implies{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cquotient [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='quotient' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CfactorialOp []',
+ "<ltx:XMTok meaning='factorial' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cfactorial [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='factorial' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CdivideOp []',
+ "<ltx:XMTok meaning='divide' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cdivide [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='divide' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CmaxOp []',
+ "<ltx:XMTok meaning='max' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cmax [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='max' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CminOp []',
+ "<ltx:XMTok meaning='min' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cmin [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='min' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CminusOp []',
+ "<ltx:XMTok meaning='minus' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cminus [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='ADDOP' meaning='minus' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cuminus [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='uminus' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CplusOp []',
+ "<ltx:XMTok meaning='plus' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cplus [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='ADDOP' meaning='plus' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\Cpower [] {} {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='power' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CremOp []',
+ "<ltx:XMTok meaning='rem' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Crem [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='rem' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CtimesOp []',
+ "<ltx:XMTok meaning='times' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ctimes [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='MULOP' meaning='times' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CrootOp []',
+ "<ltx:XMTok meaning='root' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Croot [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='root' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cgcd [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='gcd' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CandOp []',
+ "<ltx:XMTok meaning='and' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cand [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONNECTIVE' meaning='and' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CorOp []',
+ "<ltx:XMTok meaning='or' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cor [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONNECTIVE' meaning='or' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CxorOp []',
+ "<ltx:XMTok meaning='xor' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cxor [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONNECTIVE' meaning='xor' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CnotOp []',
+ "<ltx:XMTok meaning='not' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnot [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONNECTIVE' meaning='not' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CimpliesOp []',
+ "<ltx:XMTok meaning='implies' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cimplies [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONNECTIVE' meaning='implies' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+% \ednote{need to do something about the associative things in ltxml}
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@AndDA#1#2{\bigwedge_{#1}{#2}} % set, scope
+\newcommand{\CAndDA}[3][]{\CMathML@AndDA{#2}{#3}}
+\def\CMathML@AndCond#1#2#3{\bigwedge_{#2}{#3}} % bvars,condition, scope
+\newcommand{\CAndCond}[4][]{\CMathML@AndCond{#2}{#2}{#3}}
+\def\CMathML@OrDA#1#2{\bigvee_{#1}{#2}} % set, scope
+\newcommand{\COrDa}[3][]{\CMathML@OrDA{#2}{#3}}
+\def\CMathML@OrCond#1#2#3{\bigvee_{#2}{#3}}% bvars,condition, scope
+\newcommand{\COrCond}[4][]{\CMathML@OrCond{#2}{#3}{#4}}
+\def\CMathML@XorDA#1#2{\bigoplus_{#1}{#2}} % set, scope
+\newcommand{\CXorDA}[3][]{\CMathML@XorDA{#2}{#3}}
+\def\CMathML@XorCond#1#2#3{\bigoplus_{#2}{#3}}% bvars,condition, scope
+\newcommand{\CXorCond}[4][]{\CMathML@XorCond{#2}{#3}{#4}}
+%
+\def\CMathML@forall#1#2{\forall{#1}\colon{#2}}
+\newcommand{\Cforall}[3][]{\CMathML@forall{#2}{#3}}
+\def\CMathML@forallCond#1#2#3{\forall{#1},{#2}\colon{#3}} % list), condition, scope
+\newcommand{\CforallCond}[4][]{\CMathML@forallCond{#2}{#3}{#4}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CAndDa [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='and' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CAndCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='and' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\COrDa [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='or' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\COrCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='or' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CXorDa [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='xor' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CXorCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='xor' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cforall [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='forall' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CforallCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='forall' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@exists#1#2{\exists{#1}\colon{#2}}
+\newcommand{\Cexists}[3][]{\CMathML@exists{#2}{#3}}
+\def\CMathML@esistsCont#1#2#3{\exists{#1},{#2}\colon{#3}}
+\newcommand{\CexistsCond}[4][]{\CMathML@esistsCont{#2}{#3}{#4}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cexists [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='exists' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CexistsCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BINDER' meaning='exists' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@abs#1{\left|#1\right|}
+\newcommand{\Cabs}[2][]{\CMathML@abs{#2}}
+\def\CMathML@conjugate#1{\overline{#1}}
+\newcommand{\Cconjugate}[2][]{\CMathML@conjugate{#2}}
+\def\CMathML@arg#1{\angle #1}
+\newcommand{\Carg}[2][]{\CMathML@arg{#2}}
+\def\CMathML@real#1{\Re #1}
+\newcommand{\Creal}[2][]{\CMathML@real{#2}}
+\def\CMathML@imaginary#1{\Im #1}
+\newcommand{\Cimaginary}[2][]{\CMathML@imaginary{#2}}
+\def\CMathML@lcm#1{\mbox{lcm}(#1)}
+\newcommand{\Clcm}[2][]{\CMathML@lcm{#2}}
+\def\CMathML@floor#1{\left\lfloor{#1}\right\rfloor}
+\newcommand{\Cfloor}[2][]{\CMathML@floor{#2}}
+\def\CMathML@ceiling#1{\left\lceil{#1}\right\rceil}
+\newcommand{\Cceiling}[2][]{\CMathML@ceiling{#2}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cabs [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='abs' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cconjugate [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='conjugate' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carg [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='arg' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Creal [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='real' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cimaginary [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='imaginary' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Clcm [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='lcm' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cfloor [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='floor' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cceiling [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='ceiling' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Relations}\label{impl:rels}
+%
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@eqOp{=}
+ \newcommand{\CeqOp}{\CMathML@eqOp}
+\def\CMathML@eq#1{\assoc[p=700]{\CMathML@eqOp}{#1}}
+\newcommand{\Ceq}[2][]{\CMathML@eq{#2}}
+ \def\CMathML@neqOp{\neq}
+ \newcommand{\CneqOp}{\CMathML@neqOp}
+\def\CMathML@neq#1#2{\infix[p=700]{\CMathML@neqOp}{#1}{#2}}
+\newcommand{\Cneq}[3][]{\CMathML@neq{#2}{#3}}
+ \def\CMathML@gtOp{>}
+ \newcommand{\CgtOp}{\CMathML@gtOp}
+\def\CMathML@gt#1{\assoc[p=700]{\CMathML@gtOp}{#1}}
+\newcommand{\Cgt}[2][]{\CMathML@gt{#2}}
+ \def\CMathML@ltOp{<}
+ \newcommand{\CltOp}{\CMathML@ltOp}
+\def\CMathML@lt#1{\assoc[p=700]{\CMathML@ltOp}{#1}}
+\newcommand{\Clt}[2][]{\CMathML@lt{#2}}
+ \def\CMathML@geqOp{\geq}
+ \newcommand{\CgeqOp}{\CMathML@geqOp}
+\def\CMathML@geq#1{\assoc[p=700]{\CMathML@geqOp}{#1}}
+\newcommand{\Cgeq}[2][]{\CMathML@geq{#2}}
+ \def\CMathML@leqOp{\leq}
+ \newcommand{\CleqOp}{\CMathML@leqOp}
+\def\CMathML@leq#1{\assoc[p=700]{\CMathML@leqOp}{#1}}
+\newcommand{\Cleq}[2][]{\CMathML@leq{#2}}
+ \def\CMathML@equivalentOp{\equiv}
+ \newcommand{\CequivalentOp}{\CMathML@equivalentOp}
+\def\CMathML@equivalent#1{\assoc[p=700]{\CMathML@equivalentOp}{#1}}
+\newcommand{\Cequivalent}[2][]{\CMathML@equivalent{#2}}
+ \def\CMathML@approxOp{\approx}
+ \newcommand{\CapproxOp}{\CMathML@approxOp}
+\def\CMathML@approx#1#2{#1\CMathML@approxOp{#2}}
+\newcommand{\Capprox}[3][]{\CMathML@approx{#2}{#3}}
+ \def\CMathML@factorofOp{\mid}
+ \newcommand{\CfactorofOp}{\CMathML@factorofOp}
+\def\CMathML@factorof#1#2{#1\CMathML@factorofOp{#2}}
+\newcommand{\Cfactorof}[3][]{\CMathML@factorof{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CeqOp []',
+ "<ltx:XMTok meaning='eq' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ceq [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='eq' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CneqOp []',
+ "<ltx:XMTok meaning='neq' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cneq [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='neq' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CgtOp []',
+ "<ltx:XMTok meaning='gt' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cgt [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='gt' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CltOp []',
+ "<ltx:XMTok meaning='lt' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Clt [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='lt' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CgeqOp []',
+ "<ltx:XMTok meaning='geq' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cgeq [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='geq' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CleqOp []',
+ "<ltx:XMTok meaning='leq' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cleq [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='leq' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CequivalentOp []',
+ "<ltx:XMTok meaning='equivalent' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cequivalent [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='equivalent' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>");
+DefConstructor('\CapproxOp []',
+ "<ltx:XMTok meaning='approx' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Capprox [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='approx' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CfactorofOp []',
+ "<ltx:XMTok meaning='factorof' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cfactorof [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='factorof' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+
+ \def\CMathML@intOp{\int}
+ \newcommand{\CintOp}{\CMathML@intOp}
+\def\CMathML@int#1{\CMathML@intOp{#1}}
+\newcommand{\Cint}[2][]{\CMathML@int{#2}}
+\def\CMathML@intLimits#1#2#3#4{\CMathML@intOp_{#2}^{#3}{#4}d{#1}} %bvars,llimit, ulimit,body
+\newcommand{\CintLimits}[5][]{\CMathML@intLimits{#2}{#3}{#4}{#5}}
+\def\CMathML@intSet#1#2{\CMathML@intOp_{#1}{#2}}% set,function
+\newcommand{\CintDA}[3][]{\CMathML@intSet{#2}{#3}}
+\def\CMathML@intCond#1#2#3{\CMathML@intOp_{#2}{#3}d{#1}} %bvars, condition, body
+\newcommand{\CintCond}[4][]{\CMathML@intCond{#2}{#3}{#4}}
+
+%</sty>
+%<*ltxml>
+DefConstructor('\CintOp []',
+ "<ltx:XMTok meaning='int' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cint [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='int' role='INTOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CintLimits [] {}{}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='int' role='INTOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "<ltx:XMArg>#5</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CintDA [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='int' role='INTOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CintCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='int' role='INTOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@diff#1{#1'}
+\newcommand{\Cdiff}[2][]{\CMathML@diff{#2}}
+\def\CMathML@ddiff#1#2{{d{#2}(#1)\over{d{#1}}}}
+\newcommand{\Cddiff}[3][]{\CMathML@ddiff{#2}{#3}}
+\def\CMathML@partialdiff#1#2#3{{\partial^{#1}\over\partial{#2}}{#3}}% degree, bvars, body
+\newcommand{\Cpartialdiff}[4][]{\CMathML@partialdiff{#2}{#3}{#4}}
+\newcommand{\Cdegree}[2]{#1^{#2}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cdiff [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='diff' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cddiff [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='diff' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cpartialdiff [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='diff' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "?#2(<ltx:XMArg>#2</ltx:XMArg>)()"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cdegree {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='degree'/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#1</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@limit#1#2#3{\lim_{#1\rightarrow{#2}}{#3}}
+\newcommand{\Climit}[4][]{\CMathML@limit{#2}{#3}{#4}} % bvar, lowlimit, scope
+\def\CMathML@limitCond#1#2#3{\lim_{#2}{#3}}
+\newcommand{\ClimitCond}[4][]{\CMathML@limitCond{#2}{#3}{#4}} % bvars, condition, scope
+%</sty>
+%<*ltxml>
+DefConstructor('\Climit [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='limit' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\ClimitCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='limit' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@tendstoOp{\rightarrow}
+ \newcommand{\CtendstoOp}{\CMathML@tendstoOp}
+\def\CMathML@tendsto#1#2{#1\CMathML@tendstoOp{#2}}
+\newcommand{\Ctendsto}[3][]{\CMathML@tendsto{#2}{#3}}
+ \def\CMathML@tendstoAboveOp{\searrow}
+ \newcommand{\CtendstoAboveOp}{\CMathML@tendstoAboveOp}
+\def\CMathML@tendstoAbove#1#2{#1\searrow{#2}}
+\newcommand{\CtendstoAbove}[3][]{\CMathML@tendstoAbove{#2}{#3}}
+ \def\CMathML@tendstoBelowOp{\nearrow}
+ \newcommand{\CtendstoBelowOp}{\CMathML@tendstoBelowOp}
+\def\CMathML@tendstoBelow#1#2{#1\CMathML@tendstoBelowOp{#2}}
+\newcommand{\CtendstoBelow}[3][]{\CMathML@tendstoBelow{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CtendstoOp []',
+ "<ltx:XMTok meaning='tendsto' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ctendsto [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='RELOP' meaning='tendsto' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CtendstoAboveOp []',
+ "<ltx:XMTok meaning='tendsto' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CtendstoAbove [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='RELOP'meaning='tendsto' type='above' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CtendstoBelowOp []',
+ "<ltx:XMTok meaning='tendsto' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CtendstoBelow [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='RELOP' meaning='tendsto' type='below' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@divergence#1{\nabla\cdot{#1}}
+\newcommand{\Cdivergence}[2][]{\CMathML@divergence{#2}}
+\def\CMathML@grad#1{\nabla{#1}}
+\newcommand{\Cgrad}[2][]{\CMathML@grad{#2}}
+\def\CMathML@curl#1{\nabla\times{#1}}
+\newcommand{\Ccurl}[2][]{\CMathML@curl{#2}}
+\def\CMathML@laplacian#1{\nabla^2#1}
+\newcommand{\Claplacian}[2][]{\CMathML@laplacian{#2}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cdivergence [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='divergence' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cgrad [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='grad' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Curl [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='url' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Claplacian [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='OPFUNCTION' meaning='laplacian' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Sets and their Operations}\label{impl:sets}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@set#1{\left\{#1\right\}}
+\newcommand{\Cset}[2][]{\CMathML@set{#2}}
+\def\CMathML@setRes#1#2{\{#1|#2\}}
+\newcommand{\CsetRes}[3][]{\CMathML@setRes{#2}{#3}}
+\def\CMathML@setCond#1#2#3{\{#2|#3\}}
+\newcommand{\CsetCond}[4][]{\CMathML@setCond{#2}{#3}{#4}}
+\def\CMathML@setDA#1#2#3{\{#1\in{#2}|#3\}}
+\newcommand{\CsetDA}[4][]{\CMathML@setDA{#2}{#3}{#4}}
+ \def\CMathML@listOp{\mbox{list}}
+ \newcommand{\ClistOp}{\CMathML@listOp}
+\def\CMathML@list#1{\CMathML@listOp({#1})}
+\newcommand{\Clist}[2][]{\CMathML@list{#2}}
+ \def\CMathML@unionOp{\cup}
+ \newcommand{\CunionOp}{\CMathML@unionOp}
+\def\CMathML@union#1{\assoc[p=500]{\CMathML@unionOp}{#1}}
+\newcommand{\Cunion}[2][]{\CMathML@union{#2}}
+ \def\CMathML@intersectOp{\cap}
+ \newcommand{\CintersectOp}{\CMathML@intersectOp}
+\def\CMathML@intersect#1{\assoc[p=400]{\CMathML@intersectOp}{#1}}
+\newcommand{\Cintersect}[2][]{\CMathML@intersect{#2}}
+ \def\CMathML@inOp{\in}
+ \newcommand{\CinOp}{\CMathML@inOp}
+\def\CMathML@in#1#2{#1\CMathML@inOp{#2}}
+\newcommand{\Cin}[3][]{\CMathML@in{#2}{#3}}
+ \def\CMathML@notinOp{\notin}
+ \newcommand{\CnotinOp}{\CMathML@notinOp}
+\def\CMathML@notin#1#2{#1\CMathML@notinOp{#2}}
+\newcommand{\Cnotin}[3][]{\CMathML@notin{#2}{#3}}
+ \def\CMathML@setdiffOp{\setminus}
+ \newcommand{\CsetdiffOp}{\CMathML@setdiffOp}
+\def\CMathML@setdiff#1#2{#1\CMathML@setdiffOp{#2}}
+\newcommand{\Csetdiff}[3][]{\CMathML@setdiff{#2}{#3}}
+ \def\CMathML@cardOp{\#}
+ \newcommand{\CcardOp}{\CMathML@cardOp}
+\def\CMathML@card#1{\CMathML@cardOp #1}
+\newcommand{\Ccard}[2][]{\CMathML@card{#2}}
+ \def\CMathML@cartesianproductOp{\times}
+ \newcommand{\CcartesianproductOp}{\CMathML@cartesianproductOp}
+\def\CMathML@cartesianproduct#1{\assoc[p=400]{\CMathML@cartesianproductOp}{#1}}
+\newcommand{\Ccartesianproduct}[2][]{\CMathML@cartesianproduct{#2}}
+ \def\CMathML@subsetOp{\subseteq}
+ \newcommand{\CsubsetOp}{\CMathML@subsetOp}
+\def\CMathML@subset#1{\assoc[p=700]{\CMathML@subsetOp}{#1}}
+\newcommand{\Csubset}[2][]{\CMathML@subset{#2}}
+ \def\CMathML@prsubsetOp{\subset}
+ \newcommand{\CprsubsetOp}{\CMathML@prsubsetOp}
+\def\CMathML@prsubset#1{\assoc[p=700]{\CMathML@prsubsetOp}{#1}}
+\newcommand{\Cprsubset}[2][]{\CMathML@prsubset{#2}}
+ \def\CMathML@notsubsetOp{\not\subseteq}
+ \newcommand{\CnotsubsetOp}{\CMathML@notsubsetOp}
+\def\CMathML@notsubset#1#2{#1\CMathML@notsubsetOp{#2}}
+\newcommand{\Cnotsubset}[3][]{\CMathML@notsubset{#2}{#3}}
+ \def\CMathML@notprsubsetOp{\not\subset}
+ \newcommand{\CnotprsubsetOp}{\CMathML@notprsubsetOp}
+\def\CMathML@notprsubset#1#2{#1\CMathML@notprsubsetOp{#2}}
+\newcommand{\Cnotprsubset}[3][]{\CMathML@notprsubset{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cset [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='set' role='CONSTRUCTOR' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CsetRes [] {}{}',
+ "<ltx:XMApp role='BIGOP'>"
+ . "<ltx:XMTok role='BIGOP' meaning='set' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg role='BVAR'>#2</ltx:XMArg>"
+ . "<ltx:XMArg role='CONDITION'>#3</ltx:XMArg>"
+ . "<ltx:XMArg role='SCOPE'>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CsetCond [] {}{}{}',
+ "<ltx:XMApp role='BIGOP'>"
+ . "<ltx:XMTok role='BIGOP' meaning='set' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg role='BVAR'>#2</ltx:XMArg>"
+ . "<ltx:XMArg role='CONDITION'>#3</ltx:XMArg>"
+ . "<ltx:XMArg role='SCOPE'>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CsetDA [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='set' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg role='BVAR'>#2</ltx:XMArg>"
+ . "<ltx:XMArg role='DOMAINOFAPPLICATION'>#3</ltx:XMArg>"
+ . "<ltx:XMArg role='SCOPE'>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\ClistOp []',
+ "<ltx:XMTok meaning='list' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Clist [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='list' role='CONSTRUCTOR' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CunionOp []',
+ "<ltx:XMTok meaning='union' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cunion [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='union' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CintersectOp []',
+ "<ltx:XMTok meaning='intersect' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cintersect [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='intersect' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CinOp []',
+ "<ltx:XMTok meaning='in' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cin [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='in' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CnotinOp []',
+ "<ltx:XMTok meaning='notin' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnotin [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='notin' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CsubsetOp []',
+ "<ltx:XMTok meaning='subset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Csubset [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='subset' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CprsubsetOp []',
+ "<ltx:XMTok meaning='prsubset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cprsubset [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='prsubset' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\CnotsubsetOp []',
+ "<ltx:XMTok meaning='notsubset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnotsubset [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='notsubset' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CnotprsubsetOp []',
+ "<ltx:XMTok meaning='notprsubset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnotprsubset [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='notprsubset' role='RELOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CsetdiffOp []',
+ "<ltx:XMTok meaning='setdiff' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Csetdiff [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='setdiff' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CcardOp []',
+ "<ltx:XMTok meaning='card' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ccard [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='card' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CcartesianproductOp []',
+ "<ltx:XMTok meaning='cartesianproduct' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ccartesianproduct [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='cartesianproduct' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+%</ltxml>
+% \end{macrocode}
+% The next set of macros are needed, since they are presentational.
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@supsetOp{\supseteq}
+ \newcommand{\CsupsetOp}{\CMathML@supsetOp}
+\def\CMathML@supset#1{\assoc[p=700]{\CMathML@supsetOp}{#1}}
+\newcommand{\Csupset}[2][]{\CMathML@supset{#2}}
+ \def\CMathML@prsupsetOp{\supset}
+ \newcommand{\CprsupsetOp}{\CMathML@prsupsetOp}
+\def\CMathML@prsupset#1{\assoc[p=700]{\CMathML@prsupsetOp}{#1}}
+\newcommand{\Cprsupset}[2][]{\CMathML@prsupset{#2}}
+ \def\CMathML@notsupsetOp{\not\supseteq}
+ \newcommand{\CnotsupsetOp}{\CMathML@notsupsetOp}
+\def\CMathML@notsupset#1#2{#1\CMathML@notsupsetOp{#2}}
+\newcommand{\Cnotsupset}[3][]{\CMathML@notsupset{#2}{#3}}
+ \def\CMathML@notprsupsetOp{\not\supset}
+ \newcommand{\CnotprsupsetOp}{\CMathML@notprsupsetOp}
+\def\CMathML@notprsupset#1#2{#1\CMathML@notprsupsetOp{#2}}
+\newcommand{\Cnotprsupset}[3][]{\CMathML@notprsupset{#2}{#3}}
+%</sty>
+% \end{macrocode}
+%
+% On the semantic side (in {\latexml}), we need to implement them in terms of the
+% {\mathml} elements. Fortunately, we can just turn them around. \ednote{ooooops, this
+% does not work for the associative ones.}
+%
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\CsupsetOp []',
+ "<ltx:XMTok meaning='supset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CprsupsetOp []',
+ "<ltx:XMTok meaning='prsupset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CnotsupsetOp []',
+ "<ltx:XMTok meaning='notsupset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CnotprsupsetOp []',
+ "<ltx:XMTok meaning='notprsupset' role='ID' ?#1(definitionURL='#1')()/>");
+DefMacro('\Csupset[]{}','\Csubset[#1]{#2}');
+DefMacro('\Cprsupset[]{}','\Cprsubset[#1]{#2}');
+DefMacro('\Cnotsupset[]{}{}','\Cnotsubset[#1]{#3}{#2}');
+DefMacro('\Cnotprsupset[]{}{}','\Cnotprsubset[#1]{#3}{#2}');
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@UnionDAOp{\bigwedge}
+ \newcommand{\CUnionDAOp}{\CMathML@UnionDAOp}
+\def\CMathML@UnionDA#1#2{\CMathML@UnionDAOp_{#1}{#2}} % set, scope
+\newcommand{\CUnionDA}[3][]{\CMathML@UnionDA{#2}{#3}}
+\def\CMathML@UnionCond#1#2#3{\CMathML@UnionDAOp_{#2}{#3}} % bvars,condition, scope
+\newcommand{\CUnionCond}[4][]{\CMathML@UnionCond{#2}{#2}{#3}}
+ \def\CMathML@IntersectDAOp{\bigvee}
+ \newcommand{\CIntersectDAOp}{\CMathML@IntersectDAOp}
+\def\CMathML@IntersectDA#1#2{\CMathML@IntersectDAOp_{#1}{#2}} % set, scope
+\newcommand{\CIntersectDa}[3][]{\CMathML@IntersectDA{#2}{#3}}
+\def\CMathML@IntersectCond#1#2#3{\CMathML@IntersectDAOp_{#2}{#3}}% bvars,condition, scope
+\newcommand{\CIntersectCond}[4][]{\CMathML@IntersectCond{#2}{#3}{#4}}
+ \def\CMathML@CartesianproductDAOp{\bigoplus}
+ \newcommand{\CCartesianproductDAOp}{\CMathML@CartesianproductDAOp}
+\def\CMathML@CartesianproductDA#1#2{\CMathML@CartesianproductDAOp_{#1}{#2}} % set, scope
+\newcommand{\CCartesianproductDA}[3][]{\CMathML@CartesianproductDA{#2}{#3}}
+\def\CMathML@CartesianproductCond#1#2#3{\CMathML@CartesianproductDAOp_{#2}{#3}}% bvars,condition, scope
+\newcommand{\CCartesianproductCond}[4][]{\CMathML@CartesianproductCond{#2}{#3}{#4}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CUnionDAOp []',
+ "<ltx:XMTok meaning='union' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CUnionDA [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='union' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CUnionCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='union' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CIntersectDaOp []',
+ "<ltx:XMTok meaning='intersect' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CIntersectDa [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='intersect' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CIntersectCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='intersect' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CCartesianproductDaOp []',
+ "<ltx:XMTok meaning='cartesianproduct' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CCartesianproductDa [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='cartesianproduct' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CCartesianproductCond [] {}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='BIGOP' meaning='cartesianproduct' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Sequences and Series}\label{impl:sequences}
+%
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@sumOp{\sum}
+ \newcommand{\CsumOp}{\CMathML@sumOp}
+\def\CMathML@sumLimits#1#2#3#4{\CMathML@sumOp_{#1=#2}^{#3}#4}% bvar, llimit, ulimit, body
+\newcommand{\CsumLimits}[5][]{\CMathML@sumLimits{#2}{#3}{#4}{#5}}
+\def\CMathML@sumCond#1#2#3{\CMathML@sumOp_{#1\in{#2}}#3} % bvar, condition, body
+\newcommand{\CsumCond}[4][]{\CMathML@sumCond{#2}{#3}{#4}}
+\def\CMathML@sumDA#1#2{\CMathML@sumOp_{#1}#2} % set, body
+\newcommand{\CsumDA}[3][]{\CMathML@sumDA{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CsumOp []',
+ "<ltx:XMTok meaning='sum' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CsumLimits [] {}{}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sum' role='SUMOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "#5</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+% \ednote{complete the other cases}\ednote{add a keyword argument to all newcommands}
+% \begin{macrocode}
+%<*sty>
+ \def\CMathML@prodOp{\prod}
+ \newcommand{\CprodOp}{\CMathML@prodOp}
+\def\CMathML@prodLimits#1#2#3#4{\CMathML@prodOp_{#1=#32^{#3}#4}}% bvar, llimit, ulimit, body
+\newcommand{\CprodLimits}[5][]{\CMathML@prodLimits{#2}{#3}{#4}{#5}}
+\def\CMathML@prodCond#1#2#3{\CMathML@prodOp_{#1\in{#2}}#3} % bvar, condition, body
+\newcommand{\CprodCond}[4][]{\CMathML@prodCond{#2}{#3}{#4}}
+\def\CMathML@prodDA#1#2{\CMathML@prodOp_{#1}#2} % set, body
+\newcommand{\CprodDA}[3]{\CMathML@prodDA{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\CprodOp []',
+ "<ltx:XMTok meaning='prod' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\CprodLimits [] {}{}{}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='prod' role='SUMOP' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg><ci>#2</ci></ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "<ltx:XMArg>#4</ltx:XMArg>"
+ . "#5</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+% \ednote{complete the other cases}
+% \subsection{Elementary Classical Functions}\label{impl:specfun}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@sin#1{\sin(#1)}
+\newcommand{\Csin}[2][]{\CMathML@sin{#2}}
+\def\CMathML@cos#1{\cos(#1)}
+\newcommand{\Ccos}[2][]{\CMathML@cos{#2}}
+\def\CMathML@tan#1{\tan(#1)}
+\newcommand{\Ctan}[2][]{\CMathML@tan{#2}}
+\def\CMathML@sec#1{\sec(#1)}
+\newcommand{\Csec}[2][]{\CMathML@sec{#2}}
+\def\CMathML@csc#1{\csc(#1)}
+\newcommand{\Ccsc}[2][]{\CMathML@csc{#2}}
+\def\CMathML@cot#1{\cot(#1)}
+\newcommand{\Ccot}[2][]{\CMathML@cot{#2}}
+\def\CMathML@sinh#1{\sinh(#1)}
+\newcommand{\Csinh}[2][]{\CMathML@sinh{#2}}
+\def\CMathML@cosh#1{\cosh(#1)}
+\newcommand{\Ccosh}[2][]{\CMathML@cosh{#2}}
+\def\CMathML@tanh#1{\tanh(#1)}
+\newcommand{\Ctanh}[2][]{\CMathML@tanh{#2}}
+\def\CMathML@sech#1{\mbox{sech}(#1)}
+\newcommand{\Csech}[2][]{\CMathML@sech{#2}}
+\def\CMathML@csch#1{\mbox{csch}(#1)}
+\newcommand{\Ccsch}[2][]{\CMathML@csch{#2}}
+\def\CMathML@coth#1{\mbox{coth}(#1)}
+\newcommand{\Ccoth}[2][]{\CMathML@coth{#2}}
+\def\CMathML@arcsin#1{\arcsin(#1)}
+\newcommand{\Carcsin}[2][]{\CMathML@arcsin{#2}}
+\def\CMathML@arccos#1{\arccos(#1)}
+\newcommand{\Carccos}[2][]{\CMathML@arccos{#2}}
+\def\CMathML@arctan#1{\arctan(#1)}
+\newcommand{\Carctan}[2][]{\CMathML@arctan{#2}}
+\def\CMathML@arccosh#1{\mbox{arccosh}(#1)}
+\newcommand{\Carccosh}[2][]{\CMathML@arccosh{#2}}
+\def\CMathML@arccot#1{\mbox{arccot}(#1)}
+\newcommand{\Carccot}[2][]{\CMathML@arccot{#2}}
+\def\CMathML@arccoth#1{\mbox{arccoth}(#1)}
+\newcommand{\Carccoth}[2][]{\CMathML@arccoth{#2}}
+\def\CMathML@arccsc#1{\mbox{arccsc}(#1)}
+\newcommand{\Carccsc}[2][]{\CMathML@arccsc{#2}}
+\def\CMathML@arcsinh#1{\mbox{arcsinh}(#1)}
+\newcommand{\Carcsinh}[2][]{\CMathML@arcsinh{#2}}
+\def\CMathML@arctanh#1{\mbox{arctanh}(#1)}
+\newcommand{\Carctanh}[2][]{\CMathML@arctanh{#2}}
+
+\def\CMathML@exp#1{\exp(#1)}
+\newcommand{\Cexp}[2][]{\CMathML@exp{#2}}
+\def\CMathML@ln#1{\ln(#1)}
+\newcommand{\Cln}[2][]{\CMathML@ln{#2}}
+\def\CMathML@log#1#2{\log_{#1}(#2)}
+\newcommand{\Clog}[3][]{\CMathML@log{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Csin [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sin' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccos [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='cos' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ctan [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='tan' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Csec [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sec' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccsc [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='csc' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccot [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='cot' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Csinh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sinh' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccosh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='cosh' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ctanh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='tanh' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Csech [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sech' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccsch [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='csch' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ccoth [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='coth' role='TRIGFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carcsin [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arcsin' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccos [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccos' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carctan [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arctan' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carcsec [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arcsec' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccsc [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccsc' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccot [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccot' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carcsinh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arcsinh' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccosh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccosh' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carctanh [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arctanh' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carcsech [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arcsech' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccsch [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccsch' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Carccoth [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='arccoth' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cexp [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='exp' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cln [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='ln' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Clog [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='log' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Statistics}\label{impl:statistics}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@mean#1{\mbox{mean}(#1)}
+\newcommand{\Cmean}[2][]{\CMathML@mean{#2}}
+\def\CMathML@sdev#1{\mbox{std}(#1)}
+\newcommand{\Csdev}[2][]{\CMathML@sdev{#2}}
+\def\CMathML@var#1{\mbox{var}(#1)}
+\newcommand{\Cvar}[2][]{\CMathML@var{#2}}
+\def\CMathML@median#1{\mbox{median}(#1)}
+\newcommand{\Cmedian}[2][]{\CMathML@median{#2}}
+\def\CMathML@mode#1{\mbox{mode}(#1)}
+\newcommand{\Cmode}[2][]{\CMathML@mode{#2}}
+\def\CMathML@moment#1#2{\langle{#2}^{#1}\rangle}% degree, momentabout, scope
+\newcommand{\Cmoment}[3][]{\CMathML@moment{#2}{#3}}
+\def\CMathML@momentA#1#2{\langle{#2}^{#1}\rangle}% degree, momentabout, scope
+\newcommand{\CmomentA}[4][]{\CMathML@momentA{#2}{#3}{#4}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cmean [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='mean' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Csdev [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='sdev' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cvar [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='var' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cmedian [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='median' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cmode [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='mode' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cmoment [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='moment' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+% \ednote{we do not seem to need the momentabout.}\ednote{moment and momentA have funny
+% elided arguments}
+%
+% \subsection{Linear Algebra}\label{impl:linalg}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@vector#1{(#1)}
+\newcommand{\Cvector}[2][]{\CMathML@vector{#2}}
+\def\CMathML@matrix#1#2{\left(\begin{array}{#1}#2\end{array}\right)}% row pattern, body
+\newcommand{\Cmatrix}[3][]{\CMathML@matrix{#2}{#3}}
+\def\CMathML@determinant#1{\left|#1\right|}
+\newcommand{\Cdeterminant}[2][]{\CMathML@determinant{#2}}
+\def\CMathML@transpose#1{#1^\top}
+\newcommand{\Ctranspose}[2][]{\CMathML@transpose{#2}}
+\def\CMathML@selector#1#2{#1_{#2}}
+\newcommand{\Cselector}[3][]{\CMathML@selector{#2}{#3}}
+ \def\CMathML@vectproductOp{\cdot}
+ \newcommand{\CvectproductOp}{\CMathML@vectproductOp}
+\def\CMathML@vectproduct#1#2{#1\CMathML@vectproductOp{#2}}
+\newcommand{\Cvectproduct}[3][]{\CMathML@vectproduct{#2}{#3}}
+\def\CMathML@scalarproduct#1#2{{#1}#2}
+\newcommand{\Cscalarproduct}[3][]{\CMathML@scalarproduct{#2}{#3}}
+ \def\CMathML@outerproductOp{\times}
+ \newcommand{\CouterproductOp}{\CMathML@outerproductOp}
+\def\CMathML@outerproduct#1#2{#1\CMathML@outerproductOp{#2}}
+\newcommand{\Couterproduct}[3][]{\CMathML@outerproduct{#2}{#3}}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cvector [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='vector' ?#1(definitionURL='#1')()/>"
+ . "#2"
+ . "</ltx:XMApp>",
+ afterDigest=>sub { remove_math_commas($_[1], 2); });
+DefConstructor('\Cmatrix [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok role='CONSTRUCTOR' meaning='matrix' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cdeterminant [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='determinant' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Ctranspose [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='transpose' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cselector [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='selector' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CvectorproductOp []',
+ "<ltx:XMTok meaning='vectorproduct' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cvectorproduct [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='vectorproduct' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\Cscalarproduct [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='scalarproduct' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+DefConstructor('\CouterproductOp []',
+ "<ltx:XMTok meaning='outerproduct' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Couterproduct [] {}{}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='outerproduct' role='OPFUNCTION' ?#1(definitionURL='#1')()/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "<ltx:XMArg>#3</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Constant and Symbol Elements}\label{impl:constants}
+%
+% \begin{macrocode}
+%<*sty>
+\def\CMathML@integers{{\mathbb{Z}}}
+\newcommand{\Cintegers}[1][]{\CMathML@integers}
+\def\CMathML@reals{{\mathbb{R}}}
+\newcommand{\Creals}[1][]{\CMathML@reals}
+\def\CMathML@rationals{{\mathbb{Q}}}
+\newcommand{\Crationals}[1][]{\CMathML@rationals}
+\def\CMathML@naturalnumbers{{\mathbb{N}}}
+\newcommand{\Cnaturalnumbers}[1][]{\CMathML@naturalnumbers}
+\def\CMathML@complexes{{\mathbb{C}}}
+\newcommand{\Ccomplexes}[1][]{\CMathML@complexes}
+\def\CMathML@primes{{\mathbb{P}}}
+\newcommand{\Cprimes}[1][]{\CMathML@primes}
+\def\CMathML@exponemtiale{e}
+\newcommand{\Cexponemtiale}[1][]{\CMathML@exponemtiale}
+\def\CMathML@imaginaryi{i}
+\newcommand{\Cimaginaryi}[1][]{\CMathML@imaginaryi}
+\def\CMathML@notanumber{{\mathrm{NaN}}}
+\newcommand{\Cnotanumber}[1][]{\CMathML@notanumber}
+\def\CMathML@true{{\mathrm{true}}}
+\newcommand{\Ctrue}[1][]{\CMathML@true}
+\def\CMathML@false{{\mathrm{false}}}
+\newcommand{\Cfalse}[1][]{\CMathML@false}
+\def\CMathML@emptyset{\emptyset}
+\newcommand{\Cemptyset}[1][]{\CMathML@emptyset}
+\def\CMathML@pi{\pi}
+\newcommand{\Cpi}[1][]{\CMathML@pi}
+\def\CMathML@eulergamma{\gamma}
+\newcommand{\Ceulergamma}[1][]{\CMathML@eulergamma}
+\def\CMathML@infinit{\infty}
+\newcommand{\Cinfinit}[1][]{\CMathML@infinit}
+%</sty>
+%<*ltxml>
+DefConstructor('\Cintegers []',
+ "<ltx:XMTok meaning='integers' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Creals []',
+ "<ltx:XMTok meaning='reals' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Crationals []',
+ "<ltx:XMTok meaning='rationals' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnaturalnumbers []',
+ "<ltx:XMTok meaning='naturalnumbers' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ccomplexes []',
+ "<ltx:XMTok meaning='complexes' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cprimes []',
+ "<ltx:XMTok meaning='primes' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cexponentiale []',
+ "<ltx:XMTok meaning='exponentiale' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cimaginaryi []',
+ "<ltx:XMTok meaning='imaginaryi' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cnotanumber []',
+ "<ltx:XMTok meaning='notanumber' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ctrue []',
+ "<ltx:XMTok meaning='true' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cfalse []',
+ "<ltx:XMTok meaning='false' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cemptyset []',
+ "<ltx:XMTok meaning='emptyset' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cpi []',
+ "<ltx:XMTok meaning='pi' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Ceulergamma []',
+ "<ltx:XMTok meaning='eulergamma' role='ID' ?#1(definitionURL='#1')()/>");
+DefConstructor('\Cinfinit []',
+ "<ltx:XMTok meaning='infinit' role='ID' ?#1(definitionURL='#1')()/>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Extensions}\label{sec:impl:cmathmlx}
+% \begin{macro}{\Ccomplement}
+% \begin{macrocode}
+%<*styx>
+\def\CMathML@complement#1{#1^c}
+\newcommand{\Ccomplement}[2][]{\CMathML@complement{#2}}
+%</styx>
+%<*ltxmlx>
+DefConstructor('\Ccomplement [] {}',
+ "<ltx:XMApp>"
+ . "<ltx:XMTok meaning='complement' role='CSYMBOL'/>"
+ . "<ltx:XMArg>#2</ltx:XMArg>"
+ . "</ltx:XMApp>");
+%</ltxmlx>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Finale}\label{sec:impl:finale}
+%
+% Finally, we need to terminate the file with a success mark for perl.
+% \begin{macrocode}
+%<ltxml>1;
+% \end{macrocode}
+% \Finale
+\endinput
+
+% \iffalse
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+
+% LocalWords: STeX cmathml symdefs CMathML dom codom Im ll reln fn bvar arith
+% LocalWords: alg lcm rels Ceq llimit ulimit bvars lowlimit specfun sech csch
+% LocalWords: coth arccosh arccot arccoth arccsc arcsinh arctanh logbase std
+% LocalWords: var momentabout linalg matrixrow bruce NaN stex cnxml symdef sc
+% LocalWords: DefinitionURLs domainofapplication CmomentA concl iffalse scsys
+% LocalWords: cmathml.dtx sc newenvironment pcmtab hline cmtab hbox ttfamily
+% LocalWords: xslt xslt mathml scshape latexml twintoo atwin atwintoo texttt
+% LocalWords: fileversion maketitle newpage tableofcontents newpage exfig exp
+% LocalWords: usepackage vspace cmathml-eip varpi ednote nd cmatml Capply Cexp
+% LocalWords: cdot ary Cond bigcup subseteq Cnaturalnumbers Cunion csymbol Ccn
+% LocalWords: Ccsymbol camthml Cinverse Ccompose Cident Cdomain Ccodomain Clt
+% LocalWords: Cimage Clambda ClambdaDA Crestrict ccinterval cointerval Cpiece
+% LocalWords: ocinterval oointerval Cccinterval Cccinterval Cccinterval Cminus
+% LocalWords: Ccointerval Ccointerval Ccointerval Cocinterval Cocinterval Cmax
+% LocalWords: Cocinterval Coointerval Coointerval Coointerval Cpiecewise Cplus
+% LocalWords: Cotherwise footnotesize Cuminus Cquotient Cfactorial Cdivide Cgt
+% LocalWords: Cpower Ctimes Croot Cmin Cgcd Cand Cxor Cnot Cimplies forall cn
+% LocalWords: Cforall CforallCond Cexists CexistsCond Cconjugate Carg Creal eq
+% LocalWords: Cimaginary Cfloor Cceiling Cneq Cgeq Cleq Cequivalent Capprox gt
+% LocalWords: Cfactorof Cint CintLimits CintDA CintCond Cinfinit infty Creals
+% LocalWords: mathbb Cdiff Cddiff varible Cpartialdiff Cdegree Climit Ctendsto
+% LocalWords: ClimitCond CtendstoAbove CtendstoBelow tendsto Csin Csin Ccos ln
+% LocalWords: Cdivergence Cgrad Ccurl Claplacian Cset Clist Cintersect Ccard
+% LocalWords: Ccartesianproduct Csetdiff Cnotin CCartesianproductDA Csubset ln
+% LocalWords: CCartesianproductCond Cprsubset Cnotsubset Cnotprsubset reations
+% LocalWords: Csupset Cprsupset Cnotsupset Cnotprsupset CsumLimits CsumCond
+% LocalWords: CsumDA CprodLimist CprodCond CprodDA Cintegers CprodLimits Ctan
+% LocalWords: CprodLimits CprodLimits Csec Ccsc Ccot Csinh Ccosh Ctanh Csech
+% LocalWords: Ccsch Ccoth Carcsin Carccos Carctan Carcsec Carccsc Carccot Cln
+% LocalWords: Carccosh Carccosh Carccosh Carcsinh Carctanh Carcsech Carccsch
+% LocalWords: Carccoth Cln Cln Cmean Csdev Cvar Cmedian Cmode Cmoment Cvector
+% LocalWords: Cmatrix Cdeterminant Ctranspose Cselector Cvectorproduct Cprimes
+% LocalWords: Cscalarproduct Couterproduct Cvectproduct Cvectproduct Ctrue Cpi
+% LocalWords: Cvectproduct Crationals Ccomplexes Cexponentiale Cimaginaryi ltx
+% LocalWords: Cfalse Cemptyset Ceulergamma Cexponemtiale Cexponemtiale impl
+% LocalWords: Cexponemtiale Cnotanumber Cnotanumber Cnotanumber cmathmlx ltxml
+% LocalWords: Ccomplement printbibliography textsf langle textsf langle ltxml
+% LocalWords: plementing ltxmlx itroduce unlist whatsit argno newcommand circ
+% LocalWords: OPFUNCTION assoc ident mathrm mbox mathbf uminus bmod sqrt oplus
+% LocalWords: Longrightarrow bigwedge bigvee bigoplus esistsCont overline eqOp
+% LocalWords: lfloor rfloor lceil rceil neqOp neq gtOp geqOp geq leqOp leq csc
+% LocalWords: equiv approxOp approx factorofOp factorof ddiff partialdiff csc
+% LocalWords: rightarrow searrow nearrow RELOP'meaning setdiffOp setdiff sinh
+% LocalWords: cartesianproductOp cartesianproduct prsubsetOp prsubset supseteq
+% LocalWords: notsubsetOp notsubset notprsubsetOp notprsubset prsupsetOp sinh
+% LocalWords: prsupset notsupsetOp notsupset notprsupsetOp notprsupset ooooops
+% LocalWords: CsumOp newcommands CprodOp tanh tanh arccos arccos TRIGFUNCTION
+% LocalWords: arcsec arcsech arccsch sdev vectproductOp vectproduct imaginaryi
+% LocalWords: scalarproduct outerproductOp outerproduct vectorproduct emptyset
+% LocalWords: naturalnumbers exponemtiale notanumber emptyset eulergamma
+% LocalWords: exponentiale doctex
diff --git a/Master/texmf-dist/source/latex/stex/cnx/cnx.dtx b/Master/texmf-dist/source/latex/stex/cnx/cnx.dtx
new file mode 100644
index 00000000000..4a83a3702de
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/cnx/cnx.dtx
@@ -0,0 +1,1176 @@
+% \iffalse meta-comment
+% A LaTeX Class for CNXML
+% Copyright (c) 2006 Michael Kohlhase, all rights reserved
+% this file is released under the
+% Gnu Library Public Licences (LGPL)
+%
+% The development version of this file can be found at
+% $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/cnx/cnx.dtx $
+% \fi
+%
+% \iffalse
+%<class>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<class>\ProvidesClass{cnx}[2010/06/25 v1.0 LaTeX Bindings for CNXML]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,float,stex-logo}
+\usepackage[show]{ed}
+\usepackage[hyperref=auto,style=alphabetic]{biblatex}
+\bibliography{kwarc}
+\usepackage{ctansvn}
+\usepackage[eso-foot,today]{svninfo}
+\svnInfo $Id: cnx.dtx 1483 2010-07-19 07:11:16Z kohlhase $
+\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/cnx/cnx.dtx $
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{cnx.dtx}\end{document}
+%</driver>
+% \fi
+%
+%\CheckSum{1}
+%
+% \changes{v0.1}{2005/12/06}{Initial Version}
+% \changes{v0.2}{2006/01/11}{Namespaces now work}
+% \changes{v1.0}{2006/01/11}{this is a good as it is every going to get}
+%
+% \GetFileInfo{cnx.cls}
+%
+% \MakeShortVerb{\|}
+%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\xml{\scshape{XML}}
+% \def\cnxml{\scshape{CNXml}}
+% \def\connexions{\scshape{Connexions}}
+% \def\element#1{{\ttfamily{#1}}}
+% \def\snippet#1{{\ttfamily{#1}}}
+% \def\cnxlatex{CNX\LaTeX}
+% \def\mathml{{\scshape{MathML}}}
+% \def\latexml{\hbox{{\LaTeX}ML}}
+% \title{{\cnxlatex}: A {\LaTeX}-based Syntax for Connexions Modules\thanks{Version {\fileversion}
+% (last revised {\filedate})}}
+% \author{Michael Kohlhase\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% We present {\cnxlatex}, a collection of {\LaTeX} macros that allow to write
+% {\connexions} modules without leaving the {\LaTeX} workflow. Modules are authored in
+% {\cnxlatex} using only a text editor, transformed to PDF and proofread as usual. In
+% particular, the {\LaTeX} workflow is independent of having access to the {\connexions}
+% system, which makes {\cnxlatex} attractive for the initial version of single-author
+% modules.
+%
+% For publication, {\cnxlatex} modules are transformed to {\cnxml} via the {\latexml}
+% translator and can be uploaded to the {\connexions} system.
+% \end{abstract}
+%
+% \newpage\tableofcontents\newpage
+%
+%\section{Introduction}
+%
+% The Connexions project is a\ednote{continue; copy from somewhere...}
+%
+% The {\cnxml} format --- in particular the embedded content {\mathml} --- is hard to write
+% by hand, so we provide a set of environments that allow to embed the {\cnxml} document
+% model into {\LaTeX}.
+%
+%\section{The User Interface}
+%
+% This document is not a manual for the Connexions XML encoding, or a practical guide how
+% to write Connexions modules. We only document the {\LaTeX} bindings for {\cnxml} and will
+% presuppose experience with the format or familiarity with\ednote{cite the relevant stuff
+% here}. Note that formatting {\cnxlatex} documents with the {\LaTeX} formatter does
+% little to enforce the restrictions imposed by the {\cnxml} document model. You will need to
+% run the {\latexml} converter for that (it includes DTD validation) and any CNX-specific
+% quality assurance tools after that. \ednote{talk about Content {\mathml} and cmathml.sty
+% somewhere}
+%
+% The {\cnxlatex} class makes heavy use of the |KeyVal| package, which is part of your
+% {\LaTeX} distribution. This allows to add optional information to {\LaTeX} macros in the
+% form of key-value pairs: A macro |\foo| that takes a KeyVal argument and a regular one,
+% so a call might look like |\foo{bar}| (no KeyVal information given) or
+% |\foo[key1=val1,...,keyn=valn]{bar}|, where |key1|,\dots,|keyn| are predefined keywords
+% and values are {\LaTeX} token sequences that do not contain comma characters (though
+% they may contain blank characters). If a value needs to contain commas, then it must be
+% enclosed in curly braces, as in |\foo[args={a,comma,separated,list}]|. Note that the
+% order the key/value pairs appear in a KeyVal Argument is immaterial.
+%
+% \subsection{Document Structure}
+%
+% \begin{exfig}
+%\begin{verbatim}
+% \documentclass{cnx}
+% \begin{document}
+% \begin{cnxmodule}[name=Hello World,id=m4711]
+% \begin{ccontent}
+% \begin{cpara}[id=p01] Hello World\end{cpara}
+% \end{ccontent}
+% \end{cnxmodule}
+% \end{document}
+% \end{verbatim}
+% \caption{A Minimal {\cnxlatex} Document}\label{fig:minimal}
+%\end{exfig}
+%
+% The first set of {\cnxlatex} environments concern the top-level structure of the
+% modules. The minimal Connexions document in {\LaTeX} can be seen in
+% Figure~\ref{fig:minimal}: we still need the {\LaTeX} document environment, then
+% \DescribeEnv{cnxmodule}
+% the |cnxmodule| environment contains the module-specific information as a KeyVal
+% argument with the two keys: |id| for the module identifier supplied by the
+% {\connexions} system) and |name| for the title of the module.
+%
+% \DescribeEnv{ccontent}
+% The |content| environment delineates the module content from the metadata (see
+% Section~\ref{sec:metadata}). It is needed to make the conversion to {\cnxml} simpler.
+%
+% \DescribeEnv{c*section}
+% {\cnxml} knows three levels of sectioning, so the {\cnxlatex} class supplies three as
+% well: |csection|, |csubsection| and |csubsubsection|. In contrast to regular
+% {\LaTeX}, these are environments to keep the tight connection between the
+% formats. These environments take an optional KeyVal argument with key |id| for the
+% identifier and a regular argument for the title of the section (to be transformed into
+% the {\cnxml} {\element{name}} element).
+%
+% \DescribeEnv{cpara, cnote}
+% The lowest levels of the document structure are given by paragraphs and notes. The
+% |cpara| and |cnote| environment take a KeyVal argument with the |id| key for
+% identification, the latter also allows a |type| key for the note type (an unspecified
+% string\ednote{what are good values?}).
+%
+%
+% \subsection{Mathematics}
+%
+% Mathematical formulae are integrated into text via the {\LaTeX} math mode, i.e. wrapped
+% in |$| characters or between |\(| and |\)| for inline mathematics and wrapped in |$$| or
+% between |\[| and |\]| for display-style math. Note that {\cnxml} expects Content
+% {\mathml} as the representation format for mathematical formulae, while run-of-the-mill
+% {\LaTeX} only specifies the presentation (i.e. the two-dimensional layout of
+% formulae). The {\latexml} converter can usually figure out some of the content {\mathml}
+% from regular {\LaTeX}, in other cases, the author has to specify it e.g. using the
+% infrastructure supplied by the |cmathml| package.
+%
+% \DescribeEnv{cequation}
+% For numbered equations, {\cnxml} supplies the {\element{equation}} element, for which
+% {\cnxlatex} provides the |cequation| environment. This environment takes a KeyVal
+% argument with the |id| key for the (required) identifier.
+%
+%
+% \subsection{Statements}
+%
+% {\cnxml} provides special elements that make various types of claims; we
+% collectively call them statements.
+%
+% \DescribeEnv{cexample}
+% The |cexample| environment and |definition| elements take a KeyVal argument with key
+% |id| for identification.
+%
+%
+% \DescribeEnv{crule, statement, proof}
+% In {\cnxml}, the {\element{rule}} element is used to represent a general assertion
+% about the state of the world. The {\cnxlatex} |rule|\ednote{we have called this
+% ``crule'', since ``rule'' is already used by {\TeX}.} environment is its {\cnxlatex}
+% counterpart. It takes a KeyVal attribute with the keys |id| for identification, |type|
+% to specify the type of the assertion (e.g. ``Theorem'', ``Lemma'' or ``Conjecture''),
+% and |name|, if the assertion has a title. The body of the |crule| environment contains
+% the statement of assertion in the |statement| environment and (optionally) a proof in
+% the |proof| environment. Both take a KeyVal argument with an |id| key for
+% identification.
+%
+%\begin{exfig}
+%\begin{verbatim}
+% \begin{crule}[id=prop1,type=Proposition]
+% \begin{statement}[id=prop1s]
+% Sample statement
+% \end{statement}
+% \begin{proof}[id=prop1p]
+% Your favourite proof
+% \end{proof}
+% \end{crule}
+% \end{verbatim}
+% \caption{A Basic crule Example}\label{fig:crule}
+%\end{exfig}
+%
+% \DescribeEnv{definition, cmeaning} A definition defines a new technical term or concept
+% for later use. The |definition| environment takes a KeyVal argument with the keys |id|
+% for identification and |term| for the concept (definiendum) defined in this form. The
+% definition text is given in the |cmeaning| environment\footnote{we have called this
+% |cmeaning|, since |meaning| is already taken by {\TeX}}, which takes a KeyVal argument
+% with key |id| for identification. After the |cmeaning| environment, a |definition| can
+% contain arbitrarily many |cexample|s.
+%
+%\begin{exfig}
+%\begin{verbatim}
+% \begin{definition}{term=term-to-be-defined, id=termi-def]
+% \begin{cmeaning}[id=termi-meaning]
+% {\term{Term-to-be-defined}} is defined as: Sample meaning
+% \end{cmeaning}
+% \end{definition}
+%\end{verbatim}
+% \caption{A Basic {\tt{definition}} and {\tt{cmeaning}} Example}\label{fig:def-cmean}
+%\end{exfig}
+%
+% \subsection{Connexions: Links and Cross-References}
+%
+% As the name {\connexions} already suggests, links and cross-references are very
+% important for {\connexions} modules. {\cnxml} provides three kinds of them. Module
+% links, hyperlinks, and concept references.
+%
+% \DescribeMacro{cnxn}
+% Module links are specified by the |\cnxn| macro, which takes a keyval argument with
+% the keys |document|, |target|, and |strength|. The |document| key allows to specify
+% the module identifier of the desired module in the repository, if it is empty, then
+% the current module is intended. The |target| key allows to specify the document
+% fragment. Its value is the respective identifier (given by its |id| attribute in
+% {\cnxml} or the |id| key of the corresponding environment in {\cnxlatex}). Finally,
+% the |strength| key allows to specify the relevance of the link.
+%
+% The regular argument of the |\cnxn| macro is used to supply the link text.
+%
+%
+% \DescribeMacro{link}
+% Hyperlinks can be specified by the |\link| macro in {\cnxlatex}. It takes a KeyVal
+% argument with the key |src| to specify the URL of the link. The regular argument of
+% the |\link| macro is used to supply the link text.
+%
+%
+% \DescribeMacro{term}
+% The |\term| marco can be used to specify the\ednote{continue, pending Chuck's
+% investigation. }
+%
+%
+% \subsection{Metadata}\label{sec:metadata}
+%
+% Metadata is mostly managed by the system in {\connexions}, so we often do not need to
+% care about it. On the other hand, it influences the system, so if we have work on the
+% module extensively before converting it to {\cnxml}, it may be worth-wile specify some of
+% the data in advance.
+%
+% \begin{exfig}
+%\begin{verbatim}
+% \begin{metadata}[version=2.19,
+% created=2000/07/21,revised=2004/08/17 22:07:27.213 GMT-5]
+% \begin{authorlist}
+% \cnxauthor[id=miko,firstname=Michael,surname=Kohlhase,
+% email=m.kohlhase@iu-bremen.de]
+% \end{authorlist}
+% \begin{keywordlist}\keyword{Hello}\end{keywordlist}
+% \begin{cnxabstract}
+% A Minimal CNXLaTeX Document
+% \end{cnxabstract}
+% \end{metadata}
+% \end{verbatim}
+% \caption{Typical {\cnxlatex} Metadata}\label{fig:metadata}
+%\end{exfig}
+%
+% \DescribeEnv{metadata}
+% The |metadata| environment takes a KeyVal argument with the keys |version|, |created|,
+% and |revised| with the obvious meanings. The latter keys take ISO 8601 norm
+% representations for dates and times. Concretely, the format is
+% {\snippet{CCYY-MM-DDThh:mm:ss}} where ``{\snippet{CC}}'' represents the century,
+% ``{\snippet{YY}}'' the year, ``{\snippet{MM}}'' the month, and ``{\snippet{DD}}'' the
+% day, preceded by an optional leading ``{\snippet{-}}'' sign to indicate a negative
+% number. If the sign is omitted, ``{\snippet{+}}'' is assumed. The letter
+% ``{\snippet{T}}'' is the date/time separator and ``{\snippet{hh}}'',
+% ``{\snippet{mm}}'', ``{\snippet{ss}}'' represent hour, minutes, and seconds
+% respectively.
+%
+%
+% \DescribeEnv{authorlist, maintainerlist}
+% The lists of authors and maintainers can be specified in the |authorlist| and
+% |maintainerlist| environments, which take no arguments.
+%
+% \DescribeMacro{cnxauthor,maintainer}
+% The entries on this lists are specified by the |\cnxauthor| and |\maintainer|
+% macros. Which take a KeyVal argument specifying the individual. The |id| key is the
+% identifier for the person, the |honorific|, |firstname|, |other|, |surname|, and
+% |lineage| keys are used to specify the various name parts, and the |email| key is used
+% to specify the e-mail address of the person.
+%
+%
+% \DescribeEnv{keywordlist, keyword}
+% The keywords are specified with a list of |keyword| macros, which take the respective
+% keyword in their only argument, inside a |keyword| environment. Neither take any
+% KeyVal arguments.
+%
+%
+% \DescribeEnv{cnxabstract}
+% The abstract of a {\connexions} module is considered to be part of the metadata. It is
+% specified using the |cnxabstract| environment. It does not take any arguments.
+%
+%
+% \subsection{Exercises}
+%
+% \DescribeEnv{cexercise, cproblem, csolution}
+% An exercise or problem in {\connexions} is specified by the |cexercise| environment,
+% which takes an optional keyval argument with the keys |id| and |name|. It must contain
+% a |cproblem| environment for the problem statement and a (possibly) empty set of
+% |csolution| environments. Both of these take an optional keyval argument with the key
+% |id|.
+%
+% \subsection{Graphics, etc.}
+%
+% \DescribeMacro{cfigure} For graphics we will use the |cfigure|\ednote{probably better
+% call it {\tt{cgraphics}}} macro, which provides a non-floating environment for
+% including graphics into {\cnxml} files. |cfigure| takes three arguments first an
+% optional {\cnxml} keys, then the keys of the |graphicx| package in a regular argument
+% (leave that empty if you don't have any) and finally a path. So
+% \begin{center}
+% |\cfigure[id=foo,type=image/jpeg,caption=The first FOO]{width=7cm,height=2cm}{../images/foo}|
+% \end{center}
+% Would include a graphic from the file at the path |../images/foo|, equip this image with
+% a caption, and tell {\latexml} that\ednote{err, exactly what does it tell latexml?} the
+% original of the images has the MIME type |image/jpeg|.
+%
+% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\newpage
+%
+% \section{The Implementation}
+%
+% The |cnx| 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 |sref|~\ctancite{Kohlhase:sref} and |graphicx| packages are
+% loaded.
+% \begin{macrocode}
+%<*cls>
+\RequirePackage{sref}
+\RequirePackage{graphicx}
+% \end{macrocode}
+%
+% The next step is to declare (a few) class options that handle the paper size; this is
+% useful for printing.
+% \begin{macrocode}
+\DeclareOption{letterpaper}
+ {\setlength\paperheight {11in}%
+ \setlength\paperwidth {8.5in}}
+\DeclareOption{a4paper}
+ {\setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\ExecuteOptions{letterpaper}
+\ProcessOptions
+% \end{macrocode}
+% Finally, we input all the usual size settings. There is no sense to use something else,
+% and we initialize the page numbering counter and tell it to output the numbers in arabic
+% numerals (otherwise label and reference do not work).
+% \begin{macrocode}
+\input{size10.clo}
+\pagenumbering{roman}
+%</cls>
+% \end{macrocode}
+% Now comes the equivalent for {\latexml}: this is something that we will have throughout
+% this document. Every part of the {\TeX/\LaTeX} implementation has a {\latexml}
+% equivalent. We keep them together to ensure that they do not get out of sync.
+% \begin{macrocode}
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+RequirePackage('omd');
+% \end{macrocode}
+% We set up the necessary namespaces, the first one is the default one for {\cnxml}
+% \begin{macrocode}
+RegisterNamespace('cnx'=>"http://cnx.rice.edu/cnxml");
+RegisterNamespace('md'=>"http://cnx.rice.edu/mdml/0.4");
+RegisterNamespace('bib'=>"http://bibtexml.sf.net/");
+RegisterNamespace('m'=>"http://www.w3.org/1998/Math/MathML");
+% \end{macrocode}
+% For {\latexml} we also have to set up the correct document type information. The first line
+% gives the root element. The second gives the public identifier for the CNX DTD, then we
+% have its URL, and finally the CNX namespace.
+% \begin{macrocode}
+DocType("cnx:document",
+ "-//CNX//DTD CNXML 0.5 plus LaTeXML//EN",
+ "../dtd/cnxml+ltxml.dtd",
+ '#default'=>"http://cnx.rice.edu/cnxml",
+ 'md'=>"http://cnx.rice.edu/mdml/0.4",
+ 'bib'=>"http://bibtexml.sf.net/",
+ 'm'=>"http://www.w3.org/1998/Math/MathML",
+ 'ltx'=>"http://dlmf.nist.gov/LaTeXML");
+% \end{macrocode}
+%
+% And finally, we need to set up the counters for itemization, since we are defining a
+% class file from scratch.\ednote{this will have to change, when Bruce updates to the next
+% version (0.6?)}
+%
+% \begin{macrocode}
+NewCounter('@itemizei', 'document', idprefix=>'I');
+NewCounter('@itemizeii', '@itemizei', idprefix=>'I');
+NewCounter('@itemizeiii', '@itemizeii', idprefix=>'I');
+NewCounter('@itemizeiv', '@itemizeiii',idprefix=>'I');
+NewCounter('@itemizev', '@itemizeiv', idprefix=>'I');
+NewCounter('@itemizevi', '@itemizev', idprefix=>'I');
+
+NewCounter('enumi', '@itemizei', idprefix=>'i');
+NewCounter('enumii', '@itemizeii', idprefix=>'i');
+NewCounter('enumiii','@itemizeiii', idprefix=>'i');
+NewCounter('enumiv', '@itemizeiv', idprefix=>'i');
+# A couple of more levels, since we use these for ID's!
+NewCounter('enumv', '@itemizev', idprefix=>'i');
+NewCounter('enumvi', '@itemizevi', idprefix=>'i');
+
+DefMacro('\theenumi', '\arabic{enumi}');
+DefMacro('\theenumii', '\alph{enumii}');
+DefMacro('\theenumiii', '\roman{enumiii}');
+DefMacro('\theenumiv', '\Alph{enumiv}');
+
+NewCounter('equation', 'document', idprefix=>'E');
+DefMacro('\theequation', '\arabic{equation}');
+DefMacro('\textwidth','16cm');
+% \end{macrocode}
+%
+% And another thing that is now needed:
+%
+% \begin{macrocode}
+Let('\thedocument@ID','\@empty');
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Document Structure}
+%
+% Now, we start with the document structure markup. The |cnxmodule| environment does not
+% add anything to the {\LaTeX} output, it's attributes only show up in the {\xml}. There
+% we have a slight complication: we have to put an |id| attribute on the |document|
+% element in {\cnxml}, but we cannot redefine the |document| environment in
+% {\LaTeX}. Therefore we specify the information in the |cnxmodule| environment. This
+% means however that we have to put in on the |document| element when we are already past
+% this. The solution here is that when we parse the |cnxmodule| environement, we store the
+% value and put it on the |document| element when we leave the |document| environment
+% (thanks for Ioan Sucan for the code).
+%
+% \begin{environment}{cnxmodule}
+% \begin{macrocode}
+%<*cls>
+\omdaddkey{cnxmodule}{name}
+\srefaddidkey{cnxmodule}{id}
+\newenvironment{cnxmodule}[1][]{\omdsetkeys{cnxmodule}{#1}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('cnxmodule','name','Semiverbatim');
+DefKeyVal('cnxmodule','id','Semiverbatim');
+DefEnvironment('{document}','<cnx:document>#body</cnx:document>',
+ beforeDigest=> sub { AssignValue(inPreamble=>0); },
+ afterDigest=> sub { $_[0]->getGullet->flush; return; });
+DefEnvironment('{cnxmodule} OptionalKeyVals:cnxmodule',
+ "<cnx:name>&KeyVal('#1','name')</cnx:name>\n#body\n",
+ afterDigestBegin => sub {
+ AssignValue('cnxmodule_id',
+ KeyVal($_[1]->getArg(1), 'id')->toString,
+ 'global');
+ });#$
+Tag('cnx:document', afterClose => sub {
+ $_[1]->setAttribute('id', LookupValue('cnxmodule_id'));
+ });
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{ccontent}
+% The |ccontent| environment is only used for transformation. Its optional |id| attribute
+% is not taken up in the {\LaTeX} bindings.
+% \begin{macrocode}
+%<*cls>
+\newenvironment{ccontent}{}{}
+%</cls>
+%<*ltxml>
+DefEnvironment('{ccontent}',"<cnx:content>#body</cnx:content>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{c*section}
+% The sectioning environments employ the obvious nested set of counters.
+% \begin{macrocode}
+%<*cls>
+\newcounter{section}
+\srefaddidkey{sectioning}{id}
+\newenvironment{csection}[2][]%
+{\stepcounter{section}\strut\\[1.5ex]\noindent%
+{\Large\bfseries\arabic{section}.~{#2}}\\[1.5ex]
+\omdsetkeys{sectioning}{#1}}
+{}
+\newcounter{subsection}[section]
+\newenvironment{csubsection}[2][]
+{\refstepcounter{subsection}\strut\\[1ex]\noindent%
+{\large\bfseries{\arabic{section}.\arabic{subsection}.~#2\\[1ex]}}%
+\omdsetkeys{sectioning}{#1}}%
+{}
+\newcounter{subsubsection}[subsection]
+\newenvironment{csubsubsection}[2][]
+{\refstepcounter{subsubsection}\strut\\[.5ex]\noindent
+{\bfseries\arabic{section}.\arabic{subsection}.\arabic{subsubsecction}~#2\\[.5ex]}%
+\omdsetkeys{sectioning}{#1}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('sectioning','id','Semiverbatim');
+DefEnvironment('{csection}OptionalKeyVals:sectioning{}',
+ "<cnx:section %&KeyVals(#1)>\n"
+ . "?#2(<cnx:name>#2</cnx:name>\n)()"
+ . "#body\n</cnx:section>\n");
+DefEnvironment('{csubsection}OptionalKeyVals:sectioning{}',
+ "<cnx:section %&KeyVals(#1)>\n"
+ . "?#2(<cnx:name>#2</cnx:name>\n)()"
+ . "#body\n</cnx:section>\n");
+DefEnvironment('{csubsubsection}OptionalKeyVals:sectioning{}',
+ "<cnx:section %&KeyVals(#1)>\n"
+ . "?#2(<cnx:name>#2</cnx:name>\n)()"
+ . "#body\n</cnx:section>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{cpara}
+% For the |<cnx:para>| element we have to do some work, since we want them to be
+% numbered. This handling is adapted from Bruce Miller's |LaTeX.ltxml|
+% numbered.
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{para}{id}
+\newenvironment{cpara}[1][]{\omdsetkeys{para}{#1}}{\par}
+%</cls>
+%<*ltxml>
+DefKeyVal('para','id','Semiverbatim');
+DefEnvironment('{cpara} OptionalKeyVals:para','<cnx:para %&KeyVals(#1)>#body</cnx:para>');
+sub number_para {
+ my($document,$node,$whatsit)=@_;
+ # Get prefix from first parent with an id.
+ my(@parents)=$document->findnodes('ancestor::*[@id]',$node); # find 1st id'd parent.
+ my $prefix= (@parents ? $parents[$#parents]->getAttribute('id')."." : '');
+ # Get the previous number within parent; Worried about intervening elements around para's, but...
+ my(@siblings)=$document->findnodes("preceding-sibling::cnx:para",$node);
+ my $n=1;
+ $n = $1+1 if(@siblings && $siblings[$#siblings]->getAttribute('id')=~/(\d+)$/);
+ $node->setAttribute(id=>$prefix."p$n"); }
+Tag('cnx:para',afterOpen=>\&number_para);
+DefConstructor('\par',sub { $_[0]->maybeCloseElement('cnx:para'); },alias=>"\\par\n");
+Tag('cnx:para', autoClose=>1, autoOpen=>1);
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{cnote}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{note}
+\omdaddkey{note}{type}
+\newenvironment{cnote}[1][]%
+{\omdsetkeys{note}{#1}\par\noindent\strut\hfill\begin{minipage}{10cm}{\bfseries\note@type}:~}%
+{\end{minipage}\hfill\strut\par}
+%</cls>
+%<*ltxml>
+DefKeyVal('note','id','Semiverbatim');
+DefKeyVal('note','type','Semiverbatim');
+DefEnvironment('{cnote}OptionalKeyVals:note','<cnx:note %&KeyVals(#1)>#body</cnx:note>');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Mathematics}
+%
+% \begin{environment}{cequation}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{equation}{id}
+\newenvironment{cequation}[1][]%
+{\omdsetkeys{equation}{#1}\begin{displaymath}}
+{\end{displaymath}}
+%</cls>
+%<*ltxml>
+DefKeyVal('equation','id','Semiverbatim');
+DefEnvironment('{cequation} OptionalKeyVals:equation',
+ "<cnx:equation %&KeyVals(#1)>"
+ . "<ltx:Math mode='display'>"
+ . "<ltx:XMath>#body</ltx:XMath>"
+ . "</ltx:Math></cnx:equation>",
+ mode=>'display_math');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Rich Text}
+%
+% In this section, we redefine some of {\LaTeX} commands that have their counterparts in
+% {\cnxml}.
+%
+% \begin{environment}{quote}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{cquote}
+\omdaddkey{cquote}{type}
+\omdaddkey{cquote}{src}
+\newenvironment{cquote}[1][]{%
+\omdsetkeys{cquote}{#1}\begin{center}\begin{minipage}{.8\textwidth}}{\end{minipage}\end{center}}
+%</cls>
+%<*ltxml>
+DefKeyVal('cquote','id','Semiverbatim');
+DefKeyVal('cquote','type','Semiverbatim');
+DefKeyVal('cquote','src','Semiverbatim');
+DefEnvironment('{cquote} OptionalKeyVals:cquote',
+ "<cnx:quote %&KeyVals(#1)>#body</cnx:quote>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{footnote}
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\footnote[]{}',"<cnx:note type='foot'>#2</cnx:note>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{emph}
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\emph{}',"<cnx:emphasis>#1</cnx:emphasis>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{displaymath, eqnarray}
+% We redefine the abbreviate display math envionment and the |eqnarray| and |eqnarray*|
+% environments to use the {\cnxml} equation tags, everything else stays the same.
+%
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\[',
+ "<cnx:equation id='#id'>"
+ . "<ltx:Math mode='display'>"
+ . "<ltx:XMath>"
+ . "#body"
+ . "</ltx:XMath>"
+ . "</ltx:Math>"
+ ."</cnx:equation>",
+ beforeDigest=> sub{ $_[0]->beginMode('display_math'); },
+ captureBody=>1,
+ properties=> sub { RefStepID('equation') });
+DefConstructor('\]' ,"",beforeDigest=> sub{ $_[0]->endMode('display_math'); });
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{displaymath}
+% We redefine the abbreviate display math envionment to use the {\cnxml} equation tags,
+% everything else stays the same.\ednote{check {\tt{LaTeX.ltxml}} frequently and try to
+% keep in sync, it would be good, if the code in LaTeXML.ltxml could be modularized,
+% so that the {\tt{cnx}}/{\tt{ltx}} namespace differences could be relegated to
+% config options}
+%
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\[',
+ "<cnx:equation id='#id'>"
+ . "<ltx:Math mode='display'>"
+ . "<ltx:XMath>"
+ . "#body"
+ . "</ltx:XMath>"
+ . "</ltx:Math>"
+ ."</cnx:equation>",
+ beforeDigest=> sub{ $_[0]->beginMode('display_math'); },
+ captureBody=>1,
+ properties=> sub { RefStepID('equation') });
+DefConstructor('\]' ,"",beforeDigest=> sub{ $_[0]->endMode('display_math'); });
+
+DefMacro('\eqnarray', '\@@eqnarray\@start@alignment');
+DefMacro('\endeqnarray', '\@finish@alignment\end@eqnarray');
+DefMacro('\csname eqnarray*\endcsname', '\@@eqnarray*\@start@alignment');
+DefMacro('\csname endeqnarray*\endcsname', '\@finish@alignment\end@eqnarray');
+DefConstructor('\@@eqnarray OptionalMatch:* AlignmentBody:\end@eqnarray',
+ sub {
+ my($document,$star,$body,%props)=@_;
+ $document->openElement('cnx:equation',refnum=>$props{refnum},id=>$props{id});
+ $document->openElement('ltx:Math',mode=>'display');
+ $document->openElement('ltx:XMath');
+ constructAlignment($document,$body,attributes=>{name=>'eqnarray'});
+ $document->closeElement('ltx:XMath');
+ $document->closeElement('ltx:Math');
+ $document->closeElement('cnx:equation'); },
+ mode=>'display_math',
+ beforeDigest=>sub { alignmentBindings('rcl'); },
+ properties=> sub { ($_[1] ? RefStepID('equation') : RefStepCounter('equation')); },
+ afterDigest=>sub {
+ $_[1]->setProperty(body=>$_[1]->getArg(2));}, # So we get TeX
+ reversion=>'\begin{eqnarray#1}#2\end{eqnarray#1}');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{displaymath}
+% We redefine the abbreviate display math envionment to use the {\cnxml} equation tags,
+% everything else stays the same.\ednote{check {\tt{LaTeX.ltxml}} frequently and try to
+% keep in sync, it would be good, if the code in LaTeXML.ltxml could be modularized,
+% so that the {\tt{cnx}}/{\tt{ltx}} namespace differences could be relegated to
+% config options}
+%
+% \begin{macrocode}
+%<*cls>
+\newcommand{\litem}[2][]{\item[#1]\label{#2}}
+%</cls>
+%<*ltxml>
+Tag('cnx:item', autoClose=>1);
+DefConstructor('\item[]',"<cnx:item>?#1(<cnx:name>#1</cnx:name>)");
+DefConstructor('\litem[]{}',"<cnx:item id='#2'>?#1(<cnx:name>#1</cnx:name>)");
+DefConstructor('\itemize@item[]',
+ "<cnx:item id='#id'>?#1(<cnx:name>#1</cnx:name>)",
+ properties=>sub{ RefStepItemCounter(); });
+DefConstructor('\enumerate@item[]',
+ "<cnx:item id='#id'>?#1(<cnx:name>#1</cnx:name>)",
+ properties=>sub{ RefStepItemCounter(); });
+DefConstructor('\description@item[]',
+ "<cnx::item id='#id'>?#1(<cnx:name>#1</cnx:name>)",
+ properties=>sub{ RefStepItemCounter(); });
+AssignValue(itemlevel=>0);
+DefEnvironment('{itemize}',
+ "<cnx:list id='#id' type='itemize'>#body</cnx:list>",
+ properties=>sub { beginItemize('itemize'); });
+DefEnvironment('{enumerate}',
+ "<cnx:list type='enumerate' id='#id'>#body</cnx:list>",
+ properties=>sub { beginItemize('enumerate'); });
+DefEnvironment('{description}',
+ "<cnx:list type='description' id='#id'>#body</cnx:list>",
+ properties=>sub { beginItemize('description'); });
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% The next set of commands and environments are largely presentational, so we just skip
+% them.
+%
+% \begin{macrocode}
+%<*ltxml>
+DefEnvironment('{center}','#body');
+DefEnvironment('{minipage}{}','#body');
+DefEnvironment('{small}','#body');
+DefEnvironment('{footnotesize}','#body');
+DefEnvironment('{tiny}','#body');
+DefEnvironment('{scriptsize}','#body');
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\ref Semiverbatim', "<cnx:cnxn target='#1'>&LookupValue('LABEL@#1')</cnx:cnxn>");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Statements}
+%
+% \begin{environment}{cexample}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{example}
+\omdaddkey{example}{name}
+\newenvironment{cexample}[1][]{\omdsetkeys{example}{#1}
+{\ifx\example@name\@empty\else\noindent\bfseries{\example@name}\fi}}
+{}
+%</cls>
+%<*ltxml>
+DefKeyVal('example','id','Semiverbatim');
+DefEnvironment('{cexample}OptionalKeyVals:example',
+ "<cnx:example %&KeyVals(#1)>#body</cnx:example>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{cexercise}
+% The |cexercise|, |cproblem| and |csolution| environments are very simple to set up for
+% {\LaTeX}. For the {\latexml} side, we simplify matters considerably for the moment by
+% restricting the possibilities we have on the {\cnxml} side: We assume that the content
+% is just one |<cnx:para>| element for the |<cnx:problem>| and |<cnx:solution>|
+% elements.\ednote{relax this when we have automated the generation of {\tt{cnx:para}}
+% elements}
+% \begin{macrocode}
+%<*cls>
+\newcounter{cexercise}
+\srefaddidkey{cexercise}
+\omdaddkey{cexercise}{name}
+\newenvironment{cexercise}[1][]{\omdsetkeys{cexercise}{#1}
+{\ifx\cexercise@name\@empty\else\stepcounter{cexercise}\noindent\bfseries{\cexercise@name~\arabic{cexercise}}\fi}}
+{}
+\srefaddidkey{cproblem}
+\newenvironment{cproblem}[1][]{\omdsetkeys{cproblem}{#1}}{}{}
+\srefaddidkey{csolution}
+\newenvironment{csolution}[1][]{\omdsetkeys{csolution}{#1}}{\par\noindent\bfseries{Solution}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('cexercise','id','Semiverbatim');
+DefKeyVal('cexercise','name','Semiverbatim');
+DefEnvironment('{cexercise}OptionalKeyVals:exercise',
+ "<cnx:exercise ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')()>"
+ . "#body"
+ . "</cnx:exercise>");
+DefKeyVal('cproblem','id','Semiverbatim');
+DefKeyVal('cproblem','name','Semiverbatim');
+DefEnvironment('{cproblem}OptionalKeyVals:cproblem',
+ "<cnx:problem ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')()>"
+ . "?&defined(&KeyVal(#1,'name'))(<cnx:name>&KeyVal(#1,'name')</cnx:name>\n)()"
+ . "#body"
+ . "</cnx:problem>");
+DefKeyVal('csolution','id','Semiverbatim');
+DefKeyVal('csolution','name','Semiverbatim');
+DefEnvironment('{csolution}OptionalKeyVals:cproblem',
+ "<cnx:solution ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')()>"
+ . "?&defined(&KeyVal(#1,'name'))(<cnx:name>&KeyVal(#1,'name')</cnx:name>\n)()"
+ . "#body"
+ . "</cnx:solution>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{crule}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{rule}
+\omdaddkey{rule}{name}
+\omdaddkey{rule}{type}
+\newenvironment{crule}[1][]{\omdsetkeys{rule}{#1}%
+{\noindent\bfseries{\rule@type:}\ifx\rule@name\@empty\else~(\rule@name)\fi}}%
+{}
+%</cls>
+%<*ltxml>
+DefKeyVal('rule','id','Semiverbatim');
+DefKeyVal('rule','name','Semiverbatim');
+DefKeyVal('rule','type','Semiverbatim');
+DefEnvironment('{crule}OptionalKeyVals:rule',
+ "<cnx:rule ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')() type='&KeyVal(#1,'type')'>\n"
+ . "?&defined(&KeyVal(#1,'name'))(<cnx:name>&KeyVal(#1,'name')</cnx:name>\n)()"
+ . "\n#body\n"
+ . "</cnx:rule>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{statement}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{statement}
+\newenvironment{statement}[1][]{\omdsetkeys{statement}{#1}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('statement','id','Semiverbatim');
+DefEnvironment('{statement} OptionalKeyVals:statement','<cnx:statement %&KeyVals(#1)>#body</cnx:statement>');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{proof}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{proof}
+\newenvironment{proof}[1][]{\omdsetkeys{proof}{#1}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('proof','id','Semiverbatim');
+DefEnvironment('{proof}OptionalKeyVals:proof','<cnx:proof %&KeyVals(#1)>#body</cnx:proof>');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{definition}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{definition}
+\omdaddkey{definition}{term}
+\omdaddkey{definition}{seealso}
+\newenvironment{definition}[1][]{\omdsetkeys{definition}{#1}{\noindent\bfseries{Definition:}}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('definition','id','Semiverbatim');
+DefKeyVal('definition','term','Semiverbatim');
+DefKeyVal('definition','seealso','Semiverbatim');
+DefEnvironment('{definition}OptionalKeyVals:definition',
+ "<cnx:definition ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')()>\n"
+ . "?&defined(&KeyVal(#1,'term'))(<cnx:term>&KeyVal(#1,'term')</cnx:term>\n)()"
+ . "\n#body\n"
+ . "?&defined(&KeyVal(#1,'seealso'))(<cnx:seealso><cnx:term>&KeyVal(#1,'term')</cnx:term></cnx:seealso>\n)()"
+ . "</cnx:definition>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{cmeaning}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{meaning}
+\newenvironment{cmeaning}[1][]{\omdsetkeys{meaning}{#1}}{}
+%</cls>
+%<*ltxml>
+DefKeyVal('meaning','id','Semiverbatim');
+DefEnvironment('{cmeaning}OptionalKeyVals:meaning','<cnx:meaning %&KeyVals(#1)>#body</cnx:meaning>');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Conexxions}
+%
+% \begin{macro}{cnxn}
+% \begin{macrocode}
+%<*cls>
+\omdaddkey{cnxn}{document}
+\omdaddkey{cnxn}{target}
+\omdaddkey{cnxn}{strength}
+\newcommand{\cnxn}[2][]% keys, link text
+{\omdsetkeys{cnxn}{#1}{\underline{#2}}\footnote{{\ttfamily\@ifx\cnxn@document\@empty\cnxn@document\fi\#\cnxn@target}}}
+\newcommand\@makefntext[1]{\parindent 1em\noindent\hb@xt@1.8em{\hss\@makefnmark}#1}
+%</cls>
+%<*ltxml>
+DefKeyVal('cnxn','document','Semiverbatim');
+DefKeyVal('cnxn','target','Semiverbatim');
+DefKeyVal('cnxn','strength','Semiverbatim');
+DefConstructor('\cnxn OptionalKeyVals:cnxn {}','<cnx:cnxn %&KeyVals(#1)>#1</cnx:cnxn>');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{link}
+% \begin{macrocode}
+%<*cls>
+\omdaddkey{link}{src}
+\newcommand{\link}[2][]{\omdsetkeys{link}{#1}\underline{#2}}
+%</cls>
+%<*ltxml>
+DefKeyVal('link','src','Semiverbatim');
+DefConstructor('\link OptionalKeyVals:link {}','<cnx:link %&KeyVals(#1)>#2</cnx:link>');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{cfigure}
+% The |cfigure| only gives us one of the possible instances of the |<figure>|
+% element\ednote{extend that}.\ednote{do more about required and optional keys in
+% arguments.} In {\LaTeX}, we just pipe the size information through to
+% |includegraphics|, in {\latexml}, we construct the {\cnxml} structure\ednote{what do
+% we do with the graphicx information about size,... CSS?}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{cfigure}
+\omdaddkey{cfigure}{type}
+\omdaddkey{cfigure}{caption}
+\newcounter{figure}
+\newcommand{\cfigure}[3][]{% cnx_keys, graphicx_keys, path
+\begin{center}%
+\includegraphics[#2]{#3}%
+\omdsetkeys{cfigure}{#1}\sref@target%
+\ifx\cfigure@caption\@empty\else
+\par\noindent Figure\refstepcounter{figure} {\arabic{figure}}: \cfigure@caption%
+\protected@edef\@currentlabel{\arabic{figure}}%
+\sref@label@id{Figure \thefigure}\fi
+\end{center}}
+%</cls>
+%<*ltxml>
+DefKeyVal('cfigure','id','Semiverbatim');
+DefKeyVal('cfigure','name','Semiverbatim');
+DefKeyVal('cfigure','type','Semiverbatim');
+DefKeyVal('cfigure','caption','Semiverbatim');
+DefConstructor('\cfigure OptionalKeyVals:cfigure Semiverbatim Semiverbatim',
+ "<cnx:figure ?&defined(&KeyVal(#1,'id'))(id='&KeyVal(#1,'id')')()>"
+ . "?&defined(&KeyVal(#1,'name'))(<cnx:name>&KeyVal(#1,'name')</cnx:name>\n)()"
+ . "<cnx:media type='&KeyVal(#1,'type')' src='#3'/>"
+ . "?&defined(&KeyVal(#1,'caption'))(<cnx:caption>&KeyVal(#1,'caption')</cnx:caption>\n)()"
+ . "</cnx:figure>");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ccite}
+% \begin{macrocode}
+%<*cls>
+\omdaddkey{ccite}{src}
+\newcommand{\ccite}[2][]{\omdsetkeys{ccite}{#1}\emph{#2}}
+%</cls>
+%<*ltxml>
+DefKeyVal('ccite','src','Semiverbatim');
+DefConstructor('\ccite OptionalKeyVals:ccite {}','<cnx:cite %&KeyVals(#1)>#2</cnx:cite>');
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{term}
+% \begin{macrocode}
+%<*cls>
+\newcommand{\term}[1]{{\bfseries\underline{#1}}}
+%</cls>
+%<*ltxml>
+DefConstructor('\term[]{}',"<cnx:term>#2</cnx:term>");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Metadata}
+%
+% \begin{environment}{metadata}
+% \begin{macrocode}
+%<*cls>
+\omdaddkey{metadata}{version}
+\omdaddkey{metadata}{created}
+\omdaddkey{metadata}{revised}
+\newsavebox{\metadatabox}
+\newenvironment{metadata}[1][]%
+{\noindent\hfill\begin{lrbox}{\metadatabox}
+\begin{minipage}{.8\textwidth}%
+{\Large\bfseries CNX Module: \cnx@name\hfill\strut}\\[2ex]}%
+{\end{minipage}\end{lrbox}\fbox{\usebox\metadatabox}\hfill}
+% \newenvironment{metadata}[1][]%
+% {\noindent\strut\hfill\begin{lrbox}{\metadatabox}\begin{minipage}{10cm}%
+% {\strut\hfill\Large\bfseries CNX Module: \cnx@name\hfill\strut}\\[2ex]}%
+% {\end{minipage}\end{lrbox}\fbox{\usebox\metadatabox}\hfill\strut\\[3ex]}
+%</cls>
+%<*ltxml>
+DefKeyVal('metadata','version','Semiverbatim');
+DefKeyVal('metadata','created','Semiverbatim');
+DefKeyVal('metadata','revised','Semiverbatim');
+DefEnvironment('{metadata}OptionalKeyVals:metadata',
+ "<cnx:metadata>\n"
+ . "<md:version>&KeyVal('#1','version')</md:version>\n"
+ . "<md:created>&KeyVal('#1','created')</md:created>\n"
+ . "<md:revised>&KeyVal('#1','revised')</md:revised>\n"
+ . "#body\n"
+ . "</cnx:metadata>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{authorlist}
+% \begin{macrocode}
+%<*cls>
+\newenvironment{authorlist}{{\bfseries{Authors}:~}}{\\[1ex]}
+%</cls>
+%<*ltxml>
+DefEnvironment('{authorlist}',"<md:authorlist>#body</md:authorlist>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{maintainerlist}
+% \begin{macrocode}
+%<*cls>
+\newenvironment{maintainerlist}{{\bfseries{Maintainers}:~}}{\\[1ex]}
+%</cls>
+%<*ltxml>
+DefEnvironment('{maintainerlist}',"<md:maintainerlist>#body</md:maintainerlist>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{cnxauthor}
+% \begin{macrocode}
+%<*cls>
+\srefaddidkey{auth}
+\omdaddkey{auth}{honorific}
+\omdaddkey{auth}{firstname}
+\omdaddkey{auth}{other}
+\omdaddkey{auth}{surname}
+\omdaddkey{auth}{lineage}
+\omdaddkey{auth}{email}
+\newcommand{\cnxauthor}[1][]{\omdsetkeys{auth}{#1}\auth@first~\auth@sur,}
+%</cls>
+%<*ltxml>
+DefKeyVal('auth','id','Semiverbatim');
+DefKeyVal('auth','firstname','Semiverbatim');
+DefKeyVal('auth','surname','Semiverbatim');
+DefKeyVal('auth','email','Semiverbatim');
+DefConstructor('\cnxauthor OptionalKeyVals:auth',
+ "<md:author id='&KeyVal('#1','id')'>\n"
+ . "?&defined(&KeyVal(#1,'honorific'))(<md:honorific>&KeyVal('#1','honorific')</md:honorific>\n)()"
+ . "?&defined(&KeyVal(#1,'firstname'))(<md:firstname>&KeyVal('#1','firstname')</md:firstname>\n)()"
+ . "?&defined(&KeyVal(#1,'other'))(<md:other>&KeyVal('#1','other')</md:other>\n)()"
+ . "?&defined(&KeyVal(#1,'surname'))(<md:surname>&KeyVal('#1','surname')</md:surname>\n)()"
+ . "?&defined(&KeyVal(#1,'lineage'))(<md:lineage>&KeyVal('#1','lineage')</md:lineage>\n)()"
+ . "?&defined(&KeyVal(#1,'email'))(<md:email>&KeyVal('#1','email')</md:email>\n)()"
+ . "</md:author>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{maintainer}
+% \begin{macrocode}
+%<*cls>
+\newcommand{\maintainer}[1][]{\omdsetkeys{auth}{#1}\auth@first~\auth@sur,}
+%</cls>
+%<*ltxml>
+DefConstructor('\maintainer OptionalKeyVals:auth',
+ "<md:maintainer id='&KeyVal('#1','id')'>\n"
+ . "?&defined(&KeyVal(#1,'honorific'))(<md:honorific>&KeyVal('#1','honorific')</md:honorific>\n)()"
+ . "?&defined(&KeyVal(#1,'firstname'))(<md:firstname>&KeyVal('#1','firstname')</md:firstname>\n)()"
+ . "?&defined(&KeyVal(#1,'other'))(<md:other>&KeyVal('#1','other')</md:other>\n)()"
+ . "?&defined(&KeyVal(#1,'surname'))(<md:surname>&KeyVal('#1','surname')</md:surname>\n)()"
+ . "?&defined(&KeyVal(#1,'lineage'))(<md:lineage>&KeyVal('#1','lineage')</md:lineage>\n)()"
+ . "?&defined(&KeyVal(#1,'email'))(<md:email>&KeyVal('#1','email')</md:email>\n)()"
+ . "</md:maintainer>\n");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{keywordlist}
+% \begin{macrocode}
+%<*cls>
+\newenvironment{keywordlist}{\bfseries{Keywords}:~}{\\[1ex]}
+%</cls>
+%<*ltxml>
+DefEnvironment('{keywordlist}',"<md:keywordlist>\n#body\n</md:keywordlist>");
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{keyword}
+% \begin{macrocode}
+%<*cls>
+\newcommand{\keyword}[1]{#1,}
+%</cls>
+%<*ltxml>
+DefConstructor('\keyword {}',"<md:keyword>#1</md:keyword>");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{cnxabstract}
+% \begin{macrocode}
+%<*cls>
+\newenvironment{cnxabstract}%
+{\par\noindent\strut\hfill\begin{minipage}{10cm}{\bfseries{Abstract}:~}}%
+{\end{minipage}\hfill}
+%</cls>
+%<*ltxml>
+DefEnvironment('{cnxabstract} OptionalKeyVals:cnxabstract',
+ "<md:abstract>\n#body\n</md:abstract>\n");
+1;
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+% \Finale
+\endinput
+
+% \iffalse
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+
+% LocalWords: iffalse cnx cnx.dtx cnx.cls scsys sc sc scshape cnxml ttfamily
+% LocalWords: cnxlatex mathml latexml hbox fileversion maketitle newpage foo
+% LocalWords: tableofcontents newpage ednote cmathml.sty keyn valn keyn exfig
+% LocalWords: DescribeEnv cnxmodule ccontent csection csubsection cpara cnote
+% LocalWords: csubsubsection cmathml cequation cexample crule cmeaning tt tt
+% LocalWords: def-cmean cnxn keyval hh ss authorlist maintainerlist cnxauthor
+% LocalWords: firstname keywordlist cnxabstract cexercise cproblem csolution
+% LocalWords: cfigure cfigure cgraphics graphicx printbibliography textsf sref
+% LocalWords: langle textsf langle ltxml ctancite sref cls setlength omd ltx
+% LocalWords: paperheight paperwidth size10.clo pagenumbering ltxml.dtd enumi
+% LocalWords: itemizei idprefix itemizeii itemizeiii itemizeiv itemizev enumii
+% LocalWords: itemizevi enumiii enumiv enumv enumvi theenumi theenumii Sucan
+% LocalWords: theenumiii theenumiv theequation textwidth thedocument omdaddkey
+% LocalWords: environement srefaddidkey newenvironment omdsetkeys Semiverbatim
+% LocalWords: OptionalKeyVals newcounter stepcounter noindent bfseries
+% LocalWords: refstepcounter subsubsection whatsit findnodes hfill
+% LocalWords: displaymath cquote emph eqnarray envionment endeqnarray csname
+% LocalWords: endcsname refnum refnum rcl newcommand itemlevel
+% LocalWords: footnotesize scriptsize ifx Conexxions makefntext parindent hss
+% LocalWords: makefnmark includegraphics currentlabel thefigure ccite lrbox
+% LocalWords: newsavebox metadatabox fbox usebox auth doctex
diff --git a/Master/texmf-dist/source/latex/stex/mikoslides.dtx b/Master/texmf-dist/source/latex/stex/mikoslides.dtx
new file mode 100644
index 00000000000..2ed715feb0f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/mikoslides.dtx
@@ -0,0 +1,503 @@
+% \iffalse meta-comment
+% A LaTeX Class for Jacobs University Slides
+% Copyright (c) 2007 Michael Kohlhase, all rights reserved
+% this file is released under the
+% Gnu Library Public Licences (LGPL)
+%
+% The development version of this file can be found at
+% https://svn.kwarc.info/repos/kwarc/projects/stex/sty/mikoslides.dtx
+% \fi
+%
+% \iffalse
+%<cls>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<cls>\ProvidesClass{mikoslides}[2010/06/25 v0.9 Jacobs slides]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,array,float}
+\usepackage[show]{ed}
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{mikoslides.dtx}\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{1}
+%
+% \changes{v0.1}{2005/12/06}{Initial Version}
+% \changes{v0.2}{2006/01/11}{course notes back on seminar}
+% \changes{v0.3}{2007/05/16}{changing to jacobs logo}
+% \changes{v0.4}{2007/10/16}{re-basing the whole thing on beamer}
+% \changes{v0.4}{2008/09/06}{moving line-end-comment to \texttt{omdoc.dtx}}
+% \changes{v0.5}{2009/06/17}{eliminating mytwocolumns, this is better done by \texttt{beamer.cls}}
+% \changes{v0.9}{2010/06/18}{this is almost done}
+%
+% \GetFileInfo{mikoslides.cls}
+% \MakeShortVerb{\|}
+%
+% \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}}
+%
+%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\stex{\hbox{\raisebox{-.5ex}S\kern-.5ex\TeX}}
+% \def\sTeX{\stex}
+% \def\cnxml{\scshape{CNXml}}
+% \def\connexions{\scshape{Connexions}}
+% \def\element#1{{\ttfamily{#1}}}
+% \def\snippet#1{{\ttfamily{#1}}}
+% \def\cnxlatex{CNX\LaTeX}
+% \def\mathml{{\scshape{MathML}}}
+% \def\latexml{\hbox{{\LaTeX}ML}}
+% \def\omdoc{OMDoc}
+% \def\activemath{{\scshape{ActiveMath}}}
+%
+% \title{Slides and Course Notes for Jacobs University\thanks{Version {\fileversion}
+% (last revised {\filedate})}}
+% \author{Michael Kohlhase\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% We present a document class from which we can generate both course slides and course
+% notes in a transparent way. Furthermore, we present a set of {\latexml} bindings for
+% these, so that we can also generate {\omdoc}-based course materials, e.g. for
+% inclusion in the {\activemath} system.
+% \end{abstract}
+% \tableofcontents\newpage
+%\section{Introduction}
+% This Document class is derived from |beamer.cls|, specializes it with Jacobs stuff and
+% adds a notes version that is more suited to printing than the one supplied by
+% |beamer.cls|.
+%
+%\section{The User Interface}\label{sec:user}
+% \StopEventually{\newpage\PrintChanges}
+%
+%\section{The Implementation}\label{sec:impl}
+%
+%\subsection{Initialization and Class Options}\label{sec:impl:init}
+%
+% For the {\latexml} bindings, we make sure the right perl packages are loaded.
+%
+% \begin{macrocode}
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+%</ltxml>
+% \end{macrocode}
+%
+% For {\LaTeX} we define some Package Options and switches for the |mikoslides| class and activate
+% them by passing them on to |beamer.cls| the appropriate packages.
+%
+% \begin{macrocode}
+%<*cls>
+\newif\ifnotes\notesfalse
+\newif\ifproblems\problemstrue
+\DeclareOption{notes}{\notestrue}
+\DeclareOption{slides}{\notesfalse}
+\DeclareOption{noproblems}{\problemsfalse}
+\ifnotes\else\DeclareOption*{\PassOptionsToClass{\CurrentOption}{beamer}}\fi
+\ProcessOptions
+%</cls>
+%<*ltxml>
+RawTeX('\newif\ifnotes\notesfalse');
+RawTeX('\newif\ifproblems\problemsfalse');
+%</ltxml>
+% \end{macrocode}
+%
+% Depending on the options, we either load the |article|-based |omdoc| or the |beamer| class. In the first
+% case, we also have to make the |beamer|-specific things available to |article| via the
+% |beamerarticle| package. We use options to avoid loading theorem-like environments,
+% since we want to use our own from the $\sTeX$ packages.
+% \begin{macrocode}
+%<*cls>
+\ifnotes
+\LoadClass{omdoc}
+\RequirePackage{a4wide}
+\RequirePackage[notheorems,noamsthm]{beamerarticle}
+\else
+\LoadClass[notheorems,noamsthm,10pt]{beamer}
+\newcounter{Item}
+\newcounter{paragraph}
+\newcounter{subparagraph}
+\newcounter{Hfootnote}
+\usetheme{Jacobs}
+\fi
+%</cls>
+%<*ltxml>
+LoadClass('omdoc');
+%</ltxml>
+% \end{macrocode}
+%
+% now, we load the remaining packages for both versions.
+%
+% \begin{macrocode}
+%<*cls>
+\RequirePackage{stex}
+\RequirePackage{latexml}
+\RequirePackage{amssymb}
+\RequirePackage{tikz}
+\usepgflibrary{shapes}\usetikzlibrary{arrows}
+\RequirePackage{url}
+\RequirePackage{amsmath}
+\RequirePackage{comment}
+%</cls>
+%<*ltxml>
+RequirePackage('stex');
+RequirePackage('latexml');
+RequirePackage('amssymb');
+RequirePackage('graphicx');
+RequirePackage('tikz');
+RequirePackage('amsmath');
+%</ltxml>
+% \end{macrocode}
+% \begin{oldpart}{we do not seem to load this any more, what to do
+% there?}% The |etex.sty| package is needed in the {\LaTeX}, since it makes the extended the number
+% of internal registers of the |etex| program available for processing. These tend to run
+% out with {\sTeX} otherwise.
+% \end{oldpart}
+%
+% \subsection{Notes and Slides}\label{sec:impl:noteslides}
+%
+% We define the sizes of slides in the notes. Somehow, we cannot get by with the same
+% here.
+%
+% \begin{macrocode}
+%<*cls>
+\newcounter{slide}
+\newlength{\slidewidth}\setlength{\slidewidth}{13.5cm}
+\newlength{\slideheight}\setlength{\slideheight}{9cm}
+%</cls>
+%<*ltxml>
+DefRegister('\slidewidth' => Dimension('13.5cm'));
+DefRegister('\slideheight' => Dimension('9cm'));
+%</ltxml>
+% \end{macrocode}
+%
+% For course notes, we define the |note| environment to be a no-operation otherwise we declare the |note| environment as
+% a comment via the |comment| package.
+%
+% \begin{environment}{note}
+% \begin{macrocode}
+%<*cls>
+\ifnotes\renewenvironment{note}{}{}\else\excludecomment{note}\fi
+%</cls>
+%<*ltxml>
+DefEnvironment('{note}','#body');
+%</ltxml>
+% \end{macrocode}
+% \end{environment}
+%
+%
+% the next step is to set up the slide boxes in |article| mode. We set up sizes and
+% provide a box register for the frames and a counter for the slides.
+%
+% \begin{macrocode}
+%<*cls>
+\ifnotes
+\newlength{\slideframewidth}\setlength{\slideframewidth}{2pt}
+\newsavebox{\myframebox}
+%</cls>
+% \end{macrocode}
+%
+% \begin{environment}{frame}
+% For the |frame| environment we construct a |lrbox| in the |\myframebox| register that
+% we can later put into an |\fbox| so that it looks like a slide. Furthermore, we
+% redefine the |itenize| environment so that it looks more like the one in |beamer| with
+% |Jacobs| theme.
+% \begin{macrocode}
+%<*cls>
+\renewenvironment{frame}[1][]%
+{\stepcounter{slide}
+\def\itemize@level{outer}
+\def\itemize@outer{outer}
+\def\itemize@inner{inner}
+\renewenvironment{itemize}
+{\ifx\itemize@level\itemize@outer\def\itemize@label{$\rhd$}\fi
+ \ifx\itemize@level\itemize@inner\def\itemize@label{$\scriptstyle\rhd$}\fi
+ \begin{list}
+ {\itemize@label}
+ {\setlength{\labelsep}{.3em}\setlength{\labelwidth}{.5em}\setlength{\leftmargin}{1.5em}}
+ \edef\itemize@level{\itemize@inner}}
+{\end{list}}
+ \noindent\hfill\begin{lrbox}{\myframebox}
+ \begin{minipage}{\slidewidth}\sf}%
+ {\miko@slidelabel\end{minipage}\end{lrbox}%
+ \begin{center}\fbox{\usebox\myframebox}\end{center}\hfill}
+%</cls>
+%<*ltxml>
+DefEnvironment('{frame}[]',
+ "<omdoc:omgroup layout='slide' ?#locator(stex:srcref='#locator')()>"
+ . "#body\n"
+ ."</omdoc:omgroup>\n\n",
+ afterDigestBegin=>sub {
+ $_[1]->setProperty(theory=>LookupValue('current_module')); });
+%</ltxml>#$
+% \end{macrocode}
+% \end{environment}
+%
+% the next step is to set up the slide boxes in |article| mode.
+%
+% \begin{macrocode}
+%<*cls>
+\renewcommand{\frametitle}[1]{{\Large\bf\sf\color{blue}{#1}}}
+\fi
+\makeindex
+%</cls>
+%<*ltxml>
+DefConstructor('\frametitle{}',
+ "\n<omdoc:metadata ?#locator(stex:srcref='#locator')()><dc:title>#1</dc:title></omdoc:metadata>");
+%</ltxml>
+% \end{macrocode}
+%
+% We start by giving the {\latexml} binding for the |frame| environment from the |beamer|
+% class. The |note| environment is used to blend out text in the |slides| mode. It does
+% not have a counterpart in OMDoc.
+%
+% \begin{macrocode}
+%<*cls>
+\ifproblems\newenvironment{problems}{}{}\else\excludecomment{problems}\fi
+%</cls>
+%<*ltxml>
+DefEnvironment('{problems}','#body');
+%</ltxml>
+% \end{macrocode}
+%\ednote{subtitle is difficult to model in DC metadata. I guess that we want to collect
+%the subtitle into dc:title}
+%
+% \subsection{Header and Footer Lines}\label{sec:impl:headfootlines}
+%
+% Now, we set up the infrastructure for the footer line of the slides, we use boxes for
+% the logos, so that they are only loaded once, that considerably speeds up processing.
+% \begin{macrocode}
+%<*cls>
+\newlength{\slidelogoheight}
+\ifnotes\setlength{\slidelogoheight}{.4cm}\else\setlength{\slidelogoheight}{1cm}\fi
+\newsavebox{\slidelogo}\sbox{\slidelogo}{\includegraphics[height=\slidelogoheight]{jacobs-logo}}
+% \end{macrocode}
+%
+% Now, we set up the copyright and licensing, the copyright remains with the author, but
+% we use the Creative Commons Attribuition-ShareAlike license to strengthen den public
+% domain. Here the problem is that we want a hyperref on the CC logo, if hyperref is
+% loaded, and otherwise not. As hyperref is always loaded, we have to find out at the
+% beginning of the document whether it is, set up a switch, and later in the footer line
+% decide what to do.
+%
+% \begin{macrocode}
+\def\source{Michael Kohlhase}% customize locally
+\def\copyrightnotice{\footnotesize\copyright:\hspace{.3ex}{\source}}
+\newsavebox{\cclogo}\sbox{\cclogo}{\includegraphics[height=\slidelogoheight]{cc_somerights}}
+\newif\ifcchref\cchreffalse
+\AtBeginDocument{\@ifpackageloaded{hyperref}{\cchreftrue}{\cchreffalse}}
+\def\licensing{\ifcchref\href{http://creativecommons.org/licenses/by-sa/2.5/}{\usebox{\cclogo}}\else{\usebox{\cclogo}}\fi}
+% \end{macrocode}
+%
+% Now, we set up the slide label for the |article| mode\ednote{see that we can use the
+% themes for the slides some day. This is all fake.}
+%
+% \begin{macro}{\slidelabel}
+% \begin{macrocode}
+\newcommand{\miko@slidelabel}%
+{\vbox to \slidelogoheight{\vss\hbox to \slidewidth%
+{\licensing\hfill\copyrightnotice\hfill\arabic{slide}\hfill\usebox{\slidelogo}}}}
+%</cls>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Colors and Highlighting}\label{sec:impl:highlighting}
+%
+% Now, we set up an infrastructure for highlighting phrases in slides. Note that we use
+% content-oriented macros for highlighting rather than directly using color markup.
+% The first thing to to is to adapt the green so that it is dark enough for most beamers
+% \begin{macrocode}
+%<*cls>
+\AtBeginDocument{\definecolor{green}{rgb}{0,.5,0}\definecolor{purple}{cmyk}{.3,1,0,.17}}
+% \end{macrocode}
+%
+% We customize the |\defemph|, |\notemph|, and |\stDMemph| macros with colors for the use
+% in the |statements| package. Furthermore we customize the |\@@lec| macro for the
+% appearance of line end comments in |\lec|.
+%
+% \begin{macrocode}
+\def\defemph#1{{\textcolor{magenta}{#1}}}
+\def\notemph#1{{\textcolor{magenta}{#1}}}
+\def\stDMemph#1{{\textcolor{blue}{#1}}}
+\def\@@lec#1{(\textcolor{green}{#1})}
+%</cls>
+%<*ltxml>
+#DefMacro('\defemph{}','{\textcolor{magenta}{#1}}');
+#DefMacro('\notemph{}','{\textcolor{magenta}{#1}}');
+%</ltxml>
+% \end{macrocode}
+%
+% I like to use the dangerous bend symbol for warnings, so we provide it here.
+% \begin{macrocode}
+%<*cls>
+\def\textwarning{\raisebox{-.05cm}{\includegraphics[width=1.2em]{dangerous-bend}}\xspace}
+%</cls>
+%<*ltxml>
+DefMacro('\textwarning',"");
+%</ltxml>
+% \end{macrocode}
+% Now, we specialize the slide environment that we have implemented above or inherited
+% from |seminar.cls| for some abbreviations, e.g. separator slides and title slides.
+% \begin{macrocode}
+%<*cls>
+\newenvironment{ttitle}{\begin{center}\LARGE\begin{tabular}{|c|}\hline}%
+ {\\\hline\end{tabular}\end{center}\vspace{1ex minus 1ex}}
+\newenvironment{ttitlejoint}[1]%
+{\newbox\boxwith\setbox\boxwith\hbox{\begin{tabular}{c}{\em joint work with}\\#1\end{tabular}}%
+\begin{center}\LARGE\begin{tabular}{c}\color{red}}%
+{\\\box\boxwith\end{tabular}\end{center}%
+\vspace{1ex minus 1ex}}
+%</cls>
+%<*ltxml>
+DefEnvironment('{titleslide}',"");
+DefEnvironment('{titleslide}',"<omdoc:omgroup ?#locator(stex:srcref='#locator')()>#body</omdoc:omgroup>");
+DefEnvironment('{ttitle}', "\n<Title>#body</Title>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+% Must be first command on slide to make positioning work.
+%<*cls>
+\newcommand{\putgraphicsat}[3]{%
+ \begin{picture}(0,0)\put(#1){\includegraphics[#2]{#3}}\end{picture}}
+\newcommand{\putat}[2]{%
+ \begin{picture}(0,0)\put(#1){#2}\end{picture}}
+%</cls>
+%<*ltxml>
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Miscellaneous}
+%
+% Some shortcuts that use math symbols but are not mathematical at all; in particular,
+% they should not be translated by {\latexml}.
+%
+% \begin{macrocode}
+%<*cls>
+\newcommand\hateq{\ensuremath{\hat=}}
+\newcommand\textleadsto{\ensuremath{\leadsto}}
+%</cls>
+%<*ltxml>
+DefConstructor('\hateq',"=\x{03C2}");
+DefConstructor('\textleadsto',"=\x{219D}");
+%</ltxml>
+% \end{macrocode}
+%
+% We need to disregard the columns macros introduced by the |beamer| class
+% \begin{macrocode}
+%<*ltxml>
+DefEnvironment('{columns}','#body');
+DefEnvironment('{column}{}','#body');
+%</ltxml>
+% \end{macrocode}
+%
+% We also need to deal with overlay specifications introduced by the |beamer|
+% class.\ednote{this is just to keep latexml quiet, no real functionality here.}
+%
+% \ednote{Deyan: We reuse the CMP itemizations defined in the omdoc.cls.ltxml binding,
+% adjusting the parameters to be overlay-sensitive }
+% \begin{macrocode}
+%<*ltxml>
+DefConstructor('\uncover','#1');
+#Define a Beamer Overlay Parameter type
+ DefParameterType('BeamerOverlay', sub {
+ my ($gullet) = @_;
+ my $tok = $gullet->readXToken;
+ if (ref $tok && ToString($tok) eq '<') {
+ $gullet->readUntil(T_OTHER('>'));
+ } else {
+ $gullet->unread($tok) if ref $tok;
+ undef; }},
+ reversion=> sub {
+ (T_OTHER('<'), $_[0]->revert, T_OTHER('>'));
+ });
+
+#Take the "from" field of the overlay range
+sub overlayFrom {
+ return "" unless defined $_[0];
+ my $overlay=ToString($_[0]); $overlay =~ /^(\d+)/; $1;}
+
+#Reuse the CMP itemizations, only adjust the \item constructors.
+DefMacro('\beamer@group@item[] OptionalBeamerOverlay IfBeginFollows', sub {
+ my($gullet,$tag,$overlay,$needwrapper)=@_;
+ $overlay=$overlay||T_OTHER("");
+ ( T_CS('\group@item@maybe@unwrap'),
+ ($needwrapper ? (Invocation(T_CS('\beamer@group@item@wrap'),$tag,$overlay)->unlist) : ()) ); });
+DefConstructor('\beamer@group@item@wrap {} OptionalBeamerOverlay',
+ "<omdoc:omtext ?#locator(stex:srcref='#locator')() ?#2(overlay='&overlayFrom(#2)')()>"
+ . "?#1(<dc:title>#1</dc:title>)()"
+ . "<omdoc:CMP ?#locator(stex:srcref='#locator')()><omdoc:p ?#locator(stex:srcref='#locator')()>",
+ beforeDigest=>sub {
+ Let('\group@item@maybe@unwrap','\group@item@unwrap');
+ #$_[0]->bgroup;
+ useCMPItemizations();
+ return; },
+ properties=>sub{ RefStepItemCounter(); });
+
+
+DefConstructor('\beamer@itemize@item[] OptionalBeamerOverlay',
+ "<omdoc:li ?#locator(stex:srcref='#locator')() ?#2(overlay='&overlayFrom(#2)')() >"
+ . "?#1(<dc:title ?#locator(stex:srcref='#locator')()>#1</dc:title>)()",
+ properties=>sub{ RefStepItemCounter(); });
+DefConstructor('\beamer@enumerate@item[] OptionalBeamerOverlay',
+ "<omdoc:li ?#locator(stex:srcref='#locator')() ?#2(overlay='&overlayFrom(#2)')() >"
+ . "?#1(<dc:title ?#locator(stex:srcref='#locator')()>#1</dc:title>)()",
+ properties=>sub{ RefStepItemCounter(); });
+DefConstructor('\beamer@description@item[] OptionalBeamerOverlay',
+ "<omdoc:di ?#locator(stex:srcref='#locator')() ?#2(overlay='&overlayFrom(#2)')() >"
+ . "?#1(<omdoc:dt ?#locator(stex:srcref='#locator')()>#1</omdoc:dt>)()<omdoc:dd>", # trust di and dt to autoclose
+ properties=>sub{ RefStepItemCounter(); });
+
+#We ALWAYS use the beamer itemizations for the slides:
+Let('\CMP@itemize@item'=>'\beamer@itemize@item');
+Let('\CMP@enumerate@item'=> '\beamer@enumerate@item');
+Let('\CMP@description@item'=> '\beamer@description@item');
+Let('\group@item' =>'\beamer@group@item');
+Let('\itemize@item'=>'\beamer@group@item');
+Let('\enumerate@item'=>'\beamer@group@item');
+Let('\description@item'=>'\beamer@group@item');
+Let('\only'=>'\beamer@group@item');
+%</ltxml>#$
+% \end{macrocode}
+% Now, some things that are imported from the |pgf| and |beamer| packages:
+% \begin{macrocode}
+%<*ltxml>
+DefMacro('\putgraphicsat{}{}{}','\mygraphics[#2]{#3}');
+DefMacro('\putat{}{}','#2');
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Finale}
+%
+% Finally, we set the slide body font to the sans serife, and we terminate the {\latexml}
+% bindings file with a success mark for perl.
+% \begin{macrocode}
+%<cls>\ifnotes\else\sf\fi
+%<ltxml>1;
+% \end{macrocode}
+% \Finale
+\endinput
+
+% \iffalse
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+
+% LocalWords: mikoslides dtx beamer omdoc notheorems noamsthm beamerarticle
+% LocalWords: graphicx slidelabel stex latexml amssymb tikz url CPERL amsmath
+% LocalWords: LoadClass RequirePackage DefRegister DefEnvironment omgroup rgb
+% LocalWords: afterDigestBegin setProperty LookupValue DefConstructor hyperref
+% LocalWords: cmyk lec DefMacro titleslide ttitle RawTeX metadata etoolbox
+% LocalWords: noproblems linkcolor bookmarksopen citecolor urlcolor colorlinks
+% LocalWords: breaklinks plainpages pdfpagelabels locator srcref
diff --git a/Master/texmf-dist/source/latex/stex/problem/problem.dtx b/Master/texmf-dist/source/latex/stex/problem/problem.dtx
new file mode 100644
index 00000000000..b1103449f1b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/problem/problem.dtx
@@ -0,0 +1,540 @@
+% \iffalse meta-comment
+% An Infrastructure for Problems
+% $URL: https://svn.kwarc.info/repos/stex-content/sty/problem/problem.dtx $
+% $Rev: 2674 $; last modified by $Author: deyan $
+% $Date: 2010-03-24 04:09:39 +0100 (Wed, 24 Mar 2010) $
+% Copyright (c) 2006-2008 Michael Kohlhase, all rights reserved
+% this file is released under the
+% LaTeX Project Public License (LPPL)
+% \fi
+%
+% \iffalse
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{problem}[2010/06/25 v0.9c Semantic Markup for Problems]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{url,float}
+\usepackage[show]{ed}
+\usepackage{latexml}
+\usepackage[solutions,hints,notes]{problem}
+\usepackage{hyperref}
+\makeindex
+\floatstyle{boxed}
+\newfloat{exfig}{thp}{lop}
+\floatname{exfig}{Example}
+\begin{document}\DocInput{problem.dtx}\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{1}
+%
+% \changes{v0.9}{2006/09/18}{First Version with Documentation}
+% \changes{v0.9a}{2007/01/02}{Renamed to \texttt{problem.sty}}
+% \changes{v0.9b}{2008/10/01}{added extraction}
+% \changes{v0.9c}{2010/01/03}{based on \texttt{omd.sty} now}
+%
+% \GetFileInfo{problem.sty}
+%
+% \MakeShortVerb{\|}
+%
+% \title{An Infrastructure for formatting Problems\thanks{Version {\fileversion} (last revised
+% {\filedate})}}
+% \author{Michael Kohlhase\\
+% Jacobs University, Bremen\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+% \begin{abstract}
+% The |problem| package supplies an infrastructure that allows specify problems and to
+% reuse them efficiently in multiple environments.
+% \end{abstract}
+% \setcounter{tocdepth}{2}\tableofcontents\newpage
+%
+%\section{Introduction}\label{sec:intro}
+%
+% The |problem| package supplies an infrastructure that allows specify problem. Problems
+% are text fragments that come with auxiliary functions: hints, notes, and
+% solutions\footnote{for the momenet multiple choice problems are not supported, but may
+% well be in a future version}. Furthermore, we can specify how long the solution to a
+% given problem is estimated to take and how many points will be awarded for a perfect
+% solution.
+%
+% Finally, the |problem| package facilitates the management of problems in small files,
+% so that problems can be re-used in multiple environment.
+%
+% \section{The User Interface}\label{sec:ui}
+%
+% \subsection{Package Options}
+% The |problem| package takes the options \DescribeMacro{solutions}|solutions| (should
+% solutions be output?), \DescribeMacro{notes}|notes| (should the problem notes be
+% presented?), \DescribeMacro{hints}|hints| (do we give the hints?),
+% \DescribeMacro{pts}|pts| (do we display the points awarded for solving the problem?),
+% \DescribeMacro{min}|min| (do we display the estimated minutes for problem soling). If
+% theses are specified, then the corresponding auxiliary parts of the problems are output,
+% otherwise, they remain invisible.
+%
+% The \DescribeMacro{boxed} option specifies that problems should be formatted in framed
+% boxes so that they are more visible in the text. Finally, the \DescribeMacro{test}|test|
+% option signifies that we are in a test sitution, so this option does not show the
+% solutions (of course), but leaves space for the students to solve them.
+%
+% The \DescribeMacro{extract}|extract| option can be set if we want to extract a problems
+% file, e.g. to display the solutions, see Section~\ref{sec:user:includeproblem} for a
+% discussion.
+%
+% \subsection{Problems and Solutions}\label{sec:user:probsols}
+%
+% \DescribeEnv{problem} The main enviornment provided by the |problem| package is
+% (surprise surprise) the |problem| environment. It is used to mark up problems and
+% excercises. The environment takes an optional KeyVal argument with the keys
+% \DescribeMacro{id}|id| as an identifier that can be reference later,
+% \DescribeMacro{pts}|pts| for the points to be gained from this exercise in homework or
+% quiz situations, \DescribeMacro{min}|min| for the estimated minutes needed to solve the
+% problem, and finally \DescribeMacro{title}|title| for an informative title of the
+% problem. For an example of a marked up problem see Figure~\ref{fig:problem} and the
+% resulting markup see Figure~\ref{fig:result}.
+%
+%\begin{exfig}
+% \begin{verbatim}
+% \usepackage[solutions,hints,pts,min]{problem}
+% \begin{document}
+% \begin{problem}[id=elefants,pts=10,min=2,title=Fitting Elefants]
+% How many Elefants can you fit into a Volkswagen beetle?
+% \begin{hint} Think positively, this is simple!\end{hint}
+% \begin{exnote}Justify your answer\end{exnote}
+% \begin{solution}[for=elefants,height=3cm]
+% Four, two in the front seats, and two in the back.
+% \end{solution}
+% \end{problem}
+% \end{document}
+% \end{verbatim}
+% \caption{A marked up Problem}\label{fig:problem}
+% \end{exfig}
+%
+% \DescribeEnv{solution} The |solution| environment can be to specify a solution to a
+% problem. If the \DescribeMacro{solutions}|solutions| option is set or |\solutionstrue|
+% is set in the text, then the solution will be presented in the output. The |solution|
+% environment takes an optional KeyVal argument with the keys \DescribeMacro{id}|id| for
+% an identifier that can be reference \DescribeMacro{for}|for| to specify which problem
+% this is a solution for, and \DescribeMacro{height}|height| that allows to specify the
+% amount of space to be left in test situations (i.e. if the \DescribeMacro{test}|test|
+% option is set in the |\usepackage| statement).
+%
+%\begin{exfig}
+% \begin{minipage}{.9\linewidth}
+% \begin{problem}[id=elefants.prob,title=Fitting Elefants]
+% How many Elefants can you fit into a Volkswagen beetle?
+% \begin{hint} Think positively, this is simple!\end{hint}
+% \begin{exnote}Justify your answer\end{exnote}
+% \begin{solution}%[for=elefants.prob,height=3cm]
+% Four, two in the front seats, and two in the back.
+% \end{solution}
+% \end{problem}
+% \end{minipage}
+% \caption{The Formmatted Problem from Figure~\ref{fig:problem}}\label{fig:result}
+% \end{exfig}
+%
+% \DescribeEnv{hint}\DescribeEnv{note}, the |hint| and |exnote| environments can be used
+% in a |problem| enviroment to give hints and to make notes that elaborate certain aspects
+% of the problem.
+%
+% \subsection{Including Problems}\label{sec:user:includeproblem}
+%
+% The \DescribeMacro{\includeproblem}|\includeproblem| macro can be used to include a
+% problem from another file. It takes an optional KeyVal argument and a second argument
+% which is a path to the file containing the problem (the macro assumes that there is only
+% one problem in the include file). The keys \DescribeMacro{title}|title|,
+% \DescribeMacro{min}|min|, and \DescribeMacro{pts}|pts| specify the problem title, the
+% estimated minutes for solving the problem and the points to be gained, and their values
+% (if given) overwrite the ones specified in the |problem| environment in the included
+% file.
+%
+% Sometimes we want to collect all the included problems into a separate file that can be
+% typeset independently. The main application is to have course notes into which the
+% problems are included (usually in boxed form to distinguish them from the rest of the
+% text and without solutions) and to have the problems with solutions in a separate file
+% (to encourage students to try and solve the problems before looking up solutions). In
+% this situation set the \DescribeMacro{extract}|extract| option on the notes file
+% \meta{notes}|.tex|, which causes a file \meta{notes}|-solutions.tex| to be generated
+% that has the |\includeproblem| statements with the respective numbers from the main
+% document. This can then be imported into a document with the respective front and
+% backmatter. In particular the frontmatter of the importing will ususlly specify the
+% \DescribeMacro{solutions}|solutions| option to generate solutions.
+%
+% \subsection{Reporting Metadata}\label{sec:user:reporting}
+%
+% The sum of the points and estimated minutes (that we specified in the |pts| and |min|
+% keys to the |problem| environment or the |\includeproblem| macro) to the log file and
+% the screen after each run. This is useful in preparing exams, where we want to make sure
+% that the students can indeed solve the problems in an alotted time period.
+%
+% The |\min| and |\pts| macros allow to specify (i.e. to print to the margin) the
+% distribution of time and reward to parts of a problem, if the |pts| and |pts| package
+% options are set. This allows to give students hints about the estimated time and the
+% points to be awarded.
+%
+% \StopEventually{\newpage\PrintChanges}
+% \newpage
+%
+% \section{The Implementation}\label{sec:implementation}
+%
+% \subsection{Package Options}\label{sec:impl:options}
+%
+% The first step is to declare (a few) package options that handle whether certain
+% information is printed or not. They all come with their own conditionals that are set by
+% the options.
+%
+% \begin{macrocode}
+%<*package>
+\newif\ifexnotes\exnotesfalse\DeclareOption{notes}{\exnotestrue}
+\newif\ifhints\hintsfalse\DeclareOption{hints}{\hintstrue}
+\newif\ifsolutions\solutionsfalse\DeclareOption{solutions}{\solutionstrue}
+\newif\ifpts\ptsfalse\DeclareOption{pts}{\ptstrue}
+\newif\ifmin\minfalse\DeclareOption{min}{\mintrue}
+\newif\ifboxed\boxedfalse\DeclareOption{boxed}{\boxedtrue}
+\newif\ifextract\extractfalse\DeclareOption{extract}{\extracttrue}
+\ProcessOptions
+%</package>
+% \end{macrocode}
+%
+% Then we make sure that the necessary packages are loaded (in the right versions).
+% \begin{macrocode}
+%<*package>
+\RequirePackage{keyval}[1997/11/10]
+\RequirePackage{xcomment}
+\RequirePackage{sref}
+%</package>
+% \end{macrocode}
+%
+% Here comes the equivalent header information for {\LaTeXML}, we also initialize the
+% package inclusions. Since {\LaTeXML} currently does not process package options, we have
+% nothing to do.
+% \begin{macrocode}
+%<*ltxml>
+# -*- CPERL -*-
+package LaTeXML::Package::Pool;
+use strict;
+use LaTeXML::Package;
+RequirePackage('sref');
+%</ltxml>
+% \end{macrocode}
+%
+% Then we register the namespace of the requirements ontology
+% \begin{macrocode}
+%<*ltxml>
+RegisterNamespace('prob'=>"http://omdoc.org/ontology/problems#");
+RegisterDocumentNamespace('prob'=>"http://omdoc.org/ontology/problems#");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Problems and Solutions}\label{sec:impl:probsols}
+%
+% We now prepare the KeyVal support for problems. The key macros just set appropriate
+% internal macros.
+%
+% \begin{macrocode}
+%<*package>
+\srefaddidkey[prefix=prob.]{problem}
+\omdaddkey{problem}{pts}
+\omdaddkey{problem}{min}
+\omdaddkey{problem}{title}
+\omdaddkey{problem}{refnum}
+% \end{macrocode}
+%
+% Then we set up a box and a counter for problems
+%
+% \begin{macrocode}
+\newsavebox{\probbox}
+\newcounter{problem}[section]
+% \end{macrocode}
+%
+% \begin{macro}{\prob@number}
+% We consolidate the problem number into a reusable internal macro
+% \begin{macrocode}
+\def\prob@number{\ifx\inclprob@refnum\@empty
+\ifx\problem@refnum\@empty\thesection.\theproblem\else\problem@refnum\fi
+\inclprob@refnum\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% We consolidate the problem header line into a separate internal macro that can be reused
+% in various settings.
+%
+% \begin{macro}{\prob@heading}
+% We consolidate the problem header line into a separate internal macro that can be
+% reused in various settings.
+% \begin{macrocode}
+\def\prob@heading{Problem \prob@number%
+\ifx\sref@id\@empty\else{\sref@label@id{Problem \thesection.\theproblem}}\fi%
+\ifx\inclprob@title\@empty% if there is no outside title
+\ifx\problem@title\@empty{:\quad}\else{\quad(\problem@title)\hfill\\}\fi
+\else\quad(\inclprob@title)\hfill\\\fi}% else show the outside title
+% \end{macrocode}
+% \end{macro}
+%
+% With this in place, we can now define the |problem| environment. It comes in two shapes,
+% depending on whether we are in boxed mode or not. In both cases we increment the problem
+% number and output the points and minutes (depending) on whehter the respective options
+% are set.
+% \begin{environment}{problem}
+% \begin{macrocode}
+\ifboxed
+\newenvironment{problem}[1][]{\omdsetkeys{problem}{#1}\sref@target%
+\stepcounter{problem}\show@pts\show@min\record@problem%
+\begin{lrbox}{\probbox}\begin{minipage}{.9\textwidth}}
+{\end{minipage}\end{lrbox}
+\setbox0=\hbox{\begin{minipage}{.9\textwidth}%
+\noindent\textbf\prob@heading\rm%
+\end{minipage}}
+\smallskip\noindent\fbox{\vbox{\box0\vspace*{.2em}\usebox\probbox}}\smallskip}
+\else
+\newenvironment{problem}[1][]{\omdsetkeys{problem}{#1}\sref@target%
+\stepcounter{problem}\show@pts\show@min\record@problem%
+\par\noindent\textbf\prob@heading\rm}
+{\smallskip}
+\fi%boxed
+%</package>
+% \end{macrocode}
+% \end{environment}
+%
+% Note that we allow hints and solutions in the body of a |problem| environment so we have
+% to allow the |omdoc:CMP| and |omdoc:p| elements to autoclose.
+%
+% \begin{macrocode}
+%<*ltxml>
+DefCMPEnvironment('{problem} OptionalKeyVals:problem',
+ "<omdoc:exercise ?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')()"
+ . "prob:dummy='for the namespace'"
+ . "?#locator(stex:srcref='#locator')()>"
+ . "?&KeyVal(#1,'title')(<dc:title ?#locator(stex:srcref='#locator')()>&KeyVal(#1,'title')</dc:title>)()"
+ . "?&KeyVal(#1,'min')(<omdoc:meta property='prob:solvedinminutes' "
+ . "?#locator(stex:srcref='#locator')()>&KeyVal(#1,'min')</omdoc:meta>)()"
+ . "?&KeyVal(#1,'pts')(<omdoc:meta property='prob:points' "
+ . "?#locator(stex:srcref='#locator')()>&KeyVal(#1,'pts')</omdoc:meta>)()"
+ . "<omdoc:CMP ?#locator(stex:srcref='#locator')()><omdoc:p>#body"
+ ."</omdoc:exercise>\n");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macro}{\record@problem}
+% This macro records information about the problems in the |*.aux| file.
+% \begin{macrocode}
+%<*package>
+\def\record@problem{\protected@write\@auxout{}%
+{\string\@problem{\prob@number}%
+{\ifx\inclprob@pts\@empty\problem@pts\else\inclprob@pts\fi}%
+{\ifx\inclprob@min\@empty\problem@min\else\inclprob@min\fi}}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@problem}
+% This macro acts on a problem's record in the |*.aux| file. It does not have any
+% functionality here, but can be redefined elsewhere (e.g. in the |assignment|
+% package).
+% \begin{macrocode}
+%<*package>
+\def\@problem#1#2#3{}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% The |solution| environment is similar to the |problem| environment, only that it is
+% independent of the boxed mode. It also has it's own keys that we need to define first.
+%
+% \begin{macrocode}
+%<*package>
+\define@key{soln}{id}{\def\soln@id{#1}}
+\define@key{soln}{for}{\def\soln@for{#1}}
+\define@key{soln}{height}{\def\soln@height{#1}}
+\ifsolutions
+\newenvironment{solution}[1][]%
+{\hrule\smallskip{\bf Solution: }\begin{small}}%
+{\hrule\end{small}}
+\else\newxcomment[]{solution}\fi
+% \newsavebox{\solution@box}
+% \newlength{\solution@width}
+% \setlength{\solution@width}{14cm}
+% \newenvironment{solution}[1][]%
+% {\begin{lrbox}{\solution@box}\begin{minipage}{\solution@width}
+% \hrule\smallskip{\bf Solution: }\small}
+% {\smallskip\hrule\end{minipage}\end{lrbox}
+% \ifsolutions\begin{center}\usebox{\solution@box}\end{center}\fi}
+%</package>
+%<*ltxml>
+DefKeyVal('soln','id','Semiverbatim');
+DefKeyVal('soln','height','Semiverbatim');
+DefKeyVal('soln','for','Semiverbatim');
+DefCMPEnvironment('{solution} OptionalKeyVals:soln',
+ "<omdoc:solution ?&KeyVals(#1,'for')(for='&KeyVal(#1,'for')')() ?#locator(stex:srcref='#locator')()>"
+ . "#body"
+ . "</omdoc:solution>");
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ifexnotes
+\newenvironment{exnote}[1][]%
+{\par\noindent\hrule\smallskip{\bf Note: }\small}
+{\smallskip\hrule}
+\else%ifexnotes
+\newxcomment[]{exnote}
+\fi%ifexnotes
+\ifhints
+\newenvironment{hint}[1][]%
+{\par\noindent\hrule\smallskip{\bf Hint: }\small}
+{\smallskip\hrule}
+\else%ifhints
+\newxcomment[]{hint}
+\fi%ifhints
+%</package>
+%<*ltxml>
+DefCMPEnvironment('{exnote}',
+ "<omdoc:hint ?#locator(stex:srcref='#locator')()>"
+ . "<omdoc:CMP ?#locator(stex:srcref='#locator')()>"
+ . "<omdoc:p>#body<omdoc:p>"
+ . "</omdoc:CMP>"
+ ."</omdoc:hint>");
+DefCMPEnvironment('{hint}',
+ "<omdoc:hint ?#locator(stex:srcref='#locator')()>"
+ . "<omdoc:CMP ?#locator(stex:srcref='#locator')()>"
+ . "<omdoc:p>#body</omdoc:p>"
+ . "</omdoc:CMP>"
+ ."</omdoc:hint>");
+DefConstructor('\pts{}',"");
+DefConstructor('\min{}',"");
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Including Problems}\label{sec:impl:includeproblem}
+%
+% The first action is to make a \meta{jobname}|-problems.tex| file, if the |extract|
+% option is set.
+%
+% \begin{macrocode}
+%<*package>
+\ifextract
+\newwrite\problem@file
+\immediate\openout\problem@file=\jobname-problems.tex
+\AtEndDocument{\closeout\problem@file}
+\fi
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{\includeproblem}
+% The |\includeproblem| command is essentially a glorified |\input| statement, it sets
+% some internal macros first that overwrite the local points. After that (so that the
+% included problem had time to step the problem number) it writes the |\includeproblem|
+% statement to the problems file, if the |extract| option is set. Here we add a key
+% |refnum=\prob@num| to the inlcudeproblem, so that we can remember the number from the
+% main document.\ednote{do something about the overwriting of problem metadata in the
+% {\LaTeXML} binding.}
+%
+% \begin{macrocode}
+%<*package>
+\omdaddkey{inclprob}{pts}
+\omdaddkey{inclprob}{min}
+\omdaddkey{inclprob}{title}
+\omdaddkey{inclprob}{refnum}
+\clear@inclprob@keys
+\newcommand{\includeproblem}[2][]{%
+\bgroup\omdsetkeys{inclprob}{#1}\input{#2}\ifsolutions\newpage\fi\egroup
+\ifextract\def\@test{#1}
+\def\prob@num{\ifx\inclprob@refnum\@empty\thesection.\theproblem\else\inclprob@refnum\fi}
+\def\inclprob@keys{#1\ifx\@test\@empty\else,\fi refnum=\prob@num}
+\protected@write\problem@file{}{\string\includeproblem[\inclprob@keys]{#2}}
+\fi}
+%</package>
+%<*ltxml>
+DefKeyVal('prob','pts','Semiverbatim');
+DefKeyVal('prob','min','Semiverbatim');
+DefKeyVal('prob','title','Semiverbatim');
+DefConstructor('\includeproblem OptionalKeyVals:prob Semiverbatim',
+ "<omdoc:ref xref='#2' ?#locator(stex:srcref='#locator')() "
+ . "prob:dummy='for the namespace'>"
+ . "?&KeyVal(#1,'title')(<dc:title ?#locator(stex:srcref='#locator')()>&KeyVal(#1,'title')</dc:title>)()"
+ . "?&KeyVal(#1,'min')(<omdoc:meta property='prob:solvedinminutes' "
+ . "?#locator(stex:srcref='#locator')()>&KeyVal(#1,'min')</omdoc:meta>)()"
+ . "?&KeyVal(#1,'pts')(<omdoc:meta property='prob:points' "
+ . "?#locator(stex:srcref='#locator')()>&KeyVal(#1,'pts')</omdoc:meta>)()"
+ ."</omdoc:ref>");
+%</ltxml>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<*ltxml>
+Tag('omdoc:exercise',afterOpen=>\&numberIt);
+Tag('omdoc:solution',afterOpen=>\&numberIt);
+Tag('omdoc:hint',afterOpen=>\&numberIt);
+%</ltxml>
+% \end{macrocode}
+%
+% \subsection{Reporting Metadata}
+%
+% \begin{macrocode}
+%<*package>
+\def\pts#1{\ifpts\marginpar{#1 pt}\fi}
+\def\min#1{\ifmin\marginpar{#1 min}\fi}
+%</package>
+%<*ltxml>
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\AtEndDocument{\ifpts\message{Total: \arabic{pts} points}\fi
+\ifmin\message{Total: \arabic{min} minutes}\fi}
+%</package>
+%<*ltxml>
+%</ltxml>
+% \end{macrocode}
+%
+% \begin{macro}{\show@pts}
+% The |\show@pts| shows the points: if no points are given from the outside and also no
+% points are given locally do nothing, else show and add. If there are outside points
+% then we show them in the margin.
+% \begin{macrocode}
+%<*package>
+\newcounter{pts}
+\def\show@pts{\ifx\inclprob@pts\@empty%
+\ifx\problem@pts\@empty\else%
+\ifpts\marginpar{\problem@pts pt\smallskip}\addtocounter{pts}{\problem@pts}\fi%
+\fi\else%
+\ifpts\marginpar{\inclprob@pts pt\smallskip}\addtocounter{pts}{\inclprob@pts}\fi%
+\fi}
+% \end{macrocode}
+% \end{macro}
+% and now the same for the minutes
+% \begin{macro}{\show@min}
+% \begin{macrocode}
+\newcounter{min}
+\def\show@min{\ifx\inclprob@min\@empty%
+\ifx\problem@min\@empty\else%
+\ifmin\marginpar{\problem@min min}\addtocounter{min}{\problem@min}\fi%
+\fi\else%
+\ifmin\marginpar{\inclprob@min min}\addtocounter{min}{\inclprob@min}\fi
+\fi}
+%</package>
+% \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
+
+% \iffalse
+% LocalWords: GPL structuresharing STR dtx pts keyval xcomment CPERL DefKeyVal
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+% LocalWords: RequirePackage Semiverbatim DefEnvironment OptionalKeyVals soln
+% LocalWords: exnote DefConstructor inclprob
diff --git a/Master/texmf-dist/source/latex/stex/xsl/ltxml2cnx.xsl b/Master/texmf-dist/source/latex/stex/xsl/ltxml2cnx.xsl
new file mode 100644
index 00000000000..9f854abee37
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/xsl/ltxml2cnx.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ltx="http://dlmf.nist.gov/LaTeXML"
+ xmlns='http://cnx.rice.edu/cnxml'
+ xmlns:m='http://www.w3.org/1998/Math/MathML'
+ xmlns:md="http://cnx.rice.edu/mdml/0.4"
+ xmlns:bib="http://bibtexml.sf.net/"
+ exclude-result-prefixes="ltx md bib"
+ version="1.0">
+
+ <xsl:output method="xml" indent="yes"
+ doctype-public="-//CNX//DTD CNXML 0.5 plus MathML//EN"
+ doctype-system="http://cnx.rice.edu/cnxml/0.5/DTD/cnxml_mathml.dtd"/>
+
+ <xsl:strip-space elements="*"/>
+
+<!-- if there is no other template, give a warning -->
+<!-- <xsl:template match="*">
+ <xsl:message>Cannot deal with element <xsl:value-of select="local-name()"/> yet! (id=<xsl:value-of select="@xml:id"/>)</xsl:message>
+ <xsl:comment>elided element <xsl:value-of select="local-name()"/></xsl:comment>
+ </xsl:template> -->
+
+ <xsl:template match="*">
+ <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="ltx:Math">
+ <xsl:copy-of select="m:math"/>
+ </xsl:template>
+
+<xsl:template match="ltx:*">
+ <xsl:element name="{local-name()}">
+ <xsl:copy-of select="@*"/><xsl:apply-templates/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="ltx:tabular">
+ <table>
+ <xsl:copy-of select="@*"/><xsl:apply-templates/>
+ </table>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/Master/texmf-dist/source/latex/stex/xsl/omdocpost.xsl b/Master/texmf-dist/source/latex/stex/xsl/omdocpost.xsl
new file mode 100644
index 00000000000..d49f692a387
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/xsl/omdocpost.xsl
@@ -0,0 +1,441 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- this style sheet transforms the tex.xml file to OMDoc -->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://omdoc.org/ns"
+ xmlns:omdoc="http://omdoc.org/ns"
+ xmlns:mcd="http://www.w3.org/ns/mathml-cd"
+ xmlns:ltx="http://dlmf.nist.gov/LaTeXML"
+ xmlns:stex="http://kwarc.info/ns/sTeX"
+ xmlns:m="http://www.w3.org/1998/Math/MathML"
+ xmlns:om="http://www.openmath.org/OpenMath"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="xsl omdoc ltx m om dc">
+
+<xsl:output method="xml" indent="yes" cdata-section-elements="data"/>
+<xsl:strip-space elements="*"/>
+
+<!-- these parameters set the paths to the special latexml cds. The default is made so that it works for GenCS -->
+<xsl:param name="latexmlcds" select="'../../../slides/extcds/stex'"/>
+<xsl:param name="omcds" select="'../../../slides/extcds/omstd'"/>
+
+<xsl:template match="/">
+ <xsl:comment>This OMDoc document is generated from an sTeX-encoded one via LaTeXML, you may want to reconsider editing it.</xsl:comment>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="omdoc:omdoc">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ <xsl:comment>The data elements</xsl:comment>
+ <xsl:apply-templates mode="extract-data"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="*">
+ <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
+</xsl:template>
+
+<xsl:template match="ltx:ERROR"/>
+<xsl:template match="*|text()" mode="extract-data">
+ <xsl:apply-templates mode="extract-data"/>
+</xsl:template>
+
+<xsl:template match="ltx:Math">
+ <xsl:apply-templates select="om:OMOBJ"/>
+</xsl:template>
+
+<!-- we directly access the content of titles -->
+<xsl:template match="ltx:title"/>
+<xsl:template match="ltx:chapter|ltx:part|ltx:section|ltx:subsection|ltx:subsubsection|ltx:paragraph">
+ <omgroup layout="sectioning">
+ <xsl:copy-of select="@*"/>
+ <metadata>
+ <dc:title><xsl:apply-templates select="ltx:title/*|ltx:title/text()"/></dc:title>
+ </metadata>
+ <xsl:apply-templates/>
+ </omgroup>
+</xsl:template>
+
+<xsl:template match="ltx:p">
+ <p><xsl:copy-of select="@*"/><xsl:apply-templates/></p>
+</xsl:template>
+
+<xsl:template match="ltx:para">
+ <omtext><xsl:copy-of select="@*"/><CMP><xsl:apply-templates/></CMP></omtext>
+</xsl:template>
+
+<xsl:template match="ltx:text">
+ <phrase>
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="@font">
+ <xsl:attribute name="class"><xsl:value-of select="@font"/></xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </phrase>
+</xsl:template>
+
+
+<xsl:template match="ltx:graphics|ltx:verbatim">
+ <omlet action="display" data="#{generate-id()}" show="embed" style="{translate(@options,'=',':')}">
+ <xsl:copy-of select="@*"/>
+ </omlet>
+</xsl:template>
+
+<xsl:template match="omdoc:tikz">
+ <omlet action="display" data="#{generate-id()}" show="embed" style="{translate(@options,'=',':')}">
+ <xsl:copy-of select="@*"/>
+ </omlet>
+</xsl:template>
+
+<!-- for citations we just extract the bibrefs at the moment. -->
+<xsl:template match="ltx:cite"><xsl:apply-templates select="ltx:bibref"/></xsl:template>
+<xsl:template match="ltx:bibref">
+ <xsl:for-each select="str:tokenize(@bibrefs,',')">
+ <ref type="cite" xref="{.}"/>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- we ignore LaTeXML breaks -->
+<xsl:template match="ltx:break"/>
+
+<xsl:template match="ltx:figure[ltx:graphics]">
+ <omlet action="display" data="#{generate-id(ltx:graphics)}" show="embed" class="float-figure-{@placement}">
+ <xsl:if test="@label">
+ <xsl:attribute name="xml:id"><xsl:value-of select="@label"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="ltx:graphics/@options">
+ <xsl:attribute name="style"><xsl:value-of select="translate(ltx:graphics/@options,'=',':')"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="ltx:caption/*|ltx:caption/text()">
+ <metadata><dc:title><xsl:apply-templates select="ltx:caption/*|ltx:caption/text()"/></dc:title></metadata>
+ </xsl:if>
+ </omlet>
+</xsl:template>
+
+<xsl:template match="ltx:graphics" mode="extract-data">
+ <private>
+ <xsl:attribute name="xml:id"><xsl:value-of select="generate-id()"/></xsl:attribute>
+ <xsl:variable name="sources" select="str:tokenize(@sources,',')"/>
+ <xsl:variable name="graphic" select="@graphic"/>
+ <xsl:for-each select="$sources">
+ <xsl:variable name="current" select="."/>
+ <xsl:variable name="type">
+ <xsl:choose>
+ <xsl:when test="$current='jpg'">
+ <xsl:value-of select="'image/jpeg'"/>
+ </xsl:when>
+ <xsl:when test="$current='jpeg'">
+ <xsl:value-of select="'image/jpeg'"/>
+ </xsl:when>
+ <xsl:when test="$current='png'">
+ <xsl:value-of select="'image/png'"/>
+ </xsl:when>
+ <xsl:when test="$current='gif'">
+ <xsl:value-of select="'image/gif'"/>
+ </xsl:when>
+ <xsl:when test="$current='eps'">
+ <xsl:value-of select="'application/postscript'"/>
+ </xsl:when>
+ <xsl:when test="$current='ps'">
+ <xsl:value-of select="'application/postscript'"/>
+ </xsl:when>
+ <xsl:when test="$current='ai'">
+ <xsl:value-of select="'application/postscript'"/>
+ </xsl:when>
+ <xsl:when test="$current='pdf'">
+ <xsl:value-of select="'application/pdf'"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$current"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <data format="{$type}" href="{$graphic}.{.}"/>
+ </xsl:for-each>
+ </private>
+</xsl:template>
+<xsl:template match="ltx:verbatim" mode="extract-data">
+ <private>
+ <xsl:attribute name="xml:id"><xsl:value-of select="generate-id()"/></xsl:attribute>
+ <data format="text"><xsl:value-of select="text()"/></data>
+ </private>
+</xsl:template>
+
+<xsl:template match="omdoc:tikz|ltx:tikz" mode="extract-data">
+ <private>
+ <xsl:attribute name="xml:id"><xsl:value-of select="generate-id()"/></xsl:attribute>
+ <data format="tikz"><xsl:value-of select="."/></data>
+ </private>
+</xsl:template>
+
+<!-- for LaTeXML tables -->
+<xsl:template match="ltx:tabular"><table><xsl:apply-templates/></table></xsl:template>
+<xsl:template match="ltx:tbody"><xsl:apply-templates/></xsl:template>
+<xsl:template match="ltx:tr"><tr><xsl:apply-templates/></tr></xsl:template>
+<xsl:template match="ltx:td"><td><xsl:apply-templates/></td></xsl:template>
+<xsl:template match="ltx:thead"><xsl:apply-templates/></xsl:template>
+
+<!-- for LaTeXML references from \url -->
+<xsl:template match="ltx:ref[@class='url']">
+ <link href="{@href}" class="url">
+ <xsl:value-of select="ltx:text"/>
+ </link>
+</xsl:template>
+
+<xsl:template match="ltx:ref[@labelref]">
+ <ref type="cite" xref="{@labelref}"/>
+</xsl:template>
+
+<!-- LaTeXML listings -->
+<xsl:template match="ltx:text[@class='listing']">
+ <omdoc:phrase type='progsnippet'><xsl:copy-of select="@*"/><xsl:apply-templates/></omdoc:phrase>
+</xsl:template>
+
+<xsl:template match="ltx:listingblock">
+ <omlet action='display' show='embed' style='display:block'>
+ <xsl:copy-of select="@*"/>
+ <code>
+ <data format='listingblock'><xsl:apply-templates mode="listing"/></data>
+ </code>
+ </omlet>
+</xsl:template>
+
+<xsl:template match="ltx:tabular" mode="listing">
+ <table class="listing"><xsl:apply-templates mode="listing"/></table>
+</xsl:template>
+
+<xsl:template match="ltx:tr" mode="listing">
+ <tr><xsl:apply-templates mode="listing"/></tr>
+</xsl:template>
+
+<xsl:template match="ltx:td" mode="listing">
+ <td><xsl:apply-templates mode="listing"/></td>
+</xsl:template>
+
+<xsl:template match="ltx:text[not(@*)]" mode="listing">
+ <xsl:apply-templates mode="listing"/>
+</xsl:template>
+
+<xsl:template match="ltx:text[@font='bold']" mode="listing">
+ <keyword><xsl:apply-templates mode="listing"/></keyword>
+</xsl:template>
+
+<xsl:template match="ltx:text[@color]" mode="listing">
+ <phrase>
+ <xsl:attribute name='type'><xsl:text>lstemph</xsl:text></xsl:attribute>
+ <xsl:attribute name='style'><xsl:text>color:</xsl:text><xsl:value-of select="@color"/></xsl:attribute>
+ <xsl:apply-templates mode="listing"/>
+ </phrase>
+</xsl:template>
+
+<xsl:template match="ltx:text[@class]" mode="listing">
+ <xsl:apply-templates mode="listing"/>
+</xsl:template>
+
+
+<xsl:template match="ltx:*" mode="listing">
+ <xsl:message>cannot deal with element <xsl:value-of select="local-name()"/> yet!</xsl:message>
+</xsl:template>
+
+
+<xsl:template match="ltx:equation">
+ <om:OMOBJ style="display:block">
+ <xsl:apply-templates select="ltx:Math/om:OMOBJ/*"/>
+ </om:OMOBJ>
+</xsl:template>
+
+<!-- equationgroups come from eqnarray and eqnarray*, they really need OMDoc-level parallel markup -->
+<xsl:template match="ltx:equationgroup">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="ltx:equationgroup/ltx:equation">
+ <om:OMOBJ style="display:block">
+ <xsl:apply-templates select="ltx:MathFork/ltx:Math/om:OMOBJ/*"/>
+ </om:OMOBJ>
+</xsl:template>
+
+
+<!-- for notations -->
+<xsl:template match="omdoc:rendering">
+ <xsl:apply-templates select="." mode="rendering"/>
+</xsl:template>
+<xsl:template match="ltx:Math" mode="rendering">
+ <xsl:apply-templates select="m:math/*" mode="rendering"/>
+</xsl:template>
+
+<!-- copy where not specified otherwise -->
+<xsl:template match="*" mode="rendering">
+ <xsl:copy><xsl:copy-of select="@*[not(name()='argprec')]"/><xsl:apply-templates mode="rendering"/></xsl:copy>
+</xsl:template>
+
+<xsl:template match="ltx:text" mode="rendering">
+ <text><xsl:value-of select="text()"/></text>
+</xsl:template>
+
+<!-- Template to recover the appropriate argument precedence" -->
+<xsl:template name="argument-precedence">
+ <xsl:param name="count" select="1"/>
+ <xsl:param name="precattr" select="1"/>
+ <xsl:choose>
+ <xsl:when test="$count > 1">
+ <xsl:call-template name="argument-precedence">
+ <xsl:with-param name="count" select="$count - 1"/>
+ <xsl:with-param name="precattr" select="substring-after($precattr,' ')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-before($precattr,' ')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- we have to treat the m:mi that come from an
+ #i argument invocation differently -->
+<xsl:template match="m:mi[starts-with(.,'arg:')]|m:mo[starts-with(.,'arg:')]" mode="rendering">
+ <xsl:variable name="precedence">
+ <xsl:call-template name="argument-precedence">
+ <xsl:with-param name="count" select="substring-after(.,'arg:')"/>
+ <xsl:with-param name="precattr" select="ancestor::omdoc:rendering[1]/@argprec"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <render name="arg{substring-after(.,'arg:')}">
+ <xsl:choose>
+ <xsl:when test="string($precedence)">
+ <xsl:attribute name="precedence"><xsl:value-of select="$precedence"/></xsl:attribute>
+ </xsl:when>
+ <xsl:when test="string(ancestor::omdoc:rendering[1]/@precedence)">
+ <xsl:attribute name="precedence"><xsl:value-of select="ancestor::omdoc:rendering[1]/@precedence"/></xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise/>
+ </xsl:choose>
+ </render>
+</xsl:template>
+
+
+<!-- make an mrow around the generated things. -->
+<xsl:template match="omdoc:style[@format='pmml']">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <element name="mrow" ns="http://www.w3.org/1998/Math/MathML">
+ <xsl:apply-templates/>
+ </element>
+ </xsl:copy>
+</xsl:template>
+
+
+<xsl:template match="omdoc:separator/ltx:Math">
+ <xsl:apply-templates select="m:math/*" mode="elementize"/>
+</xsl:template>
+
+<xsl:template match="omdoc:map/ltx:Math">
+ <xsl:apply-templates select="m:math/*" mode="elementize"/>
+</xsl:template>
+
+
+<xsl:template match="text()" mode="elementize">
+ <text><xsl:value-of select="."/></text>
+</xsl:template>
+
+<xsl:template match="ltx:text" mode="elementize">
+ <element name="mtext" ns="http://www.w3.org/1998/Math/MathML">
+ <xsl:value-of select="."/>
+ </element>
+</xsl:template>
+
+<xsl:template match="m:*" mode="elementize">
+ <element name="{local-name()}" ns="{namespace-uri()}">
+ <xsl:for-each select="@*">
+ <attribute name="{local-name()}" select="'{.}'"/>
+ </xsl:for-each>
+ <xsl:apply-templates mode="elementize"/>
+ </element>
+</xsl:template>
+
+<!-- get rid of the list OMAs LaTeXML uses -->
+<xsl:template match="om:OMA[om:OMS[position()=1 and @name='list' and @cd='latexml']]">
+ <xsl:apply-templates select="*[position() &gt; 1]"/>
+</xsl:template>
+
+<!-- special treatment for latexml symbols -->
+<!-- we have a set of special CDs that correspond to the ones latexml postulates -->
+<!-- they need to be imported whereever necessary -->
+<xsl:template match="omdoc:theory">
+ <theory>
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="//om:OMS[@cd='latexml' and @name='multirelation']">
+ <imports from="{$latexmlcds}/multirel.omdoc#multirel"/>
+ </xsl:if>
+ <xsl:if test="//om:OMS[@cd='latexml' and
+ (@name='times' or
+ @name='divide' or
+ @name='plus' or
+ @name='minus')]">
+ <imports from="{$omcds}/arith1.omdoc#arith1"/>
+ </xsl:if>
+ <xsl:if test="//om:OMS[@cd='latexml' and
+ (@name='greater-than' or
+ @name='less-than' or
+ @name='greater-than-or-equals' or
+ @name='less-than-or-equals')]">
+ <imports from="{$omcds}/relation1.omdoc#relation1"/>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </theory>
+</xsl:template>
+
+<!-- and we need to convert the symbols -->
+<xsl:template match="om:OMS[@cd='latexml' and @name='multirelation']">
+ <om:OMS cd="multirel" name="multirelation"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='multirelation']"/>
+
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='plus']">
+ <om:OMS cd="arith1" name="plus"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='minus']">
+ <om:OMS cd="arith1" name="minus"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='times']">
+ <om:OMS cd="arith1" name="times"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='divide']">
+ <om:OMS cd="arith1" name="divide"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='greater-than']">
+ <om:OMS cd="relation1" name="gt"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='greater-than-or-equals']">
+ <om:OMS cd="relation1" name="gt"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='less-than']">
+ <om:OMS cd="relation1" name="lt"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='less-than-or-equals']">
+ <om:OMS cd="relation1" name="lt"/>
+</xsl:template>
+
+<xsl:template match="om:OMS[@cd='latexml' and @name='not-equals']">
+ <om:OMS cd="relation1" name="ne"/>
+</xsl:template>
+
+<!-- get rid of the sectioning commands -->
+<xsl:template match="omdoc:chapter|omdoc:section|omdoc:subsection|omdoc:subsubsection|omdoc:paragraph|omdoc:subparagraph">
+ <omgroup class="{local-name()}">
+ <xsl:copy-of select="@*|*"/>
+ </omgroup>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/Master/texmf-dist/source/latex/stex/xsl/owl2post.xsl b/Master/texmf-dist/source/latex/stex/xsl/owl2post.xsl
new file mode 100644
index 00000000000..530d9265c03
--- /dev/null
+++ b/Master/texmf-dist/source/latex/stex/xsl/owl2post.xsl
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- this style sheet transforms the tex.xml file to OMDoc -->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ltx="http://dlmf.nist.gov/LaTeXML"
+ xmlns:omdoc="http://omdoc.org/ns"
+ xmlns:stex="http://kwarc.info/ns/sTeX"
+ xmlns="http://www.w3.org/2002/07/owl#"
+ xmlns:owl="http://www.w3.org/2002/07/owl#"
+ exclude-result-prefixes="xsl omdoc ltx stex owl">
+
+<xsl:output method="xml" indent="yes" cdata-section-elements="data"/>
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <xsl:comment>This OWL2 ontology is generated from an sTeX-encoded one via LaTeXML, you may want to reconsider editing it.</xsl:comment>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="*">
+ <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
+</xsl:template>
+
+<xsl:template match="omdoc:imports">
+ <Import><xsl:value-of select="@from"/></Import>
+</xsl:template>
+
+
+<xsl:template match="owl:Axiom">
+ <xsl:variable name="anno" select="*[2]"/>
+ <xsl:apply-templates select="*[1]">
+ <xsl:with-param name="anno" select="$anno"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="ltx:Math|ltx:XMath">
+ <xsl:param name="anno"/>
+ <xsl:apply-templates>
+ <xsl:with-param name="anno" select="$anno"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="ltx:XMApp[ltx:XMTok[position()=1 and @meaning='list']]">
+ <xsl:apply-templates select="*[position() &gt; 1]"/>
+</xsl:template>
+
+<xsl:template match="ltx:XMApp">
+ <xsl:param name="anno"/>
+ <xsl:element name="{ltx:XMTok[1]/@meaning}">
+ <xsl:copy-of select="$anno"/>
+ <xsl:apply-templates select="*[position() &gt; 1]"/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="ltx:XMTok">
+ <Class IRI="{@name}"/>
+</xsl:template>
+
+<xsl:template match="ltx:ERROR">
+ <Class IRI="{substring-after(ltx:XMTok,'\')}"/>
+</xsl:template>
+</xsl:stylesheet>