% -------------------------------------------------------------------------- % the EXSHEETS package % % Yet another package for the creation of exercise sheets % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://bitbucket.org/cgnieder/exsheets/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2011-2012 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. % -------------------------------------------------------------------------- % The exsheets package consists of the files % - exsheets.sty, exsheets_headings.def, exsheets_headings.cfg, % exsheets_tasks.def, exsheets_tasks.cfg, exsheets_configurations.cfg, % - exsheets_en.tex, exsheets_en.pdf, % - README % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- % TASKS: LIST-LIKE ENVIRONMENT \ProvidesFile{exsheets_tasks.def} [\exsheets@date\space v\exsheets@version\space ExSheets tasks object] \RequirePackage { epic } % variables: \seq_new:N \l__exsheets_tasks_seq \int_new:N \l__exsheets_tasks_depth_int \int_new:N \l__exsheets_tasks_int \int_new:N \l__exsheets_tasks_total_items_int \int_new:N \l__exsheets_tasks_columns_int \int_new:N \l__exsheets_tasks_rows_int \bool_new:N \l__exsheets_tasks_enumerate_bool \tl_new:N \l__exsheets_tasks_instance_tl \tl_new:N \l__exsheets_tasks_label_tl \tl_new:N \l__exsheets_tasks_label_pattern_tl \tl_new:N \l__exsheets_tasks_custom_label_format_tl \dim_new:N \l__exsheets_tasks_item_indent_dim \dim_new:N \l__exsheets_tasks_after_item_skip_dim \dim_new:N \l__exsheets_tasks_item_width_dim \dim_new:N \l__exsheets_tasks_label_width_dim \dim_new:N \l__exsheets_tasks_default_label_width_dim \skip_new:N \l__exsheets_tasks_before_list_skip \skip_set:Nn \l__exsheets_tasks_before_list_skip { .33\baselineskip } \skip_new:N \l__exsheets_tasks_after_list_skip \skip_new:N \l__exsheets_tasks_after_list_default_skip \skip_set:Nn \l__exsheets_tasks_after_list_default_skip { .33\baselineskip } \NewCounterPattern* [ exsheets ] { task } { tsk } \ReadCounterFrom [ exsheets ] { task } \l__exsheets_tasks_int % scratch coffins: \cs_if_exist:NF \l__exsheets_tmpa_coffin { \coffin_new:N \l__exsheets_tmpa_coffin } \cs_if_exist:NF \l__exsheets_tmpb_coffin { \coffin_new:N \l__exsheets_tmpb_coffin } \cs_if_exist:NF \l__exsheets_tmpc_coffin { \coffin_new:N \l__exsheets_tmpc_coffin } % collect the tasks: % #1: instance % #2: number of columns % #3: environment body \cs_new:Npn \__exsheets_tasks:nnw #1#2#3 \end { \par \addvspace { \l__exsheets_tasks_before_list_skip } \seq_set_split:Nnn \l__exsheets_tasks_seq { ; } { #3 } % remove the last (empty) item: \seq_pop_right:NN \l__exsheets_tasks_seq \l__exsheets_tmpa_tl \tl_if_blank:VF \l__exsheets_tmpa_tl { % TODO ERROR } \int_set:Nn \l__exsheets_tasks_total_items_int { \seq_length:N \l__exsheets_tasks_seq } \UseInstance { exsheets-tasks } { #1 } { \l__exsheets_tasks_total_items_int } { #2 } { \l__exsheets_tasks_custom_label_format_tl } % just to be sure: \seq_clear:N \l__exsheets_tasks_seq \par \skip_vertical:N \l__exsheets_tasks_after_list_skip % we gobbled this from the input stream, let's put it back: \end } \cs_generate_variant:Nn \__exsheets_tasks:nnw { V } \cs_new:Npn \__exsheets_task:nnw #1#2[#3,#4][#5,#6](#7,#8) { \dim_set:Nn \l__exsheets_tasks_item_width_dim { \linewidth / \l__exsheets_tasks_columns_int - \l__exsheets_tasks_depth_int\l__exsheets_tasks_item_indent_dim } \int_incr:N \l__exsheets_tmpa_int \__exsheets_tasks_set_rows_num:NN \l__exsheets_tasks_total_items_int \l__exsheets_tasks_columns_int \int_compare:nT { \l__exsheets_tmpa_int > \l__exsheets_tasks_columns_int } { \int_set:Nn \l__exsheets_tmpa_int { 1 } } % the item: \hcoffin_set:Nn \l__exsheets_tmpa_coffin { \vcoffin_set:Nnn \l__exsheets_tmpc_coffin { \l__exsheets_tasks_item_width_dim } { \__exsheets_tasks_setup: #2 } \coffin_typeset:Nnnnn \l__exsheets_tmpc_coffin { l } { b } { 0pt } { 0pt } } % the label: \hcoffin_set:Nn \l__exsheets_tmpb_coffin { \strut #1 } \coffin_attach:NnnNnnnn \l__exsheets_tmpa_coffin { l } { t } \l__exsheets_tmpb_coffin { l } { t } { -\l__exsheets_tasks_label_width_dim } { 0pt } % typeset label & item: % need this when a new row starts: \int_compare:nT { \l__exsheets_tmpa_int = 1 } { \par\noindent } \skip_horizontal:N \l__exsheets_tasks_item_indent_dim \coffin_typeset:Nnnnn \l__exsheets_tmpa_coffin { l } { T } { 0pt } { 0pt } % need this before a new row starts: \int_compare:nT { \l__exsheets_tmpa_int = \l__exsheets_tasks_columns_int } { \skip_vertical:N \l__exsheets_tasks_after_item_skip_dim } \coffin_clear:N \l__exsheets_tmpa_coffin \coffin_clear:N \l__exsheets_tmpb_coffin \coffin_clear:N \l__exsheets_tmpc_coffin } \cs_generate_variant:Nn \__exsheets_task:nnw { VV } \cs_new:Npn \__exsheets_tasks_setup: { \dim_set:Nn \parskip { 0pt } \noindent \dim_set_eq:NN \parskip \parsep \dim_set_eq:NN \parindent \listparindent \strut } \cs_new:Npn \__exsheets_tasks_set_rows_num:NN #1#2 { \int_set:Nn \l__exsheets_tasks_rows_int { \int_div_truncate:nn { #1 } { #2 } } \int_compare:nNnT { \int_mod:nn { #1 } { #2 } } > { 0 } { \int_incr:N \l__exsheets_tasks_rows_int } } % the `exsheets-tasks' object: % #1: number of items % #2: number of columns % #3: label-format \DeclareObjectType { exsheets-tasks } { 3 } % the `default' template interface: \DeclareTemplateInterface { exsheets-tasks } { default } { 3 } { enumerate : boolean = true , label : tokenlist , indent : length = 2.5em , label-format : tokenlist = tsk[a]) , label-width : length = 3ex , after-item-skip : length = 2ex } % the `default' template code: \DeclareTemplateCode { exsheets-tasks } { default } { 3 } { enumerate = \l__exsheets_tasks_enumerate_bool , label = \l__exsheets_tasks_label_tl , indent = \l__exsheets_tasks_item_indent_dim , label-format = \l__exsheets_tasks_label_pattern_tl , label-width = \l__exsheets_tasks_default_label_width_dim , after-item-skip = \l__exsheets_tasks_after_item_skip_dim } { \AssignTemplateKeys \skip_set:Nn \l__exsheets_tasks_after_list_skip { \l__exsheets_tasks_after_list_default_skip - \l__exsheets_tasks_after_item_skip_dim } \dim_compare:nT { \l__exsheets_tasks_label_width_dim = 0pt } { \dim_set_eq:NN \l__exsheets_tasks_label_width_dim \l__exsheets_tasks_default_label_width_dim } % need this for enumerate list: \int_zero:N \l__exsheets_tasks_int \int_set:Nn \l__exsheets_tasks_columns_int { #2 } % set all the items in their own coffins and join with the ground: \int_zero:N \l__exsheets_tmpa_int \tl_if_blank:VF \l__exsheets_tasks_custom_label_format_tl { \tl_set_eq:NN \l__exsheets_tasks_label_pattern_tl \l__exsheets_tasks_custom_label_format_tl } \seq_map_inline:Nn \l__exsheets_tasks_seq { \__exsheets_read_item:w ##1\task{}{}\q_stop \bool_if:NTF \l__exsheets_tasks_enumerate_bool { \int_incr:N \l__exsheets_tasks_int \tl_if_blank:VT \l__exsheets_tasks_label_tl { \tl_set:Nn \l__exsheets_tasks_label_tl { \ReadCounterPatternFrom [ exsheets ] \l__exsheets_tasks_label_pattern_tl } } } { \tl_if_blank:VT \l__exsheets_tasks_label_tl { \tl_set_eq:NN \l__exsheets_tasks_label_tl \labelitemi } } \tl_if_blank:VTF \l__exsheets_tasks_tmp_label_tl { \__exsheets_task:VVw \l__exsheets_tasks_label_tl \l__exsheets_tasks_item_tl [ l , b ] [ l , t ] ( 0pt , 0pt ) } { \__exsheets_task:VVw \l__exsheets_tasks_tmp_label_tl \l__exsheets_tasks_item_tl [ l , b ] [ l , t ] ( 0pt , 0pt ) \tl_clear:N \l__exsheets_tasks_tmp_label_tl } } } \tl_new:N \task \tl_new:N \l__exsheets_tasks_item_tl \tl_new:N \l__exsheets_tasks_tmp_label_tl \cs_new:Npn \__exsheets_read_item:w #1 \task #2#3 \q_stop { \tl_set:Nn \l__exsheets_tmpa_tl { #1 } \tl_set:Nn \l__exsheets_tmpb_tl { #2 } \tl_set:Nn \l__exsheets_tmpc_tl { #3 } \tl_if_blank:VTF \l__exsheets_tmpa_tl { \tl_set_eq:NN \l__exsheets_tasks_item_tl \l__exsheets_tmpc_tl \tl_set_eq:NN \l__exsheets_tasks_tmp_label_tl \l__exsheets_tmpb_tl } { \tl_set_eq:NN \l__exsheets_tasks_item_tl \l__exsheets_tmpa_tl } } % choice box: \bool_new:N \l__exsheets_choice_checked_bool \dim_new:N \l__exsheets_choice_width_dim \dim_set:Nn \l__exsheets_choice_width_dim { 1.25ex } \dim_new:N \l__exsheets_choice_linewidth_dim \dim_set:Nn \l__exsheets_choice_linewidth_dim { .3pt } \dim_new:N \l__exsheets_choice_checkwidth_dim \dim_set:Nn \l__exsheets_choice_checkwidth_dim { .5pt } \dim_new:N \l__exsheets_choice_raise_dim \dim_set:Nn \l__exsheets_choice_raise_dim { .1ex } \cs_new:Npn \exsheets_choice: { \leavevmode \bool_set_false:N \l__exsheets_choice_checked_bool \box_move_up:nn { \l__exsheets_choice_raise_dim } { \hbox:n { \__exsheets_choice: } } } \cs_new:Npn \exsheets_choice_checked: { \leavevmode \bool_set_true:N \l__exsheets_choice_checked_bool \box_move_up:nn { \l__exsheets_choice_raise_dim } { \hbox:n { \__exsheets_choice: } } } \cs_new:Npn \__exsheets_choice: {% \dim_set:Nn \unitlength { .1\l__exsheets_choice_width_dim } \begin{picture}(10,0) \linethickness \l__exsheets_choice_linewidth_dim \drawline(0,0)(0,10)(10,10)(10,0)(0,0) \linethickness \l__exsheets_choice_checkwidth_dim \bool_if:NT \l__exsheets_choice_checked_bool { \drawline(2,2)(8,8) \drawline(2,8)(8,2) } \end{picture}% } \cs_if_exist:NF \choicebox { \cs_new:Npn \choicebox { \exsheets_choice: } } \cs_if_exist:NF \ckeckedchoicebox { \cs_new:Npn \ckeckedchoicebox { \exsheets_choice_checked: } } % base instance: % ALPHABETIZE: a) b) c) \DeclareInstance { exsheets-tasks } { alphabetize } { default } { } \keys_define:nn { exsheets / tasks } { style .tl_set:N = \l__exsheets_tasks_instance_tl , label .tl_set:N = \l__exsheets_tasks_custom_label_format_tl , label-width .dim_set:N = \l__exsheets_tasks_label_width_dim , before-skip .skip_set:N = \l__exsheets_tasks_before_list_skip , after-skip .skip_set:N = \l__exsheets_tasks_after_list_skip } % the user environment: \NewDocumentEnvironment { tasks } { oG{1} } { \IfNoValueTF { #1 } { \keys_set:nn { exsheets / tasks } { style = alphabetize } } { \keys_set:nn { exsheets / tasks } { #1 } \tl_if_blank:VT \l__exsheets_tasks_instance_tl { \keys_set:nn { exsheets / tasks } { style = alphabetize } } } \int_incr:N \l__exsheets_tasks_depth_int \__exsheets_tasks:Vnw \l__exsheets_tasks_instance_tl { #2 } } { } \tex_endinput:D