1

When i try to redefine \\ inside a tabular,my redefining not works. I understood,what probably after hook \AtBeginEnvironment something redefine my \\ command,but i dont know,how to fix it. Help me please,how to redefine \\ inside a tabular. Thanks everybody for any help.

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

It's hard...

Well, redefining is actually the easy part: your code didn't work because one of the first things the tabular environment does is \let \\=\@tabularcr, so your redefinition is gone. You have to redefine \@tabularcr instead. Also remember that \\ has an optional argument, so you have to cope with that too. And since \@tabularcr is the actual command you want, you can redefine it just once, rather than at every environment.

The hard part is that after \@tabularcr, TeX starts scanning for \omit, so if you do \message at this point you completely break \multicolumn. You have to either issue the \message (or whatever you intend to do here) before the original \@tabularcr, or inside \noalign.

You probably want to also take into account the array package and tabularx. array undefines \@tabularcr and uses only \@arraycr, so you have to check for that. The redefinition will depend if it happens before or after the package loads, so I put it \AtBeginDocument to be sure.


The generic \kozlovskiy_tabular_cr:Nnn takes three arguments:

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

then it does

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

That line will x-expand everything:

  • \exp_not:N prevents the expansion of <cr command>
  • \IfValueT {#2} { * } expands to * or nothing, depending if there was a * argument
  • \IfValueT {#3} { [{#3}] } expands to [#3] or nothing, depending if there was an optional argument

and finally become:

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

Also note that tabularx will execute the environment body multiple times, so you may want instead:

\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}
5
  • Thank you very very much. Now i almost understood,how to use commands with optional arguments. I want to clarify two things: Why we should use use:x variant and how to solve the problem in future,if my control sequences will have: things like orig@##1. In this case use:x will not works? 2. Why we use exp_not function? – Aleksandr Kozlovskiy Nov 9 '20 at 3:48
  • 1
    @AleksandrKozlovskiy I used \use:x to make the correct call to \LTX@tabularcr depending on the optional arguments given. If the table uses \\[2pt] (for example) then the call to \LTX@tabularcr will be \LTX@tabularcr[2pt], and so on. If you didn't use \use:x there it would not detect the optional arguments (try using \\[2pt] in the table and comment \use:x to see). If the command you are copying is ##1 and you want to copy it to orig@##1 then use \cs_new_eq:NN { orig@##1 } { ##1 }, then \cs_gset_protected:cpn { ##1 } { ... } or `\exp_args:Nc \RenewDocumentCommand { ##1 – Phelype Oleinik Nov 9 '20 at 4:07
  • 1
    this doesn't work if the array package is loaded and so also it doesn't work with e.g. tabularx or colortbl (with different behaviour, depending on if the loading is before or after the code). – Ulrike Fischer Nov 9 '20 at 7:41
  • 1
    @UlrikeFischer array support added. Thanks! – Phelype Oleinik Nov 9 '20 at 12:36
  • @phelype-oleinik Thank you very very much. Now,i hope,i understood,how use command with optional arguments. Let God bless you forever. – Aleksandr Kozlovskiy Nov 9 '20 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.