%%
%% 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'.
