expl3 的按键行为异常

expl3 的按键行为异常

考虑以下 MWE:

\documentclass{article}

\usepackage{amsthm}
\usepackage{xparse}

\newtheorem{theorem}{Theorem}
\newtheorem{definition}{Definition}

\ExplSyntaxOn

\tl_new:N \l_theorem_name_tl

\keys_define:nn { keys-loop } {
  thmname
    .tl_set:N = \l_theorem_name_tl,
}

\clist_map_inline:nn { {thmname=theorem}, {thmname=definition} } {
  \keys_set:nn { keys-loop } { #1 }

  % At this level \l_theorem_name_tl is 'theorem' the first time and
  % 'definition' the second time.
  \cs_set_eq:cc {inner\l_theorem_name_tl} {\l_theorem_name_tl}
  \cs_set_eq:cc {endinner\l_theorem_name_tl} {end\l_theorem_name_tl}

  \RenewDocumentEnvironment{ \l_theorem_name_tl }{ O{} }{
    % Now \l_theorem_name_tl is 'definition' both the first and second time?
    % What is going on?
    \begin{inner\l_theorem_name_tl}
      This
  }{
    \end{inner\l_theorem_name_tl}
  }
}

\ExplSyntaxOff

\begin{document}

\begin{theorem}
  is a theorem.
\end{theorem}

\begin{definition}
  is a definition.
\end{definition}

\begin{innertheorem}
  is a theorem.
\end{innertheorem}

\begin{innerdefinition}
  is a definition.
\end{innerdefinition}

\end{document}

产生

在此处输入图片描述

为什么第一个theorem变成了definition

答案1

您需要使用的内容\l_theorem_name_tl

\documentclass{article}

\usepackage{amsthm}
\usepackage{xparse}

\newtheorem{theorem}{Theorem}
\newtheorem{definition}{Definition}

\ExplSyntaxOn

\tl_new:N \l_theorem_name_tl

\keys_define:nn { keys-loop }
{
    thmname .tl_set:N = \l_theorem_name_tl,
}

\cs_new_protected:Npn \noibe_keyset:n #1
{
    \clist_map_inline:nn {#1}
    {
        \keys_set:nn { keys-loop } {##1}
        \noibe_cs_set_eq:V \l_theorem_name_tl
        \noibe_renew_env:V \l_theorem_name_tl
    }
}

\cs_new_protected:Npn \noibe_cs_set_eq:n #1
{
    \cs_set_eq:cc { inner#1 } {#1}
    \cs_set_eq:cc { endinner#1 } { end#1 }
}
\cs_generate_variant:Nn \noibe_cs_set_eq:n { V }

\cs_new_protected:Npn \noibe_renew_env:n #1
{
    \RenewDocumentEnvironment{#1}{ O{} }
    {
        \begin{inner#1}
            This
    }
    {
        \end{inner#1}
    }
}
\cs_generate_variant:Nn \noibe_renew_env:n { V }

\NewDocumentCommand{\setkeys}{ m }
{
    \noibe_keyset:n {#1}
}

\setkeys{thmname=theorem, thmname=definition}

\ExplSyntaxOff

\begin{document}

\begin{theorem}
  is a theorem.
\end{theorem}

\begin{definition}
  is a definition.
\end{definition}

\begin{innertheorem}
  is a theorem.
\end{innertheorem}

\begin{innerdefinition}
  is a definition.
\end{innerdefinition}

\end{document}

在此处输入图片描述

答案2

我不知道你为什么要通过 传递信息\keys_set:nn。在你的 MWE 中,这完全没有必要,只会让事情变得复杂。相反,你可以直接在里面使用你的代码\clist_map_inline:nn,并使用 访问环境名称#1

\documentclass{article}

\usepackage{amsthm}
\usepackage{xparse}

\newtheorem{theorem}{Theorem}
\newtheorem{definition}{Definition}

\ExplSyntaxOn

\clist_map_inline:nn { theorem, definition }
  {
    \cs_set_eq:cc { inner #1 } {#1}
    \cs_set_eq:cc { endinner #1 } { end #1 }

    \RenewDocumentEnvironment {#1}{ O{} }
      {
        \begin{inner#1}
          This
      }
      {
        \end{inner#1}
      }
  }

\ExplSyntaxOff

\begin{document}

\begin{theorem}
  is a theorem.
\end{theorem}

\begin{definition}
  is a definition.
\end{definition}

\begin{innertheorem}
  is a theorem.
\end{innertheorem}

\begin{innerdefinition}
  is a definition.
\end{innerdefinition}

\end{document}

相关内容