Когда я пытаюсь переопределить \\
внутри табличного, мое переопределение не работает. Я понял, что, вероятно, после хука \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
. array
undefines \@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}