%%
%% This is file `ctexpatch.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% ctex-auxpkg.dtx  (with options: `ctexpatch')
%% -----------------------------------------------------------------------
%%   Copyright (C) 2003--2026                                            *
%%   CTEX.ORG and any individual authors listed elsewhere in this file.  *
%% -----------------------------------------------------------------------
%%   This work may be distributed and/or modified under the conditions   *
%%   of the LaTeX Project Public License (LPPL), either version 1.3c 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.3c or later is part of all distributions of LaTeX     *
%%   version 2008 or later.                                              *
%%                                                                       *
%%   This work has the LPPL maintenance status `maintained'.             *
%% -----------------------------------------------------------------------
\NeedsTeXFormat{LaTeX2e}[2026/06/01]
\RequirePackage{expl3}
\GetIdInfo $Id: ctex-auxpkg.dtx 2.6.3 2026-07-08 18:13:24 +0800 8c6212ee Mingyu Hsia <myhsia@outlook.com>$
  {Patching commands (CTEX)}
\ProvidesExplPackage{ctexpatch}
  {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\cs_new_protected:Npn \ctex_patch_cmd_once:NnnnTF #1#2
  {
    \ctex_patch_boot:NNnnTF \__ctex_patch_cmd:Nnnnnw #1
      { once } {#2} { \use_i:nn } { \use_ii:nn }
  }
\cs_new_protected:Npn \ctex_patch_cmd_all:NnnnTF #1#2
  {
    \ctex_patch_boot:NNnnTF \__ctex_patch_cmd:Nnnnnw #1
      { all } {#2} { \use_i:nn } { \use_ii:nn }
  }
\cs_new_protected:Npn \ctex_patch_cmd:Nnn #1
  {
    \ctex_patch_boot:NNnnTF \__ctex_patch_cmd:Nnnnnw #1
      { once }
      {
        \ExplSyntaxOff
        \char_set_catcode_letter:n { 64 }
      }
      { }
      { \ctex_patch_failure:N #1 }
  }
\cs_new_protected:Npn \ctex_patch_failure:N #1
  { \msg_warning:nne { ctexpatch } { patch-failure } { \token_to_str:N #1 } }
\msg_new:nnn { ctexpatch } { patch-failure }
  { Oops!~Command~`#1'~is~NOT~patchable.\\ }
