% \iffalse meta-comment
% A LaTeX Class and Package for OMDoc Document Structures
% Copyright (c) 2009 Michael Kohlhase, all rights reserved
%               this file is released under the
%               LaTeX Project Public License (LPPL)
%
% The development version of this file can be found at
% $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/omdoc/omdoc.dtx $
% \fi
%   
% \iffalse
%<package|cls>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{omdoc}[2010/06/25 v1.0 OMDoc document Structure]
%<cls>\ProvidesClass{omdoc}[2010/06/25 v1.0 OMDoc Documents]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{url,array,omdoc,omtext,float}
\usepackage[show]{ed}
\usepackage[hyperref=auto,style=alphabetic]{biblatex}
\bibliography{kwarc}
\usepackage[eso-foot,today]{svninfo}
\svnInfo $Id: omdoc.dtx 1671 2010-11-06 07:05:15Z kohlhase $
\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/omdoc/omdoc.dtx $
\usepackage{stex-logo}
\usepackage{../ctansvn}
\usepackage{hyperref}
\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{omdoc.dtx}\end{document}
%</driver>
% \fi
% 
%\iffalse\CheckSum{275}\fi
% 
% \changes{v0.1}{2006/1/17}{First Version}
% \changes{v0.2}{2006/7/11}{added OMDoc class}
% \changes{v0.3}{2007/09/09}{moved omtext and friends here from the statements package}
% \changes{v0.4}{2008/09/06}{added quotes}
% \changes{v0.5}{2008/03/28}{more package/class options}
% \changes{v0.7}{2009/11/24}{giving keyval arguments to the document environment}
% \changes{v1.0}{2010/05/25}{separated out \texttt{omtext.dtx}}
%
% 
% \GetFileInfo{omdoc.sty}
% 
% \MakeShortVerb{\|}
%
% \def\omdoc{OMDoc}
% \def\latexml{{\LaTeX}ML}
% \title{{\texttt{omdoc.sty/cls}}: Semantic Markup for Open Mathematical Documents in {\LaTeX}\thanks{Version {\fileversion} (last revised
%        {\filedate})}}
%    \author{Michael Kohlhase\\
%            Jacobs University, Bremen\\
%            \url{http://kwarc.info/kohlhase}}
% \maketitle
%
% \begin{abstract}
%   The |omdoc| 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 supplies an infrastructure for writing {\omdoc} documents in {\LaTeX}.
%   This includes a simple structure sharing mechanism for {\sTeX} that allows to to move
%   from a copy-and-paste document development model to a copy-and-reference model, which
%   conserves space and simplifies document management. The augmented structure can be
%   used by MKM systems for added-value services, either directly from the {\sTeX}
%   sources, or after translation.
% \end{abstract}
%
%\newpage\tableofcontents\newpage
% 
%\begin{omgroup}[id=sec:STR]{Introduction}
%
%  The |omdoc| package supplies macros and environment that allow to label document
%  fragments and to reference them later in the same document or in other documents. In
%  essence, this enhances the document-as-trees model to
%  documents-as-directed-acyclic-graphs (DAG) model. This structure can be used by MKM
%  systems for added-value services, either directly from the {\sTeX} sources, or after
%  translation. Currently, trans-document referencing provided by this package can only
%  be used in the {\sTeX} collection.
%
%  {\sTeX} is a version of {\TeX/\LaTeX} that allows to markup {\TeX/\LaTeX} documents
%  semantically without leaving the document format, essentially turning {\TeX/\LaTeX}
%  into a document format for mathematical knowledge management (MKM). The package
%  supports direct translation to the {\omdoc} format~\cite{Kohlhase:omdoc1.2}
%
%  DAG models of documents allow to replace the ``Copy and Paste'' in the source document
%  with a label-and-reference model where document are shared in the document source and
%  the formatter does the copying during document formatting/presentation.\ednote{talk
%    about the advantages and give an example.}\ednote{is there a way to load documents at
%    URIs in LaTeX?}\ednote{integrate with latexml's XMRef in the Math mode.}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:user]{The User Interface}\
% 
% The |omdoc| package generates four files: |omdoc.cls|, |omdoc.sty| and their {\latexml}
% bindings |omdoc.cls.ltxml| and |omdoc.sty.ltxml|. We keep the corresponding code
% fragments together, since the documentation applies to both of them and to prevent them
% from getting out of sync. The {\omdoc} class is a minimally changed variant of the
% standard |article| class that includes the functionality provided by |omdoc.sty|. Most
% importantly, |omdoc.cls| sets up the {\latexml} infrastructure and thus should be used
% if {\omdoc} is to be generated from the {\sTeX} sources. The rest of the documentation
% pertains to the functionality introduced by |omdoc.sty|.
%
% \begin{omgroup}[id=sec:user:options]{Package and Class Options}
% 
%   |omdoc.sty| has the \DescribeMacro{noindex}|noindex| package option, which allows to
%   suppress the creation of index entries. The \DescribeMacro{extrefs} option can be set
%   to activate multifile support, see~\ctancite{Kohlhase:sref} for details. 
% 
%   |omdoc.cls| accepts all options of the |omdoc.sty| (see~\sref{sec:user:options}) and
%   |article.cls| and just passes them on to these.  \ednote{describe them}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:user:struct]{Document Structure}
% 
%   The top-level \DescribeEnv{document}|document| environment is augmented with an
%   optional key/value argument that can be used to give metadata about the document. For
%   the moment only the \DescribeMacro{id}|id| key is used to give an identifier to the
%   \texttt{omdoc} element resulting from the {\latexml} transformation.
% 
%   \DescribeEnv{omgroup} The structure of the document is given by the |omgroup|
%   environment just like in {\omdoc}. In the {\LaTeX} route, the |omgroup| environment is
%   flexibly mapped to sectioning commands, inducing the proper sectioning level from the
%   nesting of |omgroup| environments. Correspondingly, the |omgroup| environment takes an
%   optional key/value argument for metadata followed by a regular argument for the
%   (section) title of the omgroup. The optional metadata argument has the keys
%   \DescribeMacro{id}|id| for an identifier, \DescribeMacro{creators}|creators| and
%   \DescribeMacro{contributors}|contributors| for the Dublin Core
%   metadata~\cite{DCMI:dmt03}; see~\ctancite{Kohlhase:dcm} for details of the format. The
%   \DescribeMacro{short}|short| allows to give a short title for the generated section.
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:user:ignore]{Ignoring Inputs}
% 
% The \DescribeEnv{ignore}|ignore| environment can be used for hiding text parts from the
% document structure. The body of the environment is not PDF or DVI output unless the
% \DescribeMacro{showignores}|showignores| option is given to the |omdoc| class or
% |package|. But in the generated {\omdoc} result, the body is marked up with a |ignore|
% element. This is useful in two situations. For
% \begin{description}
% \item[editing] One may want to hide unfinished or obsolete parts of a document
% \item[narrative/content markup] In {\stex} we mark up narrative-structured documents. In
%   the generated {\omdoc} documents we want to be able to cache content objects that are
%   not directly visible. For instance in the |statements|
%   package~\ctancite{Kohlhase:smms} we use the |\inlinedef| macro to mark up
%   phrase-level definitions, which verbalize more formal definitions. The latter can be
%   hidden by an ignore and referenced by the |verbalizes| key in |\inlinedef|.
% \end{description}
% 
% \end{omgroup}
%
% \begin{omgroup}[id=sec:user:sharing]{Structure Sharing}
%
% \DescribeMacro{\STRlabel}\DescribeMacro{\STRcopy} The |\STRlabel| macro takes two
% arguments: a label and the content and stores the the content for later use by
% |\STRcopy{label}|, which expands to the previously stored content.
%
% \DescribeMacro{\STRsemantics} The |\STRlabel| macro has a variant |\STRsemantics|, where
% the label argument is optional, and which takes a third argument, which is ignored in
% {\LaTeX}. This allows to specify the meaning of the content (whatever that may mean) in
% cases, where the source document is not formatted for presentation, but is transformed
% into some content markup format. \ednote{make an example}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:user:colors]{Colors}
% 
%   For convenience, the |omdoc| package defines a couple of color macros for the |color|
%   package: For instance \DescribeMacro{\blue}|\blue| abbreviates |\textcolor{blue}|, so
%   that |\blue{|\meta{something}|}| writes \meta{something} in blue. The macros
%   \DescribeMacro{\red}|\red| \DescribeMacro{...}|\green|, |\cyan|, |\magenta|, |\brown|,
%   |\yellow|, |\orange|, |\gray|, and finally \DescribeMacro{\black}|\black| are
%   analogous.
% \end{omgroup}
% \end{omgroup}
%
% \begin{omgroup}[id=sec:limitations]{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}
% \end{omgroup}
% 
% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\newpage
%
% \begin{omgroup}[id=sec:impl:cls]{Implementation: The OMDoc Class}
%
%   The functionality is spread over the |omdoc| class and package. The class provides the
%   |document| environment and the |omdoc| element corresponds to it, whereas the
%   package provides the concrete functionality.
% 
% |omdoc.dtx| generates four files: |omdoc.cls| (all the code between
% {\textsf{$\langle$*cls$\rangle$}} and {\textsf{$\langle$/cls$\rangle$}}), |omdoc.sty|
% (between {\textsf{$\langle$*package$\rangle$}} and
% {\textsf{$\langle$/package$\rangle$}}) and their {\latexml} bindings (between
% {\textsf{$\langle$*ltxml.cls$\rangle$}} and {\textsf{$\langle$/ltxml.cls$\rangle$}} and
% {\textsf{$\langle$*ltxml.sty$\rangle$}} and {\textsf{$\langle$/ltxml.sty$\rangle$
% respetively}}). We keep the corresponding code fragments together, since the
% documentation applies to both of them and to prevent them from getting out of sync.
%
% \begin{omgroup}[id=sec:impl:cls:options]{Class Options}
% To initialize the |omdoc| class, we declare and process the necessary options.  
% 
%    \begin{macrocode}
%<*cls>
\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
\def\omdoc@class{article}
\DeclareOption{report}{\def\omdoc@class{report}\PassOptionsToPackage{\CurrentOption}{omdoc}}
\DeclareOption{book}{\def\omdoc@class{book}\PassOptionsToPackage{\CurrentOption}{omdoc}}
\DeclareOption{chapter}{\PassOptionsToPackage{\CurrentOption}{omdoc}}
\DeclareOption{part}{\PassOptionsToPackage{\CurrentOption}{omdoc}}
\DeclareOption{showignores}{\PassOptionsToPackage{\CurrentOption}{omdoc}}
\DeclareOption{extrefs}{\PassOptionsToPackage{\CurrentOption}{sref}}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
%</cls>
%<*ltxml.cls>
# -*- CPERL -*-
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Package;
use LaTeXML::Util::Pathname;
use Cwd qw(cwd abs_path);
DeclareOption('report',sub {PassOptions('omdoc','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption('book',sub {PassOptions('omdoc','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption('chapter',sub {PassOptions('omdoc','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption('part',sub {PassOptions('omdoc','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption('showignores',sub {PassOptions('omdoc','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption('extrefs',sub {PassOptions('sref','sty',ToString(Digest(T_CS('\CurrentOption')))); }); 
DeclareOption(undef,sub {PassOptions('article','cls',ToString(Digest(T_CS('\CurrentOption')))); });
ProcessOptions();
%</ltxml.cls>
%    \end{macrocode}
%
% We load |article.cls|, and the desired packages. For the {\latexml} bindings, we make
% sure the right packages are loaded.
%
%    \begin{macrocode}
%<*cls>
\LoadClass{\omdoc@class}
\RequirePackage{omdoc}
%</cls>
%<*ltxml.cls>
LoadClass('article');
RequirePackage('sref');
%</ltxml.cls>
%    \end{macrocode}
% \end{omgroup}
%
% \begin{omgroup}[id=sec:impl:cls:namespaces]{Setting up Namespaces and Schemata for LaTeXML}
%
% Now, we also need to register the namespace prefixes for {\latexml} to use. 
%    \begin{macrocode}
%<*ltxml.cls>
RegisterNamespace('omdoc'=>"http://omdoc.org/ns");
RegisterNamespace('om'=>"http://www.openmath.org/OpenMath");
RegisterNamespace('m'=>"http://www.w3.org/1998/Math/MathML");
RegisterNamespace('dc'=>"http://purl.org/dc/elements/1.1/");
RegisterNamespace('cc'=>"http://creativecommons.org/ns");
RegisterNamespace('stex'=>"http://kwarc.info/ns/sTeX");
RegisterNamespace('ltx'=>"http://dlmf.nist.gov/LaTeXML");
%</ltxml.cls>
%    \end{macrocode}
% Since we are dealing with a class, we need to set up the document type in the {\latexml}
% bindings. 
%    \begin{macrocode}
%<*ltxml.cls>
RelaxNGSchema('omdoc+ltxml',
        '#default'=>"http://omdoc.org/ns",
        'om'=>"http://www.openmath.org/OpenMath",
        'm'=>"http://www.w3.org/1998/Math/MathML",
        'dc'=>"http://purl.org/dc/elements/1.1/",
        'cc'=>"http://creativecommons.org/ns",
        'ltx'=>"http://dlmf.nist.gov/LaTeXML",
        'stex'=>"http://kwarc.info/ns/sTeX");
%</ltxml.cls>
%    \end{macrocode}
% Then we load the |omdoc| package, which we define separately in the next section so that
% it can be loaded separately\ednote{reword}
%    \begin{macrocode}
%<*ltxml.cls>
RequirePackage('omdoc');
%</ltxml.cls>
%    \end{macrocode}
% \end{omgroup}
%
% \begin{omgroup}[id=sec:impl:cls:document]{Beefing up the \texttt{document} environment}
%
% Now, we will define the environments we need.  The top-level one is the |document|
% environment, which we redefined so that we can provide keyval arguments.
%
% \begin{environment}{document}
%   For the moment we do not use them on the {\LaTeX} level, but the document identifier
%   is picked up by {\latexml}.
%    \begin{macrocode}
%<*cls>
\let\orig@document=\document
\srefaddidkey{document}
\renewcommand{\document}[1][]{\metasetkeys{document}{#1}\orig@document}
%</cls>
%<*ltxml.cls>
sub xmlBase {
  my $baseuri = LookupValue('baseuri');
  my $baselocal = LookupValue('baselocal');
  my $cdir = abs_path(cwd());
  $cdir =~ s/^$baselocal//;
  my ($d,$f,$t) = pathname_split(LookupValue('SOURCEFILE'));
  $t = '' if LookupValue('cooluri');
  Tokenize($baseuri.$cdir.'/'.$f.$t); }
DefEnvironment('{document} OptionalKeyVals:omdoc',
       "<omdoc:omdoc "
      .    "?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')"
      .     "(?&Tokenize(&LookupValue('SOURCEBASE'))"
      .      "(xml:id='&Tokenize(&LookupValue('SOURCEBASE')).omdoc')()) "
      .    "?&Tokenize(&LookupValue('baseuri'))"
      .    "(xml:base='&xmlBase()')() "
      .    "?#locator(stex:srcref='#locator')()>"
      .  "#body"
      ."</omdoc:omdoc>",
  beforeDigest=> sub { AssignValue(inPreamble=>0); },
  afterDigest=> sub { $_[0]->getGullet->flush; return; });
%</ltxml.cls>
%    \end{macrocode}
% \end{environment}
% \end{omgroup}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:impl:sty]{Implementation: OMDoc Package}
%
% \begin{omgroup}[id=sec:impl:options]{Package Options}
% 
% The initial setup for {\latexml}: 
%
%    \begin{macrocode}
%<*ltxml.sty>
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Package;
use Cwd qw(cwd abs_path);
%</ltxml.sty>
%    \end{macrocode}
%
% We declare some switches which will modify the behavior according to the package
% options. Generally, an option |xxx| will just set the appropriate switches to true
% (otherwise they stay false).\ednote{need an implementation for {\latexml}}
%
%    \begin{macrocode}
%<*package>
\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
\newif\if@chapter\@chapterfalse
\newif\if@part\@partfalse
\newcount\section@level\section@level=3
\newif\ifshow@ignores\show@ignoresfalse
\def\omdoc@class{article}
\DeclareOption{report}{\def\omdoc@class{report}\section@level=2}
\DeclareOption{book}{\def\omdoc@class{book}\section@level=1}
\DeclareOption{chapter}{\section@level=2\@chaptertrue}
\DeclareOption{part}{\section@level=1\@chaptertrue\@parttrue}
\DeclareOption{showignores}{\show@ignorestrue}
\DeclareOption{extrefs}{\PassOptionsToPackage{\CurrentOption}{sref}}
\ProcessOptions
%</package>
%<*ltxml.sty>
DeclareOption('report','');
DeclareOption('book','');
DeclareOption('chapter','');
DeclareOption('part','');
DeclareOption('showignores','');
DeclareOption('extrefs','');
%</ltxml.sty>
%    \end{macrocode}
%
% Then we need to set up the packages by requiring the |sref| package to be loaded.
%
%    \begin{macrocode}
%<*package>
\RequirePackage{sref}
\RequirePackage{comment}
%</package>
%<*ltxml.sty>
RequirePackage('sref');
RequirePackage('omtext');
%</ltxml.sty>
%    \end{macrocode}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:impl:struct]{Document Structure}
% 
% The structure of the document is given by the |omgroup| environment just like in
% OMDoc. The hierarchy is adjusted automatically\ednote{maybe define the toplevel
%   according to a param, need to know how to detect that the chapter macro exists.}
% 
% \begin{environment}{omgroup}
%    \begin{macrocode}
%<*package>
\srefaddidkey{omgroup}
\addmetakey{omgroup}{creators}
\addmetakey{omgroup}{contributors}
\addmetakey{omgroup}{type}
\addmetakey*{omgroup}{short}
\addmetakey*{omgroup}{display}
\newenvironment{omgroup}[2][]% title
{\bgroup\metasetkeys{omgroup}{#1}\sref@target
\ifx\omgroup@display\st@flow\noindent{\Large\textbf{#2}\\[.3ex]\noindent\ignorespaces}
\else
\if@part\ifnum\section@level=1\part{#2}\sref@label@id{Part \thepart}\fi\fi
\if@chapter\ifnum\section@level=2\chapter{#2}\sref@label@id{Chapter \thechapter}\fi\fi
\ifnum\section@level=3\section{#2}\sref@label@id{Section \thesection}\fi
\ifnum\section@level=4\subsection{#2}\sref@label@id{Subsection \thesubsection}\fi
\ifnum\section@level=5\subsubsection{#2}\sref@label@id{Subsubsection \thesubsubsection}\fi
\ifnum\section@level=6\paragraph{#2}\sref@label@id{this paragraph}\fi
\ifnum\section@level=7\subparagraph{#2}\sref@label@id{this subparagraph}\fi
\advance\section@level by 1
\fi}{\egroup}
%</package>
%<*ltxml.sty> 
DefEnvironment('{omgroup} OptionalKeyVals:omgroup {}',
               "<omdoc:omgroup layout='sectioning'"
               .   "?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')()"
               .   "?&KeyVal(#1,'type')(type='&KeyVal(#1,'type')')()>\n"
  	       . "<dc:title ?#locator(stex:srcref='#locator')()>#2</dc:title>\n"
	       . "#body\n"
	     . "</omdoc:omgroup>");
%</ltxml.sty>
%    \end{macrocode}
% \end{environment}
% 
% the |itemize|, |description|, and |enumerate| environments originally introduced in the
% |omtext| package do double duty in OMDoc, outside a |CMP| they are transformed into a 
%   |<omgroup layout='itemize|description|enumerate'>|, where the text after the macros
%   |\item| come to be the children. If that is only text, then it is enclosed in an
%   |<omtext><CMP>|, otherwise it is left as it is. The optional argument of the |\item|
%   is transformed into the |<metadata><dc:title>| of the generated |\item| element.
%    \begin{macrocode}
%<*ltxml.sty>
DefParameterType('IfBeginFollows', sub {
		   my ($gullet) = @_;
		   $gullet->skipSpaces;
                   my $next = $gullet->readToken;
                   $gullet->unread($next);
                   $next = ToString($next);
                   #Hm, falling back to regexp handling, the $gullet->ifNext approach didn't work properly
                   return 1 unless ($next=~/^\\begin/);
                   return;
                 },
		 reversion=>'', optional=>1);#$
Let('\group@item@maybe@unwrap','\relax');
DefMacro('\group@item[] IfBeginFollows', sub {
  my($gullet,$tag,$needswrapper)=@_;
  ( T_CS('\group@item@maybe@unwrap'),
    ($needswrapper ? (Invocation(T_CS('\group@item@wrap'),$tag)->unlist) : ()) ); });
DefConstructor('\group@item@wrap {}',
	       "<omdoc:omtext>"
	       . "?#1(<dc:title>#1</dc:title>)()"
               . "<omdoc:CMP><omdoc:p>",
	       beforeDigest=>sub {
		 Let('\group@item@maybe@unwrap','\group@item@unwrap'); 
		 #$_[0]->bgroup;
		 useCMPItemizations();
		 return; },
	       properties=>sub{ RefStepItemCounter(); });
DefConstructor('\group@item@unwrap',
               "",
               beforeDigest=>sub {
                 # $_[0]->egroup;#$
                 Let('\group@item@maybe@unwrap','\relax'); },
               beforeConstruct=>sub {
                 $_[0]->maybeCloseElement('omdoc:p');
                 $_[0]->maybeCloseElement('omdoc:CMP');
                 $_[0]->maybeCloseElement('omdoc:omtext');
               });
Let('group@item@maybe@unwrap','\relax');
Let('\itemize@item'=>'\group@item');
Let('\enumerate@item'=>'\group@item');
Let('\description@item'=>'\group@item');
DefEnvironment('{itemize}',
	       "<omdoc:omgroup xml:id='#id' layout='itemize'>"
              .  "#body"
              ."</omdoc:omgroup>",
	       properties=>sub { beginItemize('itemize'); },
	       beforeDigestEnd=>sub { Digest(T_CS('\group@item@maybe@unwrap')); });
DefEnvironment('{enumerate}',
	       "<omdoc:omgroup xml:id='#id' layout='enumerate'>#body</omdoc:omgroup>",
	       properties=>sub { beginItemize('enumerate'); },
	       beforeDigestEnd=>sub { Digest(T_CS('\group@item@maybe@unwrap')); });
DefEnvironment('{description}',
	       "<omdoc:omgroup xml:id='#id' layout='description'>"
              .  "#body"
              ."</omdoc:omgroup>",
	       properties=>sub { beginItemize('description'); },
	       beforeDigestEnd=>sub { Digest(T_CS('\group@item@maybe@unwrap')); });
%</ltxml.sty>
%    \end{macrocode}
% \end{omgroup}
%
% \begin{omgroup}[id=sec:user:docmatter]{Front and Backmatter}
% 
%   Index markup is provided by the |omtext| package~\cite{Kohlhase:smmtf:ctan}, so in the
%   |omdoc| package we only need to supply the correpsonding |\printindex| command, if it
%   is not already defined
% \begin{macro}{\printindex}
%    \begin{macrocode}
%<*package>
\providecommand\printindex{\IfFileExists{\jobname.ind}{\input{\jobname.ind}}{}} 
%</package>
%<*ltxml.sty>
DefConstructor('\printindex','<omdoc:index/>');
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\tableofcontents}
%   The table of contents already exists in {\LaTeX}, so we only need to provide a
%   {\latexml} binding for it.\ednote{@Deyan, we need to insert the current value of the
%   {\texttt{tocdepth}} counter into a @level attribute.}
%    \begin{macrocode}
%<*ltxml.sty>
DefConstructor('\tableofcontents',"<omdoc:tableofcontents level='2'/>");
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
%
% The case of the |\bibliography| command is similar
%
% \begin{macro}{\bibliography}
%    \begin{macrocode}
%<*ltxml.sty>
DefConstructor('\bibliography{}',"<omdoc:bibliography files='#1'/>");
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
% \end{omgroup}
%
% \begin{omgroup}[id=sec:impl:ignore]{Ignoring Inputs}
% \begin{environment}{ignore}
%    \begin{macrocode}
%<*package>
\ifshow@ignores
\addmetakey{ignore}{type}
\addmetakey{ignore}{comment}
\newenvironment{ignore}[1][]
{\metasetkeys{ignore}{#1}\textless\ignore@type\textgreater\bgroup\itshape}
{\egroup\textless/\ignore@type\textgreater}
\renewenvironment{ignore}{}{}\else\excludecomment{ignore}\fi
%</package>
%<*ltxml.sty>
DefKeyVal('ignore','type','Semiverbatim');
DefKeyVal('ignore','comment','Semiverbatim');
DefEnvironment('{ignore} OptionalKeyVals:ignore',
               "<omdoc:ignore  %&KeyVals(#1)>#body</omdoc:ignore>");
%</ltxml.sty>
%    \end{macrocode}
% \end{environment}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:impl:share]{Structure Sharing}
%
% \begin{macro}{\STRlabel}
%    The main macro, it it used to attach a label to some text expansion. Later on, using the
%    |\STRcopy| macro, the author can use this label to get the expansion originally assigned.
%    \begin{macrocode}
%<*package>
\long\def\STRlabel#1#2{\STRlabeldef{#1}{#2}{#2}}
%</package>
%<*ltxml.sty>
DefConstructor('\STRlabel{}{}', sub {
  my($document,$label,$object)=@_;
  $document->absorb($object);
  $document->addAttribute('xml:id'=>ToString($label)) if $label; });
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\STRcopy}
%    The |\STRcopy| macro is used to call the expansion of a given label. In case the label is
%    not defined it will issue a warning.
%    \begin{macrocode}
%<*package>
\def\STRcopy#1{\expandafter\ifx\csname STR@#1\endcsname\relax
\message{STR warning: reference #1 undefined!}
\else\csname STR@#1\endcsname\fi}
%</package>
%<*ltxml.sty>
DefConstructor('\STRcopy{}',"<omdoc:ref xref='##1'/>");
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\STRsemantics}
%    if we have a presentation form and a semantic form, then we can use
%    \begin{macrocode}
%<*package>
\newcommand{\STRsemantics}[3][]{#2\def\@test{#1}\ifx\@test\@empty\STRlabeldef{#1}{#2}\fi}
%</package>
%<*ltxml.sty>
DefConstructor('\STRsemantics[]{}{}', sub {
  my($document,$label,$ignore,$object)=@_;
  $document->absorb($object);
  $document->addAttribute('xml:id'=>ToString($label)) if $label; });
%</ltxml.sty>#$
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\STRlabeldef}
%    This is the macro that does the actual labeling. Is it called inside |\STRlabel|
%    \begin{macrocode}
%<*package>
\def\STRlabeldef#1{\expandafter\gdef\csname STR@#1\endcsname}
%</package>
%<*ltxml.sty>
DefMacro('\STRlabeldef{}{}', "");
%</ltxml.sty>
%    \end{macrocode}
% \end{macro}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:impl:colors]{Colors}
% 
% \begin{environment}{blue, red, green, magenta}
%    We will use the following abbreviations for colors from |color.sty|
%    \begin{macrocode}
%<*package>
\def\black#1{\textcolor{black}{#1}}
\def\gray#1{\textcolor{gray}{#1}}
\def\blue#1{\textcolor{blue}{#1}}
\def\red#1{\textcolor{red}{#1}}
\def\green#1{\textcolor{green}{#1}}
\def\cyan#1{\textcolor{cyan}{#1}}
\def\magenta#1{\textcolor{magenta}{#1}}
\def\brown#1{\textcolor{brown}{#1}}
\def\yellow#1{\textcolor{yellow}{#1}}
\def\orange#1{\textcolor{orange}{#1}}
%</package>
%    \end{macrocode}
% For the {\latexml} bindings, we go a generic route, we replace |\blue{#1}| by 
% |{\@omdoc@color{blue}\@omdoc@color@content{#1}}|. 
%    \begin{macrocode}
%<*ltxml.sty>
sub omdocColorMacro {
  my ($color, @args) = @_;
  my $tok_color = TokenizeInternal($color);
  (T_BEGIN, T_CS('\@omdoc@color'), T_BEGIN, $tok_color->unlist,
   T_END, T_CS('\@omdoc@color@content'), T_OTHER('['), $tok_color->unlist, T_OTHER(']'),
   T_BEGIN, $args[1]->unlist, T_END, T_END); }
DefMacro('\@omdoc@color{}', sub { MergeFont(color=>$_[1]->toString); return; });#$
%</ltxml.sty>
%    \end{macrocode}
% Ideally, here we will remove the optional argument and have a conversion module
% add the attribute at the end (or maybe add it just for math?)
% or, we can take the attributes for style from the current font ?
%    \begin{macrocode}
%<*ltxml.sty>
DefConstructor('\@omdoc@color@content[]{}',
   "?#isMath(#2)(<omdoc:phrase ?#1(style='color:#1')()>#2</omdoc:phrase>)");
foreach my $color(qw(black gray blue red green cyan magenta brown yellow orange)) {
  DefMacro("\\".$color.'{}', sub { omdocColorMacro($color, @_); }); }#$
%</ltxml.sty>
%    \end{macrocode}
% \end{environment}
% \end{omgroup}
% 
% \begin{omgroup}{{\LaTeX} Commands we interpret differently}
%
%   The reinterpretations are quite simple, we either disregard presentational markup or
%   we re-interpret it in terms of {\omdoc}.
%    \begin{macrocode}
%<*ltxml.sty>
DefConstructor('\newpage','');
%</ltxml.sty>
%    \end{macrocode}
% \end{omgroup}
% 
% \begin{omgroup}[id=sec:impl:ids]{Providing IDs for {\omdoc} Elements}
% 
%   To provide default identifiers, we tag all {\omdoc} elements that allow |xml:id|
%   attributes by executing the |numberIt| procedure below.
% 
%    \begin{macrocode}
%<*ltxml.sty>
Tag('omdoc:ignore',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:ref',afterOpen=>\&numberIt,afterClose=>\&locateIt);
%</ltxml.sty>
%    \end{macrocode}
% \end{omgroup}
% 
% \begin{omgroup}{Leftovers}
%
%    \begin{macrocode}
%<*package>
\newcommand{\baseURI}[2][]{}
%</package>
%<*ltxml.sty>
DefMacro('\baseURI []Semiverbatim', sub {
    AssignValue('baselocal'=>abs_path(ToString(Expand($_[1]))));
    AssignValue('baseuri'=>ToString(Expand($_[2])));});
DefConstructor('\url Semiverbatim',"<omdoc:link href='#1'>#1</omdoc:link>");
DefConstructor('\href Semiverbatim {}',"<omdoc:link href='#1'>#2</omdoc:link>");
%</ltxml.sty>
%    \end{macrocode}
% \ednote{this should be handled differently, omdoc.sty should include url and give a new
% macro for it, which we then use in omdoc}
% and finally, we need to terminate the file with a success mark for perl.
%    \begin{macrocode}
%<ltxml.sty|ltxml.cls>1;
%    \end{macrocode}
% \end{omgroup}
% \end{omgroup}
% \Finale
\endinput
% \iffalse
% LocalWords:  GPL structuresharing STR omdoc dtx stex CPERL LoadClass url dc
%%% Local Variables: 
%%% mode: doctex
%%% TeX-master: t
%%% End: 
% \fi
% LocalWords:  RequirePackage RegisterNamespace namespace xsl DocType ltxml dtd
% LocalWords:  ltx DefEnvironment beforeDigest AssignValue inPreamble getGullet
% LocalWords:  afterDigest keyval omgroup DefKeyVal Semiverbatim KeyVal locator
% LocalWords:  OptionalKeyVals DefParameterType IfBeginFollows skipSpaces CMP
% LocalWords:  ifNext DefMacro needwrapper unlist DefConstructor omtext bgroup
% LocalWords:  useCMPItemizations RefStepItemCounter egroup beginItemize li di
% LocalWords:  beforeDigestEnd dt autoclose ul ol dl env showignores srcref Cwd
% LocalWords:  afterOpen LastSeenCMP autoClose DefCMPEnvironment proto ToString
% LocalWords:  addAttribute nlex nlcex omdocColorMacro args tok MergeFont qw
% LocalWords:  TokenizeInternal toString isMath foreach maybeCloseElement id'd
% LocalWords:  autoOpen minipage footnotesize scriptsize numberIt whatsit href
% LocalWords:  getAttribute setAttribute OMDoc RelaxNGSchema noindex xml lec
% LocalWords:  Subsubsection useDefaultItemizations refundefinedtrue sblockquote
% LocalWords:  DefCMPConstructor sinlinequote idx idt ide idp emph  extrefs sref
% LocalWords:  flushleft flushright DeclareOption PassOptions undef cls iffalse
% LocalWords:  ProcessOptions subparagraph ignoresfalse ignorestrue texttt ttin
% LocalWords:  texttt latexml fileversion maketitle newpage tableofcontents cwd
% LocalWords:  newpage ednote ctancite dmt03 smms inlinedef STRlabel STRcopy
% LocalWords:  STRlabel STRsemantics STRsemantics textcolor printbibliography
% LocalWords:  textsf langle textsf langle respetively orig renewcommand cdir
% LocalWords:  baseuri baseuri baselocal baselocal SOURCEFILE cooluri newif ifx
% LocalWords:  SOURCEBASE chapterfalse partfalse newcount ifshow chaptertrue
% LocalWords:  parttrue srefaddidkey newenvironment textbf
% LocalWords:  noindent noindent ignorespaces ifnum thepart thechapter regexp
% LocalWords:  thesection thesubsection thesubsubsection needswrapper itshape
% LocalWords:  textgreater renewenvironment excludecomment STRlabeldef csname
% LocalWords:  expandafter endcsname xref newcommand gdef doctex
