I did a little poking around trying to figure out what tokens are executed in what order with such a hook, and diagnostically print the first 2 (that follow my \addmeafter
argument) out. The second diagnostic token is key: \csname
. That means what follows is the environment name and is of variable length. Thus, what I do is expand the \csname
and pass the same sequence of tokens to \zzz
. By expanding it once, the 2nd token following my argument (aka #3
) is no longer \csname
, but \zz
or \tabular
. Thus, by placing my desired #1
argument following #3
, it gets placed as if it were the first thing in the environment.
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\newcommand\addmeafter[3]{(\detokenize{#2!#3!})\par% <--FOR DIAGNOSIS
\def\tmp{\zzz{#1}}\expandafter\tmp\expandafter#2#3}
\newcommand\zzz[3]{#2#3#1}
\newenvironment{zz}{[}{]}
\AtBeginEnvironment{zz}{\addmeafter{Q}}
\AtBeginEnvironment{tabular}{\addmeafter{{|c|c|}}}
\begin{document}
\begin{zz}
hello world
\end{zz}
\bigskip
\begin{tabular}
\hline
a & b\\
\hline
c&d\\
\hline
\end{tabular}
\end{document}
If I comment out my diagnostics, and implement the hook as a macro \tabcols
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\newcommand\addmeafter[3]{%(\detokenize{#2!#3!})\par% <--FOR DIAGNOSIS
\def\tmp{\zzz{#1}}\expandafter\tmp\expandafter#2#3}
\newcommand\zzz[3]{#2#3#1}
\newenvironment{zz}{[}{]}
\AtBeginEnvironment{zz}{\addmeafter{Q}}
\AtBeginEnvironment{tabular}{\addmeafter{{\tabcols}}}
\begin{document}
\begin{zz}
hello world
\end{zz}
\bigskip
\def\tabcols{|c|c|}
\begin{tabular}
\hline
a & b\\
\hline
c&d\\
\hline
\end{tabular}
\bigskip
\def\tabcols{|c|c|c|}
\begin{tabular}
\hline
a & b & xxx\\
\hline
c&d& y\\
\hline
\end{tabular}
\end{document}
I get the desired result, allowing me to pre-specify the tabular
column format in the macro \tabcols
, and not specify it at the time of execution.
SUPPLEMENT
On the possibility, as Don suggests, that I misread the question..
If it is not desired to stick in a column specification, but merely to read it in advance, the change is straightforward. Here I read the column specification, #4
in \zzz
, and pass it as an argument to #1
(which is the macro \tabcols
), in advance of executing the tabular
#3
.
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\newcommand\readafter[3]{%
\def\tmp{\zzz{#1}}\expandafter\tmp\expandafter#2#3}
\newcommand\zzz[4]{#1{#4}#2#3{#4}}
\newcommand\tabcols[1]{%
The spec for the next tabular will be \detokenize{#1}\par}
\AtBeginEnvironment{tabular}{\readafter\tabcols}
\begin{document}
\begin{tabular}{|c|c|}
\hline
a & b\\
\hline
c&d\\
\hline
\end{tabular}
\bigskip
\begin{tabular}{|c|c|c|}
\hline
a & b & xxx\\
\hline
c&d& y\\
\hline
\end{tabular}
\end{document}
DOUBLE SUPPLEMENT
The OP asks in a comment about tabular*
and tabularx
. I will show how to address the two mandatory arguments of tabular*
. It is the same logic as the above solutions, but taken to absorb one further argument. For example, compare \readafter
to \readtwoafter
, then compare \zzz
to \zzzz
and finally compare \tabcols
to \tabstarinputs
.
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\newcommand\readafter[3]{%
\def\tmp{\zzz{#1}}\expandafter\tmp\expandafter#2#3}
\newcommand\readtwoafter[3]{%
\def\tmp{\zzzz{#1}}\expandafter\tmp\expandafter#2#3}
\newcommand\zzz[4]{#1{#4}#2#3{#4}}
\newcommand\zzzz[5]{#1{#4}{#5}#2#3{#4}{#5}}
\newcommand\tabcols[1]{%
The spec for the next tabular will be \detokenize{#1}\par}
\newcommand\tabstarinputs[2]{%
The width for the next tabular* will be \detokenize{#1}\par
The spec for the next tabular* will be \detokenize{#2}\par}
\AtBeginEnvironment{tabular}{\readafter\tabcols}
\AtBeginEnvironment{tabular*}{\readtwoafter\tabstarinputs}
\begin{document}
\begin{tabular}{|c|c|}
\hline
a & b\\
\hline
c&d\\
\hline
\end{tabular}
\bigskip
\begin{tabular}{|c|c|c|}
\hline
a & b & xxx\\
\hline
c&d& y\\
\hline
\end{tabular}
\bigskip
\begin{tabular*}{2in}{|c|c||}
\hline
a & big list of stuff here\\
\hline
c&d\\
\hline
\end{tabular*}
\end{document}
cc
.