\cs_new_protected:Npn \ctex_preto_cmd:NnnTF #1#2
  {
    \ctex_patch_boot:NNnnTF \__ctex_hookto_cmd:Nnnnw #1
      { left } {#2} { \use_i:nn } { \use_ii:nn }
  }
\cs_new_protected:Npn \ctex_appto_cmd:NnnTF #1#2
  {
    \ctex_patch_boot:NNnnTF \__ctex_hookto_cmd:Nnnnw #1
      { right } {#2} { \use_i:nn } { \use_ii:nn }
  }
\cs_new_protected:Npn \ctex_patch_boot:NNnnTF #1#2#3#4#5#6
  {
    \cs_set_protected:Npx \__ctex_patch_true:w  { \exp_not:n {#5} }
    \cs_set_protected:Npx \__ctex_patch_false:w { \exp_not:n {#6} }
    \group_begin:
      \char_set_catcode_other:n { 35 }
      \ctex_parse_name:NN #1 #2 {#3} {#4}
  }
\cs_new_eq:NN \__ctex_patch_true:w  \use_i:nn
\cs_new_eq:NN \__ctex_patch_false:w \use_ii:nn
\cs_new_protected:Npn \ctex_parse_name:NN #1#2
  { \ctex_parse_name:NNe #1#2 { \cs_to_str:N #2 } }
\group_begin:
\cs_set_protected:Npn \__ctex_tmp:w #1#2#3
  {
    \cs_new_protected:Npn \ctex_parse_name:NNn ##1##2##3
      {
        \bool_lazy_or:nnTF
          { \cs_if_exist_p:c { ##3 ~ } }
          { \cs_if_exist_p:c { #1##3 } }
          {
            \group_begin:
            \use:e
              {
                \group_end:
                \__ctex_parse_name:nNNNnN
                  { \cs_replacement_spec:N ##2 }
                  \exp_not:N ##2
                  \exp_not:c { ##3 ~ }
                  \exp_not:c { #1##3 }
              } { ##3 } ##1
          }
          { ##1##2 }
      }
    \cs_new_protected:Npn \__ctex_parse_name:nNNNnN ##1##2##3##4##5##6
      {
        \exp_args:Nc ##6
          {
            \str_case:nnTF {##1}
              {
                { \protect ##3 } { }
                { \x@protect ##2 \protect ##3 } { }
              }
              {
                \str_if_eq:eeTF
                  { \exp_not:n { #1@protected@ ##3 #1##3 } }
                  {
                    \exp_last_unbraced:Ne \__ctex_parse_name:w
                      { \cs_replacement_spec:N ##3 } #3 ~ #2 \q_stop
                  }
                  { #1##5 ~ } { ##5 ~ }
              }
              {
                \str_case:onTF { \__ctex_parse_name:w ##1 #3 ~ #2 \q_stop }
                  {
                    { #1@protected@ ##2 ##4 } { }
                    { #1@ ##4 } { }
                  }
                  { #1##5 } {##5}
              }
          }
      }
    \cs_new:Npn \__ctex_parse_name:w ##1 #3 ~ ##2 #2 ##3 \q_stop { ##1##2 }
  }
\use:e
  {
    \__ctex_tmp:w
      { \c_backslash_str }
      { \c_left_brace_str }
      { \tl_to_str:n { testopt } }
  }
\group_end:
\cs_generate_variant:Nn \ctex_parse_name:NNn { NNe }
\str_new:N \l__ctex_prefix_str
\str_new:N \l__ctex_parameter_str
\str_new:N \l__ctex_replacement_str
\group_begin:
  \cs_set_protected:Npn \__ctex_tmp:w #1
    {
      \prg_new_protected_conditional:Npnn
        \ctex_get_macro_meaning:N ##1 { TF }
        {
          \exp_after:wN \__ctex_get_macro_meaning:w
            \token_to_meaning:N ##1 \q_mark #1 -> \q_mark \q_stop
        }
      \cs_new_protected:Npn \__ctex_get_macro_meaning:w
          ##1 #1 ##2 -> ##3 \q_mark ##4 \q_stop
        {
          \tl_if_empty:nTF { ##4 }
            { \prg_return_false: }
            {
              \str_set:Nn \l__ctex_prefix_str      { ##1 }
              \str_set:Nn \l__ctex_parameter_str   { ##2 }
              \str_set:Nn \l__ctex_replacement_str { ##3 }
              \prg_return_true:
            }
        }
    }
  \exp_args:No \__ctex_tmp:w { \tl_to_str:n { macro: } }
\group_end:
\cs_new_protected:Npn \ctex_if_rescanable:NnTF #1#2#3#4
  {
    \ctex_get_macro_meaning:NTF #1
      {
        \__ctex_patch_rebuild:Nn \__ctex_rebuild_cmd:w {#2}
        \cs_if_eq:NNTF #1 \__ctex_rebuild_cmd:w {#3} {#4}
      }
      {#4}
  }
\cs_new_eq:NN \__ctex_rebuild_cmd:w \prg_do_nothing:
\cs_new_protected:Npn \__ctex_patch_rebuild:Nn #1#2
  {
    \__ctex_patch_rescan:NNn \l__ctex_prefix_tl      \l__ctex_prefix_str      {#2}
    \__ctex_patch_rescan:NNn \l__ctex_parameter_tl   \l__ctex_parameter_str   {#2}
    \__ctex_patch_rescan:NNn \l__ctex_replacement_tl \l__ctex_replacement_str {#2}
    \use:e
      {
        \exp_not:o { \l__ctex_prefix_tl } \tex_def:D \exp_not:N #1
          \exp_not:o { \l__ctex_parameter_tl }
            { \exp_not:o { \l__ctex_replacement_tl } }
      }
  }
\cs_new_protected:Npn \__ctex_patch_rescan:NNn #1#2#3
  {
    \str_if_empty:NTF #2
      { \tl_clear:N #1 }
      { \tl_set_rescan:Nno #1 {#3} {#2} }
  }
\tl_new:N \l__ctex_prefix_tl
\tl_new:N \l__ctex_parameter_tl
\tl_new:N \l__ctex_replacement_tl
\cs_new_protected:Npn \__ctex_patch_cmd:Nnnnnw #1#2#3#4#5
  {
    \group_end:
    \ctex_if_rescanable:NnTF #1 {#3}
      {
        \use:e
          {
            \__ctex_patch_replace:nnnTF {#2}
              { \tl_to_str:n {#4} }
              { \tl_to_str:n {#5} }
          }
          {
            \__ctex_patch_rebuild:Nn #1 {#3}
            \__ctex_patch_true:w
          }
          { \__ctex_patch_false:w }
      }
      { \__ctex_patch_false:w }
  }
\cs_new_protected:Npn \__ctex_patch_replace:nnnTF #1#2#3#4
  {
    \tl_if_in:NnTF \l__ctex_replacement_str {#2}
      { \use:c { tl_replace_ #1 :Nnn } \l__ctex_replacement_str {#2} {#3} #4 }
  }
\cs_new_protected:Npn \__ctex_hookto_cmd:Nnnnw #1#2#3#4
  {
    \group_end:
    \ctex_get_macro_meaning:NTF #1
      {
        \str_if_empty:NTF \l__ctex_parameter_str
          { \__ctex_hookto_cmd_parameterless:Nnnnw }
          { \__ctex_hookto_cmd_parameter:Nnnnw }
          #1 {#2} {#3} {#4}
      }
      { \__ctex_patch_false:w }
  }
\cs_new_protected:Npn \__ctex_hookto_cmd_parameterless:Nnnnw #1#2#3#4
  {
    \str_if_empty:NF \l__ctex_prefix_str
      { \tl_rescan:no {#3} { \l__ctex_prefix_str } }
    \tex_edef:D #1
      {
        \use:c { __ctex_ #2 _hook_aux:nn }
          { \exp_not:o {#1} }
          { \exp_not:n {#4} }
      }
    \__ctex_patch_true:w
  }
\cs_generate_variant:Nn \tl_rescan:nn { no }
\cs_new:Npn \__ctex_left_hook_aux:nn #1#2 { #2#1 }
\cs_new_eq:NN \__ctex_right_hook_aux:nn \use:nn
\cs_new_protected:Npn \__ctex_hookto_cmd_parameter:Nnnnw #1#2#3#4
  {
    \__ctex_patch_rebuild:Nn \__ctex_rebuild_cmd:w {#3}
    \cs_if_eq:NNTF #1 \__ctex_rebuild_cmd:w
      {
        \use:c { str_put_ #2 :Nn } \l__ctex_replacement_str {#4}
        \__ctex_patch_rebuild:Nn #1 {#3}
        \__ctex_patch_true:w
      }
      { \__ctex_patch_false:w }
  }
%% 
%%
%% End of file `ctexpatch.sty'.
