summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/stex/source/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/stex/source/extensions')
-rw-r--r--macros/latex/contrib/stex/source/extensions/Makefile24
-rw-r--r--macros/latex/contrib/stex/source/extensions/document-structure.dtx922
-rw-r--r--macros/latex/contrib/stex/source/extensions/extensions.ins39
-rw-r--r--macros/latex/contrib/stex/source/extensions/hwexam.dtx684
-rw-r--r--macros/latex/contrib/stex/source/extensions/notesslides.dtx1078
-rw-r--r--macros/latex/contrib/stex/source/extensions/problem.dtx910
-rw-r--r--macros/latex/contrib/stex/source/extensions/tikzinput.dtx146
7 files changed, 3803 insertions, 0 deletions
diff --git a/macros/latex/contrib/stex/source/extensions/Makefile b/macros/latex/contrib/stex/source/extensions/Makefile
new file mode 100644
index 0000000000..6a6b18a4c8
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/Makefile
@@ -0,0 +1,24 @@
+DTX = $(shell ls *.dtx)
+DOC = $(DTX:%.dtx=%.pdf)
+INS = extensions.ins
+
+PDFLATEX = pdflatex -interaction=batchmode
+TEXDIR = ../../tex
+TEXINPUTS = $(TEXDIR)//:
+
+all: package doc
+
+doc: $(DOC)
+
+package: $(DTX) $(INS)
+ $(PDFLATEX) $(INS)
+ mv *.sty *.cls $(TEXDIR)
+
+$(DOC): %.pdf: %.dtx
+ $(PDFLATEX) $<
+ biber -q $(basename $<)
+ $(PDFLATEX) $<
+
+
+echo:
+ @echo $(DTX)
diff --git a/macros/latex/contrib/stex/source/extensions/document-structure.dtx b/macros/latex/contrib/stex/source/extensions/document-structure.dtx
new file mode 100644
index 0000000000..80c95d643b
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/document-structure.dtx
@@ -0,0 +1,922 @@
+% \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/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/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/24}{3.0.0}{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/24}{3.0.0}{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{omdoc-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
diff --git a/macros/latex/contrib/stex/source/extensions/extensions.ins b/macros/latex/contrib/stex/source/extensions/extensions.ins
new file mode 100644
index 0000000000..e3594e88cf
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/extensions.ins
@@ -0,0 +1,39 @@
+ %%
+%% This file generates files required to use the ed package.
+%% At your command prompt write
+%%
+%% latex extensions.ins
+%%
+%% Copyright (c) 2021 Michael Kohlhase
+%%
+%% This file is distributed under the terms of the LaTeX Project Public
+%% License from CTAN archives in directory macros/latex/base/lppl.txt.
+%% Either version 1.0 or, at your option, any later version.
+%%
+\input docstrip
+\preamble
+\endpreamble
+
+\keepsilent
+\askforoverwritefalse
+
+\generate{
+ \file{document-structure.cls}{\from{document-structure.dtx}{cls}}
+ \file{document-structure.sty}{\from{document-structure.dtx}{package}}
+ \file{notesslides.cls}{\from{notesslides.dtx}{cls}}
+ \file{notesslides.sty}{\from{notesslides.dtx}{package}}
+ \file{tikzinput.sty}{\from{tikzinput.dtx}{package}}
+ \file{stex-tikzinput.sty}{\from{tikzinput.dtx}{stex}}
+ \file{problem.sty}{\from{problem.dtx}{package}}
+ \file{hwexam.sty}{\from{hwexam.dtx}{package}}
+ \file{hwexam.cls}{\from{hwexam.dtx}{cls}}
+}
+
+\Msg{*}
+\Msg{* You probably need to move the generated style files into a directory searched by TeX.}
+\Msg{*}
+\Msg{* And don't forget to refresh your filename database}
+\Msg{* if your TeX distribution uses such a database.}
+\Msg{*}
+
+\endbatchfile
diff --git a/macros/latex/contrib/stex/source/extensions/hwexam.dtx b/macros/latex/contrib/stex/source/extensions/hwexam.dtx
new file mode 100644
index 0000000000..3136f488d7
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/hwexam.dtx
@@ -0,0 +1,684 @@
+% \iffalse meta-comment
+% An Infrastructure for marking up Assignments
+% 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/
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\def\bibfolder{../../lib/bib}
+\input{../../doc/docheader}
+
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%\iffalse\CheckSum{464}\fi
+%
+% ^^A\changes{v0.9}{2006/09/18}{First Version with Documentation}
+%
+% \GetFileInfo{hwexam.sty}
+%
+% \MakeShortVerb{\|}
+% \def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\latexml{\scsys{LaTeXML}}
+%
+% \title{\texttt{hwexam.sty/cls}: An Infrastructure for formatting Assignments
+% and Exams\thanks{Version {\fileversion} (last revised {\filedate})}}
+% \author{Michael Kohlhase\\
+% FAU Erlangen-N\"urnberg\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+%\ifinfulldoc\else
+% This is the documentation for the \pkg{hwexam} 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/hwexam}
+% \fi
+%
+% \begin{documentation}
+%
+% The |hwexam| package and class allows individual course assignment sheets and
+% compound assignment documents using problem files marked up with the |problem| package.
+% \setcounter{tocdepth}{2}\tableofcontents\newpage
+%
+%\section{Introduction}\label{sec:intro}
+%
+% The |hwexam| package and class supplies an infrastructure that allows to format
+% nice-looking assignment sheets by simply including problems from problem files marked up
+% with the |problem| package~\cite{Kohlhase:problem}. It is designed to be
+% compatible with |problems.sty|, and inherits some of the functionality.
+%
+% \section{The User Interface}
+%
+% \subsection{Package and Class Options}\label{sec:user:options}
+%
+% The |hwexam| package and class take the options |solutions|, |notes|, |hints|, |gnotes|,
+% |pts|, |min|, and |boxed| that are just passed on to the |problems| package (cf. its
+% documentation for a description of the intended behavior).
+%
+% If the \DescribeMacro{showmeta}|showmeta| option is set, then the metadata keys are
+% shown (see~\cite{Kohlhase:metakeys} for details and customization options).
+%
+% The |hwexam| class additionally accepts the options |report|, |book|, |chapter|, |part|,
+% and |showignores|, of the |omdoc| package~\cite{Kohlhase:smomdl} on which it is
+% based and passes them on to that. For the |extrefs| option
+% see~\cite{Kohlhase:sref}.
+%
+% \subsection{Assignments}
+%
+% This package supplies the \DescribeEnv{assignment}|assignment| environment that groups
+% problems into assignment sheets. It takes an optional KeyVal argument with the keys
+% \DescribeMacro{number}|number| (for the assignment number; if none is given, 1 is
+% assumed as the default or --- in multi-assignment documents --- the ordinal of the
+% |assignment| environment), \DescribeMacro{title}|title| (for the assignment title; this
+% is referenced in the title of the assignment sheet), \DescribeMacro{type}|type| (for the
+% assignment type; e.g. ``quiz'', or ``homework''), \DescribeMacro{given}|given| (for the
+% date the assignment was given), and \DescribeMacro{due}|due| (for the date the
+% assignment is due).
+%
+% \subsection{Typesetting Exams}
+%
+% Furthermore, the |hwexam| package takes the option
+% \DescribeMacro{multiple}|multiple| that allows to combine multiple assignment sheets into
+% a compound document (the assignment sheets are treated as section, there is a table of
+% contents, etc.).
+%
+% Finally, there is the option \DescribeMacro{test}|test| that modifies the behavior to
+% facilitate formatting tests. Only in |test| mode, the macros |\testspace|,
+% |\testnewpage|, and |\testemptypage| have an effect: they generate space for the
+% students to solve the given problems. Thus they can be left in the {\LaTeX} source.
+%
+% \DescribeMacro{\testspace}|\testspace| takes an argument that expands to a dimension,
+% and leaves vertical space accordingly. \DescribeMacro{\testnewpage}|\testnewpage| makes
+% a new page in |test| mode, and \DescribeMacro{\testemptypage}|\testemptypage| generates
+% an empty page with the cautionary message that this page was intentionally left empty.
+%
+% Finally, the \DescribeEnv{testheading}|\testheading| takes an optional keyword argument
+% where the keys \DescribeMacro{duration}|duration| specifies a string that specifies the
+% duration of the test, \DescribeMacro{min}|min| specifies the equivalent in number of
+% minutes, and \DescribeMacro{reqpts}|reqpts| the points that are required for a perfect
+% grade.
+% \begin{exfig}[ht]
+% \makeatletter
+% \@problem{1.1}{4}{10}
+% \@problem{2.1}{4}{8}
+% \@problem{2.2}{6}{10}
+% \@problem{2.3}{6}{10}
+% \@problem{3.1}{4}{8}
+% \@problem{3.2}{4}{8}
+% \@problem{3.3}{2}{4}
+% \makeatother
+% \begin{verbatim}
+% \title{320101 General Computer Science (Fall 2010)}
+% \begin{testheading}[duration=one hour,min=60,reqpts=27]
+% Good luck to all students!
+% \end{testheading}
+% \end{verbatim}
+% \vspace*{-3ex}\hrule\vspace*{.5ex} formats to\vspace*{1ex}
+% \hrule\par\noindent\vspace*{2ex}
+% \title{320101 General Computer Science (Fall 2010)}
+% \begin{testheading}[duration=one hour,min=60,reqpts=27]
+% good luck
+% \end{testheading}
+% \caption{A generated test heading.}\label{fig:testheading}
+% \end{exfig}
+%
+% \subsection{Including Assignments}
+%
+% The \DescribeMacro{\inputassignment}|\inputassignment| macro can be used to input
+% an assignment from another file. It takes an optional KeyVal argument and a second
+% argument which is a path to the file containing the problem (the macro assumes that
+% there is only one |assignment| environment in the included file). The keys
+% \DescribeMacro{number}|number|, \DescribeMacro{title}|title|,
+% \DescribeMacro{type}|type|, \DescribeMacro{given}|given|, and \DescribeMacro{due}|due|
+% are just as for the |assignment| environment and (if given) overwrite the ones specified
+% in the |assignment| environment in the included file.
+%
+% \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 GitHub repository~\cite{sTeX:github:on}.
+% \begin{enumerate}
+% \item none reported yet.
+% \end{enumerate}
+%
+% \end{documentation}
+%
+%\begin{implementation}
+% \section{Implementation: The hwexam Class}\label{sec:impl:cls}
+%
+% The functionality is spread over the |hwexam| class and package. The class provides
+% the |document| environment and pre-loads some convenience packages, whereas the package
+% provides the concrete functionality.
+%
+% \subsection{Class Options}\label{sec:impl:cls:options}
+%
+% To initialize the |hwexam| class, we declare and process the necessary options by
+% passing them to the respective packages and classes they come from.
+%
+% \begin{macrocode}
+%<@@=hwexam>
+%<*cls>
+\ProvidesExplClass{hwexam}{2022/02/24}{3.0.0}{homework assignments and exams}
+\RequirePackage{l3keys2e}
+\DeclareOption*{
+ \PassOptionsToClass{\CurrentOption}{document-structure}
+ \PassOptionsToPackage{\CurrentOption}{stex}
+ \PassOptionsToPackage{\CurrentOption}{hwexam}
+ \PassOptionsToPackage{\CurrentOption}{tikzinput}
+}
+\ProcessOptions
+% \end{macrocode}
+%
+% We load |omdoc.cls|, and the desired packages. For the {\latexml} bindings, we make
+% sure the right packages are loaded.
+%
+% \begin{macrocode}
+\LoadClass{document-structure}
+\RequirePackage{stex}
+\RequirePackage{hwexam}
+\RequirePackage{tikzinput}
+\RequirePackage{graphicx}
+\RequirePackage{a4wide}
+\RequirePackage{amssymb}
+\RequirePackage{amstext}
+\RequirePackage{amsmath}
+% \end{macrocode}
+% Finally, we register another keyword for the |document| environment. We give a default
+% assignment type to prevent errors
+% \begin{macrocode}
+\newcommand\assig@default@type{\hwexam@assignment@kw}
+\def\document@hwexamtype{\assig@default@type}
+%<@@=document_structure>
+\keys_define:nn { document-structure / document }{
+ id .str_set_x:N = \c_document_structure_document_id_str,
+ hwexamtype .tl_set:N = \document@hwexamtype
+}
+%<@@=hwexam>
+%</cls>
+% \end{macrocode}
+%
+% \section{Implementation: The hwexam Package}
+%
+% \subsection{Package Options}
+%
+% The first step is to declare (a few) package options that handle whether certain
+% information is printed or not. Some come with their own conditionals that are set by the
+% options, the rest is just passed on to the |problems| package.
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage{hwexam}{2022/02/24}{3.0.0}{homework assignments and exams}
+\RequirePackage{l3keys2e}
+
+\newif\iftest\testfalse
+\DeclareOption{test}{\testtrue}
+\newif\ifmultiple\multiplefalse
+\DeclareOption{multiple}{\multipletrue}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{problem}}
+\ProcessOptions
+% \end{macrocode}
+% Then we make sure that the necessary packages are loaded (in the right versions).
+% \begin{macrocode}
+\RequirePackage{keyval}[1997/11/10]
+\RequirePackage{problem}
+% \end{macrocode}
+%
+% \begin{macro}{\hwexam@*@kw}
+% For multilinguality, we define internal macros for keywords that can be specialized in
+% |*.ldf| files.
+% \begin{macrocode}
+\newcommand\hwexam@assignment@kw{Assignment}
+\newcommand\hwexam@given@kw{Given}
+\newcommand\hwexam@due@kw{Due}
+\newcommand\hwexam@testemptypage@kw{This~page~was~intentionally~left~
+ blank~for~extra~space}
+ \def\hwexam@minutes@kw{minutes}
+\newcommand\correction@probs@kw{prob.}
+\newcommand\correction@pts@kw{total}
+\newcommand\correction@reached@kw{reached}
+\newcommand\correction@sum@kw{Sum}
+\newcommand\correction@grade@kw{grade}
+\newcommand\correction@forgrading@kw{To~be~used~for~grading,~do~not~write~here}
+% \end{macrocode}
+% \end{macro}
+%
+% For the other languages, we set up triggers
+% \begin{macrocode}
+\AddToHook{begindocument}{
+ \ltx@ifpackageloaded{babel}{
+ \makeatletter
+ \clist_set:Nx \l_tmpa_clist {\bbl@loaded}
+ \clist_if_in:NnT \l_tmpa_clist {ngerman}{
+ \input{hwexam-ngerman.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {finnish}{
+ \input{hwexam-finnish.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {french}{
+ \input{hwexam-french.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {russian}{
+ \input{hwexam-russian.ldf}
+ }
+ \makeatother
+ }{}
+}
+
+% \end{macrocode}
+% \subsection{Assignments}
+%
+% Then we set up a counter for problems and make the problem counter inherited from
+% |problem.sty| depend on it. Furthermore, we specialize the |\prob@label| macro to take
+% the assignment counter into account.
+% \begin{macrocode}
+\newcounter{assignment}
+\numberproblemsin{assignment}
+\renewcommand\prob@label[1]{\assignment@number.#1}
+% \end{macrocode}
+%
+% We will prepare the keyval support for the |assignment| environment.
+%
+% \begin{macrocode}
+\keys_define:nn { hwexam / assignment } {
+ id .str_set_x:N = \l_@@_assign_id_str,
+ number .int_set:N = \l_@@_assign_number_int,
+ title .tl_set:N = \l_@@_assign_title_tl,
+ type .tl_set:N = \l_@@_assign_type_tl,
+ given .tl_set:N = \l_@@_assign_given_tl,
+ due .tl_set:N = \l_@@_assign_due_tl,
+ loadmodules .code:n = {
+ \bool_set_true:N \l_@@_assign_loadmodules_bool
+ }
+}
+\cs_new_protected:Nn \_@@_assignment_args:n {
+ \str_clear:N \l_@@_assign_id_str
+ \int_set:Nn \l_@@_assign_number_int {-1}
+ \tl_clear:N \l_@@_assign_title_tl
+ \tl_clear:N \l_@@_assign_type_tl
+ \tl_clear:N \l_@@_assign_given_tl
+ \tl_clear:N \l_@@_assign_due_tl
+ \bool_set_false:N \l_@@_assign_loadmodules_bool
+ \keys_set:nn { hwexam / assignment }{ #1 }
+}
+% \end{macrocode}
+%
+% The next three macros are intermediate functions that handle the case gracefully, where
+% the respective token registers are undefined.
+%
+% The |\given@due| macro prints information about the given and due status of the
+% assignment. Its arguments specify the brackets.
+%
+% \begin{macrocode}
+\newcommand\given@due[2]{
+ \bool_lazy_all:nF {
+ {\tl_if_empty_p:V \l_@@_inclassign_given_tl}
+ {\tl_if_empty_p:V \l_@@_assign_given_tl}
+ {\tl_if_empty_p:V \l_@@_inclassign_due_tl}
+ {\tl_if_empty_p:V \l_@@_assign_due_tl}
+ }{ #1 }
+
+ \tl_if_empty:NTF \l_@@_inclassign_given_tl {
+ \tl_if_empty:NF \l_@@_assign_given_tl {
+ \hwexam@given@kw\xspace\l_@@_assign_given_tl
+ }
+ }{
+ \hwexam@given@kw\xspace\l_@@_inclassign_given_tl
+ }
+
+ \bool_lazy_or:nnF {
+ \bool_lazy_and_p:nn {
+ \tl_if_empty_p:V \l_@@_inclassign_due_tl
+ }{
+ \tl_if_empty_p:V \l_@@_assign_due_tl
+ }
+ }{
+ \bool_lazy_and_p:nn {
+ \tl_if_empty_p:V \l_@@_inclassign_due_tl
+ }{
+ \tl_if_empty_p:V \l_@@_assign_due_tl
+ }
+ }{ ,~ }
+
+ \tl_if_empty:NTF \l_@@_inclassign_due_tl {
+ \tl_if_empty:NF \l_@@_assign_due_tl {
+ \hwexam@due@kw\xspace \l_@@_assign_due_tl
+ }
+ }{
+ \hwexam@due@kw\xspace \l_@@_inclassign_due_tl
+ }
+
+ \bool_lazy_all:nF {
+ { \tl_if_empty_p:V \l_@@_inclassign_given_tl }
+ { \tl_if_empty_p:V \l_@@_assign_given_tl }
+ { \tl_if_empty_p:V \l_@@_inclassign_due_tl }
+ { \tl_if_empty_p:V \l_@@_assign_due_tl }
+ }{ #2 }
+}
+% \end{macrocode}
+%
+% \begin{macro}{\assignment@title}
+% This macro prints the title of an assignment, the local title is overwritten, if there
+% is one from the |\inputassignment|. |\assignment@title| takes three arguments the
+% first is the fallback when no title is given at all, the second and third go around
+% the title, if one is given.
+% \begin{macrocode}
+\newcommand\assignment@title[3]{
+ \tl_if_empty:NTF \l_@@_inclassign_title_tl {
+ \tl_if_empty:NTF \l_@@_assign_title_tl {
+ #1
+ }{
+ #2\l_@@_assign_title_tl#3
+ }
+ }{
+ #2\l_@@_inclassign_title_tl#3
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\assignment@number}
+% Like |\assignment@title| only for the number, and no around part.
+% \begin{macrocode}
+\newcommand\assignment@number{
+ \int_compare:nNnTF \l_@@_inclassign_number_int = {-1} {
+ \int_compare:nNnTF \l_@@_assign_number_int = {-1} {
+ \arabic{assignment}
+ } {
+ \int_use:N \l_@@_assign_number_int
+ }
+ }{
+ \int_use:N \l_@@_inclassign_number_int
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% With them, we can define the central |assignment| environment. This has two forms
+% (separated by |\ifmultiple|) in one we make a title block for an assignment sheet, and
+% in the other we make a section heading and add it to the table of contents. We first
+% define an assignment counter
+%
+% \begin{environment}{assignment}
+% For the |assignment| environment we delegate the work to the |@assignment| environment
+% that depends on whether |multiple| option is given.
+% \begin{macrocode}
+\newenvironment{assignment}[1][]{
+ \_@@_assignment_args:n { #1 }
+ %\sref@target
+ \int_compare:nNnTF \l_@@_assign_number_int = {-1} {
+ \global\stepcounter{assignment}
+ }{
+ \global\setcounter{assignment}{\int_use:N\l_@@_assign_number_int}
+ }
+ \setcounter{problem}{0}
+ \def\current@section@level{\document@hwexamtype}
+ %\sref@label@id{\document@hwexamtype \thesection}
+ \begin{@assignment}
+}{
+ \end{@assignment}
+}
+% \end{macrocode}
+% In the multi-assignment case we just use the |omdoc| environment for suitable
+% sectioning.
+% \begin{macrocode}
+\def\ass@title{
+ \protect\document@hwexamtype~\arabic{assignment}
+ \assignment@title{}{\;(}{)\;} -- \given@due{}{}
+}
+\ifmultiple
+ \newenvironment{@assignment}{
+ \bool_if:NTF \l_@@_assign_loadmodules_bool {
+ \begin{sfragment}[loadmodules]{\ass@title}
+ }{
+ \begin{sfragment}{\ass@title}
+ }
+ }{
+ \end{sfragment}
+ }
+% \end{macrocode}
+% for the single-page case we make a title block from the same components.
+% \begin{macrocode}
+\else
+ \newenvironment{@assignment}{
+ \begin{center}\bf
+ \Large\@title\strut\\
+ \document@hwexamtype~\arabic{assignment}\assignment@title{\;}{:\;}{\\}
+ \large\given@due{--\;}{\;--}
+ \end{center}
+ }{}
+\fi% multiple
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Including Assignments}
+%
+% \begin{macro}{\in*assignment}
+% This macro is essentially a glorified |\include| statement, it just sets some internal
+% macros first that overwrite the local points Importantly, it resets the |inclassig|
+% keys after the input.
+% \begin{macrocode}
+\keys_define:nn { hwexam / inclassignment } {
+ %id .str_set_x:N = \l_@@_assign_id_str,
+ number .int_set:N = \l_@@_inclassign_number_int,
+ title .tl_set:N = \l_@@_inclassign_title_tl,
+ type .tl_set:N = \l_@@_inclassign_type_tl,
+ given .tl_set:N = \l_@@_inclassign_given_tl,
+ due .tl_set:N = \l_@@_inclassign_due_tl,
+ mhrepos .str_set_x:N = \l_@@_inclassign_mhrepos_str
+}
+\cs_new_protected:Nn \_@@_inclassignment_args:n {
+ \int_set:Nn \l_@@_inclassign_number_int {-1}
+ \tl_clear:N \l_@@_inclassign_title_tl
+ \tl_clear:N \l_@@_inclassign_type_tl
+ \tl_clear:N \l_@@_inclassign_given_tl
+ \tl_clear:N \l_@@_inclassign_due_tl
+ \str_clear:N \l_@@_inclassign_mhrepos_str
+ \keys_set:nn { hwexam / inclassignment }{ #1 }
+}
+\_@@_inclassignment_args:n {}
+
+\newcommand\inputassignment[2][]{
+ \_@@_inclassignment_args:n { #1 }
+ \str_if_empty:NTF \l_@@_inclassign_mhrepos_str {
+ \input{#2}
+ }{
+ \stex_in_repository:nn{\l_@@_inclassign_mhrepos_str}{
+ \input{\mhpath{\l_@@_inclassign_mhrepos_str}{#2}}
+ }
+ }
+ \_@@_inclassignment_args:n {}
+}
+\newcommand\includeassignment[2][]{
+ \newpage
+ \inputassignment[#1]{#2}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Typesetting Exams}
+%
+% \begin{macro}{\quizheading}
+% \begin{macrocode}
+\ExplSyntaxOff
+\newcommand\quizheading[1]{%
+ \def\@tas{#1}%
+ \large\noindent NAME: \hspace{8cm} MAILBOX:\\[2ex]%
+ \ifx\@tas\@empty\else%
+ \noindent TA:~\@for\@I:=\@tas\do{{\Large$\Box$}\@I\hspace*{1em}}\\[2ex]%
+ \fi%
+}
+\ExplSyntaxOn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\testheading}
+% \begin{macrocode}
+
+\def\hwexamheader{\input{hwexam-default.header}}
+
+\def\hwexamminutes{
+ \tl_if_empty:NTF \testheading@duration {
+ {\testheading@min}~\hwexam@minutes@kw
+ }{
+ \testheading@duration
+ }
+}
+
+\keys_define:nn { hwexam / testheading } {
+ min .tl_set:N = \testheading@min,
+ duration .tl_set:N = \testheading@duration,
+ reqpts .tl_set:N = \testheading@reqpts,
+ tools .tl_set:N = \testheading@tools
+}
+\cs_new_protected:Nn \_@@_testheading_args:n {
+ \tl_clear:N \testheading@min
+ \tl_clear:N \testheading@duration
+ \tl_clear:N \testheading@reqpts
+ \tl_clear:N \testheading@tools
+ \keys_set:nn { hwexam / testheading }{ #1 }
+}
+\newenvironment{testheading}[1][]{
+ \_@@_testheading_args:n{ #1 }
+ \newcount\check@time\check@time=\testheading@min
+ \advance\check@time by -\theassignment@totalmin
+ \newif\if@bonuspoints
+ \tl_if_empty:NTF \testheading@reqpts {
+ \@bonuspointsfalse
+ }{
+ \newcount\bonus@pts
+ \bonus@pts=\theassignment@totalpts
+ \advance\bonus@pts by -\testheading@reqpts
+ \edef\bonus@pts{\the\bonus@pts}
+ \@bonuspointstrue
+ }
+ \edef\check@time{\the\check@time}
+
+ \makeatletter\hwexamheader\makeatother
+}{
+ \newpage
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\testspace}
+% \begin{macrocode}
+\newcommand\testspace[1]{\iftest\vspace*{#1}\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\testnewpage}
+% \begin{macrocode}
+\newcommand\testnewpage{\iftest\newpage\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\testemptypage}
+% \begin{macrocode}
+\newcommand\testemptypage[1][]{\iftest\begin{center}\hwexam@testemptypage@kw\end{center}\vfill\eject\else\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@problem}
+% This macro acts on a problem's record in the |*.aux| file. Here we redefine it (it was
+% defined to do nothing in |problem.sty|) to generate the correction table.
+% \begin{macrocode}
+%<@@=problems>
+\renewcommand\@problem[3]{
+ \stepcounter{assignment@probs}
+ \def\@@pts{#2}
+ \ifx\@@pts\@empty\else
+ \addtocounter{assignment@totalpts}{#2}
+ \fi
+ \def\@@min{#3}\ifx\@@min\@empty\else\addtocounter{assignment@totalmin}{#3}\fi
+ \xdef\correction@probs{\correction@probs & #1}%
+ \xdef\correction@pts{\correction@pts & #2}
+ \xdef\correction@reached{\correction@reached &}
+}
+%<@@=hwexam>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\correction@table}
+% This macro generates the correction table
+% \begin{macrocode}
+\newcounter{assignment@probs}
+\newcounter{assignment@totalpts}
+\newcounter{assignment@totalmin}
+\def\correction@probs{\correction@probs@kw}
+\def\correction@pts{\correction@pts@kw}
+\def\correction@reached{\correction@reached@kw}
+\stepcounter{assignment@probs}
+\newcommand\correction@table{
+ \resizebox{\textwidth}{!}{%
+\begin{tabular}{|l|*{\theassignment@probs}{c|}|l|}\hline%
+&\multicolumn{\theassignment@probs}{c||}%|
+{\footnotesize\correction@forgrading@kw} &\\\hline
+\correction@probs & \correction@sum@kw & \correction@grade@kw\\\hline
+\correction@pts &\theassignment@totalpts & \\\hline
+\correction@reached & & \\[.7cm]\hline
+\end{tabular}}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Leftovers}
+%
+% at some point, we may want to reactivate the logos font, then we use
+% \begin{verbatim}
+% here we define the logos that characterize the assignment
+% \font\bierfont=../assignments/bierglas
+% \font\denkerfont=../assignments/denker
+% \font\uhrfont=../assignments/uhr
+% \font\warnschildfont=../assignments/achtung
+%
+% \newcommand\bierglas{{\bierfont\char65}}
+% \newcommand\denker{{\denkerfont\char65}}
+% \newcommand\uhr{{\uhrfont\char65}}
+% \newcommand\warnschild{{\warnschildfont\char 65}}
+% \newcommand\hardA{\warnschild}
+% \newcommand\longA{\uhr}
+% \newcommand\thinkA{\denker}
+% \newcommand\discussA{\bierglas}
+% \end{verbatim}
+% \end{implementation}
+\endinput
+% \iffalse
+
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+% LocalWords: texttt scsys sc latexml fileversion filedate maketitle setcounter newpage
+% LocalWords: tocdepth tableofcontents pts showmeta showmeta showignores omdoc extrefs
+% LocalWords: testspace testnewpage testemptypage testheading testheading reqpts reqpts
+% LocalWords: exfig makeatletter makeatother vspace hrule vspace vspace noindent textsf
+% LocalWords: includeassignment includeassignment HorIacJuc cscpnrr11 importmodule baz
+% LocalWords: includemhassignment includemhassignment importmhmodule foobar ldots sref
+% LocalWords: mhcurrentrepos mh-variants mh-variant compactenum printbibliography Cwd
+% LocalWords: langle rangle langle rangle ltxml.cls ltxml.sty respetively metakeys qw
+% LocalWords: cwd stex graphicx amssymb amstext amsmath newif iftest testfalse testtrue
+% LocalWords: ifsolutions solutionsfalse ifmultiple multiplefalse multipletrue keyval
+% LocalWords: ltxml assig srefaddidkey addmetakey ifx assignment@titleblock stepcounter
+% LocalWords: document@hwexamtype importmodules metasetkeys inclassig@title inclassig
+% LocalWords: inclassig@title inclassig@type inclassig@type inclassig@number xspace kv
+% LocalWords: inclassig@number inclassig@due inclassig@due inclassig@given ignorespaces
+% LocalWords: inclassig@given newenvironment currentsectionlevel OptionalKeyVals kvi
+% LocalWords: omgroup vals hwexamtype ednote textbackslash newcommand inputassignment
+% LocalWords: unlist quizheading tas hspace hfill textbf newcount vfill addtocounter
+% LocalWords: theassignment@totalmin theassignment@totalpts assignment@probs xdef hline
+% LocalWords: assignment@totalpts assignment@totalmin correction@probs correction@probs
+% LocalWords: newcounter theassignment@probs footnotesize mh@currentrepos endinput
+% LocalWords: inclassig@mhrepos inclassig@mhrepos doctex inputmhassignment
+% LocalWords: GPL structuresharing STR iffalse cls NeedsTeXFormat hwexam hwexam.dtx sc
diff --git a/macros/latex/contrib/stex/source/extensions/notesslides.dtx b/macros/latex/contrib/stex/source/extensions/notesslides.dtx
new file mode 100644
index 0000000000..a6ff395377
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/notesslides.dtx
@@ -0,0 +1,1078 @@
+% \iffalse meta-comment
+% A LaTeX Class for Semantic Lectures Slides (originally developed for Michael Kohlhase)
+% Copyright (c) 2019 Michael Kohlhase, all rights reserved
+% this file is released under the
+% Gnu Library Public Licences (LGPL)
+%
+% The original of this file is in the public repository at
+% http://github.com/sLaTeX/sTeX/
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\providecommand\bibfolder{../../lib/bib}
+\input{../../doc/docheader}
+
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% ^^A\changes{v0.1}{2005/12/06}{Initial Version}
+%
+% \GetFileInfo{notesslides.cls}
+% \MakeShortVerb{\|}
+%
+% \def\twin#1#2{\index{#1!#2}\index{#2!#1}}
+% \def\twintoo#1#2{{#1 #2}\twin{#1}{#2}}
+% \def\atwin#1#2#3{\index{#1!#2!#3}\index{#3!#2 (#1)}}
+% \def\atwintoo#1#2#3{{#1 #2 #3}\atwin{#1}{#2}{#3}}
+%
+% \def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
+% \def\stex{\hbox{\raisebox{-.5ex}S\kern-.5ex\TeX}}
+% \def\sTeX{\stex}
+% \def\cnxml{\scshape{CNXml}}
+% \def\connexions{\scshape{Connexions}}
+% \def\element#1{{\ttfamily{#1}}}
+% \def\snippet#1{{\ttfamily{#1}}}
+% \def\cnxlatex{CNX\LaTeX\xspace}
+% \def\mathml{{\scshape{MathML}}\xspace}
+% \def\omdoc{OMDoc\xspace}
+% \def\activemath{{\scshape{ActiveMath}}\xspace}
+% \def\textwarning{\includegraphics[width=1.2em]{dangerous-bend}\xspace}
+%
+% \title{NotesSlides -- Slides and Course Notes\thanks{Version {\fileversion}
+% (last revised {\filedate})}}
+% \author{Michael Kohlhase\\
+% FAU Erlangen-N\"urnberg\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+%\ifinfulldoc\else
+% This is the documentation for the \pkg{notesslides} 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/slides}
+% \fi
+%
+% \begin{documentation}\label{pkg:notesslides:doc}
+%
+% We present a document class from which we can generate both course slides and course
+% notes in a transparent way.
+%
+%\section{Introduction}
+%
+% The |notesslides| document class is derived from |beamer.cls|~\cite{beamerclass:on}, it
+% adds a ``notes version'' for course notes derived from the |omdoc|
+% class~\cite{Kohlhase:smomdl} that is more suited to printing than the one supplied by
+% |beamer.cls|.
+%
+%
+%\section{The User Interface}\label{sec:user}
+%
+% The |notesslides| class takes the notion of a slide frame from Till Tantau's excellent
+% |beamer| class and adapts its notion of frames for use in the \sTeX and \omdoc. To
+% support semantic course notes, it extends the notion of mixing frames and explanatory
+% text, but rather than treating the frames as images (or integrating their contents into
+% the flowing text), the |notesslides| package displays the slides as such in the course
+% notes to give students a visual anchor into the slide presentation in the course (and to
+% distinguish the different writing styles in slides and course notes).
+%
+% In practice we want to generate two documents from the same source: the slides for
+% presentation in the lecture and the course notes as a narrative document for home
+% study. To achieve this, the |notesslides| class has two modes: \emph{slides mode} and
+% \emph{notes mode} which are determined by the package option.
+%
+% \subsection{Package Options}\label{sec:user:options}
+%
+% The |notesslides| class takes a variety of class options:\ednote{leaving out noproblems
+% for the moment until we decide what to do with it.}
+% \begin{itemize}
+% \item The options \DescribeMacro{slides}|slides| and \DescribeMacro{notes}|notes| switch
+% between slides mode and notes mode (see Section~\ref{sec:user:notesslides}).
+% \item If the option \DescribeMacro{sectocframes}|sectocframes| is given, then for the
+% |omgroup|s, special frames with the |omgroup| title (and number) are generated.
+% \item \DescribeMacro{showmeta}|showmeta|. If this is set, then the metadata keys are
+% shown (see~\cite{Kohlhase:metakeys:git} for details and customization options).
+% \item If the option \DescribeMacro{frameimages}|frameimages| is set, then slide mode
+% also shows the |\frameimage|-generated frames (see
+% section~\ref{sec:user:frameimage}). If also the \DescribeMacro{fiboxed}|fiboxed|
+% option is given, the slides are surrounded by a box.
+% \item \DescribeMacro{topsect}|topsect=|\meta{sect} can be used to specify the
+% top-level sectioning level; the default for \meta{sect} is |section|.
+% \end{itemize}
+%
+% \subsection{Notes and Slides}\label{sec:user:notesslides}
+%
+% Slides are represented with the \DescribeEnv{frame}|frame| just like in the |beamer|
+% class, see~\cite{Tantau:ugbc} for details. The |notesslides| class adds the
+% \DescribeEnv{note}|note| environment for encapsulating the course note
+% fragments.\footnote{MK: it would be very nice, if we did not need this environment, and
+% this should be possible in principle, but not without intensive LaTeX trickery. Hints to
+% the author are welcome.}
+%
+% \textwarning Note that it is essential to start and end the |notes| environment at the
+% start of the line -- in particular, there may not be leading blanks -- else {\LaTeX}
+% becomes confused and throws error messages that are difficult to decipher.
+%
+% \begin{exfig}
+% \begin{verbatim}
+% \ifnotes\maketitle\else
+% \frame[noframenumbering]\maketitle\fi
+%
+% \begin{note}
+% We start this course with ...
+% \end{note}
+%
+% \begin{frame}
+% \frametitle{The first slide}
+% ...
+% \end{frame}
+% \begin{note}
+% ... and more explanatory text
+% \end{note}
+%
+% \begin{frame}
+% \frametitle{The second slide}
+% ...
+% \end{frame}
+% ...
+% \end{verbatim}
+% \caption{A typical Course Notes File}\label{fig:notesfile}
+% \end{exfig}
+%
+% By interleaving the |frame| and |note| environments, we can build course notes as shown
+% in Figure~\ref{fig:notesfile}.
+%
+% Note the use of the \DescribeMacro{\ifnotes}|\ifnotes| conditional, which allows
+% different treatment between |notes| and |slides| mode -- manually setting |\notestrue|
+% or |\notesfalse| is strongly discouraged however.
+%
+% \textwarning: We need to give the title frame the |noframenumbering| option so that the
+% frame numbering is kept in sync between the slides and the course notes.
+%
+% \textwarning: The |beamer| class recommends not to use the |allowframebreaks| option on
+% frames (even though it is very convenient). This holds even more in the |notesslides|
+% case: At least in conjunction with |\newpage|, frame numbering behaves funnily (we have
+% tried to fix this, but who knows).
+%
+% If we want to transclude a the contents of a file as a note, we can use a new variant
+% \DescribeMacro{\inputref*}|\inputref*| of the |\inputref| macro from
+% \cite{KohAmb:smmssl:git}: |\inputref*{foo}| is equivalent to
+% |\begin{note}\inputref{foo}\end{note}|.
+%
+% There are some environments that tend to occur at the top-level of |note|
+% environments. We make convenience versions of these: e.g. the
+% \DescribeEnv{nparagraph}|nparagraph| environment is just an |sparagraph| inside a |note|
+% environment (but looks nicer in the source, since it avoids one level of source
+% indenting). Similarly, we have the \DescribeEnv{nfragment}|nomgroup|,
+% \DescribeEnv{ndefinition}|ndefinition|, \DescribeEnv{nexample}|nexample|,
+% \DescribeEnv{nsproof}|nsproof|, and \DescribeEnv{nassertion}|nassertion| environments.
+%
+% \subsection{Header and Footer Lines of the Slides}\label{sec:user:headfootlines}
+%
+% The default logo provided by the |notesslides| package is the {\sTeX} logo it can be
+% customized using \DescribeMacro{\setslidelogo}|\setslidelogo{|\meta{logo name}|}|.
+%
+% The default footer line of the |notesslides| package mentions copyright and licensing. In
+% the |beamer| class, |\source| stores the author's name as the copyright holder . By
+% default it is {\it Michael Kohlhase} in the |notesslides| package since he is the main
+% user and designer of this package. \DescribeMacro{\setsource}|\setsource{|\meta{name}|}|
+% can change the writer's name. For licensing, we use the Creative Commons
+% Attribuition-ShareAlike license by default to strengthen the public domain. If package
+% |hyperref| is loaded, then we can attach a hyperlink to the license
+% logo. \DescribeMacro{\setlicensing}|\setlicensing[|\meta{url}|]{|\meta{logo name}|}| is
+% used for customization, where \meta{url} is optional.
+%
+% \subsection{Frame Images}\label{sec:user:frameimage}
+%
+% Sometimes, we want to integrate slides as images after all -- e.g. because we already
+% have a PowerPoint presentation, to which we want to add \sTeX notes. In this case we can
+% use \DescribeMacro{\frameimage}|\frameimage[|\meta{opt}|]{|\meta{path}|}|, where
+% \meta{opt} are the options of |\includegraphics| from the |graphicx|
+% package~\cite{CarRah:tpp99} and \meta{path} is the file path (extension can be left off
+% like in |\includegraphics|). We have added the |label| key that allows to give a frame
+% label that can be referenced like a regular |beamer| frame.\ednote{MK: the hyperref link
+% does not seem to work yet. I wonder why but do not have the time to fix it.}
+%
+% The \DescribeMacro{\mhframeimage}|\mhframeimage| macro is a variant of |\frameimage|
+% with repository support. Instead of writing
+% \begin{verbatim}
+% \frameimage{\MathHub{fooMH/bar/source/baz/foobar}}
+% \end{verbatim}
+% we can simply write (assuming that |\MathHub| is defined as above)
+% \begin{verbatim}
+% \mhframeimage[fooMH/bar]{baz/foobar}
+% \end{verbatim}
+% Note that the |\mhframeimage| form is more semantic, which allows more advanced document
+% management features in \textsf{MathHub}.
+%
+% If |baz/foobar| is the ``current module'', i.e. if we are on the \textsf{MathHub} path
+% \ldots|MathHub/fooMH/bar|\ldots, then stating the repository in the first optional
+% argument is redundant, so we can just use
+% \begin{verbatim}
+% \mhframeimage{baz/foobar}
+% \end{verbatim}
+%
+% \subsection{Colors and Highlighting}\label{sec:user:highlighting}
+% The \DescribeMacro{\textwarning}|\textwarning| macro generates a warning
+% sign: \textwarning
+%
+% \subsection{Front Matter, Titles, etc.}\label{sec:user:matter}
+%
+% \subsection{Excursions}\label{sec:user:excursions}
+%
+% In course notes, we sometimes want to point to an ``excursion'' -- material that is
+% either presupposed or tangential to the course at the moment -- e.g. in an appendix. The
+% typical setup is the following:
+%
+% \begin{verbatim}
+% \excursion{founif}{../ex/founif}{We will cover first-order unification in}
+% ...
+% \begin{appendix}\printexcursions\end{appendix}
+% \end{verbatim}
+%
+% The \DescribeMacro{\excursion}|\excursion{|\meta{ref}|}{|\meta{path}|}{|\meta{text}|}| is
+% syntactic sugar for \DescribeMacro{\activateexcursion}
+%
+% \begin{verbatim}
+% \begin{nparagraph}[title=Excursion]
+% \activateexcursion{founif}{../ex/founif}
+% We will cover first-order unification in \sref{founif}.
+% \end{nparagraph}
+% \end{verbatim}
+%
+% where \DescribeMacro{\activateexcursion}|\activateexcursion{|\meta{path}|}| augments the
+% |\printexcursions| macro by a call |\inputref{|\meta{path}|}|. In this way, the3
+% \DescribeMacro{\printexcursions}|\printexcursions| macro (usually in the appendix) will
+% collect up all excursions that are specified in the main text.
+%
+% Sometimes, we want to reference -- in an excursion -- part of another. We can use
+% \DescribeMacro{\excursionref}|\excursionref{|\meta{label}|}| for that.
+%
+% Finally, we usually want to put the excursions into an |omgroup| environment and add an
+% introduction, therefore we provide the a variant of the |\printexcursions| macro:
+% \DescribeMacro{\excursiongroup}|\excursiongroup[id=|\meta{id}|,intro=|\meta{path}|]| is
+% equivalent to
+% \begin{verbatim}
+% \begin{note}
+% \begin{sfragment}[id=<id>]{Excursions}
+% \inputref{<path>}
+% \printexcursions
+% \end{sfragment}
+% \end{note}
+% \end{verbatim}
+%
+% \subsection{Miscellaneous}\label{sec:user:misc}
+%
+% \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 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. This is a problem
+% of the underlying |omdoc| package.
+% \end{enumerate}
+%
+% \end{documentation}
+%
+% \begin{implementation}\label{pkg:notesslides:impl}
+%
+%\section{NotesSlides -- Implementation}\label{sec:impl}
+%
+%\subsection{Class and Package Options}\label{sec:impl:init}
+%
+% We define some Package Options and switches for the |notesslides| class and activate them
+% by passing them on to |beamer.cls| and |omdoc.cls| and the |notesslides| package. We pass
+% the |nontheorem| option to the |statements| package when we are not in notes mode, since
+% the |beamer| package has its own (overlay-aware) theorem environments.
+%
+% \begin{macrocode}
+%<*cls>
+%<@@=notesslides>
+\ProvidesExplClass{notesslides}{2022/02/24}{3.0.0}{notesslides Class}
+\RequirePackage{l3keys2e}
+
+\keys_define:nn{notesslides / cls}{
+ class .code:n = {
+ \PassOptionsToClass{\CurrentOption}{document-structure}
+ \str_if_eq:nnT{#1}{book}{
+ \PassOptionsToPackage{defaulttopsec=part}{notesslides}
+ }
+ \str_if_eq:nnT{#1}{report}{
+ \PassOptionsToPackage{defaulttopsec=part}{notesslides}
+ }
+ },
+ notes .bool_set:N = \c_@@_notes_bool ,
+ slides .code:n = { \bool_set_false:N \c_@@_notes_bool },
+ unknown .code:n = {
+ \PassOptionsToClass{\CurrentOption}{document-structure}
+ \PassOptionsToClass{\CurrentOption}{beamer}
+ \PassOptionsToPackage{\CurrentOption}{notesslides}
+ }
+}
+\ProcessKeysOptions{ notesslides / cls }
+\bool_if:NTF \c_@@_notes_bool {
+ \PassOptionsToPackage{notes=true}{notesslides}
+}{
+ \PassOptionsToPackage{notes=false}{notesslides}
+}
+%</cls>
+% \end{macrocode}
+% now we do the same for the |notesslides| package.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage{notesslides}{2022/02/24}{3.0.0}{notesslides Package}
+\RequirePackage{l3keys2e}
+
+\keys_define:nn{notesslides / pkg}{
+ topsect .str_set_x:N = \c_@@_topsect_str,
+ defaulttopsect .str_set_x:N = \c_@@_defaulttopsec_str,
+ notes .bool_set:N = \c_@@_notes_bool ,
+ slides .code:n = { \bool_set_false:N \c_@@_notes_bool },
+ sectocframes .bool_set:N = \c_@@_sectocframes_bool ,
+ frameimages .bool_set:N = \c_@@_frameimages_bool ,
+ fiboxed .bool_set:N = \c_@@_fiboxed_bool ,
+ noproblems .bool_set:N = \c_@@_noproblems_bool,
+ unknown .code:n = {
+ \PassOptionsToClass{\CurrentOption}{stex}
+ \PassOptionsToClass{\CurrentOption}{tikzinput}
+ }
+}
+\ProcessKeysOptions{ notesslides / pkg }
+\newif\ifnotes
+\bool_if:NTF \c_@@_notes_bool {
+ \notestrue
+}{
+ \notesfalse
+}
+
+% \end{macrocode}
+% we give ourselves a macro |\@@topsect| that needs only be evaluated once, so that the
+% |\ifdefstring| conditionals work below.
+% \begin{macrocode}
+\str_if_empty:NTF \c_@@_topsect_str {
+ \str_set_eq:NN \@@topsect \c_@@_defaulttopsec_str
+}{
+ \str_set_eq:NN \@@topsect \c_@@_topsect_str
+}
+%</package>
+% \end{macrocode}
+%
+% Depending on the options, we either load the |article|-based |document-structure| or the |beamer|
+% class (and set some counters).
+% \begin{macrocode}
+%<*cls>
+\bool_if:NTF \c_@@_notes_bool {
+ \LoadClass{document-structure}
+}{
+ \LoadClass[10pt,notheorems,xcolor={dvipsnames,svgnames}]{beamer}
+ \newcounter{Item}
+ \newcounter{paragraph}
+ \newcounter{subparagraph}
+ \newcounter{Hfootnote}
+ \RequirePackage{document-structure}
+}
+% \end{macrocode}
+% now it only remains to load the |notesslides| package that does all the rest.
+% \begin{macrocode}
+\RequirePackage{notesslides}
+%</cls>
+% \end{macrocode}
+%
+% In |notes| mode, we also have to make the |beamer|-specific things available to
+% |article| via the |beamerarticle| package. We use options to avoid loading theorem-like
+% environments, since we want to use our own from the $\sTeX$ packages. The first batch
+% of packages we want are loaded on |notesslides.sty|. These are the general ones, we will
+% load the \sTeX-specific ones after we have done some work (e.g. defined the counters
+% |m*|). Only the |stex-logo| package is already needed now for the default theme.
+%
+% \begin{macrocode}
+%<*package>
+\bool_if:NT \c_@@_notes_bool {
+ \RequirePackage{a4wide}
+ \RequirePackage{marginnote}
+ \PassOptionsToPackage{usenames,dvipsnames,svgnames}{xcolor}
+ \RequirePackage{mdframed}
+ \RequirePackage[noxcolor,noamsthm]{beamerarticle}
+ \RequirePackage[bookmarks,bookmarksopen,bookmarksnumbered,breaklinks,hidelinks]{hyperref}
+}
+\RequirePackage{stex-tikzinput}
+\RequirePackage{etoolbox}
+\RequirePackage{amssymb}
+\RequirePackage{amsmath}
+\RequirePackage{comment}
+\RequirePackage{textcomp}
+\RequirePackage{url}
+\RequirePackage{graphicx}
+\RequirePackage{pgf}
+% \end{macrocode}
+%
+% \subsection{Notes and Slides}\label{sec:impl:noteslides}
+%
+% For the lecture notes cases, we also provide the |\usetheme| macro that would otherwise
+% come from the the |beamer| class. While the latter loads
+% |beamertheme|\meta{theme}{.sty}, the notes version loads
+% |beamernotestheme|\meta{theme}|.sty|.\ednote{MK: This is not ideal, but I am not sure
+% that I want to be able to provide the full theme functionality there.}
+% \begin{macrocode}
+\bool_if:NT \c_@@_notes_bool {
+ \renewcommand\usetheme[2][]{\usepackage[#1]{beamernotestheme#2}}
+}
+% \end{macrocode}
+% We define the sizes of slides in the notes. Somehow, we cannot get by with the same
+% here.
+%
+% \begin{macrocode}
+\newcounter{slide}
+\newlength{\slidewidth}\setlength{\slidewidth}{13.5cm}
+\newlength{\slideheight}\setlength{\slideheight}{9cm}
+% \end{macrocode}
+%
+% \begin{environment}{note}
+% The |note| environment is used to leave out text in the |slides| mode. It does not have
+% a counterpart in OMDoc. So for course notes, we define the |note| environment to be a
+% no-operation otherwise we declare the |note| environment as a comment via the |comment|
+% package.
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \renewenvironment{note}{\ignorespaces}{}
+}{
+ \excludecomment{note}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% We first set up the slide boxes in |article| mode. We set up sizes and provide a
+% box register for the frames and a counter for the slides.
+%
+% \begin{macrocode}
+\bool_if:NT \c_@@_notes_bool {
+ \newlength{\slideframewidth}
+ \setlength{\slideframewidth}{1.5pt}
+% \end{macrocode}
+%
+% \begin{environment}{frame}
+% We first define the keys.
+% \begin{macrocode}
+ \cs_new_protected:Nn \_@@_do_yes_param:Nn {
+ \exp_args:Nx \str_if_eq:nnTF { \str_uppercase:n{ #2 } }{ yes }{
+ \bool_set_true:N #1
+ }{
+ \bool_set_false:N #1
+ }
+ }
+ \keys_define:nn{notesslides / frame}{
+ label .str_set_x:N = \l_@@_frame_label_str,
+ allowframebreaks .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_allowframebreaks_bool { #1 }
+ },
+ allowdisplaybreaks .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_allowdisplaybreaks_bool { #1 }
+ },
+ fragile .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_fragile_bool { #1 }
+ },
+ shrink .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_shrink_bool { #1 }
+ },
+ squeeze .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_squeeze_bool { #1 }
+ },
+ t .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_frame_t_bool { #1 }
+ },
+ }
+ \cs_new_protected:Nn \_@@_frame_args:n {
+ \str_clear:N \l_@@_frame_label_str
+ \bool_set_true:N \l_@@_frame_allowframebreaks_bool
+ \bool_set_true:N \l_@@_frame_allowdisplaybreaks_bool
+ \bool_set_true:N \l_@@_frame_fragile_bool
+ \bool_set_true:N \l_@@_frame_shrink_bool
+ \bool_set_true:N \l_@@_frame_squeeze_bool
+ \bool_set_true:N \l_@@_frame_t_bool
+ \keys_set:nn { notesslides / frame }{ #1 }
+ }
+% \end{macrocode}
+% We define the environment, read them, and construct the slide number and label.
+% \begin{macrocode}
+ \renewenvironment{frame}[1][]{
+ \_@@_frame_args:n{#1}
+ \sffamily
+ \stepcounter{slide}
+ \def\@currentlabel{\theslide}
+ \str_if_empty:NF \l_@@_frame_label_str {
+ \label{\l_@@_frame_label_str}
+ }
+% \end{macrocode}
+% We redefine the |itemize| environment so that it looks more like the one in |beamer|.
+% \begin{macrocode}
+ \def\itemize@level{outer}
+ \def\itemize@outer{outer}
+ \def\itemize@inner{inner}
+ \renewcommand\newpage{\addtocounter{framenumber}{1}}
+ \newcommand\metakeys@show@keys[2]{\marginnote{{\scriptsize ##2}}}
+ \renewenvironment{itemize}{
+ \ifx\itemize@level\itemize@outer
+ \def\itemize@label{$\rhd$}
+ \fi
+ \ifx\itemize@level\itemize@inner
+ \def\itemize@label{$\scriptstyle\rhd$}
+ \fi
+ \begin{list}
+ {\itemize@label}
+ {\setlength{\labelsep}{.3em}
+ \setlength{\labelwidth}{.5em}
+ \setlength{\leftmargin}{1.5em}
+ }
+ \edef\itemize@level{\itemize@inner}
+ }{
+ \end{list}
+ }
+% \end{macrocode}
+% We create the box with the |mdframed| environment from the equinymous package.
+% \begin{macrocode}
+ \begin{mdframed}[linewidth=\slideframewidth,skipabove=1ex,skipbelow=1ex,userdefinedwidth=\slidewidth,align=center]\sf
+ }{
+ \medskip\miko@slidelabel\end{mdframed}
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% Now, we need to redefine the frametitle (we are still in course notes mode).
+% \begin{macro}{\frametitle}
+% \begin{macrocode}
+ \renewcommand{\frametitle}[1]{{\Large\bf\sf\color{blue}{#1}}\medskip}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pause}
+% \ednote{MK: fake it in notes mode for now}
+% \begin{macrocode}
+\bool_if:NT \c_@@_notes_bool {
+ \newcommand\pause{}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{nparagraph}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{nparagraph}[1][]{\begin{sparagraph}[#1]}{\end{sparagraph}}
+}{
+ \excludecomment{nparagraph}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{nfragment}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{nfragment}[2][]{\begin{sfragment}[#1]{#2}}{\end{sfragment}}
+}{
+ \excludecomment{nfragment}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{ndefinition}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{ndefinition}[1][]{\begin{sdefinition}[#1]}{\end{sdefinition}}
+}{
+ \excludecomment{ndefinition}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{nassertion}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{nassertion}[1][]{\begin{sassertion}[#1]}{\end{sassertion}}
+}{
+ \excludecomment{nassertion}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{nsproof}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{nproof}[2][]{\begin{sproof}[#1]{#2}}{\end{sproof}}
+}{
+ \excludecomment{nproof}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{nexample}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{nexample}[1][]{\begin{sexample}[#1]}{\end{sexample}}
+}{
+ \excludecomment{nexample}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\inputref@*skip}
+% We customize the hooks for in |\inputref|.
+% \begin{macrocode}
+\def\inputref@preskip{\smallskip}
+\def\inputref@postskip{\medskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\inputref*}
+% \begin{macrocode}
+\let\orig@inputref\inputref
+\def\inputref{\@ifstar\ninputref\orig@inputref}
+\newcommand\ninputref[2][]{
+ \bool_if:NT \c_@@_notes_bool {
+ \orig@inputref[#1]{#2}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Header and Footer Lines}\label{sec:impl:headfootlines}
+%
+% Now, we set up the infrastructure for the footer line of the slides, we use boxes for
+% the logos, so that they are only loaded once, that considerably speeds up processing.
+%
+% \begin{macro}{\setslidelogo}
+% The default logo is the {\sTeX} logo. Customization can be done by |\setslidelogo{|\meta{logo name}|}|.
+% \begin{macrocode}
+\newlength{\slidelogoheight}
+
+\bool_if:NTF \c_@@_notes_bool {
+ \setlength{\slidelogoheight}{.4cm}
+}{
+ \setlength{\slidelogoheight}{1cm}
+}
+\newsavebox{\slidelogo}
+\sbox{\slidelogo}{\sTeX}
+\newrobustcmd{\setslidelogo}[1]{
+ \sbox{\slidelogo}{\includegraphics[height=\slidelogoheight]{#1}}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setsource}
+% |\source| stores the writer's name. By default it is {\it Michael Kohlhase} since he is the main user and designer of this package. |\setsource{|\meta{name}|}| can change the writer's name.
+% \begin{macrocode}
+\def\source{Michael Kohlhase}% customize locally
+\newrobustcmd{\setsource}[1]{\def\source{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setlicensing}
+% Now, we set up the copyright and licensing. By default we use the Creative Commons
+% Attribuition-ShareAlike license to strengthen the public domain. If package |hyperref|
+% is loaded, then we can attach a hyperlink to the license
+% logo. |\setlicensing[|\meta{url}|]{|\meta{logo name}|}| is used for customization,
+% where ||\meta{url}|| is optional.
+% \begin{macrocode}
+\def\copyrightnotice{\footnotesize\copyright :\hspace{.3ex}{\source}}
+\newsavebox{\cclogo}
+\sbox{\cclogo}{\includegraphics[height=\slidelogoheight]{cc_somerights}}
+\newif\ifcchref\cchreffalse
+\AtBeginDocument{
+ \@ifpackageloaded{hyperref}{\cchreftrue}{\cchreffalse}
+}
+\def\licensing{
+ \ifcchref
+ \href{http://creativecommons.org/licenses/by-sa/2.5/}{\usebox{\cclogo}}
+ \else
+ {\usebox{\cclogo}}
+ \fi
+}
+\newrobustcmd{\setlicensing}[2][]{
+ \def\@url{#1}
+ \sbox{\cclogo}{\includegraphics[height=\slidelogoheight]{#2}}
+ \ifx\@url\@empty
+ \def\licensing{{\usebox{\cclogo}}}
+ \else
+ \def\licensing{
+ \ifcchref
+ \href{#1}{\usebox{\cclogo}}
+ \else
+ {\usebox{\cclogo}}
+ \fi
+ }
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\slidelabel}
+% Now, we set up the slide label for the |article| mode.\ednote{see that we can use the themes for the slides some day. This is all fake.}
+% \begin{macrocode}
+\newrobustcmd\miko@slidelabel{
+ \vbox to \slidelogoheight{
+ \vss\hbox to \slidewidth
+ {\licensing\hfill\copyrightnotice\hfill\arabic{slide}\hfill\usebox{\slidelogo}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \subsection{Frame Images}\label{sec:impl:frameimage}
+%
+% \begin{macro}{\frameimage}
+% We have to make sure that the width is overwritten, for that we check the
+% |\Gin@ewidth| macro from the |graphicx| package. We also add the |label| key.
+% \begin{macrocode}
+\def\Gin@mhrepos{}
+\define@key{Gin}{mhrepos}{\def\Gin@mhrepos{#1}}
+\define@key{Gin}{label}{\def\@currentlabel{\arabic{slide}}\label{#1}}
+\newrobustcmd\frameimage[2][]{
+ \stepcounter{slide}
+ \bool_if:NT \c_@@_frameimages_bool {
+ \def\Gin@ewidth{}\setkeys{Gin}{#1}
+ \bool_if:NF \c_@@_notes_bool { \vfill }
+ \begin{center}
+ \bool_if:NTF \c_@@_fiboxed_bool {
+ \fbox{
+ \ifx\Gin@ewidth\@empty
+ \ifx\Gin@mhrepos\@empty
+ \mhgraphics[width=\slidewidth,#1]{#2}
+ \else
+ \mhgraphics[width=\slidewidth,#1,mhrepos=\Gin@mhrepos]{#2}
+ \fi
+ \else% Gin@ewidth empty
+ \ifx\Gin@mhrepos\@empty
+ \mhgraphics[#1]{#2}
+ \else
+ \mhgraphics[#1,mhrepos=\Gin@mhrepos]{#2}
+ \fi
+ \fi% Gin@ewidth empty
+ }
+ }{
+ \ifx\Gin@ewidth\@empty
+ \ifx\Gin@mhrepos\@empty
+ \mhgraphics[width=\slidewidth,#1]{#2}
+ \else
+ \mhgraphics[width=\slidewidth,#1,mhrepos=\Gin@mhrepos]{#2}
+ \fi
+ \ifx\Gin@mhrepos\@empty
+ \mhgraphics[#1]{#2}
+ \else
+ \mhgraphics[#1,mhrepos=\Gin@mhrepos]{#2}
+ \fi
+ \fi% Gin@ewidth empty
+ }
+ \end{center}
+ \par\strut\hfill{\footnotesize Slide \arabic{slide}}%
+ \bool_if:NF \c_@@_notes_bool { \vfill }
+ }
+} % ifmks@sty@frameimages
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Colors and Highlighting}\label{sec:impl:highlighting}
+%
+% We first specify sans serif fonts as the default.
+%
+% \begin{macrocode}
+\sffamily
+% \end{macrocode}
+%
+% Now, we set up an infrastructure for highlighting phrases in slides. Note that we use
+% content-oriented macros for highlighting rather than directly using color markup.
+% The first thing to to is to adapt the green so that it is dark enough for most beamers
+% \begin{macrocode}
+\AddToHook{begindocument}{
+ \definecolor{green}{rgb}{0,.5,0}
+ \definecolor{purple}{cmyk}{.3,1,0,.17}
+}
+% \end{macrocode}
+%
+% We customize the |\defemph|, |\symrefemph|, |\compemph|, and |\titleemph| macros with
+% colors. Furthermore we customize the |\__omtextlec| macro for the appearance of line end
+% comments in |\lec|.
+%
+% \begin{macrocode}
+% \def\STpresent#1{\textcolor{blue}{#1}}
+\def\defemph#1{{\textcolor{magenta}{#1}}}
+\def\symrefemph#1{{\textcolor{cyan}{#1}}}
+\def\compemph#1{{\textcolor{blue}{#1}}}
+\def\titleemph#1{{\textcolor{blue}{#1}}}
+\def\__omtext_lec#1{(\textcolor{green}{#1})}
+% \end{macrocode}
+%
+% I like to use the dangerous bend symbol for warnings, so we provide it here.
+% \begin{macro}{\textwarning}
+% as the macro can be used quite often we put it into a box register, so that it is only
+% loaded once.
+% \begin{macrocode}
+\pgfdeclareimage[width=.8em]{miko@small@dbend}{dangerous-bend}
+\def\smalltextwarning{
+ \pgfuseimage{miko@small@dbend}
+ \xspace
+}
+\pgfdeclareimage[width=1.2em]{miko@dbend}{dangerous-bend}
+\newrobustcmd\textwarning{
+ \raisebox{-.05cm}{\pgfuseimage{miko@dbend}}
+ \xspace
+}
+\pgfdeclareimage[width=2.5em]{miko@big@dbend}{dangerous-bend}
+\newrobustcmd\bigtextwarning{
+ \raisebox{-.05cm}{\pgfuseimage{miko@big@dbend}}
+ \xspace
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\newrobustcmd\putgraphicsat[3]{
+ \begin{picture}(0,0)\put(#1){\includegraphics[#2]{#3}}\end{picture}
+}
+\newrobustcmd\putat[2]{
+ \begin{picture}(0,0)\put(#1){#2}\end{picture}
+}
+% \end{macrocode}
+%
+% \subsection{Sectioning}
+%
+% If the |sectocframes| option is set, then we make section frames. We first define
+% counters for |part| and |chapter|, which |beamer.cls| does not have and we make the
+% |section| counter which it does dependent on |chapter|.
+% \begin{macrocode}
+\bool_if:NT \c_@@_sectocframes_bool {
+ \str_if_eq:VnTF \@@topsect{part}{
+ \newcounter{chapter}\counterwithin*{section}{chapter}
+ }{
+ \str_if_eq:VnT\@@topsect{chapter}{
+ \newcounter{chapter}\counterwithin*{section}{chapter}
+ }
+ }
+}
+% \end{macrocode}
+%
+% We set the \DescribeMacro{\section@level}|\section@level| counter that governs
+% sectioning according to the class options. We also introduce the sectioning counters
+% accordingly.
+%
+% \begin{macro}{\section@level}
+% \begin{macrocode}
+\def\part@prefix{}
+\@ifpackageloaded{document-structure}{}{
+ \str_case:VnF \@@topsect {
+ {part}{
+ \int_set:Nn \l_document_structure_section_level_int {0}
+ \def\thesection{\arabic{chapter}.\arabic{section}}
+ \def\part@prefix{\arabic{chapter}.}
+ }
+ {chapter}{
+ \int_set:Nn \l_document_structure_section_level_int {1}
+ \def\thesection{\arabic{chapter}.\arabic{section}}
+ \def\part@prefix{\arabic{chapter}.}
+ }
+ }{
+ \int_set:Nn \l_document_structure_section_level_int {2}
+ \def\part@prefix{}
+ }
+}
+
+\bool_if:NF \c_@@_notes_bool { % only in slides
+% \end{macrocode}
+% \end{macro}
+%
+% The new counters are used in the |omgroup| environment that choses the {\LaTeX}
+% sectioning macros according to |\section@level|.
+%
+% \begin{environment}{sfragment}
+% \begin{macrocode}
+ \renewenvironment{sfragment}[2][]{
+ \__document_structure_omgroup_args:n { #1 }
+ \int_incr:N \l_document_structure_section_level_int
+ \bool_if:NT \c_@@_sectocframes_bool {
+ \stepcounter{slide}
+ \begin{frame}[noframenumbering]
+ \vfill\Large\centering
+ \red{
+ \ifcase\l_document_structure_section_level_int\or
+ \stepcounter{part}
+ \def\@@label{\omdoc@part@kw~\Roman{part}}
+ \def\currentsectionlevel{\omdoc@part@kw}
+ \or
+ \stepcounter{chapter}
+ \def\@@label{\omdoc@chapter@kw~\arabic{chapter}}
+ \def\currentsectionlevel{\omdoc@chapter@kw}
+ \or
+ \stepcounter{section}
+ \def\@@label{\part@prefix\arabic{section}}
+ \def\currentsectionlevel{\omdoc@section@kw}
+ \or
+ \stepcounter{subsection}
+ \def\@@label{\part@prefix\arabic{section}.\arabic{subsection}}
+ \def\currentsectionlevel{\omdoc@subsection@kw}
+ \or
+ \stepcounter{subsubsection}
+ \def\@@label{\part@prefix\arabic{section}.\arabic{subsection}.\arabic{subsubsection}}
+ \def\currentsectionlevel{\omdoc@subsubsection@kw}
+ \or
+ \stepcounter{paragraph}
+ \def\@@label{\part@prefix\arabic{section}.\arabic{subsection}.\arabic{subsubsection}.\arabic{paragraph}}
+ \def\currentsectionlevel{\omdoc@paragraph@kw}
+ \else
+ \def\@@label{}
+ \def\currentsectionlevel{\omdoc@paragraph@kw}
+ \fi% end ifcase
+ \@@label%\sref@label@id\@@label
+ \quad #2%
+ }%
+ \vfill%
+ \end{frame}%
+ }
+ \str_if_empty:NF \l__document_structure_omgroup_id_str {
+ \stex_ref_new_doc_target:n\l__document_structure_omgroup_id_str
+ }
+ }{}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% We set up a |beamer| template for theorems like ams style, but without a block
+% environment.
+% \begin{macrocode}
+\def\inserttheorembodyfont{\normalfont}
+%\bool_if:NF \c_@@_notes_bool {
+% \defbeamertemplate{theorem begin}{miko}
+% {\inserttheoremheadfont\inserttheoremname\inserttheoremnumber
+% \ifx\inserttheoremaddition\@empty\else\ (\inserttheoremaddition)\fi%
+% \inserttheorempunctuation\inserttheorembodyfont\xspace}
+% \defbeamertemplate{theorem end}{miko}{}
+% \end{macrocode}
+% and we set it as the default one.
+% \begin{macrocode}
+% \setbeamertemplate{theorems}[miko]
+% \end{macrocode}
+% The following fixes an error I do not understand, this has something to do with
+% beamer compatibility, which has similar definitions but only up to 1.
+% \begin{macrocode}
+% \expandafter\def\csname Parent2\endcsname{}
+%}
+
+\AddToHook{begindocument}{ % this does not work for some reasone
+ \setbeamertemplate{theorems}[ams style]
+}
+\bool_if:NT \c_@@_notes_bool {
+ \renewenvironment{columns}[1][]{%
+ \par\noindent%
+ \begin{minipage}%
+ \slidewidth\centering\leavevmode%
+ }{%
+ \end{minipage}\par\noindent%
+ }%
+ \newsavebox\columnbox%
+ \renewenvironment<>{column}[2][]{%
+ \begin{lrbox}{\columnbox}\begin{minipage}{#2}%
+ }{%
+ \end{minipage}\end{lrbox}\usebox\columnbox%
+ }%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_if:NTF \c_@@_noproblems_bool {
+ \newenvironment{problems}{}{}
+}{
+ \excludecomment{problems}
+}
+% \end{macrocode}
+%
+% \subsection{Excursions}\label{sec:impl:excursions}
+%
+% \begin{macro}{\excursion}
+% The excursion macros are very simple, we define a new internal macro |\excursionref| and
+% use it in |\excursion|, which is just an |\inputref| that checks if the new macro is
+% defined before formatting the file in the argument.
+% \begin{macrocode}
+\gdef\printexcursions{}
+\newcommand\excursionref[2]{% label, text
+ \bool_if:NT \c_@@_notes_bool {
+ \begin{sparagraph}[title=Excursion]
+ #2 \sref[fallback=the appendix]{#1}.
+ \end{sparagraph}
+ }
+}
+\newcommand\activate@excursion[2][]{
+ \gappto\printexcursions{\inputref[#1]{#2}}
+}
+\newcommand\excursion[4][]{% repos, label, path, text
+ \bool_if:NT \c_@@_notes_bool {
+ \activate@excursion[#1]{#3}\excursionref{#2}{#4}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\excursiongroup}
+% \begin{macrocode}
+\keys_define:nn{notesslides / excursiongroup }{
+ id .str_set_x:N = \l_@@_excursion_id_str,
+ intro .tl_set:N = \l_@@_excursion_intro_tl,
+ mhrepos .str_set_x:N = \l_@@_excursion_mhrepos_str
+}
+\cs_new_protected:Nn \_@@_excursion_args:n {
+ \tl_clear:N \l_@@_excursion_intro_tl
+ \str_clear:N \l_@@_excursion_id_str
+ \str_clear:N \l_@@_excursion_mhrepos_str
+ \keys_set:nn {notesslides / excursiongroup }{ #1 }
+}
+\newcommand\excursiongroup[1][]{
+ \_@@_excursion_args:n{ #1 }
+ \ifdefempty\printexcursions{}% only if there are excursions
+ {\begin{note}
+ \begin{sfragment}[#1]{Excursions}%
+ \ifdefempty\l_@@_excursion_intro_tl{}{
+ \inputref[\l_@@_excursion_mhrepos_str]{
+ \l_@@_excursion_intro_tl
+ }
+ }
+ \printexcursions%
+ \end{sfragment}
+ \end{note}}
+}
+\ifcsname beameritemnestingprefix\endcsname\else\def\beameritemnestingprefix{}\fi
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \end{implementation}
+\endinput
+% \endinput
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End:
+
+% LocalWords: bibfolder jobname.dtx omdoc.dtx mytwocolumns beamer.cls sectocframes rhd
+% LocalWords: frameimage twintoo atwin atwintoo scsys scshape ttfamily cnxlatex xspace
+% LocalWords: mathml omdoc beamerclass:on Kohlhase:smomdl noproblems frameimages exfig
+% LocalWords: frameimages fiboxed fiboxed topsect topsect Tantau:ugbc ifnotes ifnotes
+% LocalWords: noframenumbering allowframebreaks newpage inputref inputref inputref sref
+% LocalWords: setsource setsource setlicensing setlicensing CarRah:tpp99 mhframeimage
+% LocalWords: mhframeimage printexcursions excursionref excursionref excursiongroup
+% LocalWords: excursiongroup sec:impl nontheorem mks@cls,prefix mks@cls mks@sty,prefix
+% LocalWords: mks@sty 10pt,notheorems,xcolor dvipsnames,svgnames Hfootnote mdframed
+% LocalWords: beamerarticle noxcolor,noamsthm metakeys addmetakey usetheme beamertheme
+% LocalWords: bookmarks,bookmarksopen,bookmarksnumbered,breaklinks,hidelinks sproof
+% LocalWords: beamernotestheme slideframewidth allowdisplaybreaks framenumber sproof
+% LocalWords: miko@slidelabel inputref@preskip smallskip ninputref slidelogoheight
+% LocalWords: copyrightnotice cclogo cc_somerights ifcchref cchreffalse cchreftrue
+% LocalWords: Gin@ewidth mh@currentrepos mhrepos if@iswindows defemph notemph STpresent
+% LocalWords: smalltextwarning miko@dbend bigtextwarning counterwithin ifsectocframes
+% LocalWords: subsubsection mparagraph csname stex_ref_new_doc_target:n columnbox
+% LocalWords: inserttheorembodyfont defbeamertemplate inserttheoremheadfont mhexcursion
+% LocalWords: inserttheoremname inserttheoremnumber inserttheoremaddition srefaddidkey
+% LocalWords: inserttheoremaddition inserttheorempunctuation setbeamertemplate
+% LocalWords: mhexcursiongroup
diff --git a/macros/latex/contrib/stex/source/extensions/problem.dtx b/macros/latex/contrib/stex/source/extensions/problem.dtx
new file mode 100644
index 0000000000..b21b1c493d
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/problem.dtx
@@ -0,0 +1,910 @@
+% \iffalse meta-comment
+% An Infrastructure for Problems
+% 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/
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\def\bibfolder{../../lib/bib}
+\input{../../doc/docheader}
+\RequirePackage[hints,solutions,notes]{problem}
+
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \iffalse\CheckSum{318}\fi
+%
+% ^^A\changes{v0.9}{2006/09/18}{First Version with Documentation}
+%
+% \GetFileInfo{problem.sty}
+%
+% \MakeShortVerb{\|}
+%
+% \title{\texttt{problem.sty}: An Infrastructure for formatting Problems\thanks{Version {\fileversion} (last revised
+% {\filedate})}}
+% \author{Michael Kohlhase\\
+% FAU Erlangen-N\"urnberg\\
+% \url{http://kwarc.info/kohlhase}}
+% \maketitle
+%
+%\ifinfulldoc\else
+% This is the documentation for the \pkg{problem} 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/problem}
+% \fi
+%
+% \begin{documentation}
+% The |problem| package supplies an infrastructure that allows specify problems and to
+% reuse them efficiently in multiple environments.
+%
+%\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 moment 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{gnotes}|gnotes| (do we show grading notes?), \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 situation, so this
+% option does not show the solutions (of course), but leaves space for the students to
+% solve them.
+%
+% The \DescribeMacro{mh}|mh| option turns on MathHub support; see \cite{Kohlhase:mss}.
+%
+% Finally, if the \DescribeMacro{showmeta}|showmeta| is set, then the metadata keys are
+% shown (see~\cite{Kohlhase:metakeys} for details and customization options).
+%
+% \subsection{Problems and Solutions}\label{sec:user:probsols}
+%
+% \DescribeEnv{problem} The main environment provided by the |problem| package is
+% (surprise surprise) the |problem| environment. It is used to mark up problems and
+% exercises. 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{sproblem}[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.
+% \begin{gnote}
+% if they do not give the justification deduct 5 pts
+% \end{gnote}
+% \end{solution}
+% \end{sproblem}
+% \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{sproblem}[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}
+% \smallskip\noindent\hrule\textbf{Solution:}
+% Four, two in the front seats, and two in the back.
+% \hrule
+% \end{sproblem}
+% \end{minipage}
+% \caption{The Formatted Problem from Figure~\ref{fig:problem}}\label{fig:result}
+% \end{exfig}
+%
+% \DescribeEnv{hint}\DescribeEnv{exnote} The |hint| and |exnote| environments can be used
+% in a |problem| environment to give hints and to make notes that elaborate certain
+% aspects of the problem.
+%
+% \DescribeEnv{gnote} The |gnote| (grading notes) environment can be used to document
+% situtations that may arise in grading.
+%
+% Sometimes we would like to locally override the |solutions| option we have given to the
+% package. To turn on solutions we use the
+% \DescribeMacro{\startsolutions}|\startsolutions|, to turn them off,
+% \DescribeMacro{\stopsolutions}|\stopsolutions|. These two can be used at any point in
+% the documents.
+%
+% Also, sometimes, we want content (e.g. in an exam with master solutions) conditional on
+% whether solutions are shown. This can be done with the
+% \DescribeMacro{\ifsolutions}|\ifsolutions| conditional.
+%
+% \subsection{Multiple Choice Blocks}\label{sec:user:mcq}
+%
+% Multiple choice blocks can be formatted using the \DescribeMacro{mcb}|mcb| environment,
+% in which single choices are marked up with
+% \DescribeMacro{\mcc}|\mcc[|\meta{keyvals}|]{|\meta{text}|}| macro, which takes an
+% optional key/value argument \meta{keyvals} for choice metadata and a required argument
+% \meta{text} for the proposed answer text. The following keys are supported
+% \begin{itemize}
+% \item \DescribeMacro{T}|T| for true answers, \DescribeMacro{F}|F| for false ones,
+% \item \DescribeMacro{Ttext}|Ttext| the verdict for true answers,
+% \DescribeMacro{Ftext}|Ftext| for false ones, and
+% \item \DescribeMacro{feedback}|feedback| for a short feedback text given to the student.
+% \end{itemize}
+% See Figure~\ref{fig: mcq} for an example
+%\begin{exfig}
+% \begin{verbatim}
+% \begin{sproblem}[title=Functions]
+% What is the keyword to introduce a function definition in python?
+% \begin{mcb}
+% \mcc[T]{def}
+% \mcc[F,feedback=that is for C and C++]{function}
+% \mcc[F,feedback=that is for Standard ML]{fun}
+% \mcc[F,Ftext=Nooooooooo,feedback=that is for Java]{public static void}
+% \end{mcb}
+% \end{sproblem}
+% \end{verbatim}
+% \solutionsfalse\hrule
+% \begin{sproblem}[title=Functions]
+% What is the keyword to introduce a function definition in python?
+% \begin{mcb}
+% \mcc[T]{def}
+% \mcc[F,feedback=that is for C and C++]{function}
+% \mcc[F,feedback=that is for Standard ML]{fun}
+% \mcc[F,Ftext=Nooooooooo,feedback=that is for Java]{public static void}
+% \end{mcb}
+% \end{sproblem}
+% \solutionstrue\hrule
+% \begin{sproblem}[title=Functions]
+% What is the keyword to introduce a function definition in python?
+% \begin{mcb}
+% \mcc[T]{def}
+% \mcc[F,feedback=that is for C and C++]{function}
+% \mcc[F,feedback=that is for Standard ML]{fun}
+% \mcc[F,Ftext=Nooooooooo,feedback=that is for Java]{public static void}
+% \end{mcb}
+% \end{sproblem}
+% \caption{A Problem with a multiple choice block}\label{fig:mcq}
+% \end{exfig}
+%
+% \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.
+%
+% \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 allotted 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 GitHub repository~\cite{sTeX:github:on}.
+% \begin{enumerate}
+% \item none reported yet
+% \end{enumerate}
+%
+% \end{documentation}
+% \begin{implementation}
+%
+% \section{The Implementation}\label{sec:implementation}
+%
+% \subsection{Package Options}\label{sec:impl:options}
+%
+% The first step is to declare (a few) package options that handle whether certain
+% information is printed or not. They all come with their own conditionals that are set by
+% the options.
+%
+% \begin{macrocode}
+%<*package>
+%<@@=problems>
+\ProvidesExplPackage{problem}{2022/02/24}{3.0.0}{Semantic Markup for Problems}
+\RequirePackage{l3keys2e}
+
+\keys_define:nn { problem / pkg }{
+ notes .default:n = { true },
+ notes .bool_set:N = \c_@@_notes_bool,
+ gnotes .default:n = { true },
+ gnotes .bool_set:N = \c_@@_gnotes_bool,
+ hints .default:n = { true },
+ hints .bool_set:N = \c_@@_hints_bool,
+ solutions .default:n = { true },
+ solutions .bool_set:N = \c_@@_solutions_bool,
+ pts .default:n = { true },
+ pts .bool_set:N = \c_@@_pts_bool,
+ min .default:n = { true },
+ min .bool_set:N = \c_@@_min_bool,
+ boxed .default:n = { true },
+ boxed .bool_set:N = \c_@@_boxed_bool,
+ unknown .code:n = {}
+}
+\newif\ifsolutions
+
+\ProcessKeysOptions{ problem / pkg }
+\bool_if:NTF \c_@@_solutions_bool {
+ \solutionstrue
+}{
+ \solutionsfalse
+}
+% \end{macrocode}
+%
+% Then we make sure that the necessary packages are loaded (in the right versions).
+% \begin{macrocode}
+\RequirePackage{comment}
+% \end{macrocode}
+%
+% The next package relies on the \LaTeX3 kernel, which \latexml only partially
+% supports. As it is purely presentational, we only load it when the |boxed| option is
+% given and we run {\latexml}.
+%
+% \begin{macrocode}
+\bool_if:NT \c_@@_boxed_bool { \RequirePackage{mdframed} }
+% \end{macrocode}
+%
+% \begin{macro}{\prob@*@kw}
+% For multilinguality, we define internal macros for keywords that can be specialized in
+% |*.ldf| files.
+% \begin{macrocode}
+\def\prob@problem@kw{Problem}
+\def\prob@solution@kw{Solution}
+\def\prob@hint@kw{Hint}
+\def\prob@note@kw{Note}
+\def\prob@gnote@kw{Grading}
+\def\prob@pt@kw{pt}
+\def\prob@min@kw{min}
+% \end{macrocode}
+% \end{macro}
+%
+% For the other languages, we set up triggers
+% \begin{macrocode}
+\AddToHook{begindocument}{
+ \ltx@ifpackageloaded{babel}{
+ \makeatletter
+ \clist_set:Nx \l_tmpa_clist {\bbl@loaded}
+ \clist_if_in:NnT \l_tmpa_clist {ngerman}{
+ \input{problem-ngerman.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {finnish}{
+ \input{problem-finnish.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {french}{
+ \input{problem-french.ldf}
+ }
+ \clist_if_in:NnT \l_tmpa_clist {russian}{
+ \input{problem-russian.ldf}
+ }
+ \makeatother
+ }{}
+}
+% \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}
+\keys_define:nn{ problem / problem }{
+ id .str_set_x:N = \l_@@_prob_id_str,
+ pts .tl_set:N = \l_@@_prob_pts_tl,
+ min .tl_set:N = \l_@@_prob_min_tl,
+ title .tl_set:N = \l_@@_prob_title_tl,
+ type .tl_set:N = \l_@@_prob_type_tl,
+ refnum .int_set:N = \l_@@_prob_refnum_int
+}
+\cs_new_protected:Nn \_@@_prob_args:n {
+ \str_clear:N \l_@@_prob_id_str
+ \tl_clear:N \l_@@_prob_pts_tl
+ \tl_clear:N \l_@@_prob_min_tl
+ \tl_clear:N \l_@@_prob_title_tl
+ \tl_clear:N \l_@@_prob_type_tl
+ \int_zero_new:N \l_@@_prob_refnum_int
+ \keys_set:nn { problem / problem }{ #1 }
+ \int_compare:nNnT \l_@@_prob_refnum_int = 0 {
+ \let\l_@@_prob_refnum_int\undefined
+ }
+}
+% \end{macrocode}
+%
+% Then we set up a counter for problems.
+% \begin{macro}{\numberproblemsin}
+% \begin{macrocode}
+\newcounter{problem}
+\newcommand\numberproblemsin[1]{\@addtoreset{problem}{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prob@label}
+% We provide the macro |\prob@label| to redefine later to get context involved.
+% \begin{macrocode}
+\newcommand\prob@label[1]{#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prob@number}
+% We consolidate the problem number into a reusable internal macro
+% \begin{macrocode}
+\newcommand\prob@number{
+ \int_if_exist:NTF \l_@@_inclprob_refnum_int {
+ \prob@label{\int_use:N \l_@@_inclprob_refnum_int }
+ }{
+ \int_if_exist:NTF \l_@@_prob_refnum_int {
+ \prob@label{\int_use:N \l_@@_prob_refnum_int }
+ }{
+ \prob@label\theproblem
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prob@title}
+% We consolidate the problem title into a reusable internal macro as well. |\prob@title|
+% takes three arguments the first is the fallback when no title is given at all, the
+% second and third go around the title, if one is given.
+% \begin{macrocode}
+\newcommand\prob@title[3]{%
+ \tl_if_exist:NTF \l_@@_inclprob_title_tl {
+ #2 \l_@@_inclprob_title_tl #3
+ }{
+ \tl_if_exist:NTF \l_@@_prob_title_tl {
+ #2 \l_@@_prob_title_tl #3
+ }{
+ #1
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% With these the problem header is a one-liner
+%
+% \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{
+ {\prob@problem@kw}\ \prob@number\prob@title{~}{~(}{)\strut}
+ %\sref@label@id{\prob@problem@kw~\prob@number}{}
+}
+% \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 whether the respective options
+% are set.
+% \begin{environment}{sproblem}
+% \begin{macrocode}
+\newenvironment{sproblem}[1][]{
+ \_@@_prob_args:n{#1}%\sref@target%
+ \@in@omtexttrue% we are in a statement (for inline definitions)
+ \stepcounter{problem}\record@problem
+ \def\current@section@level{\prob@problem@kw}
+ \tl_if_exist:NTF \l_@@_inclprob_type_tl {
+ \tl_set_eq:NN \sproblemtype \l_@@_inclprob_type_tl
+ }{
+ \tl_set_eq:NN \sproblemtype \l_@@_prob_type_tl
+ }
+ \str_if_exist:NTF \l_@@_inclprob_id_str {
+ \str_set_eq:NN \sproblemid \l_@@_inclprob_id_str
+ }{
+ \str_set_eq:NN \sproblemid \l_@@_prob_id_str
+ }
+
+
+ \clist_set:No \l_tmpa_clist \sproblemtype
+ \tl_clear:N \l_tmpa_tl
+ \clist_map_inline:Nn \l_tmpa_clist {
+ \tl_if_exist:cT {_@@_sproblem_##1_start:}{
+ \tl_set:Nn \l_tmpa_tl {\use:c{_@@_sproblem_##1_start:}}
+ }
+ }
+ \tl_if_empty:NTF \l_tmpa_tl {
+ \_@@_sproblem_start:
+ }{
+ \l_tmpa_tl
+ }
+ \stex_ref_new_doc_target:n \sproblemid
+}{
+ \clist_set:No \l_tmpa_clist \sproblemtype
+ \tl_clear:N \l_tmpa_tl
+ \clist_map_inline:Nn \l_tmpa_clist {
+ \tl_if_exist:cT {_@@_sproblem_##1_end:}{
+ \tl_set:Nn \l_tmpa_tl {\use:c{_@@_sproblem_##1_end:}}
+ }
+ }
+ \tl_if_empty:NTF \l_tmpa_tl {
+ \_@@_sproblem_end:
+ }{
+ \l_tmpa_tl
+ }
+
+
+ \smallskip
+}
+
+
+\cs_new_protected:Nn \_@@_sproblem_start: {
+ \par\noindent\textbf\prob@heading\show@pts\show@min\\\ignorespacesandpars
+}
+\cs_new_protected:Nn \_@@_sproblem_end: {\par\smallskip}
+
+\newcommand\stexpatchproblem[3][] {
+ \str_set:Nx \l_tmpa_str{ #1 }
+ \str_if_empty:NTF \l_tmpa_str {
+ \tl_set:Nn \_@@_sproblem_start: { #2 }
+ \tl_set:Nn \_@@_sproblem_end: { #3 }
+ }{
+ \exp_after:wN \tl_set:Nn \csname _@@_sproblem_#1_start:\endcsname{ #2 }
+ \exp_after:wN \tl_set:Nn \csname _@@_sproblem_#1_end:\endcsname{ #3 }
+ }
+}
+
+
+\bool_if:NT \c_@@_boxed_bool {
+ \surroundwithmdframed{problem}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\record@problem}
+% This macro records information about the problems in the |*.aux| file.
+% \begin{macrocode}
+\def\record@problem{
+ \protected@write\@auxout{}
+ {
+ \string\@problem{\prob@number}
+ {
+ \tl_if_exist:NTF \l_@@_inclprob_pts_tl {
+ \l_@@_inclprob_pts_tl
+ }{
+ \l_@@_prob_pts_tl
+ }
+ }%
+ {
+ \tl_if_exist:NTF \l_@@_inclprob_min_tl {
+ \l_@@_inclprob_min_tl
+ }{
+ \l_@@_prob_min_tl
+ }
+ }
+ }
+}
+% \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}
+\def\@problem#1#2#3{}
+% \end{macrocode}
+% \end{macro}
+%
+% The \DescribeEnv{solution}|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}
+\keys_define:nn { problem / solution }{
+ id .str_set_x:N = \l_@@_solution_id_str ,
+ for .tl_set:N = \l_@@_solution_for_tl ,
+ height .dim_set:N = \l_@@_solution_height_dim ,
+ creators .clist_set:N = \l_@@_solution_creators_clist ,
+ contributors .clist_set:N = \l_@@_solution_contributors_clist ,
+ srccite .tl_set:N = \l_@@_solution_srccite_tl
+}
+\cs_new_protected:Nn \_@@_solution_args:n {
+ \str_clear:N \l_@@_solution_id_str
+ \tl_clear:N \l_@@_solution_for_tl
+ \tl_clear:N \l_@@_solution_srccite_tl
+ \clist_clear:N \l_@@_solution_creators_clist
+ \clist_clear:N \l_@@_solution_contributors_clist
+ \dim_zero:N \l_@@_solution_height_dim
+ \keys_set:nn { problem / solution }{ #1 }
+}
+% \end{macrocode}
+% the next step is to define a helper macro that does what is needed to start a solution.
+% \begin{macrocode}
+\newcommand\@startsolution[1][]{
+ \_@@_solution_args:n { #1 }
+ \@in@omtexttrue% we are in a statement.
+ \bool_if:NF \c_@@_boxed_bool { \hrule }
+ \smallskip\noindent
+ {\textbf\prob@solution@kw :\enspace}
+ \begin{small}
+ \def\current@section@level{\prob@solution@kw}
+ \ignorespacesandpars
+}
+% \end{macrocode}
+%
+% \begin{macro}{\startsolutions}
+% for the |\startsolutions| macro we use the |\specialcomment| macro from the |comment|
+% package. Note that we use the |\@startsolution| macro in the start codes, that parses
+% the optional argument.
+% \begin{macrocode}
+\newcommand\startsolutions{
+ \specialcomment{solution}{\@startsolution}{
+ \bool_if:NF \c_@@_boxed_bool {
+ \hrule\medskip
+ }
+ \end{small}%
+ }
+ \bool_if:NT \c_@@_boxed_bool {
+ \surroundwithmdframed{solution}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\stopsolutions}
+% \begin{macrocode}
+\newcommand\stopsolutions{\excludecomment{solution}}
+% \end{macrocode}
+% \end{macro}
+%
+% so it only remains to start/stop solutions depending on what option was specified.
+%
+% \begin{macrocode}
+\ifsolutions
+ \startsolutions
+\else
+ \stopsolutions
+\fi
+% \end{macrocode}
+%
+% \begin{environment}{exnote}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{exnote}[1][]{
+ \par\smallskip\hrule\smallskip
+ \noindent\textbf{\prob@note@kw : }\small
+ }{
+ \smallskip\hrule
+ }
+}{
+ \excludecomment{exnote}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{hint}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{hint}[1][]{
+ \par\smallskip\hrule\smallskip
+ \noindent\textbf{\prob@hint@kw :~ }\small
+ }{
+ \smallskip\hrule
+ }
+ \newenvironment{exhint}[1][]{
+ \par\smallskip\hrule\smallskip
+ \noindent\textbf{\prob@hint@kw :~ }\small
+ }{
+ \smallskip\hrule
+ }
+}{
+ \excludecomment{hint}
+ \excludecomment{exhint}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{gnote}
+% \begin{macrocode}
+\bool_if:NTF \c_@@_notes_bool {
+ \newenvironment{gnote}[1][]{
+ \par\smallskip\hrule\smallskip
+ \noindent\textbf{\prob@gnote@kw : }\small
+ }{
+ \smallskip\hrule
+ }
+}{
+ \excludecomment{gnote}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Multiple Choice Blocks}\label{sec:impl:mcq}
+%
+% \begin{environment}{mcb}
+% \ednote{MK: maybe import something better here from a dedicated MC package}
+% \begin{macrocode}
+\newenvironment{mcb}{
+ \begin{enumerate}
+}{
+ \end{enumerate}
+}
+% \end{macrocode}
+% \end{environment}
+% we define the keys for the |mcc| macro
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_do_yes_param:Nn {
+ \exp_args:Nx \str_if_eq:nnTF { \str_lowercase:n{ #2 } }{ yes }{
+ \bool_set_true:N #1
+ }{
+ \bool_set_false:N #1
+ }
+}
+\keys_define:nn { problem / mcc }{
+ id .str_set_x:N = \l_@@_mcc_id_str ,
+ feedback .tl_set:N = \l_@@_mcc_feedback_tl ,
+ T .default:n = { true } ,
+ T .bool_set:N = \l_@@_mcc_t_bool ,
+ F .default:n = { true } ,
+ F .bool_set:N = \l_@@_mcc_f_bool ,
+ Ttext .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_mcc_Ttext_bool { #1 }
+ } ,
+ Ftext .code:n = {
+ \_@@_do_yes_param:Nn \l_@@_mcc_Ftext_bool { #1 }
+ }
+}
+\cs_new_protected:Nn \l_@@_mcc_args:n {
+ \str_clear:N \l_@@_mcc_id_str
+ \tl_clear:N \l_@@_mcc_feedback_tl
+ \bool_set_true:N \l_@@_mcc_t_bool
+ \bool_set_true:N \l_@@_mcc_f_bool
+ \bool_set_true:N \l_@@_mcc_Ttext_bool
+ \bool_set_false:N \l_@@_mcc_Ftext_bool
+ \keys_set:nn { problem / mcc }{ #1 }
+}
+% \end{macrocode}
+%
+% \begin{macro}{\mcc}
+% \begin{macrocode}
+\newcommand\mcc[2][]{
+ \l_@@_mcc_args:n{ #1 }
+ \item #2
+ \ifsolutions
+ \\
+ \bool_if:NT \l_@@_mcc_t_bool {
+ % TODO!
+ % \ifcsstring{mcc@T}{T}{}{\mcc@Ttext}%
+ }
+ \bool_if:NT \l_@@_mcc_f_bool {
+ % TODO!
+ % \ifcsstring{mcc@F}{F}{}{\mcc@Ftext}%
+ }
+ \tl_if_empty:NTF \l_@@_mcc_feedback_tl {
+ !
+ }{
+ \l_@@_mcc_feedback_tl
+ }
+ \fi
+} %solutions
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Including Problems}\label{sec:impl:includeproblem}
+%
+% \begin{macro}{\includeproblem}
+% The |\includeproblem| command is essentially a glorified |\input| statement, it sets
+% some internal macros first that overwrite the local points. Importantly, it resets the
+% |inclprob| keys after the input.
+% \begin{macrocode}
+
+\keys_define:nn{ problem / inclproblem }{
+ id .str_set_x:N = \l_@@_inclprob_id_str,
+ pts .tl_set:N = \l_@@_inclprob_pts_tl,
+ min .tl_set:N = \l_@@_inclprob_min_tl,
+ title .tl_set:N = \l_@@_inclprob_title_tl,
+ refnum .int_set:N = \l_@@_inclprob_refnum_int,
+ type .tl_set:N = \l_@@_inclprob_type_tl,
+ mhrepos .str_set_x:N = \l_@@_inclprob_mhrepos_str
+}
+\cs_new_protected:Nn \_@@_inclprob_args:n {
+ \str_clear:N \l_@@_prob_id_str
+ \tl_clear:N \l_@@_inclprob_pts_tl
+ \tl_clear:N \l_@@_inclprob_min_tl
+ \tl_clear:N \l_@@_inclprob_title_tl
+ \tl_clear:N \l_@@_inclprob_type_tl
+ \int_zero_new:N \l_@@_inclprob_refnum_int
+ \str_clear:N \l_@@_inclprob_mhrepos_str
+ \keys_set:nn { problem / inclproblem }{ #1 }
+ \tl_if_empty:NT \l_@@_inclprob_pts_tl {
+ \let\l_@@_inclprob_pts_tl\undefined
+ }
+ \tl_if_empty:NT \l_@@_inclprob_min_tl {
+ \let\l_@@_inclprob_min_tl\undefined
+ }
+ \tl_if_empty:NT \l_@@_inclprob_title_tl {
+ \let\l_@@_inclprob_title_tl\undefined
+ }
+ \tl_if_empty:NT \l_@@_inclprob_type_tl {
+ \let\l_@@_inclprob_type_tl\undefined
+ }
+ \int_compare:nNnT \l_@@_inclprob_refnum_int = 0 {
+ \let\l_@@_inclprob_refnum_int\undefined
+ }
+}
+
+\cs_new_protected:Nn \_@@_inclprob_clear: {
+ \let\l_@@_inclprob_id_str\undefined
+ \let\l_@@_inclprob_pts_tl\undefined
+ \let\l_@@_inclprob_min_tl\undefined
+ \let\l_@@_inclprob_title_tl\undefined
+ \let\l_@@_inclprob_type_tl\undefined
+ \let\l_@@_inclprob_refnum_int\undefined
+ \let\l_@@_inclprob_mhrepos_str\undefined
+}
+\_@@_inclprob_clear:
+
+\newcommand\includeproblem[2][]{
+ \_@@_inclprob_args:n{ #1 }
+ \str_if_empty:NTF \l_@@_inclprob_mhrepos_str {
+ \input{#2}
+ }{
+ \stex_in_repository:nn{\l_@@_inclprob_mhrepos_str}{
+ \input{\mhpath{\l_@@_inclprob_mhrepos_str}{#2}}
+ }
+ }
+ \_@@_inclprob_clear:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reporting Metadata}
+%
+% For messages it is OK to have them in English as the whole documentation is, and we can
+% therefore assume authors can deal with it.
+%
+% \begin{macrocode}
+\AddToHook{enddocument}{
+ \bool_if:NT \c_@@_pts_bool {
+ \message{Total:~\arabic{pts}~points}
+ }
+ \bool_if:NT \c_@@_min_bool {
+ \message{Total:~\arabic{min}~minutes}
+ }
+}
+% \end{macrocode}
+%
+% The margin pars are reader-visible, so we need to translate
+%
+% \begin{macrocode}
+\def\pts#1{
+ \bool_if:NT \c_@@_pts_bool {
+ \marginpar{#1~\prob@pt@kw}
+ }
+}
+\def\min#1{
+ \bool_if:NT \c_@@_min_bool {
+ \marginpar{#1~\prob@min@kw}
+ }
+}
+% \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}
+\newcounter{pts}
+\def\show@pts{
+ \tl_if_exist:NTF \l_@@_inclprob_pts_tl {
+ \bool_if:NT \c_@@_pts_bool {
+ \marginpar{\l_@@_inclprob_pts_tl\ \prob@pt@kw\smallskip}
+ \addtocounter{pts}{\l_@@_inclprob_pts_tl}
+ }
+ }{
+ \tl_if_exist:NT \l_@@_prob_pts_tl {
+ \bool_if:NT \c_@@_pts_bool {
+ \marginpar{\l_@@_prob_pts_tl\ \prob@pt@kw\smallskip}
+ \addtocounter{pts}{\l_@@_prob_pts_tl}
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% and now the same for the minutes
+% \begin{macro}{\show@min}
+% \begin{macrocode}
+\newcounter{min}
+\def\show@min{
+ \tl_if_exist:NTF \l_@@_inclprob_min_tl {
+ \bool_if:NT \c_@@_min_bool {
+ \marginpar{\l_@@_inclprob_pts_tl\ min}
+ \addtocounter{min}{\l_@@_inclprob_min_tl}
+ }
+ }{
+ \tl_if_exist:NT \l_@@_prob_min_tl {
+ \bool_if:NT \c_@@_min_bool {
+ \marginpar{\l_@@_prob_min_tl\ min}
+ \addtocounter{min}{\l_@@_prob_min_tl}
+ }
+ }
+ }
+}
+%</package>
+% \end{macrocode}
+% \end{macro}
+% \end{implementation}
+\endinput
+% LocalWords: GPL structuresharing STR dtx pts keyval xcomment CPERL DefKeyVal iffalse
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+% LocalWords: RequirePackage Semiverbatim DefEnvironment OptionalKeyVals soln texttt baz
+% LocalWords: exnote DefConstructor inclprob NeedsTeXFormat omd.sty textbackslash exfig
+% LocalWords: stopsolution fileversion filedate maketitle setcounter tocdepth newpage
+% LocalWords: tableofcontents showmeta showmeta solutionstrue usepackage minipage hrule
+% LocalWords: linewidth elefants.prob Elefants smallskip noindent textbf startsolutions
+% LocalWords: startsolutions stopsolutions stopsolutions includeproblem includeproblem
+% LocalWords: textsf HorIacJuc cscpnrr11 includemhproblem includemhproblem importmodule
+% LocalWords: importmhmodule foobar ldots latexml mhcurrentrepos mh-variants mh-variant
+% LocalWords: compactenum langle rangle langle rangle ltxml metakeys newif ifexnotes rm
+% LocalWords: exnotesfalse exnotestrue ifhints hintsfalse hintstrue ifsolutions ifpts
+% LocalWords: solutionsfalse ptsfalse ptstrue ifmin minfalse mintrue ifboxed boxedfalse
+% LocalWords: boxedtrue sref mdframed marginpar prob srefaddidkey addmetakey refnum kv
+% LocalWords: newcounter ifx thesection theproblem hfill newenvironment metasetkeys ltx
+% LocalWords: stepcounter currentsectionlevel xspace ignorespaces surroundwithmdframed
+% LocalWords: omdoc autoopen autoclose solvedinminutes kvi qw vals newcommand exhint
+% LocalWords: specialcomment excludecomment mhrepos xref marginpar addtocounter doctex
+% LocalWords: mh@currentrepos endinput
+
diff --git a/macros/latex/contrib/stex/source/extensions/tikzinput.dtx b/macros/latex/contrib/stex/source/extensions/tikzinput.dtx
new file mode 100644
index 0000000000..51a3a7c06a
--- /dev/null
+++ b/macros/latex/contrib/stex/source/extensions/tikzinput.dtx
@@ -0,0 +1,146 @@
+% \iffalse meta-comment
+% An Infrastructure for Semantic Macros and Module Scoping
+% 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/
+%
+% TODO update copyright
+%
+%<*driver>
+\providecommand\bibfolder{../../lib/bib}
+\input{../../doc/docheader}
+
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{Tikzinput
+% \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{tikzinput} 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/tikzinput}
+% \fi
+%
+% \begin{documentation}\label{pkg:tikzinput:doc}
+%
+%
+% \section{Macros and Environments}\label{pkg:tikzinput:doc:macros}
+%
+% \end{documentation}
+%
+% \begin{implementation}\label{pkg:tikzinput:impl}
+%
+% \section{Tikzinput Implementation}
+%
+% \begin{macrocode}
+%<*package>
+
+%%%%%%%%%%%%% tikzinput.dtx %%%%%%%%%%%%%
+
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProvidesExplPackage{tikzinput}{2022/02/24}{3.0.0}{tikzinput package}
+\RequirePackage{l3keys2e}
+
+\keys_define:nn { tikzinput } {
+ image .bool_set:N = \c_tikzinput_image_bool,
+ image .default:n = false ,
+ unknown .code:n = {}
+}
+
+\ProcessKeysOptions { tikzinput }
+
+\bool_if:NTF \c_tikzinput_image_bool {
+ \RequirePackage{graphicx}
+
+ \providecommand\usetikzlibrary[]{}
+ \newcommand\tikzinput[2][]{\includegraphics[#1]{#2}}
+}{
+ \RequirePackage{tikz}
+ \RequirePackage{standalone}
+
+ \newcommand \tikzinput [2] [] {
+ \setkeys{Gin}{#1}
+ \ifx \Gin@ewidth \Gin@exclamation
+ \ifx \Gin@eheight \Gin@exclamation
+ \input { #2 }
+ \else
+ \resizebox{!}{ \Gin@eheight }{
+ \input { #2 }
+ }
+ \fi
+ \else
+ \ifx \Gin@eheight \Gin@exclamation
+ \resizebox{ \Gin@ewidth }{!}{
+ \input { #2 }
+ }
+ \else
+ \resizebox{ \Gin@ewidth }{ \Gin@eheight }{
+ \input { #2 }
+ }
+ \fi
+ \fi
+ }
+}
+
+\newcommand \ctikzinput [2] [] {
+ \begin{center}
+ \tikzinput [#1] {#2}
+ \end{center}
+}
+
+\@ifpackageloaded{stex}{
+ \RequirePackage{stex-tikzinput}
+}{}
+
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</package>
+%<*stex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProvidesExplPackage{stex-tikzinput}{2022/02/24}{3.0.0}{stex-tikzinput}
+\RequirePackage{stex}
+\RequirePackage{tikzinput}
+
+\newcommand\mhtikzinput[2][]{%
+ \def\Gin@mhrepos{}\setkeys{Gin}{#1}%
+ \stex_in_repository:nn\Gin@mhrepos{
+ \tikzinput[#1]{\mhpath{##1}{#2}}
+ }
+}
+\newcommand\cmhtikzinput[2][]{\begin{center}\mhtikzinput[#1]{#2}\end{center}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</stex>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
+
+% LocalWords: bibfolder jobname.dtx tikzinput.dtx usetikzlibrary Gin@ewidth Gin@eheight
+% LocalWords: resizebox ctikzinput mhtikzinput Gin@mhrepos mhpath