% \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}[2012/01/28 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 1999 2012-01-28 07:32:11Z kohlhase $
\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/cnx/cnx.dtx $
\makeindex
\floatstyle{boxed}
\newfloat{exfig}{thp}{lop}
\floatname{exfig}{Example}
\def\tracissue#1{\cite{sTeX:online}, \hyperlink{http://trac.kwarc.info/sTeX/ticket/#1}{issue #1}}
\begin{document}\DocInput{cnx.dtx}\end{document}
%</driver>
% \fi
% 
%\CheckSum{439}
% 
% \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{Package Options}\label{sec:user:options}
% 
% The |cnx| package takes a single option: \DescribeMacro{showmeta}|showmeta|. If this is
% set, then the metadata keys are shown (see~\cite{Kohlhase:metakeys:ctan} for details and
% customization options).
%
% \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|. 
% 
%
% \section{Limitations}\label{sec:limitations}
% 
% In this section we document known limitations. If you want to help alleviate them,
% please feel free to contact the package author. Some of them are currently discussed in
% the \sTeX TRAC~\cite{sTeX:online}. 
% \begin{compactenum}
% \item none reported yet
% \end{compactenum}
% 
% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\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.
%
% \subsection{Package Options}\label{sec:impl:options}
%
% We declare some switches which will modify the behavior according to the package
% options. Generally, an option |xxx| will just set the appropriate switches to true
% (otherwise they stay false). First we have the general options
%    \begin{macrocode}
%<*package>
\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{omdoc}}
%    \end{macrocode}
%    Finally, we need to declare the end of the option declaration section to {\LaTeX}.
%    \begin{macrocode}
\ProcessOptions
%</package>
%    \end{macrocode}
% 
% 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('metakeys');
%    \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>
\addmetakey{cnxmodule}{name}
\srefaddidkey{cnxmodule}{id}
\newenvironment{cnxmodule}[1][]{\metasetkeys{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]
\metasetkeys{sectioning}{#1}}
{}
\newcounter{subsection}[section]
\newenvironment{csubsection}[2][]
{\refstepcounter{subsection}\strut\\[1ex]\noindent%
{\large\bfseries{\arabic{section}.\arabic{subsection}.~#2\\[1ex]}}%
\metasetkeys{sectioning}{#1}}%
{}
\newcounter{subsubsection}[subsection]
\newenvironment{csubsubsection}[2][]
{\refstepcounter{subsubsection}\strut\\[.5ex]\noindent
{\bfseries\arabic{section}.\arabic{subsection}.\arabic{subsubsecction}~#2\\[.5ex]}%
\metasetkeys{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][]{\metasetkeys{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}
\addmetakey{note}{type}
\newenvironment{cnote}[1][]%
{\metasetkeys{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][]%
{\metasetkeys{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}
\addmetakey{cquote}{type}
\addmetakey{cquote}{src}
\newenvironment{cquote}[1][]{%
\metasetkeys{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}
\addmetakey{example}{name}
\newenvironment{cexample}[1][]{\metasetkeys{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}
\addmetakey{cexercise}{name}
\newenvironment{cexercise}[1][]{\metasetkeys{cexercise}{#1}
{\ifx\cexercise@name\@empty\else\stepcounter{cexercise}\noindent\bfseries{\cexercise@name~\arabic{cexercise}}\fi}}
{}
\srefaddidkey{cproblem}
\newenvironment{cproblem}[1][]{\metasetkeys{cproblem}{#1}}{}{}
\srefaddidkey{csolution}
\newenvironment{csolution}[1][]{\metasetkeys{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}
\addmetakey{rule}{name}
\addmetakey{rule}{type}
\newenvironment{crule}[1][]{\metasetkeys{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][]{\metasetkeys{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][]{\metasetkeys{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}
\addmetakey{definition}{term}
\addmetakey{definition}{seealso}
\newenvironment{definition}[1][]{\metasetkeys{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][]{\metasetkeys{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>
\addmetakey{cnxn}{document}
\addmetakey{cnxn}{target}
\addmetakey{cnxn}{strength}
\newcommand{\cnxn}[2][]% keys, link text
{\metasetkeys{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>
\addmetakey{link}{src}
\newcommand{\link}[2][]{\metasetkeys{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}
\addmetakey{cfigure}{type}
\addmetakey{cfigure}{caption}
\newcounter{figure}
\newcommand{\cfigure}[3][]{% cnx_keys, graphicx_keys, path
\begin{center}%
\includegraphics[#2]{#3}%
\metasetkeys{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>
\addmetakey{ccite}{src}
\newcommand{\ccite}[2][]{\metasetkeys{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>
\addmetakey{metadata}{version}
\addmetakey{metadata}{created}
\addmetakey{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}
\addmetakey{auth}{honorific}
\addmetakey{auth}{firstname}
\addmetakey{auth}{other}
\addmetakey{auth}{surname}
\addmetakey{auth}{lineage}
\addmetakey{auth}{email}
\newcommand{\cnxauthor}[1][]{\metasetkeys{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][]{\metasetkeys{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 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 
% LocalWords:  environement srefaddidkey newenvironment 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
