From 71074c48404ac3f2ded230c702fd738fc613b1f1 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 10 Aug 2022 03:00:43 +0000
Subject: CTAN sync 202208100300

---
 .../xetex/latex/exam-zh/tex/exam-zh-question.sty   | 278 +++++++++++++++++----
 1 file changed, 226 insertions(+), 52 deletions(-)

(limited to 'macros/xetex/latex/exam-zh/tex/exam-zh-question.sty')

diff --git a/macros/xetex/latex/exam-zh/tex/exam-zh-question.sty b/macros/xetex/latex/exam-zh/tex/exam-zh-question.sty
index 825a6ad991..6651de7383 100644
--- a/macros/xetex/latex/exam-zh/tex/exam-zh-question.sty
+++ b/macros/xetex/latex/exam-zh/tex/exam-zh-question.sty
@@ -9,22 +9,34 @@
 \RequirePackage{expl3}
 \RequirePackage{xparse}
 
-\ProvidesExplPackage {exam-zh-question} {2022-07-28} {v0.1.13}
+\ProvidesExplPackage {exam-zh-question} {2022-08-09} {v0.1.15}
   {exam-zh question module}
 
+
 \RequirePackage { amsthm }
 \@ifpackageloaded { tcolorbox }
   { \tcbuselibrary { breakable } }
   { \RequirePackage [ most ] { tcolorbox } }
-\RequirePackage { zref-savepos }
-\RequirePackage { ulem }
+% \RequirePackage { zref-savepos }
+\RequirePackage { xeCJKfntef }
+
+% https://github.com/CTeX-org/forum/issues/264#issuecomment-1200087776
+\disable@package@load { etex }
+  {
+    \cs_set_eq:NN \globcount \newcount
+    \cs_set_eq:NN \globdimen \newdimen
+  }
+\RequirePackage { linegoal }
+
 
 \ExplSyntaxOff
+
 \usetikzlibrary{shapes.misc}
 \ExplSyntaxOn
 
 
 
