0

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}
2
  • Welcome to TeX.SX! Delimiting with spaces can be done, but what if a description has multiple words? Using & seems easier, after all, because it's a very distinguishable character.
    – egreg
    Sep 20, 2018 at 9:30
  • Because 98% of the descriptions are single words and so delimiting with spaces would reduce the need for typing several thousand '&' symbols.
    – Makenna
    Sep 20, 2018 at 12:05

2 Answers 2

3

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

0

You may like this implementation that allows to insert the items sequentially.

By default tabular is used, but there is an optional argument for specifying longtable.

\documentclass{article}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage{xparse}
\usepackage{longtable,array}

\ExplSyntaxOn

\NewDocumentCommand{\customtable}{O{tabular}m}
 {
  \makenna_customtable:nn { #1 } { #2 }
 }

\seq_new:N \l_makenna_customtable_rows_seq
\seq_new:N \l__makenna_customtable_item_seq
\tl_new:N \l_makenna_customtable_body_tl
\int_new:N \l_makenna_customtable_length_int

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }

\cs_new_protected:Nn \makenna_customtable:nn
 {
  \seq_set_split:Nnn \l_makenna_customtable_rows_seq { \\ } { #2 }
  \int_set:Nn \l_makenna_customtable_length_int
   {
    \int_div_round:nn { \seq_count:N \l_makenna_customtable_rows_seq } { 2 }
   }

  \tl_clear:N \l_makenna_customtable_body_tl

  \int_step_inline:nnnn
   { 1 } % start
   { 1 } % step
   { \l_makenna_customtable_length_int } % end
   {
    \seq_set_split:Nnx \l__makenna_customtable_item_seq { ~ }
     { \seq_item:Nn \l_makenna_customtable_rows_seq { ##1 } }
    \tl_put_right:Nx \l_makenna_customtable_body_tl
     {
      \seq_use:Nn \l__makenna_customtable_item_seq { & } &
     }
    \seq_set_split:Nnx \l__makenna_customtable_item_seq { ~ }
     { \seq_item:Nn \l_makenna_customtable_rows_seq { ##1 + \l_makenna_customtable_length_int } }
    \tl_put_right:Nx \l_makenna_customtable_body_tl
     {
      \seq_use:Nn \l__makenna_customtable_item_seq { & } \exp_not:N \\
     }
   }
  \begin{#1}{p{3cm} >{\em} p{3.5cm} @{\hspace{2.5cm}}  p{3cm} >{\em} p{3.5cm}}
  \l_makenna_customtable_body_tl
  \end{#1}
 }

\ExplSyntaxOff

\begin{document}

\section{Six items}

\customtable{
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
}

\section{Nine items}

\customtable{
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word7 description \\
  word8 description \\
  word9 description \\
}

\section{Many items}

\customtable[longtable]{
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
  word6 {three word description} \\
  word1 description \\
  word2 description \\
  word3 description \\
  word4 description \\
  word5 description \\
}

\end{document}

enter image description here

4
  • Thanks! That's really nice. But I actually don't want multicolumn tables, the four items on each row actually go together. Which part of the syntax do I change have a single column table with 4 items per row?
    – Makenna
    Sep 21, 2018 at 6:00
  • Also, which part replaces the & with space? There's so much here I'm having a hard time picking out which commands do what.
    – Makenna
    Sep 21, 2018 at 6:03
  • @Makenna Your example features a four column table with two items per row.
    – egreg
    Sep 21, 2018 at 8:33
  • Oh. I see how that was ambiguous. I changed the original example to make it more clear now.
    – Makenna
    Sep 21, 2018 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.