# How to edit \BODY of Environ package

I've got a NewEnviron from the environ package which I use to enclose a table. An example of this is in the MWE below. The purpose is to handle the table formatting in the preamble and let the user provide only the content. What I need now is some ability to interact with the \BODY command of the environ so that I can properly specify the headers (via the ltablex (really the longtable) package) and have it properly display multi-page tables.

What the table content expands to now:

\caption{#1} \\ % Include the caption at the top of the table
\endfirsthead % Only show the caption for the first page
\hiderowcolors \caption{Continued} \\ % Include a caption on subsequent pages that just says continued
\showrowcolors % row coloring was turned off for the caption, now lets turn it back on
\endhead % End of header for all pages after first
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
Header 1 & Header 2 \\   % This is part of \BODY
Content 1 & Content 2 \\ % This is part of \BODY
Content 3 & Content 4 \\ % This is part of \BODY
\hline


What I would like it to be:

\caption{#1} \\ % Include the caption at the top of the table
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
Header 1 & Header 2 \\   % This is part of \BODY
\endfirsthead % Only show the caption for the first page
\hiderowcolors \caption{Continued} \\ % Include a caption on subsequent pages that just says continued
\showrowcolors % row coloring was turned off for the caption, now lets turn it back on
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
Header 1 & Header 2 \\   % This is part of \BODY
\endhead % End of header for all pages after first
Content 1 & Content 2 \\ % This is part of \BODY
Content 3 & Content 4 \\ % This is part of \BODY
\hline


Is there a way to achieve this?

Minimum Working Example

\documentclass{article}

\usepackage[table,dvipsnames]{xcolor}   % Provides coloring for tables and text
\usepackage{ltablex}                    % Customized table formatting (uses tabularx and longtable)
\usepackage{environ}                    % Used to define custom table environment

% Fixes conflict between variable names in tabularx and xcolor
\newcounter{tblerows}
\expandafter\let\csname c@tblerows\endcsname\rownum

\definecolor{greyblue}{rgb}{0.6353,0.6863,0.7686} % Define a color used in the tables
\newcommand\setrow[1]{\gdef\rowmac{#1}#1\ignorespaces} % Used for making a row bold
\newcommand\clearrow{\global\let\rowmac\relax} \clearrow % Used for clearing a row formatting
\newcolumntype{L}[1]{>{\hsize=#1\hsize\rowmac\raggedright\arraybackslash}X} % Left-aligned column, input is relative width of page
\keepXColumns

\NewEnviron{doctable}[1]{%
\centering
\rowcolors{3}{black!5}{black!15}
\begin{tabularx}{\textwidth}{L{0.5}|L{0.5}<{\clearrow}}
\caption{#1} \\ % Include the caption at the top of the table
\endfirsthead % Only show the caption for the first page
\hiderowcolors \caption{Continued} \\ % Include a caption on subsequent pages that just says continued
\showrowcolors % row coloring was turned off for the caption, now lets turn it back on
\endhead % End of header for all pages after first
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
\BODY
\hline
\end{tabularx}
\label{tbl:somelabel}
}

\begin{document}

\begin{doctable}{Some Caption}
Content 1 & Content 2 \\
Content 3 & Content 4 \\
\end{doctable}

\end{document}

• In my opinion, this calls for \expandafter\unexpanded and xparse. – MaestroGlanz Feb 13 '17 at 15:52
• @MaestroGlantz Yes, I had figured as much, however I'm not nearly knowledgeable enough to know how to accomplish this. I was hoping some wizard here could point me in the right direction. – zephyr Feb 13 '17 at 16:06

The header line should be given as a further argument.

\documentclass{article}

\usepackage[table,dvipsnames]{xcolor}   % Provides coloring for tables and text
\usepackage{ltablex}                    % Customized table formatting (uses tabularx and longtable)
\usepackage{environ}                    % Used to define custom table environment

% Fixes conflict between variable names in tabularx and xcolor
\newcounter{tblerows}
\makeatletter
\let\c@tblerows\rownum
\makeatother

\definecolor{greyblue}{rgb}{0.6353,0.6863,0.7686} % Define a color used in the tables
\newcommand\setrow[1]{\gdef\rowmac{#1}#1\ignorespaces} % Used for making a row bold
\newcommand\clearrow{\global\let\rowmac\relax} \clearrow % Used for clearing a row formatting
\newcolumntype{L}[1]{>{\hsize=#1\hsize\rowmac\raggedright\arraybackslash}X} % Left-aligned column, input is relative width of page
\keepXColumns

\NewEnviron{doctable}[2]{%
\centering
\rowcolors{3}{black!5}{black!15}
\begin{tabularx}{\textwidth}{L{0.5}|L{0.5}<{\clearrow}}
\caption{#1} \\ % Include the caption at the top of the table
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
#2 \\
\hline
\endfirsthead % Only show the caption for the first page
\hiderowcolors \caption{Continued} \\ % Include a caption on subsequent pages that just says continued
\showrowcolors % row coloring was turned off for the caption, now lets turn it back on
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
#2 \\
\hline
\endhead % End of header for all pages after first
\BODY
\hline
\end{tabularx}
}

\begin{document}

\begin{doctable}
{Some Caption\label{somelabel}}
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
\end{doctable}

\end{document}


Alternatively, but I wouldn't recommend it,

\documentclass{article}

\usepackage[table,dvipsnames]{xcolor}   % Provides coloring for tables and text
\usepackage{ltablex}                    % Customized table formatting (uses tabularx and longtable)
\usepackage{environ}                    % Used to define custom table environment

% Fixes conflict between variable names in tabularx and xcolor
\newcounter{tblerows}
\makeatletter
\let\c@tblerows\rownum
\makeatother

\definecolor{greyblue}{rgb}{0.6353,0.6863,0.7686} % Define a color used in the tables
\newcommand\setrow[1]{\gdef\rowmac{#1}#1\ignorespaces} % Used for making a row bold
\newcommand\clearrow{\global\let\rowmac\relax} \clearrow % Used for clearing a row formatting
\newcolumntype{L}[1]{>{\hsize=#1\hsize\rowmac\raggedright\arraybackslash}X} % Left-aligned column, input is relative width of page
\keepXColumns

\makeatletter
\long\def\split@doublebar#1\\#2\@nil{%
\def\doctablebody{#2}%
}

\NewEnviron{doctable}[1]{%
\centering
\expandafter\split@doublebar\BODY\@nil
\rowcolors{3}{black!5}{black!15}
\begin{tabularx}{\textwidth}{L{0.5}|L{0.5}<{\clearrow}}
\caption{#1} \\ % Include the caption at the top of the table
\hline
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
\hline
\endfirsthead % Only show the caption for the first page
\hiderowcolors \caption{Continued} \\ % Include a caption on subsequent pages that just says continued
\showrowcolors % row coloring was turned off for the caption, now lets turn it back on
\rowcolor{greyblue} \setrow{\bfseries} % Make the header row bold and colored grey-blue
\hline
\endhead % End of header for all pages after first
\doctablebody
\hline
\end{tabularx}
}
\makeatother

\begin{document}

\begin{doctable}
{Some Caption\label{somelabel}}
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
Content 1 & Content 2 \\
Content 3 & Content 4 \\
\end{doctable}

\end{document}

• Thanks a lot! I did think about switching to have the header be an input to the environment, but I was trying to keep this backwards compatible. Is there any particular reason you don't recommend your second solution? Is it just because it can potentially break easily? – zephyr Feb 13 '17 at 16:59
• @zephyr Exactly. This way you are assuming that the first \\ separates the header from the body. – egreg Feb 13 '17 at 17:00
• What does the \@nil? – MaestroGlanz Feb 13 '17 at 17:20
• @MaestroGlanz It delimits the second argument. – egreg Feb 13 '17 at 17:45

This is a complex thing, for what I dont see any simple solution.

I will provide some strategy here to solve this:

\let\rest\BODY
\def\knabbknabb#1&#2{#1\def\rest{#2}}
\def\knibbknibb#1\\#2{#1\def\rest{#2}}
\expandafter\unexpanded\knabbknabb\rest\relax
\expandafter\unexpanded\knibbknibb\rest\relax
\let\BODY\rest


First I copy \BODY into \rest, then I define my cut functions.

The output of \knabbknabb{rest} is Header 1, the output of knibbknibb{rest} is Header 2.

After that, \rest contains

Content 1 & Content 2 \\
Content 3 & Content 4 \\


and is copied back to \BODY

That would be my strategy.

• Useful to know. Thanks for your help. I will say that this solution is specific to having two columns, which I'm not always assuming (but left in for the MWE). – zephyr Feb 13 '17 at 17:25
• I could fix that, but this is a lot of work. – MaestroGlanz Feb 16 '17 at 8:11