summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/stex/source/problem.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-03-22 03:01:52 +0000
committerNorbert Preining <norbert@preining.info>2023-03-22 03:01:52 +0000
commitcbbc6dbdbf08b70a7e7d8d184ca51c57c835415a (patch)
tree97ded8ca7095c54f6ff9b661be6b93f80bf792c4 /macros/latex/contrib/stex/source/problem.dtx
parentde9a0afa47c2ee09e1d4704821cad2b231d36b3f (diff)
CTAN sync 202303220301
Diffstat (limited to 'macros/latex/contrib/stex/source/problem.dtx')
-rw-r--r--macros/latex/contrib/stex/source/problem.dtx638
1 files changed, 638 insertions, 0 deletions
diff --git a/macros/latex/contrib/stex/source/problem.dtx b/macros/latex/contrib/stex/source/problem.dtx
new file mode 100644
index 0000000000..c62a9242ba
--- /dev/null
+++ b/macros/latex/contrib/stex/source/problem.dtx
@@ -0,0 +1,638 @@
+% \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\stexdocpath{../doc}
+\input{\stexdocpath/stex-docheader}
+\stextoptitle{The \texttt{problem} Package}{problem}
+\docmodule
+%</driver>
+% \fi
+%
+% \begin{stexmanual}
+% \begin{sfragment}{Problem Manual}
+ % \input{\stexdocpath/packages/stex-problem}
+% \end{sfragment}
+% \end{stexmanual}
+%
+% \begin{documentation}
+% \begin{sfragment}{Problem Documentation}
+% TODO
+% \end{sfragment}
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{Implementation: The problem Package}
+%
+% \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}{2023/03/19}{3.3.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,
+ test .default:n = { true },
+ test .bool_set:N = \c_@@_test_bool,
+ unknown .code:n = {
+ \PassOptionsToPackage{\CurrentOption}{stex}
+ }
+}
+\newif\ifsolutions
+
+\ProcessKeysOptions{ problem / pkg }
+\bool_if:NTF \c_@@_solutions_bool {
+ \solutionstrue
+}{
+ \solutionsfalse
+}
+\RequirePackage{stex}
+% \end{macrocode}
+%
+% \begin{macro}{\problem@kw@*}
+% For multilinguality, we define internal macros for keywords that can be specialized in
+% |*.ldf| files.
+% \begin{macrocode}
+\AddToHook{begindocument}{
+ \ExplSyntaxOn\makeatletter
+ \input{problem-english.ldf}
+ \ltx@ifpackageloaded{babel}{
+ \clist_set:Nx \l_tmpa_clist {\bbl@loaded}
+ \exp_args:NNx \clist_if_in:NnT \l_tmpa_clist {\detokenize{ngerman}}{
+ \input{problem-ngerman.ldf}
+ }
+ \exp_args:NNx \clist_if_in:NnT \l_tmpa_clist {\detokenize{finnish}}{
+ \input{problem-finnish.ldf}
+ }
+ \exp_args:NNx \clist_if_in:NnT \l_tmpa_clist {\detokenize{french}}{
+ \input{problem-french.ldf}
+ }
+ \exp_args:NNx \clist_if_in:NnT \l_tmpa_clist {\detokenize{russian}}{
+ \input{problem-russian.ldf}
+ }
+ }{}
+ \makeatother\ExplSyntaxOff
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \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}
+\stex_keys_define:nnnn{ problem }{
+ \tl_set:Nn \l_stex_key_pts_tl 0
+ \tl_set:Nn \l_stex_key_min_tl 0
+ \str_clear:N \l_stex_key_name_str
+ \str_clear:N \l_stex_key_mhrepos_str
+}{
+ pts .tl_set:N = \l_stex_key_pts_tl,
+ min .tl_set:N = \l_stex_key_min_tl,
+ name .str_set:N = \l_stex_key_name_str,
+ archive .str_set:N = \l_stex_key_mhrepos_str,
+ creators .code:n = {}
+ %imports .tl_set:N = \l_@@_prob_imports_tl,
+ %refnum .int_set:N = \l_@@_prob_refnum_int,
+}{id,title,style,uses}
+% \end{macrocode}
+%
+% Then we set up a counter for problems.
+% \begin{macro}{\numberproblemsin}
+% \begin{macrocode}
+\newcounter{sproblem}[section]
+\newcommand\numberproblemsin[1]{
+ \@addtoreset{sproblem}{#1}
+ \def\thesproblem{\arabic{#1}.\arabic{sproblem}}
+}
+\numberproblemsin{section}
+%\def\theplainsproblem{\arabic{sproblem}}
+%\def\thesproblem{\thesection.\theplainsproblem}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{sproblem}
+% \begin{macrocode}
+\newcounter{pts}
+\newcounter{min}
+\stex_new_stylable_env:nnnnnnn {problem} {O{}}{
+ \cs_if_exist:NTF \l_problem_inputproblem_keys_tl {
+ \tl_put_left:Nn \l_problem_inputproblem_keys_tl {#1,}
+ \exp_args:Nno \stex_keys_set:nn{problem}{
+ \l_problem_inputproblem_keys_tl
+ }
+ }{
+ \stex_keys_set:nn{problem}{#1}
+ }
+ \refstepcounter{sproblem}
+ \str_if_empty:NT \l_stex_key_name_str {
+ \stex_file_split_off_lang:NN \l_@@_path_seq \g_stex_current_file
+ \seq_get_right:NN \l_@@_path_seq \l_stex_key_name_str
+ }
+
+ \exp_args:No \stex_module_setup:n \l_stex_key_name_str
+
+ \stex_if_do_html:T {
+ \exp_args:Nne \begin{stex_annotate_env} {
+ shtml:problem={\l_stex_current_module_str},
+ shtml:language={ \l_stex_current_language_str},
+ shtml:signature={\l_stex_key_sig_str}
+ \tl_if_empty:NF \l_stex_metatheory_uri {,
+ shtml:metatheory={\stex_uri_use:N \l_stex_metatheory_uri}
+ }
+ }
+ \stex_annotate_invisible:n{}
+ \tl_if_empty:NF \l_stex_key_title_tl {
+ \exp_args:No \stexdoctitle \l_stex_key_title_tl
+ }
+ }
+ \stex_if_smsmode:F {
+ \str_set_eq:NN \thismoduleuri \l_stex_current_module_str
+ \tl_set_eq:NN \thismodulename \l_stex_key_name_str
+ \tl_set_eq:NN \thistitle \l_stex_key_title_tl
+ \stex_style_apply:
+ \addtocounter{pts}{\l_stex_key_pts_tl}
+ \addtocounter{min}{\l_stex_key_min_tl}
+ \_stex_do_id:
+ \_@@_record_problem:
+ }
+ \stex_reactivate_macro:N \solution
+ \stex_reactivate_macro:N \mcb
+ \stex_reactivate_macro:N \fillinsol
+ \stex_smsmode_do:
+}{
+ \stex_close_module:
+ \stex_if_smsmode:F \stex_style_apply:
+ \stex_if_do_html:T{ \end{stex_annotate_env} }
+}{
+ \par\noindent\problemheader
+ \bool_if:NT \c_@@_pts_bool {
+ \marginpar{\l_stex_key_pts_tl{}~\problem@kw@points\smallskip}
+ }
+ \bool_if:NT \c_@@_min_bool {
+ \marginpar{\l_stex_key_min_tl{}~\problem@kw@minutes\smallskip}
+ }
+ \\
+ \stex_ignore_spaces_and_pars:
+}{
+ \par\bigskip
+% \bool_if:NT \c_@@_test_bool \pagebreak
+}{s}
+\stex_sms_allow_env:n{sproblem}
+
+\tl_set:Nn \problemheader {
+ \textbf{\sproblemautorefname{~}\thesproblem
+ \tl_if_empty:NF \thistitle {
+ {~}(\thistitle)
+ }
+ }
+}
+
+\cs_new_protected:Nn \_@@_record_problem: {
+ \exp_args:NNe \iow_now:Nn \@auxout {
+ \problem@restore {\thesproblem}{\l_stex_key_pts_tl}{\l_stex_key_min_tl}
+ }
+}
+
+\cs_new_protected:Npn \problem@restore #1 #2 #3 {}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\includeproblem}
+% \begin{macrocode}
+\stex_keys_define:nnnn{ includeproblem }{
+ \str_clear:N \l_stex_key_mhrepos_str
+}{
+ archive .str_set:N = \l_stex_key_mhrepos_str,
+ unknown .code:n = {}
+}{}
+
+\NewDocumentCommand\includeproblem{O{} m}{
+ \group_begin:
+ \tl_set:Nn \l_problem_inputproblem_keys_tl {#1}
+ \stex_keys_set:nn{includeproblem}{#1}
+ \exp_args:Nno \use:nn{\inputref[}\l_stex_key_mhrepos_str]{#2}
+ \group_end:
+}
+
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{solution}
+% \begin{macrocode}
+\int_new:N \g_problem_id_counter
+
+\cs_new_protected:Nn \_@@_solution_start:n {
+ \str_set:Nn \l_stex_key_title_tl {#1}
+ \str_set:Nn \l_stex_key_id_str {#1}
+ \str_if_empty:NT \l_stex_key_id_str {
+ \int_gincr:N \g_problem_id_counter
+ \str_set:Nx \l_stex_key_id_str {
+ SOLUTION_\int_use:N \g_problem_id_counter
+ }
+ }
+ \stex_if_do_html:T{
+ \begin{stex_annotate_env}{
+ shtml:solution=\l_stex_key_id_str
+ }
+ }
+ \stex_style_apply:
+}
+
+\stex_new_stylable_env:nnnnnnn { solution }{ O{} }{
+ \stex_if_do_html:TF{
+ \_@@_solution_start:n{#1}
+ }{
+ \ifsolutions
+ \_@@_solution_start:n{#1}
+ \else
+ \setbox\l_tmpa_box\vbox\bgroup
+ \fi
+ }
+}{
+ \stex_if_do_html:TF{
+ \stex_style_apply:
+ \end{stex_annotate_env}
+ }{
+ \ifsolutions
+ \stex_style_apply:
+ \stex_if_do_html:T{
+ \end{stex_annotate_env}
+ }
+ \else
+ \egroup
+ \fi
+ }
+}{
+ \par\smallskip\hrule\smallskip
+ \noindent\emph{Solution\str_if_empty:NF \l_stex_key_title_tl{
+ {~}\l_stex_key_title_tl
+ } :~}
+}{
+ \par\smallskip\hrule
+}{}
+
+\stex_deactivate_macro:Nn \solution {sproblem~environments}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\startsolutions,\stopsolutions}
+% \begin{macrocode}
+\cs_new_protected:Npn \startsolutions{
+ \global\solutionstrue
+}
+\cs_new_protected:Npn \stopsolutions{
+ \global\solutionsfalse
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{hint}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_hint_start:n {
+ \str_set:Nn \l_stex_key_title_tl {#1}
+ \str_set:Nn \l_stex_key_id_str {#1}
+ \str_if_empty:NT \l_stex_key_id_str {
+ \int_gincr:N \g_problem_id_counter
+ \str_set:Nx \l_stex_key_id_str {
+ HINT_\int_use:N \g_problem_id_counter
+ }
+ }
+ \stex_if_do_html:T{
+ \begin{stex_annotate_env}{
+ shtml:problemhint=\l_stex_key_id_str
+ }
+ }
+ \stex_style_apply:
+}
+
+\stex_new_stylable_env:nnnnnnn { hint }{ O{} }{
+ \stex_if_do_html:TF{
+ \_@@_hint_start:n{#1}
+ }{
+ \bool_if:NTF \c_@@_hints_bool {
+ \_@@_hint_start:n{#1}
+ }{
+ \setbox\l_tmpa_box\vbox\bgroup
+ }
+ }
+}{
+ \stex_if_do_html:TF{
+ \stex_style_apply:
+ \end{stex_annotate_env}
+ }{
+ \bool_if:NTF \c_@@_hints_bool {
+ \stex_style_apply:
+ \stex_if_do_html:T{
+ \end{stex_annotate_env}
+ }
+ }{
+ \egroup
+ }
+ }
+}{
+ \par\smallskip\hrule\smallskip
+ \noindent\emph{Hint\str_if_empty:NF \l_stex_key_title_tl{
+ {~}\l_stex_key_title_tl
+ } :~}
+}{
+ \par\smallskip\hrule
+}{}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{exnote}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_exnote_start:n {
+ \str_set:Nn \l_stex_key_title_tl {#1}
+ \str_set:Nn \l_stex_key_id_str {#1}
+ \str_if_empty:NT \l_stex_key_id_str {
+ \int_gincr:N \g_problem_id_counter
+ \str_set:Nx \l_stex_key_id_str {
+ EXNOTE_\int_use:N \g_problem_id_counter
+ }
+ }
+ \stex_if_do_html:T{
+ \begin{stex_annotate_env}{
+ shtml:problemnote=\l_stex_key_id_str
+ }
+ }
+ \stex_style_apply:
+}
+
+\stex_new_stylable_env:nnnnnnn { exnote }{ O{} }{
+ \stex_if_do_html:TF{
+ \_@@_exnote_start:n{#1}
+ }{
+ \bool_if:NTF \c_@@_notes_bool {
+ \_@@_exnote_start:n{#1}
+ }{
+ \setbox\l_tmpa_box\vbox\bgroup
+ }
+ }
+}{
+ \stex_if_do_html:TF{
+ \stex_style_apply:
+ \end{stex_annotate_env}
+ }{
+ \bool_if:NTF \c_@@_notes_bool {
+ \stex_style_apply:
+ \stex_if_do_html:T{
+ \end{stex_annotate_env}
+ }
+ }{
+ \egroup
+ }
+ }
+}{
+ \par\smallskip\hrule\smallskip
+ \noindent\emph{Note\str_if_empty:NF \l_stex_key_title_tl{
+ {~}\l_stex_key_title_tl
+ } :~}
+}{
+ \par\smallskip\hrule
+}{}
+% \end{macrocode}
+% \end{environment}
+%% \begin{environment}{gnote}
+% \begin{macrocode}
+\cs_new_protected:Nn \_@@_gnote_start:n {
+ \str_set:Nn \l_stex_key_title_tl {#1}
+ \str_set:Nn \l_stex_key_id_str {#1}
+ \str_if_empty:NT \l_stex_key_id_str {
+ \int_gincr:N \g_problem_id_counter
+ \str_set:Nx \l_stex_key_id_str {
+ GNOTE_\int_use:N \g_problem_id_counter
+ }
+ }
+ \stex_if_do_html:T{
+ \begin{stex_annotate_env}{
+ shtml:problemgnote=\l_stex_key_id_str
+ }
+ }
+ \stex_style_apply:
+}
+
+\stex_new_stylable_env:nnnnnnn { gnote }{ O{} }{
+ \stex_if_do_html:TF{
+ \_@@_gnote_start:n{#1}
+ }{
+ \bool_if:NTF \c_@@_gnotes_bool {
+ \_@@_gnote_start:n{#1}
+ }{
+ \setbox\l_tmpa_box\vbox\bgroup
+ }
+ }
+}{
+ \stex_if_do_html:TF{
+ \stex_style_apply:
+ \end{stex_annotate_env}
+ }{
+ \bool_if:NTF \c_@@_gnotes_bool {
+ \stex_style_apply:
+ \stex_if_do_html:T{
+ \end{stex_annotate_env}
+ }
+ }{
+ \egroup
+ }
+ }
+}{
+ \par\smallskip\hrule\smallskip
+ \noindent\emph{Grading\str_if_empty:NF \l_stex_key_title_tl{
+ {~}\l_stex_key_title_tl
+ } :~}
+}{
+ \par\smallskip\hrule
+}{}
+% \end{macrocode}
+% \end{environment}
+%
+% The margin pars are reader-visible, so we need to translate
+%
+% \begin{macrocode}
+\def\pts#1{
+ \bool_if:NT \c_@@_pts_bool {
+ \marginpar{#1~\problem@kw@points}
+ }
+}
+\def\min#1{
+ \bool_if:NT \c_@@_min_bool {
+ \marginpar{#1~\problem@kw@minutes}
+ }
+}
+% \end{macrocode}
+%
+% \begin{environment}{mcb}
+%
+% \begin{macrocode}
+\newenvironment{mcb}{\par
+ \stex_if_do_html:T{
+ \begin{stex_annotate_env}{shtml:multiple-choice-block={}}
+ }
+ \stex_deactivate_macro:Nn \mcb {sproblem~environments}
+ \stex_deactivate_macro:Nn \solution {sproblem~environments}
+ \stex_reactivate_macro:N \mcc
+ \begin{enumerate}
+}{
+ \end{enumerate}
+ \stex_if_do_html:T{
+ \end{stex_annotate_env}
+ }
+}
+\stex_deactivate_macro:Nn \mcb {sproblem~environments}
+% \end{macrocode}
+%
+% 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
+ }
+}
+\stex_keys_define:nnnn{mcc}{
+ \tl_clear:N \l_stex_key_feedback_tl
+ \bool_set_false:N \l_stex_key_T_bool
+ \tl_clear:N \l_stex_key_Ttext_tl
+ \tl_clear:N \l_stex_key_Ftext_tl
+}{
+ feedback .tl_set:N = \l_stex_key_feedback_tl ,
+ T .default:n = { false } ,
+ T .bool_set:N = \l_stex_key_T_bool ,
+ F .default:n = { false } ,
+ F .code:n = {\bool_set_false:N \l_stex_key_T_bool} ,
+ Ttext .tl_set:N = \l_stex_key_Ttext_tl ,
+ Ftext .tl_set:N = \l_stex_key_Ftext_tl ,
+}{id}
+
+% \end{macrocode}
+%
+% \begin{macro}{\mcc}
+% \begin{macrocode}
+\tl_set:Nn \problem_mcc_box_tl {
+ \ltx@ifpackageloaded{amssymb}{$\square$}{
+ \hbox{\vrule\vbox{\hrule width 6 pt\vskip 6pt\hrule}\vrule}
+ }
+}
+\newcommand\mcc[2][]{
+ \stex_keys_set:nn{mcc}{#1}\par
+ \tl_set:Nn \l_tmpb_tl {~--~
+ \bool_if:NTF \l_stex_key_T_bool {
+ \tl_if_empty:NTF \l_stex_key_Ttext_tl \problem@kw@correct \l_stex_key_Ttext_tl
+ }{
+ \tl_if_empty:NTF \l_stex_key_Ftext_tl \problem@kw@wrong \l_stex_key_Ftext_tl
+ }
+ \tl_if_empty:NF \l_stex_key_feedback_tl {
+ \\\emph{\l_stex_key_feedback_tl}
+ }
+ }
+ \tl_set:Nn \l_tmpa_tl {
+ #2
+ \stex_if_do_html:TF{
+ \stex_annotate:nn{shtml:mcc-solution={}}{\l_tmpb_tl}
+ }{
+ \ifsolutions\l_tmpb_tl\fi
+ }
+ }
+ \item[\problem_mcc_box_tl]{}~
+ \stex_if_do_html:TF{
+ \stex_annotate:nn{shtml:mcc={
+ \bool_if:NTF \l_stex_key_T_bool {true}{false}
+ }}{\l_tmpa_tl}
+ }{\l_tmpa_tl}
+}
+\stex_deactivate_macro:Nn \mcc {mcb~environments}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fillinsol}
+% \begin{macrocode}
+\newcommand\fillinsol[2][]{
+ \quad
+ \stex_if_do_html:TF{
+ \stex_annotate:nn{shtml:fillinsol={}}{ \_stex_annotate_force_break:n{#2} }
+ }{
+ \ifsolutions
+ \textcolor{red}{\fbox{#2}}
+ \else
+ \fbox{
+ \tl_if_empty:nTF{#1}{
+ \phantom{\huge{#2}}
+ }{
+ \hspace{#1}
+ }
+ }
+ \fi
+ }
+ \quad
+}
+\stex_deactivate_macro:Nn \fillinsol {sproblem~environments}
+% \end{macrocode}
+% \end{macro}
+%
+% \end{environment}
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+% ^^A \ifinfulldoc\else\printbibliography\fi
+\endinput
+%%% Local Variables:
+%%% mode: doctex
+%%% TeX-master: t
+%%% End:
+% \fi
+% LocalWords: GPL structuresharing STR dtx pts keyval xcomment CPERL DefKeyVal iffalse
+% 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
+