4

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}
        Header 1 & Header 2 \\
        Content 1 & Content 2 \\
        Content 3 & Content 4 \\
    \end{doctable}

\end{document}
2
  • In my opinion, this calls for \expandafter\unexpanded and xparse. Commented Feb 13, 2017 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
    Commented Feb 13, 2017 at 16:06

2 Answers 2

2

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}}
  {Header 1 & Header 2}
  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}

enter image description here

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\doctableheader{#1}%
  \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
    \doctableheader \\
    \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
    \doctableheader \\
    \hline
    \endhead % End of header for all pages after first
    \doctablebody
    \hline
    \end{tabularx}
}
\makeatother

\begin{document}

\begin{doctable}
  {Some Caption\label{somelabel}}
  Header 1 & Header 2 \\
  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}
4
  • 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
    Commented Feb 13, 2017 at 16:59
  • @zephyr Exactly. This way you are assuming that the first \\ separates the header from the body.
    – egreg
    Commented Feb 13, 2017 at 17:00
  • What does the \@nil? Commented Feb 13, 2017 at 17:20
  • @MaestroGlanz It delimits the second argument.
    – egreg
    Commented Feb 13, 2017 at 17:45
1

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.

2
  • 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
    Commented Feb 13, 2017 at 17:25
  • I could fix that, but this is a lot of work. Commented Feb 16, 2017 at 8:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .