Как переопределить команду \\ внутри таблицы с помощью 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

Это сложно...

Ну, переопределение на самом деле простая часть: ваш код не работает, потому что одно из первых действий среды tabular\let \\=\@tabularcr, поэтому ваше переопределение пропало. \@tabularcrВместо этого вам нужно переопределить. Также помните, что \\у него есть необязательный аргумент, поэтому вам тоже придется с этим справиться. И поскольку \@tabularcrэто фактическая команда, которую вы хотите, вы можете переопределить ее только один раз, а не в каждой среде.

Самое сложное в том, что после \@tabularcr, TeX начинает сканирование на предмет \omit, так что если вы это сделаете \messageв этот момент, вы полностью сломаете \multicolumn. Вам нужно либо выдать \message(или что вы там собираетесь сделать)дооригинал \@tabularcrили внутри \noalign.

Вы, вероятно, также хотите принять во внимание arrayпакет и tabularx. arrayundefines \@tabularcrи использует только \@arraycr, поэтому вам нужно проверить это. Переопределение будет зависеть от того, произойдет ли это до или после загрузки пакета, поэтому я поставил его, \AtBeginDocumentчтобы быть уверенным.


Универсальный метод \kozlovskiy_tabular_cr:Nnnпринимает три аргумента:

\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}

Связанный контент