expl3 を使用して表形式内で \\ コマンドを再定義するにはどうすればよいですか?

expl3 を使用して表形式内で \\ コマンドを再定義するにはどうすればよいですか?

表形式内で再定義しようとすると\\、再定義が機能しません。おそらく\AtBeginEnvironment何かをフックした後に\\コマンドが再定義されるのだろうと理解しましたが、修正方法がわかりません。\\表形式内で再定義する方法を教えてください。ご協力いただきありがとうございます。

\documentclass{article}
\usepackage{expl3,etoolbox}
\ExplSyntaxOn
\AtBeginEnvironment{tabular}{
\cs_set_eq:Nc \\ {orig_endofline}
\cs_gset_protected:Npn \\ {
\orig_endofline
\message{new_line}
}
}
\ExplSyntaxOff
\author{Alexandr Kozlovskiy}
\title{test}
\begin{document}
\maketitle{}
\begin{tabular}{cc}
a&b\\
\end{tabular}
\end{document}

答え1

それは難しい...

再定義は実際には簡単な部分です。環境が最初に行うことの 1 つがtabularであるため\let \\=\@tabularcr、コードが機能しませんでした。そのため、再定義は失われています。代わりに を再定義する必要があります。また、 にはオプションの引数があるため、これにも対処する必要があることに\@tabularcr注意してください。は実際に必要なコマンドであるため、環境ごとにではなく、1 回だけ再定義できます。\\\@tabularcr

難しいのは\@tabularcr、 の後に TeX が をスキャンし始めることです。この時点で\omitを実行すると が完全に壊れてしまいます。 を実行するか(またはここで実行したい操作)、\message\multicolumn\message前にオリジナル\@tabularcr、または内部\noalign

arrayおそらく、パッケージと も考慮する必要がありますtabularx。 はのみをarray未定義にして使用するので、それを確認する必要があります。 再定義は、パッケージのロード前かロード後かによって異なるため、念のため入れておきます。\@tabularcr\@arraycr\AtBeginDocument


ジェネリックは\kozlovskiy_tabular_cr:Nnn次の 3 つの引数を取ります。

\kozlovskiy_tabular_cr:Nnn <cr command> <star arg> <opt arg>

そうすると

\use:x { \exp_not:N #1 \IfValueT {#2} { * } \IfValueT {#3} { [{#3}] } }

その行はxすべてを展開します:

  • \exp_not:N拡大を防ぐ<cr command>
  • \IfValueT {#2} { * }引数*の有無に応じて、展開されるか、何も展開されない。*
  • \IfValueT {#3} { [{#3}] }[#3]オプションの引数があるかどうかに応じて、展開されるか、何も展開されないか

そして最終的には次のようになります:

<cr command> <star arg (if present)> <opt arg (if present)>

また、tabularx環境本体を複数回実行するので、代わりに次のようにする必要があることに注意してください。

\cs_new_protected:Npn \kozlovskiy_tabular_cr:Nnn #1 #2 #3
  {
    \use:x { \exp_not:N #1 \IfValueT {#2} { * } \IfValueT {#3} { [{#3}] } }
    \token_if_eq_meaning:NNF \@footnotetext \TX@trial@ftn
      { \noalign { \message{<<<<new_line>>>>} } }
  }

\documentclass{article}
\usepackage{expl3,xparse}
\usepackage{array,tabularx,colortbl}
\ExplSyntaxOn
\makeatletter
\cs_new_protected:Npn \kozlovskiy_tabular_cr:Nnn #1 #2 #3
  {
    % \message{new_line} % before or
    \use:x { \exp_not:N #1 \IfValueT {#2} { * } \IfValueT {#3} { [{#3}] } }
    \noalign { \message{<<<<new_line>>>>} } % after in \noalign
    %
    % \message{new_line} % this breaks \multicolumn
  }
\AtBeginDocument
  {
    \@ifpackageloaded{array}{ }
      {
        \cs_new_eq:NN \LTX@tabularcr \@tabularcr
        \RenewDocumentCommand \@tabularcr { s o }
          { \kozlovskiy_tabular_cr:Nnn \LTX@tabularcr {#1} {#2} }
      }
    \cs_new_eq:NN \LTX@arraycr \@arraycr
    \RenewDocumentCommand \@arraycr { s o }
      { \kozlovskiy_tabular_cr:Nnn \LTX@arraycr {#1} {#2} }
  }
\ExplSyntaxOff
\author{Alexandr Kozlovskiy}
\title{test}
\begin{document}
\maketitle{}
\begin{tabular}{cc}
a&b\\
\multicolumn{2}{c}{c and d}\\
\end{tabular}
\begin{tabularx}{2cm}{Xc}
a&b\\
\multicolumn{2}{c}{c and d}\\
\end{tabularx}
\end{document}

関連情報