相當於 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,就在 a 的下面很多的符號。

因為我知道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

其中一個意外空格來自 after 的行尾\begin{foo},另一個來自 after 的行尾key

可以使用environ,如 Christian 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 的功能xparse應該是 LaTeX 團隊的待辦事項清單。

答案2

environ這是一種使用and 的方式,在包裝器環境中\NewEnviron捕獲並應用它,用s定義,這意味著- 參數說明符中的所有功能仍然可以使用。\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}

相關內容