LaTeX3의 \bgroup \egroup과 동일합니다.

LaTeX3의 \bgroup \egroup과 동일합니다.

expl3환경의 콘텐츠에 기능을 적용하려고 합니다 . LaTeX2e에서는 \bgroup및 를 사용하여 이를 달성할 수 있습니다 \egroup. 에서 expl3뭔가 작동하지 않습니다.

다음 코드는 "AAA hey BBB"를 인쇄할 것으로 예상됩니다. 대신 "AAA BBB hey"가 인쇄됩니다.

\ExplSyntaxOn

\cs_new:Npn \bar:n #1 {
    AAA #1 BBB
}

\NewDocumentEnvironment{foo}{}{
    \bar:n \bgroup
}{
    \egroup
}

\ExplSyntaxOff

\begin{document}

\begin{foo}
    hey
\end{foo}

\end{document}

이런 일이 발생하는 이유와 가능한 해결 방법에 대해 어떻게 생각하시나요?

편집하다

이것이 나의 현재 접근 방식입니다.

\cs_new:Npn \env_new:Nn #1#2 {
    \tl_new:N #1
    \tl_set:Nn #1 { #2 }
}

\cs_new:Npn \env_begin:N #1 {}
\cs_new:Npn \env_end:N #1 {}

\cs_new:Npn \env_capture_on: {
    \global \let \env_begin:N \group_begin:
    \global \let \env_end:N   \group_end:
}

\cs_new:Npn \env_capture_off: {
    \global\let\env_begin:N\env_original_begin:N
    \global\let\env_end:N\env_original_end:N
}

\cs_new:Npn \env_original_begin:N #1 {
    \env_capture_on:
    \tl_use:N #1
    \group_begin:
    \env_capture_off:
}

\cs_new:Npn \env_original_end:N #1 {
}

\env_capture_off:


\cs_new:Npn \foo:n #1 {
    AAA #1 BBB
}

\env_new:Nn \baf {
    \foo:n
}

\env_begin:N \baf
    hey
\env_end:N \baf

\group_begin: 및 \group_end:는 함수 인수를 캡처하는 데 사용할 수 없기 때문에 작동하지 않습니다(즉, \foo \group_begin: A \group_end:와 다르게 작동함 \foo { A }).

제어 시퀀스가 ​​마치 명시적 중괄호인 것처럼 동작하도록 일시적으로 강제할 수 있는 방법이 있나요?

해결책

내 생각엔 해결책이 있는 것 같아. 댓글에서 언급했듯이 패턴 일치와 \begins 수 계산을 결합하여 환경의 내용을 캡처할 수 있습니다. 이런게 있어서 좀 놀랐어요정확하게에서 무슨 일이 일어나고 있나요 environ? 바로 아래많은표기법.

의도한 응용 프로그램에서 이것이 실패했다는 것을 알았기 때문에 environ가능한 가장 간단한 방법으로 다시 구현하기로 결정했습니다. 그러면 내 코드가 어디서 실패하는지 알아낼 수 있습니다(이제 무엇이 잘못되었는지 알 수 있지만 그게 요점이 아닙니다). 아래에서 구현을 찾을 수 있습니다 expl3. 철저하게 테스트하지는 않았지만 작동한다고 믿습니다.

모든 의견이나 리뷰는 대단히 감사합니다.

\int_new:N \env_count
\cs_new:Npn \env_new:Nn #1#2 {
    \cs_new:cpn { env_defined@ \cs_to_str:N #1 :nn } ##1##2 {
        #2
    }
}

\cs_new:Npn \env_countbegin:w #1\xbegin#2 {
    \cs_if_free:NTF #2 {
        \int_incr:N \env_count
        \env_countbegin:w
    } {
        \cs_if_eq:NNTF #2 \xend {} {
            \int_incr:N \env_count
            \env_countbegin:w
        }
    }
}

