% ----------------------------------------------------------------------------
% the XSIM package - blanks module
% 
%   eXercise Sheets IMproved
% 
% ----------------------------------------------------------------------------
% Clemens Niederberger
% Web:    https://github.com/cgnieder/xsim
% E-Mail: contact@mychemistry.eu
% ----------------------------------------------------------------------------
% Copyright 2017--2018 Clemens Niederberger
% 
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
% 
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is Clemens Niederberger.
% ----------------------------------------------------------------------------
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% ----------------------------------------------------------------------------
\XSIMmodule{blanks}{add blanks, cloze}

\bool_new:N \l__xsim_blank_width_bool
\bool_new:N \l__xsim_blank_linespread_bool
\bool_new:N \l__xsim_fill_blank_bool
\tl_new:N   \l__xsim_blank_linespread_tl
\tl_new:N   \l__xsim_blank_scale_tl
\dim_new:N  \l__xsim_blank_dim
\dim_new:N  \l__xsim_blank_line_increment_dim
\dim_new:N  \l__xsim_blank_line_minimum_length_dim
\box_new:N  \l__xsim_blank_box

\cs_new_protected:Npn \xsim_write_cloze_blank:n #1 {#1}
\cs_new_protected:Npn \xsim_write_cloze_filled:n #1 {#1}

\keys_define:nn {xsim/blank}
  {
    blank-style         .code:n     =
      \cs_set_protected:Npn \xsim_write_cloze_blank:n ##1 {#1} ,
    blank-style         .initial:n  = \underline {#1} ,
    filled-style        .code:n     =
      \cs_set_protected:Npn \xsim_write_cloze_filled:n ##1 {#1} ,
    filled-style        .initial:n  = \underline {#1} ,
    style               .meta:n     =
      {
        blank-style = #1 ,
        filled-style = #1
      } ,
    fill                .bool_set:N = \l__xsim_fill_blank_bool ,
    fill                .initial:n  = false ,
    scale               .tl_set:N   = \l__xsim_blank_scale_tl ,
    scale               .initial:n  = 1 ,
    width               .code:n     =
      {
        \bool_set_true:N \l__xsim_blank_width_bool
        \dim_set:Nn \l__xsim_blank_dim {#1}
      } ,
    linespread          .code:n     =
      \bool_set_true:N \l__xsim_blank_linespread_bool
      \tl_set:Nn \l__xsim_blank_linespread_tl {#1} ,
    linespread          .initial:n  = 1 ,
    line-increment      .dim_set:N  = \l__xsim_blank_line_increment_dim ,
    line-increment      .initial:n  = 1pt ,
    line-minimum-length .dim_set:N  = \l__xsim_blank_line_minimum_length_dim ,
    line-minimum-length .initial:n  = 2em
  }

\cs_new_protected:Npn \xsim_blank:n #1
  {
    \box_clear:N \l__xsim_blank_box
    \mode_if_math:TF
      { \hbox_set:Nn \l__xsim_blank_box { $ \m@th \mathpalette{}{#1} $ } }
      { \hbox_set:Nn \l__xsim_blank_box {#1} }
    \bool_if:nTF
      { \xsim_if_inside_solution_p: || \l__xsim_fill_blank_bool }
      { \xsim_write_cloze_filled:n {#1} }
      {
        \bool_if:NTF \l__xsim_blank_width_bool
          { \__xsim_blank_skip:V \l__xsim_blank_dim }
          { \__xsim_blank_skip:n { \box_wd:N \l__xsim_blank_box } }
      }
  }
  
\cs_new_protected:Npn \__xsim_blank_skip:n #1
  {
    \bool_if:NTF \l__xsim_blank_width_bool
      { \dim_set:Nn \l__xsim_tmpa_dim {#1} }
      {
        \fp_set:Nn \l__xsim_tmpa_fp
          { \dim_to_fp:n {#1} * \l__xsim_blank_scale_tl }
        \dim_set:Nn \l__xsim_tmpa_dim { \fp_to_dim:N \l__xsim_tmpa_fp }
      }
    \dim_compare:nTF
      { \l__xsim_tmpa_dim > \l__xsim_blank_line_minimum_length_dim }
      {
        \mode_if_math:TF
          { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
          {
            \dim_do_while:nn { \l__xsim_tmpa_dim > \c_zero_dim }
              {
                % I wonder what the correct l3 way would be -- if there is
                % one, yet:
                % \tex_hfil:D
                \tex_penalty:D \hyphenpenalty
                % \tex_hfilneg:D
                \dim_compare:nTF
                  { \l__xsim_tmpa_dim < \l__xsim_blank_line_increment_dim }
                  { \xsim_write_cloze_blank:n { \skip_horizontal:N \l__xsim_tmpa_dim } }
                  {
                    \xsim_write_cloze_blank:n
                      { \skip_horizontal:N \l__xsim_blank_line_increment_dim }
                  }
                \dim_sub:Nn \l__xsim_tmpa_dim { \l__xsim_blank_line_increment_dim }
              }
          }
      }
      {
        \xsim_write_cloze_blank:n
          { \skip_horizontal:N \l__xsim_blank_line_minimum_length_dim }
      }
  }
\cs_generate_variant:Nn \__xsim_blank_skip:n { V }

% ----------------------------------------------------------------------------
\file_input_stop:

the following code from Heiko Oberdieck in d.c.t.t served as inspiration
and basis for the \blank command:
https://groups.google.com/d/msg/de.comp.text.tex/fZLwraH04jE/o1RSdFXjGuIJ

\makeatletter
\newcommand*{\luecke}{%
  \begingroup
    \setlength{\dimen@}{6cm}%
    \ifdim\dimen@>2em %
      \underline{\hspace{1em}}%
      \advance\dimen@ by -2em\relax
      \@whiledim\dimen@>0pt\do{%
        \penalty\hyphenpenalty
        \ifdim\dimen@<1pt %
          \underline{\hspace{\dimen@}}%
        \else
          \underline{\hspace{1pt}}%
        \fi
        \advance\dimen@ by -1pt %
      }%
      \underline{\hspace{1em}}%
    \else
      \underline{\hspace{\dimen@}}%
    \fi
  \endgroup
  \xspace
}
\makeatother
