\RequirePackage { xeCJK }
\bool_lazy_and:nnT { \sys_if_platform_windows_p: }
  { \tl_if_eq_p:NN \CJK@family \c_empty_tl }
  { \setCJKmainfont {SimSun} }
\cs_new:Npn \zitie_stroke_chars:nn #1#2 % operator, chars
  { \special { pdf:code ~ q ~ #1 } #2 \special { pdf:code ~ Q } }
\cs_new:Npn \zitiestrokechars { \zitie_stroke_chars:nn }

\cs_set_eq:NN \__zitie_check_num_range:nnNN \__xeCJK_check_num_range:nnNN
\cs_set_eq:NN \__zitie_int_until_do:nn \xeCJK_int_until_do:nn 
\cs_set_eq:NN \zitierawCJKfamily \CJKfamily
\prg_set_eq_conditional:NNn \zitie_family_if_exist:n \xeCJK_family_if_exist:n { T, F, TF }
\prg_set_eq_conditional:NNn \zitie_glyph_if_exist:N \xeCJK_glyph_if_exist:N { p, T, F, TF }
\cs_new_nopar:Npn \__zitie_font_select:nN #1 
  { 
    \zitie_family_if_exist:nTF { \c_zitie_font_name_prefix_tl #1 } 
      { \zitierawCJKfamily+ { \c_zitie_font_name_prefix_tl #1 } }
      { \zitierawCJKfamily+ {#1} }
  }
\NewDocumentCommand \zitieCJKfamily { t+ t- m }
  {
    \zitie_family_if_exist:nTF { \c_zitie_font_name_prefix_tl #3 }
      { \xeCJK_family:NNx #1 #2 { \c_zitie_font_name_prefix_tl #3 } }
      { \xeCJK_family:NNx #1 #2 {#3} }
    \tex_ignorespaces:D 
  }
\cs_new:Npn \__zitie_new_font_family:nnn #1#2#3 % family name, font name, feature
  { \__xeCJK_pass_args:nnnn { \xeCJK_set_family:nnn { \c_zitie_font_name_prefix_tl #1 } } {#3} {#2} { } }
\cs_new:Npn \__zitie_new_font_family_validate:nnn #1#2#3
  {
    \zitie_font_if_exist:nTF {#2} { \__zitie_new_font_family:nnn {#1} {#2} {#3} }
      { \msg_warning:nnn { zitie } { font-exist } {#2} }
  }
\cs_new:Npn \zitie_token_class_dispatch:Nnnnn #1 
  {
    \if_case:w \xeCJK_token_value_class:N #1 \exp_stop_f: 
      \exp_after:wN \use_none:nnn  % other 
    \or: \exp_after:wN \use_i:nnnn % CJK
    \or: \exp_after:wN \use_ii:nnnn % FullLeft
    \or: \exp_after:wN \use_iii:nnnn % FullRight
    \else: \exp_after:wN \use_none:nnn % other 
    \fi:
  }
\prg_new_conditional:Npnn \zitie_token_if_punctuation:N #1 { p, T, F, TF }
  {
    \int_compare:nNnTF { \xeCJK_token_value_class:N #1 } > 1
      { 
        \int_compare:nNnTF { \xeCJK_token_value_class:N #1 } < 6
          { \prg_return_true: } { \prg_return_false: }
      }
      { \prg_return_false: }
  }