[Tex/LaTex] Using tabularx in a custom environment – “misplaced \noalign”

environmentstablestabularx

Question

Currently, I'm trying to shorten the creation of small tabularx-tables with pre-defined headers, but somehow, trying to use the tabularx-environment, even though I used the \tabularx and \endtabularx commands, inside my own yields to errors I fail to understand.

My current approach:

\newenvironment{predtable}[1]%
  {%
    \par\nolinenumbers%
    \captionof{table}{#1}%
    \tabularx{\textwidth}{|l| c c c |}%
        \hline%
         & Heading & Heading & Heading \\%
        \hline%
  }%
  {%
        \hline%
    \endtabularx%
    \linenumbers%
  }

This was supposed to ease table creation such that writing

\begin{predtable}
    item1 & item2 & item3 & item4\\
\end{predtable}

would be enough.

However, while I don't get errors when defining the environment, using it gets me the error Misplaced \noalign \end{predtable}.

Working example

\documentclass[12pt,a4paper]{article}
\usepackage[top=2.5cm, left=2.5cm, bottom=2cm, right=2cm]{geometry}
\usepackage{array}
\usepackage{tabularx}
\usepackage[font=footnotesize,labelfont=sc]{caption}
\usepackage{subcaption}
\usepackage[pagewise, modulo]{lineno}
\newcolumntype{C}{>{\centering\arraybackslash}X}
\newenvironment{predtable}[1]%
{%
 \par\nolinenumbers%
 \captionof{table}{#1}%
 \tabularx{\textwidth}{|l| C C C |}%
     \hline%
       & Heading 1 & Heading 1 & Heading 1 \tabularnewline%
     \hline%
}%
{%
     \hline%
 \endtabularx%
 \linenumbers%
}
\begin{document}
    \begin{predtable}{Caption goes here!}
        Label & Contents & go & here!\tabularnewline
    \end{predtable}
\end{document}

line 26: Misplaced \noalign \end{predtable}

Best Answer

Placing any alignment material (including \hline) in the end clause here doesn't work, I think because of the way tabularx scans ahead for the table material.

Fortunately there is a much easier approach using the environ package. First a simple basic example:

Simple example

\documentclass[12pt,a4paper]{article}

\usepackage{tabularx,environ}

\NewEnviron{simplepredtable}{%
 \begin{tabularx}{0.9\textwidth}{|l| XXX |}
     \hline
       & Heading 1 & Heading 1 & Heading 1 \tabularnewline
     \hline
     \BODY
     \hline
   \end{tabularx}
}

\begin{document}

\begin{simplepredtable}
  Label & Contents & go & here!\tabularnewline
\end{simplepredtable}

\end{document}

The environ package collects the text of the new environment up in a command \BODY which can then be inserted in to some other code. This enables us to write a block that looks like a usual \begin{xtabular}...\end{xtabular}. I have reduced the width of the table, just to avoid overfull boxes.

For your case, very much the same works, and we can pass your caption argument too:

Sample output

\documentclass[12pt,a4paper]{article}

\usepackage[top=2.5cm, left=2.5cm, bottom=2cm, right=2cm]{geometry}

\usepackage{tabularx,environ}

\usepackage[font=footnotesize,labelfont=sc]{caption}
\usepackage{subcaption}

\usepackage[pagewise,modulo]{lineno}

\newcolumntype{C}{>{\centering\arraybackslash}X}

\NewEnviron{predtable}[1]{%
 \par\nolinenumbers%
 \captionof{table}{#1}%
 \begin{tabularx}{\textwidth}{|l| C C C |}
   \hline
   & Heading 1 & Heading 1 & Heading 1 \tabularnewline
   \hline
   \BODY
   \hline
 \end{tabularx}
 \vspace{\partopsep}
 \par\linenumbers%
}

\usepackage{lipsum} %For demonstration text

\begin{document}
\linenumbers

\lipsum[1]

\begin{predtable}{Caption goes here!}
  Label & Contents & go & here!\tabularnewline
\end{predtable}

\lipsum[2]

\end{document}

The lipsum package has been added so we get some text to demonstrate the line numbering, notice the extra \par command. I have also put some vertical space after the table so it doesn't run up against the followin text. However, I would seriously consider wrapping it in say a center environment instead, which would itself provide some vertical spacing.