+
 \NewDocumentCommand \questionsetup { m }
   { \keys_set:nn { exam-zh / question } { #1 } }
 \NewDocumentCommand \fillinsetup { m }
@@ -267,9 +279,10 @@
 \prg_generate_conditional_variant:Nnn \regex_extract_once:nnN { nxN } { F } 
 \cs_new:Npn \__examzh_question_begin_fillin_type_set:
   {
-    \regex_count:nVN { \[ } %]
+    \regex_count:nVN { \[ } % \]
       \l__examzh_question_combine_fillin_args_tl
       \l__examzh_question_begin_fillin_args_bracket_num_int
+    \use_none:n { \] }  % 消去 \[ 的高亮影响
     % \int_use:N \l__examzh_question_begin_fillin_args_bracket_num_int
     \int_compare:nNnT { \l__examzh_question_begin_fillin_args_bracket_num_int } = {2}
       {
@@ -687,6 +700,12 @@
 % fillin 的下划线样式控制
 \str_new:N \l__examzh_fillin_type_str
 
+% fillin type = paren 的括号类型
+\bool_new:N \l__examzh_fillin_paren_banjiao_bool
+
+% fillin 的 width 设置断行时是自动铺满行还是严格按照长度来
+\bool_new:N \l__examzh_fillin_width_fill_bool
+
 % 不显示答案时显示的类型
 \str_new:N \l__examzh_fillin_no_answer_type_str
 
@@ -700,25 +719,37 @@
         \str_set:Nn \l__examzh_fillin_type_str {#1}
       },
     show-answer .bool_set:N = \l__examzh_question_show_fillin_answer_bool,
-    width .skip_set:N = \l__examzh_fillin_F_width_skip,
+    width .dim_set:N = \l__examzh_fillin_F_width_dim,
+    width-type .choice:,
+    width-type / fill .code:n =
+      { \bool_set_true:N \l__examzh_fillin_width_fill_bool },
+    width-type / normal .code:n =
+      { \bool_set_false:N \l__examzh_fillin_width_fill_bool },
     color .tl_set:N = \l__examzh_fillin_color_tl,
     text-color .tl_set:N = \l__examzh_fillin_text_color_tl,
     no-answer-type .choices:nn =
       { blacktriangle, counter, none }
       { \str_set:Nx \l__examzh_fillin_no_answer_type_str { \l_keys_choice_tl } },
     no-answer-counter-index .int_gset:N = \g__examzh_fillin_no_answer_counter_int,
-    no-answer-counter-label .tl_set:N = \l__examzh_fillin_label_tl
+    no-answer-counter-label .tl_set:N = \l__examzh_fillin_label_tl,
+    paren-type .choice:,
+    paren-type / banjiao .code:n = 
+      { \bool_set_true:N \l__examzh_fillin_paren_banjiao_bool },
+    paren-type / quanjiao .code:n = 
+      { \bool_set_false:N \l__examzh_fillin_paren_banjiao_bool },
   }
 \keys_set:nn { exam-zh / fillin }
   {
     type                     = line,
     show-answer              = false,
-    width                    = 3em plus 1em minus 1em,
+    width                    = 3em,
     color                    = black,
     text-color               = black,
     no-answer-type           = blacktriangle,
     no-answer-counter-index  = 1,
-    no-answer-counter-label  = \arabic*
+    no-answer-counter-label  = \arabic*,
+    paren-type               = banjiao,
+    width-type               = fill,
   }
 
 \keys_define:nn { exam-zh }
@@ -756,8 +787,7 @@
             }
         }
         {
-          \keys_set:nn { exam-zh / fillin }
-            {#2}
+          \keys_set:nn { exam-zh / fillin } {#2}
           \bool_if:NTF \l__examzh_question_show_fillin_answer_bool
             {
               % 显示答案
@@ -776,7 +806,7 @@
               \__examzh_fillin_no_answer_typeset:
             }
         }
-      \group_end:
+    \group_end:
     \space \ignorespaces
   }
 \msg_new:nnn { exam-zh / fillin } { no-such-noanswertype }
@@ -924,22 +954,45 @@
   }
 \cs_new:Npn \__examzh_fillin_uline_F:
   {
-    \uline { \hspace* { \l__examzh_fillin_F_width_skip } } 
-  }
-\cs_new:Nn \__examzh_fillin_uline:
-  {
-    \bgroup
-      \color{ \l__examzh_fillin_text_color_tl } 
-      \markoverwith{\textcolor{black}{\rule[-0.7ex]{2pt}{0.4pt}}}
-      \ULon
+    % \uline { \hspace* { \l__examzh_fillin_F_width_dim } } 
+    \__examzh_fillin_breakable_hspace:NN \CJKunderline \allowbreak
+  }
+% \cs_new:Nn \__examzh_fillin_uline:
+  % {
+    % \bgroup
+    %   \color{ \l__examzh_fillin_text_color_tl } 
+    %   \markoverwith{\textcolor{black}{\rule[-0.7ex]{2pt}{0.4pt}}}
+    %   \ULon
+% xeCJKfntef.sty
+% xeCJK: 修复下划线中数学公式的错误处理
+% https://github.com/CTeX-org/ctex-kit/commit/ad44c6674bb377653544349f23b7c629bc9e4677
+\RenewDocumentCommand \CJKunderline { s t- s o }
+  {
+    \xeCJK_ulem_group_begin:
+      \xeCJK_fntef_boot:nnNNNn { underline } { uline } #1#2#3 {#4}
+      \xeCJK_fntef_initial:nnn
+        { \l__xeCJK_uline_depth_tl }
+        { \l__xeCJK_uline_sep_tl }
+        {
+          \l__xeCJK_uline_format_tl
+          \tex_vrule:D
+            height \dim_eval:n { \l__xeCJK_uline_thickness_tl }
+            depth \c_zero_dim
+            width .2em
+        }
+      % 给 CJKunderline 加了颜色控制
+      \color { \l__examzh_fillin_text_color_tl }
+      \xeCJK_ulem_on:n
   }
+  % }
 \cs_new:Npn \__examzh_fillin_uline_breakline_T:
   {
-    % \CJKunderline*
+    \CJKunderline*
     % \uline
-    \__examzh_fillin_uline:
+    % \__examzh_fillin_uline:
       {
         \hspace* { 0.5em plus .5em minus .5em }
+        % \color{ \l__examzh_fillin_text_color_tl } 
         \l_tmpa_tl
         % 答案很长时，不能完全显示，答案很长时，不能完全显示
         \hspace* { 0.5em plus .5em minus .5em }
@@ -947,27 +1000,65 @@
   }
 \cs_new:Npn \__examzh_fillin_paren_T:
   {
-    (
-      \hspace* { 0.5em plus .5em minus .5em }
-      \group_begin:
-        \box_use_drop:N \l_tmpa_box
-      \group_end:
-      \hspace* { 0.5em plus .5em minus .5em }
-    )
+    \bool_if:NTF \l__examzh_fillin_paren_banjiao_bool
+      {
+        (
+          \hspace* { 0.5em plus .5em minus .5em }
+          \group_begin:
+            \box_use_drop:N \l_tmpa_box
+          \group_end:
+          \hspace* { 0.5em plus .5em minus .5em }
+        )
+      }
+      {
+        （
+          \hspace* { 0.5em plus .5em minus .5em }
+          \group_begin:
+            \box_use_drop:N \l_tmpa_box
+          \group_end:
+          \hspace* { 0.5em plus .5em minus .5em }
+        ）
+      }
   }
 \cs_new:Npn \__examzh_fillin_paren_breakline_T:
   {
-    (
-      \hspace* { 0.5em plus .5em minus .5em }
-      \group_begin:
-        \l_tmpa_tl
-      \group_end:
-      \hspace* { 0.5em plus .5em minus .5em }
-    )
+    \bool_if:NTF \l__examzh_fillin_paren_banjiao_bool
+      {
+        (
+          \hspace* { 0.5em plus .5em minus .5em }
+          \group_begin:
+            \l_tmpa_tl
+          \group_end:
+          \hspace* { 0.5em plus .5em minus .5em }
+        )
+      }
+      {
+        （
+          \hspace* { 0.5em plus .5em minus .5em }
+          \group_begin:
+            \l_tmpa_tl
+          \group_end:
+          \hspace* { 0.5em plus .5em minus .5em }
+        ）
+      }
   }
+\box_new:N \c__examzh_banjiao_right_brace_box
+\box_new:N \c__examzh_quanjiao_right_brace_box
+\hbox_set:Nn \c__examzh_banjiao_right_brace_box { ) }
+\hbox_set:Nn \c__examzh_quanjiao_right_brace_box { ） }
+\dim_const:Nn \c__examzh_banjiao_right_brace_width_dim  % (
+  { \box_wd:N \c__examzh_banjiao_right_brace_box }
+\dim_const:Nn \c__examzh_quanjiao_right_brace_width_dim  % (
+  { \box_wd:N \c__examzh_quanjiao_right_brace_box }
 \cs_new:Npn \__examzh_fillin_paren_F:
   {
-    ( \hspace* { \l__examzh_fillin_F_width_skip} )
+    \bool_if:NTF \l__examzh_fillin_paren_banjiao_bool
+      {
+        ( \__examzh_fillin_breakable_hspace:NN \use:n \nobreak \kern-\c__examzh_banjiao_right_brace_width_dim ) \allowbreak
+      }
+      {
+        （ \__examzh_fillin_breakable_hspace:NN \use:n \nobreak \kern-\c__examzh_quanjiao_right_brace_width_dim ）\allowbreak
+      }
   }
 \cs_new:Npn \__examzh_fillin_blank_T:
   {
@@ -987,7 +1078,8 @@
   }
 \cs_new:Npn \__examzh_fillin_blank_F:
   {
-    \hspace* { \l__examzh_fillin_F_width_skip }
+    % \hspace* { \l__examzh_fillin_F_width_dim }
+    \__examzh_fillin_breakable_hspace:NN \use:n \allowbreak
   }
 \tikzset
   {
@@ -1037,6 +1129,77 @@
     \hspace* { 0.5em plus .5em minus .5em }
   }
 
+% 通过循环来达到自动断行的空白下划线
+\cs_generate_variant:Nn \dim_sub:Nn { NV }
+\cs_generate_variant:Nn \dim_add:Nn { NV }
+\cs_generate_variant:Nn \dim_set:Nn { NV, Nx }
+% 用来检测是否处于 list 环境中
+\bool_new:N \l__if_list_bool
+\int_new:N \l__list_depth_int
+\cs_generate_variant:Nn \dim_set:Nn { Nx }
+\AddToHook { cmd / list / after }
+  {
+    \bool_set_true:N \l__if_list_bool
+    \int_incr:N \l__list_depth_int
+    \dim_if_exist:cF { l__list_leftmargin_ \int_to_roman:n { \l__list_depth_int } _dim }
+      {
+        \dim_new:c { l__list_leftmargin_ \int_to_roman:n { \l__list_depth_int } _dim }
+      }
+    % 用来储存相应层级的 \leftmargin 值
+    \dim_set_eq:cN { l__list_leftmargin_ \int_to_roman:n { \l__list_depth_int } _dim } \leftmargin
+  }
+\AddToHook { cmd / endlist  / before } 
+  { \int_zero:N \l__list_depth_int }
+
+\cs_new:Npn \__examzh_fillin_breakable_hspace:NN #1#2
+  % #1: CJKunderline / use:n
+  % #2: \allowbreak
+  {
+    % 比较 \l__examzh_fillin_F_width_dim 和 linegoal
+    \dim_compare:nNnTF { \l__examzh_fillin_F_width_dim } > { \linegoal }
+      {
+        % 超过 linegoal 就排一段 linegoal，然后 \l__examzh_fillin_F_width_dim 减去 linegoal 长度
+        \dim_set:NV \l_tmpa_dim \linegoal
+        % 是否处于 list 环境中
+        \bool_if:NTF \l__if_list_bool
+          {
+            % 加上 1 到 当前层级的 leftmargin 才能让 list 中的 linegoal 正常
+            \int_step_inline:nn { \l__list_depth_int }
+              {
+                \dim_add:Nn \l_tmpa_dim { \dim_use:c { l__list_leftmargin_ \int_to_roman:n { ##1 } _dim } }
+              }
+            #1 { \hspace { \l_tmpa_dim } }
+          }
+          {
+            % 正文中
+            #1 { \hspace { \linegoal } }
+          }
+        \dim_sub:NV \l__examzh_fillin_F_width_dim \l_tmpa_dim
+        \dim_while_do:nNnn { \l__examzh_fillin_F_width_dim } > { \linewidth }
+          {
+            % 循环：\l__examzh_fillin_F_width_dim 和 \linewidth 比较，大的话就排一个，然后减掉 linewidth
+            \\ #1 { \hspace* { \linewidth } }
+            \dim_sub:Nn \l__examzh_fillin_F_width_dim { \linewidth }
+          }
+        % \\ #1 { \hspace* { \linewidth } }
+        \dim_compare:nNnT { \l__examzh_fillin_F_width_dim } < { \linewidth }
+          { 
+            % 最后一行是否 fill
+            \bool_if:NTF \l__examzh_fillin_width_fill_bool
+              {
+                \\ #1 { \hspace* { \linewidth } } 
+              }
+              {
+                \\ #1 { \hspace* { \l__examzh_fillin_F_width_dim } } 
+              }
+          }
+      }
+      {
+        #1 { \hspace* { \l__examzh_fillin_F_width_dim } }
+      }
+    #2
+  }
+
 
 \dim_new:N \l__examzh_blacktriangle_length_dim
 \dim_set:Nn \l__examzh_blacktriangle_length_dim { .7em }
@@ -1149,9 +1312,11 @@
     % \ignorespaces
     % 是否要新起一段开始
     \bool_if:NT \l__examzh_solution_par_break_bool { \par }
-    \group_begin:
+    % \group_begin:
+    \begingroup
       \color { \l__examzh_solution_text_color_tl } #1
-    \group_end:
+    \endgroup
+    % \group_end:
     \bool_if:NT \l__examzh_solution_show_qed_bool
       { \popQED }
     % \endtrivlist 
@@ -1164,6 +1329,7 @@
 \NewDocumentCommand { \score } { O{} m }
   {
     \group_begin:
+      \keys_set:nn { exam / question } {#1}
       \mode_if_math:TF
         { 
           \__examzh_score_math_version:n { #2 }
@@ -1179,20 +1345,24 @@
       {
         \__examzh_math_cdotfill:n 
           { 
-            \l__examzh_score_format_tl
-            \l__examzh_score_pre_content_tl
-            #1
-            \l__examzh_score_post_content_tl 
+            \group_begin:
+              \l__examzh_score_format_tl
+              \l__examzh_score_pre_content_tl
+              #1
+              \l__examzh_score_post_content_tl 
+            \group_end:
           }
       }
       {
         \__examzh_math_nodotfill:n
           {
             { 
-              \l__examzh_score_format_tl
-              \l__examzh_score_pre_content_tl
-              #1
-              \l__examzh_score_post_content_tl 
+              \group_begin:
+                \l__examzh_score_format_tl
+                \l__examzh_score_pre_content_tl
+                #1
+                \l__examzh_score_post_content_tl 
+              \group_end:
             }
           }
       }
@@ -1201,14 +1371,18 @@
   {
     \bool_if:NTF \l__examzh_score_show_leader_bool
       {
-        \__examzh_cdotfill:
-        \l__examzh_score_format_tl
-        \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl 
+        \group_begin:
+          \__examzh_cdotfill:
+          \l__examzh_score_format_tl
+          \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl 
+        \group_end:
       }
       {
         \hfill
-        \l__examzh_score_format_tl
-        \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl
+        \group_begin:
+          \l__examzh_score_format_tl
+          \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl
+        \group_end:
       }
     \par \noindent \ignorespaces
   }
-- 
cgit v1.2.3

