문자열에 대한 함수 확장 확인

문자열에 대한 함수 확장 확인

\Foo주어진 인수에 대해 확장해야 한다고 생각하는 것에 대해 테스트하는 함수가 있습니다 . 두 가지 문제: 1/ 의 완전히 확장된 버전을 '로그'할 수 없습니다 \Foo{arg}. 2/ pdf 출력을 보면 확장이 올바른 것처럼 보이더라도 기반 테스트는 \str_if_eq:p실패합니다.

다음은 코드의 Hook 1에 해당하는 로그 파일의 발췌입니다.

\l_tmpa_tl=\Foo {A,B,C}.

나는 RHS에서 =확장된 버전을 기대했습니다. 왜 그렇지 않으며, 할 수 있습니까?

다음은 코드의 Hook 2에 해당하는 출력입니다.

여기에 이미지 설명을 입력하세요

\Foo {A,B,C}FAIL은 중앙의 LHS에 표시된 확장 +과 RHS 의 동일성을 테스트한 결과입니다 . 불일치는 어디에서 오는가?

\documentclass{l3doc}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \foo_str_compare:nn
{
  \exp_args:NNx \tl_set:Nn \l_tmpa_tl {#1}
  \tl_log:N \l_tmpa_tl % Hook 1
  \exp_last_unbraced:Nf % Hook 2
  \str_if_eq:nnTF
  {
    {\l_tmpa_tl}
    {#2}
    {PASS}
    {FAIL+#1+#2+}
  }
}

\NewDocumentCommand{\Foo}
{m}
{
  \seq_gset_from_clist:Nn \foo_seq {#1}
  \seq_use:Nnnn \foo_seq{,~}{,~}{~and~}
}

\NewDocumentCommand{\Test}{}
{
  \foo_str_compare:nn{\Foo{A,B,C}}{A,~B~and~C}
}

\ExplSyntaxOff

\begin{document}

\Test

\end{document}

답변1

확장 가능한 자료에 대해서만 문자열 비교를 수행할 수 있습니다. \Foo보호되는 문서 명령이 있고 \seq_gset_from_clist:Nn확장할 수 없는 을(를) 사용하고 있습니다. ( 에서는 interface3별표가 표시되지 않은 기능은 확장할 수 없습니다. 대체로 할당이나 조판을 수행하는 기능은 확장할 수 없습니다.)

쉼표 목록에 확장 가능한 매핑을 사용하도록 다시 작성하면 다음과 같은 결과가 발생합니다.

\documentclass{l3doc}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new:Npn \foo_str_compare:nn #1#2
  {
    \str_if_eq:eeTF {#1} {#2}
      { PASS }
      { FAIL+#1+#2+}
  }

\NewExpandableDocumentCommand{\Foo}
{m}
{
  \int_case:nnF { \clist_count:n {#1} }
    {
      { 0 } { }
      { 1 } {#1}
      { 2 } { \__foo_two:w #1 \s_stop }
    }
    { \__foo_list:w #1 \s_stop }
}
\cs_new:Npn \__foo_two:w #1 , #2 \s_stop { #1 ~ and ~ #2 }
\cs_new:Npn \__foo_list:w #1 , #2 \s_stop
  {
    #1 , ~
    \int_compare:nNnTF { \clist_count:n {#2} } > 2
      { \__foo_list:w #2 \s_stop }
      { \__foo_two:w #2 \s_stop }
  }

\NewDocumentCommand{\Test}{}
{
  \foo_str_compare:nn{\Foo{A,B,C}}{A,~B~and~C}
}

\ExplSyntaxOff

\begin{document}

\Test

\end{document}

에서 언급한 바와 같이에그레그의 답변, 코드에 권장 패턴이 아니고 제가 피한 다양한 구성이 있습니다.

답변2

성공하려면 확장성이 필요한 확장 불가능한 기능을 사용하고 있습니다.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \foo_str_compare:nn
 {
  \tl_log:e { #1 }
  \str_if_eq:eeTF {#1} {#2}
   {PASS}
   {FAIL+#1+#2+}
 }
\cs_generate_variant:Nn \tl_log:n { e }

\NewDocumentCommand{\Test}{m}
 {
  \seq_gset_from_clist:Nn \l_tmpa_seq {#1}
  \foo_str_compare:nn{\seq_use:Nnnn \l_tmpa_seq{,~}{,~}{~and~}}{A,~B~and~C}
 }

\ExplSyntaxOff

\begin{document}

\Test{A,B,C}

\end{document}

게다가 당신은 학대하고 \exp_args:...있습니다 \exp_last_unbraced:.... 예를 들어,

\exp_args:NNx \tl_set:Nn \l_tmpa_tl { #1 }

다음과 같이 쓰는 것이 더 좋습니다

\tl_set:Nx \l_tmpa_tl { #1 }

또한 \str_if_eq:eeTF전체 확장을 얻으려면 을 참고하세요.

"PASS"가 표시되고 로그 파일에 다음이 표시됩니다.

> A, B and C.

.\tl_log:e

관련 정보