% \iffalse meta-comment
% An Infrastructure for Problems 
% $URL: https://svn.kwarc.info/repos/stex/trunk/sty/problem/problem.dtx $ 
% $Rev: 1999 $; last modified by $Author: kohlhase $ 
% $Date: 2012-01-28 08:32:11 +0100 (Sat, 28 Jan 2012) $
% 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}[2012/01/28 v0.9c Semantic Markup for Problems]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{url,float,latexml}
\usepackage[solutions,hints,notes]{problem}
\usepackage[show]{ed}
\usepackage[hyperref=auto,style=alphabetic]{biblatex}
\bibliography{kwarc}
\usepackage[eso-foot,today]{svninfo}
\svnInfo $Id: problem.dtx 1999 2012-01-28 07:32:11Z kohlhase $
\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/problem/problem.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{problem.dtx}\end{document}
%</driver>
% \fi
% 
% \CheckSum{396}
%
% \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{\texttt{problem.sty}: 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}|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.
% 
% Finally, if the \DescribeMacro{showmeta}|showmeta| is set, then the metadata keys are
% shown (see~\cite{Kohlhase:metakeys:ctan} for details and customization options).
% 
% \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.
%
% \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\PrintChanges}
% \newpage
%
% \section{The Implementation}\label{sec:implementation}
%
% The |problem| package generates two 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
%     $\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}
% 
% 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>
\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}}
\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}
%
% On the {\LaTeXML} side we only make sure that the switches are defined
%    \begin{macrocode}
%<*ltxml>
RawTeX('
\newif\ifexnotes\exnotesfalse
\newif\ifhints\hintsfalse
\newif\ifsolutions\solutionsfalse
\newif\ifpts\ptsfalse
\newif\ifmin\minfalse
\newif\ifboxed\boxedfalse
\newif\ifextract\extractfalse
');
%</ltxml>
%    \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}
\addmetakey{problem}{pts}
\addmetakey{problem}{min}
\addmetakey*{problem}{title}
\addmetakey{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][]{\metasetkeys{problem}{#1}\sref@target%
\stepcounter{problem}\show@pts\show@min\record@problem%
\begin{lrbox}{\probbox}\begin{minipage}{.9\textwidth}\ignorespaces}
{\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][]{\metasetkeys{problem}{#1}\sref@target%
\stepcounter{problem}\show@pts\show@min\record@problem%
\par\noindent\textbf\prob@heading\rm\ignorespaces}
{\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 |ltx:p| elements to autoclose. 
%
%    \begin{macrocode}
%<*ltxml>
DefEnvironment('{problem} OptionalKeyVals:problem',
   "<omdoc:exercise ?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')()>"
  .    "?&KeyVal(#1,'title')(<dc:title>&KeyVal(#1,'title')</dc:title>)()"
   .    "?&KeyVal(#1,'min')("
   .       "<omdoc:meta property='prob:solvedinminutes' prob:dummy='for the namespace'>"
   .          "&KeyVal(#1,'min')"
   .       "</omdoc:meta>)()"
   .    "?&KeyVal(#1,'pts')("
   .       "<omdoc:meta property='prob:points' prob:dummy='for the namespace'>"
   .         "&KeyVal(#1,'pts')"
   .       "</omdoc:meta>)()"
   .   "<omdoc:CMP><omdoc:p>#body"
   ."</omdoc:exercise>",
   afterDigest => sub {
     my ($stomach,$kv)=@_;
     my $kvi = LookupValue('inclprob');
     my @keys = qw(id title min pts);
     my @vals = $kvi && map($kvi->getValue($_), @keys);
     foreach my $i(0..$#vals) {
       $kv->setValue($keys[$i],$vals[$i]) if $vals[$i];
     }
     return;});#$
%</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');
DefEnvironment('{solution} OptionalKeyVals:soln',
	       "<omdoc:solution ?&KeyVals(#1,'for')(for='&KeyVal(#1,'for')')()>"
	     . "#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>
DefEnvironment('{exnote}',"<omdoc:hint><omdoc:CMP><omdoc:p>#body</omdoc:hint>");
DefEnvironment('{hint}',"<omdoc:hint><omdoc:CMP><omdoc:p>#body</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>
\addmetakey{inclprob}{pts}
\addmetakey{inclprob}{min}
\addmetakey*{inclprob}{title}
\addmetakey{inclprob}{refnum}
\clear@inclprob@keys
\newcommand{\includeproblem}[2][]{%
\bgroup\metasetkeys{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 type='cite' xref='#2'>"
 .  "?&KeyVal(#1,'title')(<dc:title>&KeyVal(#1,'title')</dc:title>)()"
 .  "?&KeyVal(#1,'min')("
 .     "<omdoc:meta property='prob:solvedinminutes' prob:dummy='for the namespace'>"
 .       "&KeyVal(#1,'min')"
 .     "</omdoc:meta>)()"
 .  "?&KeyVal(#1,'pts')("
 .     "<omdoc:meta property='prob:points' prob:dummy='for the namespace'>"
 .       "&KeyVal(#1,'pts')"
 .     "</omdoc:meta>)()"
 ."</omdoc:ref>",
 afterDigest => sub{
   my ($stomach,$kv) = @_;
   AssignValue('inclprob',$kv) if $kv;
 });
%</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{Providing IDs Elements}\label{sec:impl:ids}
%
% To provide default identifiers, we tag all elements that allow |xml:id| attributes by
% executing the |numberIt| procedure from |omdoc.sty.ltxml|.
% 
%    \begin{macrocode}
%<*ltxml>
Tag('omdoc:exercise',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:solution',afterOpen=>\&numberIt,afterClose=>\&locateIt);
Tag('omdoc:hint',afterOpen=>\&numberIt,afterClose=>\&locateIt);
%</ltxml>
%    \end{macrocode}
%
% \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