\cs_new:Npn \env_collect:w #1#2#3#4\xend#5 {
    \env_countbegin:w #4\xbegin\xend
    \int_compare:nTF { \env_count = 0 } {
        \use:c { env_defined@ \cs_to_str:N #1 :nn } { #3 #4 } { #2 }
    }{
        \int_decr:N \env_count
        \env_collect:w {#1} {#2} { #3 #4 \xend{#5} }
    }
}

\NewDocumentCommand \xbegin {mo} {
    \int_zero:N \env_count
    \env_collect:w {#1} {#2} {}
}

\NewDocumentCommand \xend {} {}

\env_new:Nn \foo {
    AAA #1 BBB
}

\xbegin{\foo}
\xbegin{\foo}
hey
\xend{\foo}
\xend{\foo}

답변1

그것은 가지고있다절대\bgroup및 으로 논쟁을 벌이는 것이 가능했습니다 \egroup. 버전

\newenvironment{foo}{%
  \baz\bgroup
}{%
  \egroup
}
\newcommand{\baz}[1]{AAA #1 BBB}

똑같은 방식으로 실패합니다. 에 대한 인수는 \baz이므로 \bgroup출력은

x\begin{foo}
key
\end{foo}y

될 것이다

xAAA<space><space>BBB<space>key<space>y

예상치 못한 공백 중 하나는 다음 줄 끝에서 나오고 \begin{foo}, 다른 하나는 다음 줄 끝에서 나옵니다 key.

environChristian Hupfer가 보여준 것처럼 다음을 사용할 수 있습니다 .

\usepackage{xparse,environ}

\ExplSyntaxOn
\NewEnviron{foo}
 {
  \jaeya_baz:V \BODY
 }

\cs_new:Nn \jaeya_baz:n { AAA~#1~BBB }
\cs_generate_variant:Nn \jaeya_baz:n { V }
\ExplSyntaxOff

위 코드의 출력은 예상된 것과 같습니다.

xAAA<space>key<space}BBBy

\NewEnvironIn 과 유사한 기능을 추가하는 것은 xparseLaTeX 팀의 할 일 목록에 있어야 합니다.

답변2

이는 's 로 정의된 래퍼 환경 내에서 이를 포착 하고 적용하는 environand 를 사용하는 방식입니다 . 이는 인수 지정자의 모든 기능을 계속 사용할 수 있음을 의미합니다.\NewEnviron\BODYxparse\NewDocumentEnvironmentxparse

\documentclass{article}
\usepackage{environ}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Nn \bar:n {
  AAA #1 BBB
}


\NewEnviron{foointernal}{
  \bar:n {\BODY}
}

\ExplSyntaxOff

\let\origfoointernal\foointernal
\let\origendfoointernal\endfoointernal

\NewDocumentEnvironment{foo}{}{%
  \origfoointernal%
}{%
  \origendfoointernal%
}

\begin{document}

\begin{foo}
    hey
\end{foo}


\begin{foo}
   \blindtext

   Hello World
\end{foo}

\end{document}

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

답변3

\bar:n콘텐츠를 가져오는 환경에서 사용하고 싶다는 것을 알고 있습니다 . 따라서 미리 스캔하여 대체 텍스트 끝에 다시 \end삽입하십시오 .\end

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Npn \bar:n #1 \end {
    AAA #1 BBB \end
}

\NewDocumentEnvironment{foo}{}{\bar:n}{}

\ExplSyntaxOff

\begin{document}

\begin{foo}
    hey
\end{foo}

\end{document}

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

답변4

전체 패키지를 다시 작성하면 제대로 작동할지는 모르겠지만 적어도 지금은 무슨 일이 일어나고 있는지 이해할 수 있습니다. 몇 가지 제한 사항이 있습니다. 정의된 환경에는 매개 변수가 두 개만 있습니다. #1은 환경의 내용을 나타냅니다. #2는 대괄호 매개변수를 나타내며 원칙적으로 키-값을 포함하는 데 사용할 수 있으므로 이 제한을 극복할 수 있습니다.

게다가 내 환경은 \xbegin{\foo} 및 \xend{\foo} 명령으로 작동합니다. 이러한 명령의 기본 구조는 LaTeX 환경과 다르기 때문에 다른 키워드를 사용하기로 결정했습니다. 어쨌든, 이 접근 방식을 LaTeX 환경에 적용하도록 확장할 수 있다고 생각합니다.

코드에 대한 모든 리뷰나 의견을 환영하고 감사하게 생각합니다!

\documentclass[10pt]{article}
\usepackage{expl3}

\ExplSyntaxOn

\int_new:N \env_count
\cs_new:Npn \env_new:Nn #1#2 {
    \cs_new:cpn { env_defined@ \cs_to_str:N #1 :nn } ##1##2 {
        #2
    }
}

\cs_new:Npn \env_countbegin:w #1\xbegin#2 {
    \cs_if_free:NTF #2 {
        \int_incr:N \env_count
        \env_countbegin:w
    } {
        \cs_if_eq:NNTF #2 \xend {} {
            \int_incr:N \env_count
            \env_countbegin:w
        }
    }
}

\cs_new:Npn \env_collect:w #1#2#3#4\xend#5 {
    \env_countbegin:w #4\xbegin\xend
    \int_compare:nTF { \env_count = 0 } {
        \use:c { env_defined@ \cs_to_str:N #1 :nn } { #3 #4 } { #2 }
    }{
        \int_decr:N \env_count
        \env_collect:w {#1} {#2} { #3 #4 \xend{#5} }
    }
}

\NewDocumentCommand \xbegin {mo} {
    \int_zero:N \env_count
    \env_collect:w {#1} {#2} {}
}

\NewDocumentCommand \xend {} {}

\env_new:Nn \foo {
    AAA #1 BBB
}

\ExplSyntaxOff

\begin{document}    

\xbegin{\foo}
\xbegin{\foo}
hey
\xend{\foo}
\xend{\foo}

\end{document}

관련 정보