[Tex/LaTex] Custom table environment

tables

I have many tables of data interspersed with text that I want to have formatted identically. Right now I'm setting widths manually for each one in tabular:

\documentclass{article}
\usepackage[no-math]{fontspec}
\setmainfont{NotoSerif}
\usepackage[margin=1in]{geometry}
\usepackage{setspace} 
\usepackage{lipsum} 
\usepackage{gb4e,cgloss}

\begin{document}

\begin{tabular}{p{3cm} >{\em} p{3.5cm} @{\hskip 1in}  p{3cm} >{\em} p{3.5cm}}
    word1       &   description &   word1a  &   description \\
    word2       &   description &   word2a  &   description \\
    \end{tabular}
\end{document}

I don't like having to set the width manually for each table, especially because it makes changing the widths a hassle. How can I define a custom table environment with certain column widths in the preamble?

Actually, a solution where the data could be listed more simply, e.g. with spaces or with brackets would also be swell, something like this:

\begin{customtable}
word1 description word1a description \\
word2 description word2a description \\ 
\end{customtable}

Best Answer

Just define an environment customtable which includes a tabular:

\documentclass[]{article}

\usepackage{array}

\newenvironment{customtable}
  {%
    \begin{tabular}
      {p{3cm} >{\itshape} p{3.5cm} @{\hskip 1in}  p{3cm} >{\itshape} p{3.5cm}}%
  }
  {%
    \end{tabular}%
  }

\begin{document}
\begin{customtable}
  word1 & description & word3 & description \\
  word2 & description & word4 & description \\
\end{customtable}
\end{document}

Introducing your space delimited syntax is possible with e.g. the following (primitive implementation, better is in no doubt possible):

\documentclass[]{article}

\usepackage{array}
\usepackage{environ}

\makeatletter
\NewEnviron{CustomTable}
  {%
    \expandafter\parseRows\BODY\\\endparseRows
    \begin{tabular*}{\linewidth}
      {
        >{\raggedright\arraybackslash}p{4em}
        >{\raggedright\arraybackslash\itshape} p{8em}
        @{\extracolsep{\fill}}
        >{\raggedright\arraybackslash}p{4em}
        >{\raggedright\arraybackslash\itshape} p{8em}
      }%
      \CustomTableBody
    \end{tabular*}%
  }
\newcommand\parseRows{}
\newcommand\CustomTableBody{}
\newcommand\parseRow{}
\def\parseRows#1\\#2\endparseRows
  {%
    \if\relax\detokenize{#1}\relax
      \expandafter\@gobble
    \else
      \parseRow#1 \endparseRow
      \edef\CustomTableBody{\unexpanded\expandafter{\CustomTableBody\\}}%
      \expandafter\@firstofone
    \fi
    {%
      \expandafter\parseRows\@firstofone#2\\\endparseRows
    }%
  }
\def\parseRow #1 #2 #3 #4\endparseRow
  {
    \edef\CustomTableBody
      {\unexpanded\expandafter{\CustomTableBody#1&#2&#3&#4}}%
  }

\begin{document}
\noindent
\begin{CustomTable}
  word1 description word3 description \\
  word2 description word4 description \\
  word3 {good multi word description} word4 description \\
  word3 {good multi word description} \\
\end{CustomTable}
\end{document}

The syntax might be fragile, use at your own risk.

enter image description here

Related Question