% \iffalse meta-comment
% A LaTeX Class and Package for OMDoc Document Structures
% Copyright (c) 2019 Michael Kohlhase, all rights reserved
%               this file is released under the
%               LaTeX Project Public License (LPPL)
%
% The original of this file is in the public repository at 
% http://github.com/sLaTeX/sTeX/
%
%
%<*driver>
\def\bibfolder{../../lib/bib}
\input{../../doc/stex-docheader}

\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% %^^A \changes{v0.1}{2006/1/17}{First Version}
%
% \title{document-structure: Semantic Markup for Open Mathematical Documents in {\LaTeX}
% 	\thanks{Version {\fileversion} (last revised {\filedate})} 
% }
%
% \author{Michael Kohlhase, Dennis Müller\\
% 	FAU Erlangen-Nürnberg\\
% 	\url{http://kwarc.info/}
% }
%
% \maketitle
%
%\ifinfulldoc\else
% This is the documentation for the \pkg{document-structure} package.
% For a more high-level introduction, 
%  see \href{\basedocurl/manual.pdf}{the \sTeX Manual} or the
% \href{\basedocurl/stex.pdf}{full \sTeX documentation}.
%
% \input{../../doc/packages/stex-document-structure}
% \fi
%
%
% \begin{documentation}\label{pkg:documentstructure:doc}
%
%   The |document-structure| 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.
%   \begin{sfragment}[id=sec:STR]{Introduction}
% 
%  \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}
%
%  The |document-structure| package supplies macros and environments 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.
%
%  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{integrate with latexml's XMRef in the Math mode.}
% \end{sfragment}
% 
% \begin{sfragment}[id=sec:user]{The User Interface}
% 
%   The |document-structure| package generates two files: |document-structure.cls|, and |document-structure.sty|. The {\omdoc}
%   class is a minimally changed variant of the standard |article| class that includes the
%   functionality provided by |document-structure.sty|. The rest of the documentation pertains to the
%   functionality introduced by |document-structure.sty|.
%
% \begin{sfragment}[id=sec:user:options]{Package and Class Options}
% 
%   The |document-strcture| class accept the following options: 
%   \begin{center}
%     \begin{tabular}{|l|p{10cm}|}\hline
%         \texttt{class=\meta{name}} & load \meta{name}|.cls| instead of |article.cls|\\\hline 
%         \texttt{topsect=\meta{sect}} & The top-level sectioning level; the default for
%         \meta{sect} is \texttt{section}\\\hline 
%         \texttt{showignores} & show the the contents of the |ignore| environment after all \\\hline
%         \texttt{showmeta} & show the metadata; see |metakeys.sty|\\\hline
%         \texttt{showmods} & show modules; see |modules.sty|\\\hline
%         \texttt{extrefs} & allow external references; see |sref.sty|\\\hline
%         \texttt{defindex} & index definienda; see |statements.sty|\\\hline
%         \texttt{minimal} & for testing; do not load any \sTeX packages\\\hline 
%     \end{tabular}
%   \end{center}
%   The |document-structure| package accepts the same except the first two.
% \end{sfragment}
% 
% \begin{sfragment}[id=sec:user:struct]{Document Structure}
% 
%   The top-level \DescribeEnv{document}|document| environment can be given key/value
%   information by the \DescribeMacro{\documentkeys}|\documentkeys| macro in the
%   preamble\footnote{We cannot patch the document environment to accept an optional
%   argument, since other packages we load already do; pity.}. This 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.
% 
%   The structure of the document is given by the \DescribeEnv{sfragment}|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~\cite{Kohlhase:dcm:git} for details of the format. The
%   \DescribeMacro{short}|short| allows to give a short title for the generated
%   section. If the title contains semantic macros, they need to be protected by
%   |\protect|, and we need to give the \DescribeMacro{loadmodules}|loadmodules| key it
%   needs no value. For instance we would have
%   \begin{verbatim}
%   \begin{smodule}{foo}
%   \symdef{bar}{B^a_r}
%    ...
%   \begin{sfragment}[id=sec.barderiv,loadmodules]{Introducing $\protect\bar$ Derivations}
%   \end{verbatim}
% 
%   \sTeX automatically computes the sectioning level, from the nesting of |omgroup|
%   environments. But sometimes, we want to skip levels (e.g. to use a subsection* as an
%   introduction for a chapter). Therefore the |document-structure| package provides a variant
%   \DescribeEnv{blindfragment}|blindomgroup| that does not produce markup, but increments
%   the sectioning level and logically groups document parts that belong together, but
%   where traditional document markup relies on convention rather than explicit
%   markup. The |blindomgroup| environment is useful e.g. for creating frontmatter at the
%   correct level. Example~\ref{fig:docstruct} shows a typical setup for the outer
%   document structure of a book with parts and chapters. We use two levels of
%   |blindomgroup|:
%   \begin{itemize}
%   \item The outer one groups the introductory parts of the book (which we assume to have
%     a sectioning hierarchy topping at the part level). This |blindomgroup| makes sure
%     that the introductory remarks become a ``chapter'' instead of a ``part''.
%   \item Th inner one groups the frontmatter\footnote{We shied away from redefining the
%     |frontmatter| to induce a blindomgroup, but this may be the ``right'' way to go in
%     the future.} and makes the preface of the book a section-level construct. Note that
%     here the |display=flow| on the |omgroup| environment prevents numbering as is
%     traditional for prefaces. 
%   \end{itemize}
%   \begin{exfig}
% \begin{verbatim}
% \begin{document}
% \begin{blindfragment}
% \begin{blindfragment}
% \begin{frontmatter}
% \maketitle\newpage
% \begin{sfragment}[display=flow]{Preface}
% ... <<preface>> ...
% \end{sfragment}
% \clearpage\setcounter{tocdepth}{4}\tableofcontents\clearpage
% \end{frontmatter}
% \end{blindfragment}
% ... <<introductory remarks>> ...
% \end{blindfragment}
% \begin{sfragment}{Introduction}
% ... <<intro>> ...
% \end{sfragment}
% ... <<more chapters>> ... 
% \bibliographystyle{alpha}\bibliography{kwarc}
% \end{document}
% \end{verbatim}
% \vspace*{-2em}
%   \caption{A typical Document Structure of a Book}\label{fig:docstruct}
% \end{exfig}
% 
% The \DescribeMacro{\skipomgroup}|\skipomgroup| ``skips an |omgroup|'', i.e. it just
% steps the respective sectioning counter. This macro is useful, when we want to keep two
% documents in sync structurally, so that section numbers match up: Any section that is
% left out in one becomes a |\skipomgroup|.
%
%   The \DescribeMacro{\currentsectionlevel}|\currentsectionlevel| macro supplies the name
%   of the current sectioning level, e.g. ``chapter'', or
%   ``subsection''. \DescribeMacro{\CurrentSectionLevel}|\CurrentSectionLevel| is the
%   capitalized variant. They are useful to write something like ``In this
%   |\currentsectionlevel|, we will\ldots'' in an |omgroup| environment, where we do not
%   know which sectioning level we will end up.
% \end{sfragment}
% 
% \begin{sfragment}[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 |document-structure| 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~\cite{Kohlhase:smms:git} 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}
%
% For prematurely stopping the formatting of a document, \sTeX provides the
% \DescribeMacro{\prematurestop}|\prematurestop| macro. It can be used everywhere in a
% document and ignores all input after that -- backing out of the omgroup environment as
% needed. After that -- and before the implicit |\end{document}| it calls the internal
% \DescribeMacro{\afterprematurestop}|\afterprematurestop|, which can be customized to do
% additional cleanup or e.g. print the bibliography.
%
% |\prematurestop| is useful when one has a driver file, e.g. for a course taught multiple
% years and wants to generate course notes up to the current point in the lecture. Instead
% of commenting out the remaining parts, one can just move the |\prematurestop| macro.
% This is especially useful, if we need the rest of the file for processing, e.g. to
% generate a theory graph of the whole course with the already-covered parts marked up as
% an overview over the progress; see |import_graph.py| from the |lmhtools|
% utilities~\cite{lmhtools:github:on}.
% \end{sfragment}
%
% \begin{sfragment}[id=sec:user:sharing]{Structure Sharing}
%
%   The \DescribeMacro{\STRlabel}|\STRlabel| macro takes two arguments: a label and the
%   content and stores the the content for later use by
%   \DescribeMacro{\STRcopy}|\STRcopy[|\meta{URL}|]{|\meta{label}|}|, which expands to the
%   previously stored content. If the |\STRlabel| macro was in a different file, then we
%   can give a URL \meta{URL} that lets {\latexml} generate the correct reference.
%
%   \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{document LMID und LMXREf here
%   if we decide to keep them.}
% \end{sfragment}
% 
% \begin{sfragment}[id=sec:user:gvars]{Global Variables}
% 
%   Text fragments and modules can be made more re-usable by the use of global
%   variables. For instance, the admin section of a course can be made course-independent
%   (and therefore re-usable) by using variables (actually token registers)
%   |courseAcronym| and |courseTitle| instead of the text itself. The variables can then
%   be set in the \sTeX preamble of the course notes file.
%   \DescribeMacro{\setSGvar}|\setSGvar{|\meta{vname}|}{|\meta{text}|}| to set the global
%   variable \meta{vname} to \meta{text} and
%   \DescribeMacro{\useSGvar}|\useSGvar{|\meta{vname}|}| to reference it.
%
%   With \DescribeMacro{\ifSGvar}|\ifSGvar| we can test for the contents of a global
%   variable: the macro call |\ifSGvar{|\meta{vname}|}{|\meta{val}|}{|\meta{ctext}|}|
%   tests the content of the global variable \meta{vname}, only if (after expansion) it is
%   equal to \meta{val}, the conditional text \meta{ctext} is formatted.
% \end{sfragment}
%
% \begin{sfragment}[id=sec:user:colors]{Colors}
% 
%   For convenience, the |document-structure| 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{sfragment}
% \end{sfragment}
%
% \begin{sfragment}[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 GitHub repository~\cite{sTeX:github:on}. 
% \begin{enumerate}
% \item when option |book| which uses |\pagestyle{headings}| is given and semantic macros
%   are given in the |omgroup| titles, then they sometimes are not defined by the time the
%   heading is formatted. Need to look into how the headings are made. 
% \end{enumerate}
% \end{sfragment}
% 
% \end{documentation}
%
% \begin{implementation}\label{pkg:documentstructure:impl}
%
% \begin{sfragment}{document-structure.sty Implementation}
%
% \begin{sfragment}[id=sec:impl:cls]{The document-structure Class}
%
%   The functionality is spread over the |document-structure| class and package. The class provides the
%   |document| environment and the |document-structure| element corresponds to it, whereas the
%   package provides the concrete functionality.
%
%    \begin{macrocode}
%<*cls>
%<@@=document_structure>
\ProvidesExplClass{document-structure}{2022/02/26}{3.0.1}{Modular Document Structure Class}
\RequirePackage{l3keys2e}
%    \end{macrocode}
%
% \begin{sfragment}[id=sec:impl:cls:options]{Class Options}
%   To initialize the |document-structure| class, we declare and process the necessary options using
%   the |kvoptions| package for  key/value options handling. For
%   |omdoc.cls| this is quite simple. We have options |report| and |book|, which set the
%   \DescribeMacro{\omdoc@cls@class}|\omdoc@cls@class| macro and pass on the macro to |omdoc.sty|
%   for further processing. 
%
%    \begin{macrocode}
\keys_define:nn{ document-structure / pkg }{
  class       .str_set_x:N  = \c_document_structure_class_str,
  minimal     .bool_set:N   = \c_document_structure_minimal_bool,
  report      .code:n       = {
    \ClassWarning{document-structure}{the option 'report' is deprecated, use 'class=report', instead}
    \str_set:Nn \c_document_structure_class_str {report}
  },
  book        .code:n       = {
    \ClassWarning{document-structure}{the option 'book' is deprecated, use 'class=book', instead}
    \str_set:Nn \c_document_structure_class_str {book}
  },
  bookpart    .code:n       = {
    \ClassWarning{document-structure}{the option 'bookpart' is deprecated, use 'class=book,topsect=chapter', instead}
    \str_set:Nn \c_document_structure_class_str {book}
    \str_set:Nn \c_document_structure_topsect_str {chapter}
  },
  docopt      .str_set_x:N  = \c_document_structure_docopt_str,
  unknown     .code:n       = {
    \PassOptionsToPackage{ \CurrentOption }{ document-structure }
  }
}
\ProcessKeysOptions{ document-structure / pkg }
\str_if_empty:NT \c_document_structure_class_str {
  \str_set:Nn \c_document_structure_class_str {article}
}
\exp_after:wN\LoadClass\exp_after:wN[\c_document_structure_docopt_str]
  {\c_document_structure_class_str}

%    \end{macrocode}
% \end{sfragment}
%
% \begin{sfragment}[id=sec:impl:cls:document]{Beefing up the \texttt{document} environment}
%
%   Now, -- unless the option |minimal| is defined -- we include the |stex| package 
%
%    \begin{macrocode}
\RequirePackage{document-structure}
\bool_if:NF \c_document_structure_minimal_bool {
%    \end{macrocode}
%
% And 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}.\ednote{faking documentkeys for now. @HANG, please implement}
%    \begin{macrocode}
\keys_define:nn { document-structure / document }{
  id .str_set_x:N = \c_document_structure_document_id_str
}
\let\_@@_orig_document=\document
\renewcommand{\document}[1][]{
  \keys_set:nn{ document-structure / document }{ #1 }
  \stex_ref_new_doc_target:n { \c_document_structure_document_id_str }
  \_@@_orig_document
}
%    \end{macrocode}
% \end{environment}
%
% Finally, we end the test for the |minimal| option. 
% 
%    \begin{macrocode}
}
%</cls>
%    \end{macrocode}
% \end{sfragment}
% \end{sfragment}
% 
% \begin{sfragment}[id=sec:impl:sty]{Implementation: document-structure Package}
%
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage{document-structure}{2022/02/26}{3.0.1}{Modular Document Structure}
\RequirePackage{l3keys2e}
%    \end{macrocode}
%
% \begin{sfragment}[id=sec:impl:options]{Package 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).
%
%
%    \begin{macrocode}

\keys_define:nn{ document-structure / pkg }{
  class       .str_set_x:N  = \c_document_structure_class_str,
  topsect     .str_set_x:N  = \c_document_structure_topsect_str,
%  showignores .bool_set:N   = \c_document_structure_showignores_bool,
}
\ProcessKeysOptions{ document-structure / pkg }
\str_if_empty:NT \c_document_structure_class_str {
  \str_set:Nn \c_document_structure_class_str {article}
}
\str_if_empty:NT \c_document_structure_topsect_str {
  \str_set:Nn \c_document_structure_topsect_str {section}
}
%    \end{macrocode}
%
% Then we need to set up the packages by requiring the |sref| package to be loaded,
% and set up triggers for other languages
%
%    \begin{macrocode}
\RequirePackage{xspace}
\RequirePackage{comment}
\AddToHook{begindocument}{
	\ltx@ifpackageloaded{babel}{
    \clist_set:Nx \l_tmpa_clist {\bbl@loaded}
    \clist_if_in:NnT \l_tmpa_clist {ngerman}{
      \makeatletter\input{document-structure-ngerman.ldf}\makeatother
    }
  }{}
}
%    \end{macrocode}
%
% Finally, we set the \DescribeMacro{\section@level}|\section@level| macro that governs
% sectioning. The default is two (corresponding to the |article| class), then we set the
% defaults for the standard classes |book| and |report| and then we take care of the
% levels passed in via the |topsect| option.
%
%    \begin{macrocode}
\int_new:N \l_document_structure_section_level_int
\str_case:VnF \c_document_structure_topsect_str {
  {part}{
    \int_set:Nn \l_document_structure_section_level_int {0}
  }
  {chapter}{
    \int_set:Nn \l_document_structure_section_level_int {1}
  }
}{
  \str_case:VnF \c_document_structure_class_str {
    {book}{
      \int_set:Nn \l_document_structure_section_level_int {0}
    }
    {report}{
      \int_set:Nn \l_document_structure_section_level_int {0}
    }
  }{
    \int_set:Nn \l_document_structure_section_level_int {2}
  }
}
%    \end{macrocode}
%
% \end{sfragment}
% 
% \begin{sfragment}[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 according to the {\LaTeX} class in
%   effect. 
% \begin{macro}{\currentsectionlevel}
%   For the |\currentsectionlevel| and |\Currentsectionlevel| macros we use an internal
%   macro |\current@section@level| that only contains the keyword (no markup). We
%   initialize it with ``document'' as a default. In the generated OMDoc, we only generate
%   a text element of class |omdoc_currentsectionlevel|, wich will be instantiated by CSS
%   later.\ednote{MK: we may have to experiment with the more powerful uppercasing macro
%   from \texttt{mfirstuc.sty} once we internationalize.}
%    \begin{macrocode}
\def\current@section@level{document}%
\newcommand\currentsectionlevel{\lowercase\expandafter{\current@section@level}\xspace}%
\newcommand\Currentsectionlevel{\expandafter\MakeUppercase\current@section@level\xspace}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\skipomgroup}
%    \begin{macrocode}
\cs_new_protected:Npn \skipomgroup {
  \ifcase\l_document_structure_section_level_int
  \or\stepcounter{part}
  \or\stepcounter{chapter}
  \or\stepcounter{section}
  \or\stepcounter{subsection}
  \or\stepcounter{subsubsection}
  \or\stepcounter{paragraph}
  \or\stepcounter{subparagraph}
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{blindfragment}
%    \begin{macrocode}
\newcommand\at@begin@blindomgroup[1]{}
\newenvironment{blindfragment}
{
  \int_incr:N\l_document_structure_section_level_int
  \at@begin@blindomgroup\l_document_structure_section_level_int
}{}
%    \end{macrocode}
% \end{environment}
%
% \begin{macro}{\omgroup@nonum}
%   convenience macro: |\omgroup@nonum{|\meta{level}|}{|\meta{title}|}| makes an unnumbered
%   sectioning with title \meta{title} at level \meta{level}.
%    \begin{macrocode}
\newcommand\omgroup@nonum[2]{
  \ifx\hyper@anchor\@undefined\else\phantomsection\fi
  \addcontentsline{toc}{#1}{#2}\@nameuse{#1}*{#2}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\omgroup@num}
%   convenience macro: |\omgroup@nonum{|\meta{level}|}{|\meta{title}|}| makes numbered
%   sectioning with title \meta{title} at level \meta{level}. We have to check the |short|
%   key was given in the |omgroup| environment and -- if it is use it. But how to do that
%   depends on whether the |rdfmeta| package has been loaded. In the end we call
%   |\sref@label@id| to enable crossreferencing.
%    \begin{macrocode}
\newcommand\omgroup@num[2]{
  \tl_if_empty:NTF \l_@@_omgroup_short_tl {
    \@nameuse{#1}{#2}
  }{
    \cs_if_exist:NTF\rdfmeta@sectioning{
      \@nameuse{rdfmeta@#1@old}[\l_@@_omgroup_short_tl]{#2}
    }{
      \@nameuse{#1}[\l_@@_omgroup_short_tl]{#2}
    }
  }
%\sref@label@id@arg{\omdoc@sect@name~\@nameuse{the#1}}\omgroup@id
}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{sfragment}
%    \begin{macrocode}
\keys_define:nn { document-structure / omgroup }{
  id            .str_set_x:N = \l_@@_omgroup_id_str,
  date          .str_set_x:N = \l_@@_omgroup_date_str,
  creators      .clist_set:N = \l_@@_omgroup_creators_clist,
  contributors  .clist_set:N = \l_@@_omgroup_contributors_clist,
  srccite       .tl_set:N    = \l_@@_omgroup_srccite_tl,
  type          .tl_set:N    = \l_@@_omgroup_type_tl,
  short         .tl_set:N    = \l_@@_omgroup_short_tl,
  display       .tl_set:N    = \l_@@_omgroup_display_tl,
  intro         .tl_set:N    = \l_@@_omgroup_intro_tl,
  loadmodules   .bool_set:N  = \l_@@_omgroup_loadmodules_bool
}
\cs_new_protected:Nn \_@@_omgroup_args:n {
  \str_clear:N \l_@@_omgroup_id_str
  \str_clear:N \l_@@_omgroup_date_str
  \clist_clear:N \l_@@_omgroup_creators_clist
  \clist_clear:N \l_@@_omgroup_contributors_clist
  \tl_clear:N \l_@@_omgroup_srccite_tl
  \tl_clear:N \l_@@_omgroup_type_tl
  \tl_clear:N \l_@@_omgroup_short_tl
  \tl_clear:N \l_@@_omgroup_display_tl
  \tl_clear:N \l_@@_omgroup_intro_tl
  \bool_set_false:N \l_@@_omgroup_loadmodules_bool
  \keys_set:nn { document-structure / omgroup } { #1 }
}
%    \end{macrocode}
% we define a switch for numbering lines and a hook for the beginning of groups: The
% \DescribeMacro{\at@begin@omgroup}|\at@begin@omgroup| macro allows customization. It is
% run at the beginning of the |omgroup|, i.e. after the section heading.
%    \begin{macrocode}
\newif\if@mainmatter\@mainmattertrue
\newcommand\at@begin@omgroup[3][]{}
%    \end{macrocode}
%
% Then we define a helper macro that takes care of the sectioning magic. It comes with its
% own key/value interface for customization.
%
%    \begin{macrocode}
\keys_define:nn { document-structure / sectioning }{
  name    .str_set_x:N  = \l_@@_sect_name_str   ,
  ref     .str_set_x:N  = \l_@@_sect_ref_str    ,
  clear   .bool_set:N   = \l_@@_sect_clear_bool ,
  clear   .default:n    = {true}                ,
  num     .bool_set:N   = \l_@@_sect_num_bool   ,
  num     .default:n    = {true}
}
\cs_new_protected:Nn \_@@_sect_args:n {
  \str_clear:N \l_@@_sect_name_str
  \str_clear:N \l_@@_sect_ref_str
  \bool_set_false:N \l_@@_sect_clear_bool
  \bool_set_false:N \l_@@_sect_num_bool
  \keys_set:nn { document-structure / sectioning } { #1 }
}
\newcommand\omdoc@sectioning[3][]{
  \_@@_sect_args:n {#1 }
  \let\omdoc@sect@name\l_@@_sect_name_str
  \bool_if:NT \l_@@_sect_clear_bool { \cleardoublepage }
  \if@mainmatter% numbering not overridden by frontmatter, etc.
    \bool_if:NTF \l_@@_sect_num_bool {
      \omgroup@num{#2}{#3}
    }{
      \omgroup@nonum{#2}{#3}
    }
    \def\current@section@level{\omdoc@sect@name}
  \else
    \omgroup@nonum{#2}{#3}
  \fi
}% if@mainmatter
%    \end{macrocode}
% and another one, if redefines the |\addtocontentsline| macro of {\LaTeX} to import the
% respective macros. It takes as an argument a list of module names.
%    \begin{macrocode}
\newcommand\omgroup@redefine@addtocontents[1]{%
%\edef\@@import{#1}%
%\@for\@I:=\@@import\do{%
%\edef\@path{\csname module@\@I  @path\endcsname}%
%\@ifundefined{tf@toc}\relax%
%     {\protected@write\tf@toc{}{\string\@requiremodules{\@path}}}}
%\ifx\hyper@anchor\@undefined% hyperref.sty loaded?
%\def\addcontentsline##1##2##3{%
%\addtocontents{##1}{\protect\contentsline{##2}{\string\withusedmodules{#1}{##3}}{\thepage}}}
%\else% hyperref.sty not loaded
%\def\addcontentsline##1##2##3{%
%\addtocontents{##1}{\protect\contentsline{##2}{\string\withusedmodules{#1}{##3}}{\thepage}{\@currentHref}}}%
%\fi
}% hypreref.sty loaded?
%    \end{macrocode}
% now the |omgroup| environment itself. This takes care of the table of contents via the
% helper macro above and then selects the appropriate sectioning command from
% |article.cls|. It also registeres the current level of omgroups in the |\omgroup@level|
% counter. 
%    \begin{macrocode}
\newenvironment{sfragment}[2][]% keys, title
{
  \_@@_omgroup_args:n { #1 }%\sref@target%
%    \end{macrocode}
% If the |loadmodules| key is set on |\begin{sfragment}|, we redefine the |\addcontetsline|
%   macro that determines how the sectioning commands below construct the entries for the
%   table of contents.
%    \begin{macrocode}
  \bool_if:NT \l_@@_omgroup_loadmodules_bool {
    \omgroup@redefine@addtocontents{
      %\@ifundefined{module@id}\used@modules%
      %{\@ifundefined{module@\module@id @path}{\used@modules}\module@id}
    }
  }
%    \end{macrocode}
% now we only need to construct the right sectioning depending on the value of
% |\section@level|.
%    \begin{macrocode}
  \int_incr:N\l_document_structure_section_level_int
  \ifcase\l_document_structure_section_level_int
    \or\omdoc@sectioning[name=\omdoc@part@kw,clear,num]{part}{#2}
    \or\omdoc@sectioning[name=\omdoc@chapter@kw,clear,num]{chapter}{#2}
    \or\omdoc@sectioning[name=\omdoc@section@kw,num]{section}{#2}
    \or\omdoc@sectioning[name=\omdoc@subsection@kw,num]{subsection}{#2}
    \or\omdoc@sectioning[name=\omdoc@subsubsection@kw,num]{subsubsection}{#2}
    \or\omdoc@sectioning[name=\omdoc@paragraph@kw,ref=this \omdoc@paragraph@kw]{paragraph}{#2}
    \or\omdoc@sectioning[name=\omdoc@subparagraph@kw,ref=this \omdoc@subparagraph@kw]{paragraph}{#2}
  \fi
  \at@begin@omgroup[#1]\l_document_structure_section_level_int{#2}
  \str_if_empty:NF \l_@@_omgroup_id_str {
    \stex_ref_new_doc_target:n\l_@@_omgroup_id_str
  }
}% for customization
{}
%    \end{macrocode}
% \end{environment}
%
% and finally, we localize the sections
%    \begin{macrocode}
\newcommand\omdoc@part@kw{Part}
\newcommand\omdoc@chapter@kw{Chapter}
\newcommand\omdoc@section@kw{Section}
\newcommand\omdoc@subsection@kw{Subsection}
\newcommand\omdoc@subsubsection@kw{Subsubsection}
\newcommand\omdoc@paragraph@kw{paragraph}
\newcommand\omdoc@subparagraph@kw{subparagraph}
%    \end{macrocode}
%
% \end{sfragment}
%
% \begin{sfragment}[id=sec:user:docmatter]{Front and Backmatter}
% 
%   Index markup is provided by the |omtext| package~\cite{Kohlhase:smmtf:git}, so in the
%   |document-structure| package we only need to supply the corresponding |\printindex| command, if it
%   is not already defined
% \begin{macro}{\printindex}
%    \begin{macrocode}
\providecommand\printindex{\IfFileExists{\jobname.ind}{\input{\jobname.ind}}{}}
%    \end{macrocode}
% \end{macro}
% 
% some classes (e.g. |book.cls|) already have |\frontmatter|, |\mainmatter|, and
% |\backmatter| macros. As we want to define |frontmatter| and |backmatter| environments,
% we save their behavior (possibly defining it) in |orig@*matter| macros and make them
% undefined (so that we can define the environments).
%    \begin{macrocode}
\cs_if_exist:NTF\frontmatter{
  \let\_@@_orig_frontmatter\frontmatter
  \let\frontmatter\relax
}{
  \tl_set:Nn\_@@_orig_frontmatter{
    \clearpage
    \@mainmatterfalse
    \pagenumbering{roman}
  }
}
\cs_if_exist:NTF\backmatter{
  \let\_@@_orig_backmatter\backmatter
  \let\backmatter\relax
}{
  \tl_set:Nn\_@@_orig_backmatter{
    \clearpage
    \@mainmatterfalse
    \pagenumbering{roman}
  }
}
%    \end{macrocode}
%
% Using these, we can now define the |frontmatter| and |backmatter| environments
% 
% \begin{environment}{frontmatter}
%  we use the |\orig@frontmatter| macro defined above and |\mainmatter| if it exists,
%  otherwise we define it.  
%    \begin{macrocode}
\newenvironment{frontmatter}{
  \_@@_orig_frontmatter
}{
  \cs_if_exist:NTF\mainmatter{
    \mainmatter
  }{
    \clearpage
    \@mainmattertrue
    \pagenumbering{arabic}
  }
}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{backmatter}
%   As backmatter is at the end of the document, we do nothing for |\endbackmatter|. 
%    \begin{macrocode}
\newenvironment{backmatter}{
  \_@@_orig_backmatter
}{
  \cs_if_exist:NTF\mainmatter{
    \mainmatter
  }{
    \clearpage
    \@mainmattertrue
    \pagenumbering{arabic}
  }
}
%    \end{macrocode}
%
% finally, we make sure that page numbering is arabic and we have main matter as the default
%
%    \begin{macrocode}
\@mainmattertrue\pagenumbering{arabic}
%    \end{macrocode}
% \end{environment}
% \end{sfragment}
%
% \begin{macro}{\prematurestop}
%   We initialize |\afterprematurestop|, and provide 
%   |\prematurestop@endomgroup| which looks up |\omgroup@level| and recursively ends
%   enough |{sfragment}|s. 
%    \begin{macrocode}
\def \c_@@_document_str{document} 
\newcommand\afterprematurestop{}
\def\prematurestop@endomgroup{
  \unless\ifx\@currenvir\c_@@_document_str
    \expandafter\expandafter\expandafter\end\expandafter\expandafter\expandafter{\expandafter\@currenvir\expandafter}
    \expandafter\prematurestop@endomgroup
  \fi
}
\providecommand\prematurestop{
  \message{Stopping~sTeX~processing~prematurely}
  \prematurestop@endomgroup
  \afterprematurestop
  \end{document}
}
%    \end{macrocode}
% \end{macro}
%
% \iffalse
% \begin{sfragment}[id=sec:impl:share]{Structure Sharing}
%   \ednote{The following is simply copied over from the |latexml| package, which we
%   eliminated, we should integrate better.}
%    \begin{macrocode}
\iffalse
\providecommand{\lxDocumentID}[1]{}%
\def\LXMID#1#2{\expandafter\gdef\csname xmarg#1\endcsname{#2}\csname xmarg#1\endcsname}
\def\LXMRef#1{\csname xmarg#1\endcsname}
%    \end{macrocode}
%
% \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}
\long\def\STRlabel#1#2{\STRlabeldef{#1}{#2}{#2}}
%    \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.\ednote{MK: we need to do something about the
%   ref!}
%    \begin{macrocode}
\newcommand\STRcopy[2][]{\expandafter\ifx\csname STR@#2\endcsname\relax
\message{STR warning: reference #2 undefined!}
\else\csname STR@#2\endcsname\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\STRsemantics}
%    if we have a presentation form and a semantic form, then we can use
%    \begin{macrocode}
\newcommand\STRsemantics[3][]{#2\def\@test{#1}\ifx\@test\@empty\STRlabeldef{#1}{#2}\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\STRlabeldef}
%    This is the macro that does the actual labeling. Is it called inside |\STRlabel|
%    \begin{macrocode}
\def\STRlabeldef#1{\expandafter\gdef\csname STR@#1\endcsname}
\fi
%    \end{macrocode}
% \end{macro}
% \end{sfragment}
%\fi
% 
% \begin{sfragment}[id=sec:impl:gvars]{Global Variables}
%
% \begin{macro}{\setSGvar}
%   set a global variable
%    \begin{macrocode}
\RequirePackage{etoolbox}
\newcommand\setSGvar[1]{\@namedef{sTeX@Gvar@#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\useSGvar}
%   use a global variable
%    \begin{macrocode}
\newrobustcmd\useSGvar[1]{%
  \@ifundefined{sTeX@Gvar@#1}
  {\PackageError{document-structure}
    {The sTeX Global variable #1 is undefined}
    {set it with \protect\setSGvar}}
\@nameuse{sTeX@Gvar@#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifSGvar}
%   execute something conditionally based on the state of the global variable. 
%    \begin{macrocode}
\newrobustcmd\ifSGvar[3]{\def\@test{#2}%
  \@ifundefined{sTeX@Gvar@#1}
  {\PackageError{document-structure}
    {The sTeX Global variable #1 is undefined}
    {set it with \protect\setSGvar}}
  {\expandafter\ifx\csname sTeX@Gvar@#1\endcsname\@test #3\fi}}
%    \end{macrocode}
% \end{macro}
%
% \end{sfragment}
% \end{sfragment}
% \end{sfragment}
%
% \end{implementation}
\endinput
% \iffalse
%%% Local Variables: 
%%% mode: doctex
%%% TeX-master: t
%%% End: 
% \fi
% LocalWords:  GPL structuresharing STR omdoc dtx stex CPERL LoadClass url dc filedate om 
% LocalWords:  RequirePackage RegisterNamespace namespace xsl DocType ltxml dtd DAG hline
% LocalWords:  ltx DefEnvironment beforeDigest AssignValue inPreamble getGullet rangle
% LocalWords:  afterDigest keyval omgroup DefKeyVal Semiverbatim KeyVal srcf frontmatter
% LocalWords:  OptionalKeyVals DefParameterType IfBeginFollows skipSpaces CMP rangle xdef
% LocalWords:  ifNext DefMacro needwrapper unlist DefConstructor omtext bgroup showmods
% LocalWords:  useCMPItemizations RefStepItemCounter egroup beginItemize li di pathsuris
% LocalWords:  beforeDigestEnd dt autoclose ul ol dl env showignores srcref Cwd rdfmeta
% LocalWords:  afterOpen LastSeenCMP autoClose DefCMPEnvironment proto ToString st@flow
% LocalWords:  addAttribute nlex nlcex omdocColorMacro args tok MergeFont qw setion@level
% LocalWords:  TokenizeInternal toString isMath foreach maybeCloseElement id'd Backmatter
% LocalWords:  autoOpen minipage footnotesize scriptsize numberIt whatsit href endinput
% LocalWords:  getAttribute setAttribute OMDoc RelaxNGSchema noindex xml lec KeyVals
% LocalWords:  Subsubsection useDefaultItemizations refundefinedtrue sblockquote defindex
% LocalWords:  DefCMPConstructor sinlinequote idx idt ide idp emph  extrefs sref Tokenize
% LocalWords:  flushleft flushright DeclareOption PassOptions undef cls iffalse noauxreq
% LocalWords:  ProcessOptions subparagraph ignoresfalse ignorestrue texttt ttin behavior
% LocalWords:  texttt latexml fileversion maketitle newpage tableofcontents cwd srccite
% LocalWords:  newpage ednote ctancite dmt03 smms inlinedef STRlabel STRcopy loadmodules
% LocalWords:  STRlabel STRsemantics STRsemantics textcolor printbibliography loadmodules
% LocalWords:  textsf langle textsf langle respetively orig renewcommand cdir capitalized
% LocalWords:  baseuri baseuri baselocal baselocal SOURCEFILE cooluri newif ifx tf@toc
% LocalWords:  SOURCEBASE chapterfalse partfalse newcount ifshow chaptertrue initialize
% LocalWords:  parttrue srefaddidkey newenvironment textbf compactenum showmeta tf@toc
% LocalWords:  noindent noindent ignorespaces ifnum thepart thechapter regexp color.sty
% LocalWords:  thesection thesubsection thesubsubsection needswrapper itshape xmarg xmarg
% LocalWords:  textgreater renewenvironment excludecomment STRlabeldef csname Section,num
% LocalWords:  expandafter endcsname xref newcommand gdef doctex metakeys Hacky arabic
% LocalWords:  metasetkeys addmetakey printindex providecommand jobname.ind importmodules
% LocalWords:  jobname.ind tocdepth hateq ensuremath xspace hatequiv equiv NeedsTeXFormat
% LocalWords:  textleadsto leadsto etoolbox blindomgroup blindomgroup docstruct setSGvar
% LocalWords:  compactitem exfig vspace currentsectionlevel currentsectionlevel setSGvar
% LocalWords:  ldots URLBASE ifclass bookfalse booktrue currentsetionlevel thedocument@ID
% LocalWords:  nonum phantomsection nameuse numtrue numfalse contentsline unnum vname
% LocalWords:  thepage hypreref.sty ifcase cleardoublepage frontmatterfalse customization
% LocalWords:  frontmattertrue pagenumbering setcounter hyperref.sty addcontetsline ctext
%  LocalWords:  mfirstuc.sty internationalize documentkeys withusedmodules Part,clear,num
% \endinput
% Local Variables:
% mode: doctex
% TeX-master: t
% End:
%  LocalWords:  crossreferencing Chapter,clear,num Subsection,num Subsubsection,num cslet
%  LocalWords:  Paragraph,ref Subparagraph,ref useSGvar useSGvar ifSGvar ifSGvar topsect
%  LocalWords:  sTeX@Gvar kvoptions omdoc@cls,prefix book,topsect xappto omdoc@sty,prefix
%  LocalWords:  ifdefstring ifcsdef cslet localization ngerman omdoc-ngerman.ldf omgroups
%  LocalWords:  Kohlhase:smmtf endbackmatter prematurestop prematurestop clear,num
%  LocalWords:  prematurestop@endomgroup textbackslash import_graph.py lmhtools bibfolder
%  LocalWords:  stepcounter jobname.dtx clist_set:Nx l_tmpa_clist clist_if_in:NnT
%  LocalWords:  ExplSyntaxOff stex_ref_new_doc_target:n
