diff options
Diffstat (limited to 'macros/latex/contrib/stex/source/extensions')
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 |