%% %% This is file `problem.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% problem.dtx (with options: `package') %% \ProvidesExplPackage{problem}{2022/05/24}{3.1.0}{Semantic Markup for Problems} \RequirePackage{l3keys2e,stex} \keys_define:nn { problem / pkg }{ notes .default:n = { true }, notes .bool_set:N = \c__problems_notes_bool, gnotes .default:n = { true }, gnotes .bool_set:N = \c__problems_gnotes_bool, hints .default:n = { true }, hints .bool_set:N = \c__problems_hints_bool, solutions .default:n = { true }, solutions .bool_set:N = \c__problems_solutions_bool, pts .default:n = { true }, pts .bool_set:N = \c__problems_pts_bool, min .default:n = { true }, min .bool_set:N = \c__problems_min_bool, boxed .default:n = { true }, boxed .bool_set:N = \c__problems_boxed_bool, unknown .code:n = {} } \newif\ifsolutions \ProcessKeysOptions{ problem / pkg } \bool_if:NTF \c__problems_solutions_bool { \solutionstrue }{ \solutionsfalse } \RequirePackage{comment} \bool_if:NT \c__problems_boxed_bool { \RequirePackage{mdframed} } \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} \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 }{} } \keys_define:nn{ problem / problem }{ id .str_set_x:N = \l__problems_prob_id_str, pts .tl_set:N = \l__problems_prob_pts_tl, min .tl_set:N = \l__problems_prob_min_tl, title .tl_set:N = \l__problems_prob_title_tl, type .tl_set:N = \l__problems_prob_type_tl, imports .tl_set:N = \l__problems_prob_imports_tl, name .str_set_x:N = \l__problems_prob_name_str, refnum .int_set:N = \l__problems_prob_refnum_int } \cs_new_protected:Nn \__problems_prob_args:n { \str_clear:N \l__problems_prob_id_str \str_clear:N \l__problems_prob_name_str \tl_clear:N \l__problems_prob_pts_tl \tl_clear:N \l__problems_prob_min_tl \tl_clear:N \l__problems_prob_title_tl \tl_clear:N \l__problems_prob_type_tl \tl_clear:N \l__problems_prob_imports_tl \int_zero_new:N \l__problems_prob_refnum_int \keys_set:nn { problem / problem }{ #1 } \int_compare:nNnT \l__problems_prob_refnum_int = 0 { \let\l__problems_prob_refnum_int\undefined } } \newcounter{problem}[section] \newcommand\numberproblemsin[1]{\@addtoreset{problem}{#1}} \newcommand\prob@label[1]{\thesection.#1} \newcommand\prob@number{ \int_if_exist:NTF \l__problems_inclprob_refnum_int { \prob@label{\int_use:N \l__problems_inclprob_refnum_int } }{ \int_if_exist:NTF \l__problems_prob_refnum_int { \prob@label{\int_use:N \l__problems_prob_refnum_int } }{ \prob@label\theproblem } } } \newcommand\prob@title[3]{% \tl_if_exist:NTF \l__problems_inclprob_title_tl { #2 \l__problems_inclprob_title_tl #3 }{ \tl_if_exist:NTF \l__problems_prob_title_tl { #2 \l__problems_prob_title_tl #3 }{ #1 } } } \def\prob@heading{ {\prob@problem@kw}\ \prob@number\prob@title{~}{~(}{)\strut} %\sref@label@id{\prob@problem@kw~\prob@number}{} } \newenvironment{sproblem}[1][]{ \__problems_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} \str_if_empty:NT \l__problems_prob_name_str { \seq_get_right:NN \g_stex_currentfile_seq \l_tmpa_str \seq_set_split:NnV \l_tmpa_seq . \l_tmpa_str \seq_get_left:NN \l_tmpa_seq \l__problems_prob_name_str } \stex_if_do_html:T{ \tl_if_empty:NF \l__problems_prob_title_tl { \exp_args:No \stex_document_title:n \l__problems_prob_title_tl } } \exp_args:Nno\stex_module_setup:nn{type=problem}\l__problems_prob_name_str \stex_reactivate_macro:N \STEXexport \stex_reactivate_macro:N \importmodule \stex_reactivate_macro:N \symdecl \stex_reactivate_macro:N \notation \stex_reactivate_macro:N \symdef \stex_if_do_html:T{ \begin{stex_annotate_env} {problem} { \l_stex_module_ns_str ? \l_stex_module_name_str } \stex_annotate_invisible:nnn{header}{} { \stex_annotate:nnn{language}{ \l_stex_module_lang_str }{} \stex_annotate:nnn{signature}{ \l_stex_module_sig_str }{} \str_if_eq:VnF \l_stex_module_meta_str {NONE} { \stex_annotate:nnn{metatheory}{ \l_stex_module_meta_str }{} } } } \stex_csl_to_imports:No \importmodule \l__problems_prob_imports_tl \tl_if_exist:NTF \l__problems_inclprob_type_tl { \tl_set_eq:NN \sproblemtype \l__problems_inclprob_type_tl }{ \tl_set_eq:NN \sproblemtype \l__problems_prob_type_tl } \str_if_exist:NTF \l__problems_inclprob_id_str { \str_set_eq:NN \sproblemid \l__problems_inclprob_id_str }{ \str_set_eq:NN \sproblemid \l__problems_prob_id_str } \stex_if_smsmode:F { \clist_set:No \l_tmpa_clist \sproblemtype \tl_clear:N \l_tmpa_tl \clist_map_inline:Nn \l_tmpa_clist { \tl_if_exist:cT {__problems_sproblem_##1_start:}{ \tl_set:Nn \l_tmpa_tl {\use:c{__problems_sproblem_##1_start:}} } } \tl_if_empty:NTF \l_tmpa_tl { \__problems_sproblem_start: }{ \l_tmpa_tl } } \stex_ref_new_doc_target:n \sproblemid \stex_smsmode_do: }{ \__stex_modules_end_module: \stex_if_smsmode:F{ \clist_set:No \l_tmpa_clist \sproblemtype \tl_clear:N \l_tmpa_tl \clist_map_inline:Nn \l_tmpa_clist { \tl_if_exist:cT {__problems_sproblem_##1_end:}{ \tl_set:Nn \l_tmpa_tl {\use:c{__problems_sproblem_##1_end:}} } } \tl_if_empty:NTF \l_tmpa_tl { \__problems_sproblem_end: }{ \l_tmpa_tl } } \stex_if_do_html:T{ \end{stex_annotate_env} } \smallskip } \seq_put_right:Nx\g_stex_smsmode_allowedenvs_seq{\tl_to_str:n{sproblem}} \cs_new_protected:Nn \__problems_sproblem_start: { \par\noindent\textbf\prob@heading\show@pts\show@min\\\ignorespacesandpars } \cs_new_protected:Nn \__problems_sproblem_end: {\par\smallskip} \newcommand\stexpatchproblem[3][] { \str_set:Nx \l_tmpa_str{ #1 } \str_if_empty:NTF \l_tmpa_str { \tl_set:Nn \__problems_sproblem_start: { #2 } \tl_set:Nn \__problems_sproblem_end: { #3 } }{ \exp_after:wN \tl_set:Nn \csname __problems_sproblem_#1_start:\endcsname{ #2 } \exp_after:wN \tl_set:Nn \csname __problems_sproblem_#1_end:\endcsname{ #3 } } } \bool_if:NT \c__problems_boxed_bool { \surroundwithmdframed{problem} } \def\record@problem{ \protected@write\@auxout{} { \string\@problem{\prob@number} { \tl_if_exist:NTF \l__problems_inclprob_pts_tl { \l__problems_inclprob_pts_tl }{ \l__problems_prob_pts_tl } }% { \tl_if_exist:NTF \l__problems_inclprob_min_tl { \l__problems_inclprob_min_tl }{ \l__problems_prob_min_tl } } } } \def\@problem#1#2#3{} \keys_define:nn { problem / solution }{ id .str_set_x:N = \l__problems_solution_id_str , for .tl_set:N = \l__problems_solution_for_tl , height .dim_set:N = \l__problems_solution_height_dim , creators .clist_set:N = \l__problems_solution_creators_clist , contributors .clist_set:N = \l__problems_solution_contributors_clist , srccite .tl_set:N = \l__problems_solution_srccite_tl } \cs_new_protected:Nn \__problems_solution_args:n { \str_clear:N \l__problems_solution_id_str \tl_clear:N \l__problems_solution_for_tl \tl_clear:N \l__problems_solution_srccite_tl \clist_clear:N \l__problems_solution_creators_clist \clist_clear:N \l__problems_solution_contributors_clist \dim_zero:N \l__problems_solution_height_dim \keys_set:nn { problem / solution }{ #1 } } \newcommand\@startsolution[1][]{ \__problems_solution_args:n { #1 } \@in@omtexttrue% we are in a statement. \bool_if:NF \c__problems_boxed_bool { \hrule } \smallskip\noindent {\textbf\prob@solution@kw :\enspace} \begin{small} \def\current@section@level{\prob@solution@kw} \ignorespacesandpars } \box_new:N \l__problems_solution_box \newenvironment{solution}[1][]{ \stex_html_backend:TF{ \stex_if_do_html:T{ \begin{stex_annotate_env}{solution}{} } }{ \setbox\l__problems_solution_box\vbox\bgroup \par\smallskip\hrule\smallskip \noindent\textbf{Solution:}~ } }{ \stex_html_backend:TF{ \stex_if_do_html:T{ \end{stex_annotate_env} } }{ \smallskip\hrule \egroup \bool_if:NT \c__problems_solutions_bool { \box\l__problems_solution_box } } } \newcommand\startsolutions{ \bool_set_true:N \c__problems_solutions_bool } \newcommand\stopsolutions{\bool_set_false:N \c__problems_solutions_bool}%\excludecomment{solution}} \ifsolutions \startsolutions \else \stopsolutions \fi \bool_if:NTF \c__problems_notes_bool { \newenvironment{exnote}[1][]{ \par\smallskip\hrule\smallskip \noindent\textbf{\prob@note@kw :~ }\small }{ \smallskip\hrule } }{ \excludecomment{exnote} } \bool_if:NTF \c__problems_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} } \bool_if:NTF \c__problems_notes_bool { \newenvironment{gnote}[1][]{ \par\smallskip\hrule\smallskip \noindent\textbf{\prob@gnote@kw :~ }\small }{ \smallskip\hrule } }{ \excludecomment{gnote} } \newenvironment{mcb}{ \begin{enumerate} }{ \end{enumerate} } \cs_new_protected:Nn \__problems_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__problems_mcc_id_str , feedback .tl_set:N = \l__problems_mcc_feedback_tl , T .default:n = { false } , T .bool_set:N = \l__problems_mcc_t_bool , F .default:n = { false } , F .bool_set:N = \l__problems_mcc_f_bool , Ttext .tl_set:N = \l__problems_mcc_Ttext_str , Ftext .tl_set:N = \l__problems_mcc_Ftext_str } \cs_new_protected:Nn \l__problems_mcc_args:n { \str_clear:N \l__problems_mcc_id_str \tl_clear:N \l__problems_mcc_feedback_tl \bool_set_false:N \l__problems_mcc_t_bool \bool_set_false:N \l__problems_mcc_f_bool \tl_clear:N \l__problems_mcc_Ttext_tl \tl_clear:N \l__problems_mcc_Ftext_tl \str_clear:N \l__problems_mcc_id_str \keys_set:nn { problem / mcc }{ #1 } } \def\mccTrueText{\textbf{(true)~}} \def\mccFalseText{\textbf{(false)~}} \newcommand\mcc[2][]{ \l__problems_mcc_args:n{ #1 } \item[$\Box$] #2 \ifsolutions \\ \bool_if:NT \l__problems_mcc_t_bool { \tl_if_empty:NTF\l__problems_mcc_Ttext_tl\mccTrueText\l__problems_mcc_Ttext_tl } \bool_if:NT \l__problems_mcc_f_bool { \tl_if_empty:NTF\l__problems_mcc_Ttext_tl\mccFalseText\l__problems_mcc_Ftext_tl } \tl_if_empty:NF \l__problems_mcc_feedback_tl { \emph{(\l__problems_mcc_feedback_tl)} } \fi } %solutions \keys_define:nn{ problem / inclproblem }{ id .str_set_x:N = \l__problems_inclprob_id_str, pts .tl_set:N = \l__problems_inclprob_pts_tl, min .tl_set:N = \l__problems_inclprob_min_tl, title .tl_set:N = \l__problems_inclprob_title_tl, refnum .int_set:N = \l__problems_inclprob_refnum_int, type .tl_set:N = \l__problems_inclprob_type_tl, mhrepos .str_set_x:N = \l__problems_inclprob_mhrepos_str } \cs_new_protected:Nn \__problems_inclprob_args:n { \str_clear:N \l__problems_prob_id_str \tl_clear:N \l__problems_inclprob_pts_tl \tl_clear:N \l__problems_inclprob_min_tl \tl_clear:N \l__problems_inclprob_title_tl \tl_clear:N \l__problems_inclprob_type_tl \int_zero_new:N \l__problems_inclprob_refnum_int \str_clear:N \l__problems_inclprob_mhrepos_str \keys_set:nn { problem / inclproblem }{ #1 } \tl_if_empty:NT \l__problems_inclprob_pts_tl { \let\l__problems_inclprob_pts_tl\undefined } \tl_if_empty:NT \l__problems_inclprob_min_tl { \let\l__problems_inclprob_min_tl\undefined } \tl_if_empty:NT \l__problems_inclprob_title_tl { \let\l__problems_inclprob_title_tl\undefined } \tl_if_empty:NT \l__problems_inclprob_type_tl { \let\l__problems_inclprob_type_tl\undefined } \int_compare:nNnT \l__problems_inclprob_refnum_int = 0 { \let\l__problems_inclprob_refnum_int\undefined } } \cs_new_protected:Nn \__problems_inclprob_clear: { \let\l__problems_inclprob_id_str\undefined \let\l__problems_inclprob_pts_tl\undefined \let\l__problems_inclprob_min_tl\undefined \let\l__problems_inclprob_title_tl\undefined \let\l__problems_inclprob_type_tl\undefined \let\l__problems_inclprob_refnum_int\undefined \let\l__problems_inclprob_mhrepos_str\undefined } \__problems_inclprob_clear: \newcommand\includeproblem[2][]{ \__problems_inclprob_args:n{ #1 } \exp_args:No \stex_in_repository:nn\l__problems_inclprob_mhrepos_str{ \stex_html_backend:TF { \str_clear:N \l_tmpa_str \prop_get:NnNF \l_stex_current_repository_prop { narr } \l_tmpa_str { \prop_get:NnNF \l_stex_current_repository_prop { ns } \l_tmpa_str {} } \stex_annotate_invisible:nnn{includeproblem}{ \l_tmpa_str / #2 }{} }{ \begingroup \inputreftrue \tl_if_empty:nTF{ ##1 }{ \input{#2} }{ \input{ \c_stex_mathhub_str / ##1 / source / #2 } } \endgroup } } \__problems_inclprob_clear: } \AddToHook{enddocument}{ \bool_if:NT \c__problems_pts_bool { \message{Total:~\arabic{pts}~points} } \bool_if:NT \c__problems_min_bool { \message{Total:~\arabic{min}~minutes} } } \def\pts#1{ \bool_if:NT \c__problems_pts_bool { \marginpar{#1~\prob@pt@kw} } } \def\min#1{ \bool_if:NT \c__problems_min_bool { \marginpar{#1~\prob@min@kw} } } \newcounter{pts} \def\show@pts{ \tl_if_exist:NTF \l__problems_inclprob_pts_tl { \bool_if:NT \c__problems_pts_bool { \marginpar{\l__problems_inclprob_pts_tl\ \prob@pt@kw\smallskip} \addtocounter{pts}{\l__problems_inclprob_pts_tl} } }{ \tl_if_exist:NT \l__problems_prob_pts_tl { \bool_if:NT \c__problems_pts_bool { \tl_if_empty:NT\l__problems_prob_pts_tl{ \tl_set:Nn \l__problems_prob_pts_tl {0} } \marginpar{\l__problems_prob_pts_tl\ \prob@pt@kw\smallskip} \addtocounter{pts}{\l__problems_prob_pts_tl} } } } } \newcounter{min} \def\show@min{ \tl_if_exist:NTF \l__problems_inclprob_min_tl { \bool_if:NT \c__problems_min_bool { \marginpar{\l__problems_inclprob_pts_tl\ min} \addtocounter{min}{\l__problems_inclprob_min_tl} } }{ \tl_if_exist:NT \l__problems_prob_min_tl { \bool_if:NT \c__problems_min_bool { \tl_if_empty:NT\l__problems_prob_min_tl{ \tl_set:Nn \l__problems_prob_min_tl {0} } \marginpar{\l__problems_prob_min_tl\ min} \addtocounter{min}{\l__problems_prob_min_tl} } } } } \endinput %% %% End of file `problem.sty'.