3

My MWE

\documentclass[a4paper,twoside,openright,12pt]{book}

\usepackage[left=1.5cm,right=1cm,top=2.5cm,bottom=2.5cm,marginparwidth=0cm,marginparsep=0cm,outer=1cm]{geometry}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{tabularx,colortbl}
\usepackage{showframe}

\newcommand{\only}[6]{% 
\begin{table}[h!]
\caption{#1}
\centering
\begin{tabularx}
{\linewidth}{ l | X | X | X | X |}
\cline{2-5}
&  #2 &  #3 &  #4 &  #5 \\\hline
\multicolumn{1}{|l|}{$R_1$} &  &  &  \\ \hline
\multicolumn{1}{|l|}{$R_2$} &  &  &    \\ \hline
\multicolumn{1}{|l|}{$R_3$} &  &  &    \\ \hline
\multicolumn{1}{|l|}{$R_4$} &  &  &    \\ \hline 
\multicolumn{1}{|l|}{$R_5$} &  &  &    \\ \hline        
\end{tabularx}
\end{table}
}

\begin{document}
\twocolumn

\only{Reading\label{tab:read}}{Colors}{Value}{Tolerance}{Power}

Table \ref{tab:read} is very important.
\end{document}

And output is

enter image description here.

I wrote the following macro I'm trying to do. I wrote the macros below that I was trying to do. The letters in the columns are centered and the cells must be evenly spaced.

\only[row][col]{Table Caption}{Row1}{Row2}{Rown}{Col1}{Col2}{Coln}

For Example

\only[2][2]{Reading\label{tab:read}}{Colors}{Value}{$R_1$}{$R_2$}

enter image description here

Thanks.

  • 1
    Related tex.stackexchange.com/questions/367979/… – Andrew Aug 12 '18 at 7:32
  • @Andrew, I am checking that codes. – Özgür Aug 12 '18 at 8:35
  • If any of the provided answers fully answers your question, you should accept the most suited one. Else, please specify why your answer (in it's current form) is not answered. – Skillmon Aug 12 '18 at 16:29
  • @Skillmon, Do not misunderstand me. I have about 100 pages of documentation. I check the tables. Until now, I have not been able to just center the text on the cell. – Özgür Aug 12 '18 at 17:07
  • @Özgür see my second edit for the centring of all those columns in the tables created with \only. In all the other tables you can use c for a centred table of natural width or, if you want to centre a p type column or an X type column, you can use >{\centering\arraybackslash}X (if the array package is loaded). – Skillmon Aug 12 '18 at 17:12
4

Version just using tabularx:

\documentclass[]{article}

\usepackage{tabularx}

\makeatletter
\@ifdefinable\only@columns{\newcount\only@columns}
\@ifdefinable\only@columns@save{\newcount\only@columns@save}
\@ifdefinable\only@rows{\newcount\only@rows}
\newcommand\only@rowdefinitions{}
\newcommand\only@columndefinitions{}
\newcommand\only@end@rowdefinition{}
\newcommand\only@columntypes{}
\newcommand\only@columntype{X} % the type of each column to be used
\newcommand\only[1]%>>>
  {%
    \begingroup
    \def\only@caption{#1}%
    \only@a
  }%<<<
\newcommand\only@a[1][2]%>>>
  {%
    \def\only@columndefinitions{}%
    \def\only@rowdefinitions{}%
    \def\only@end@rowdefinition{&}%
    \only@rows#1
    \only@b
  }%<<<
\newcommand\only@b[1][2]%>>>
  {%
    \only@columns#1
    \only@columns@save\only@columns
    \ifnum\only@rows>0
      \expandafter\only@grab@rowdefinitions
    \else
      \ifnum\only@columns>0
        \expandafter\expandafter\expandafter\only@grab@columndefinitions
      \else
        \expandafter\expandafter\expandafter\endgroup
      \fi
    \fi
  }%<<<
\newcommand\only@grab@rowdefinitions[1]%>>>
  {%
    \edef\only@rowdefinitions
      {\unexpanded\expandafter{\only@rowdefinitions#1\only@end@rowdefinition}}%
    \advance\only@rows-1
    \ifnum\only@rows>0
      \expandafter\only@grab@rowdefinitions
    \else
      \expandafter\only@grab@columndefinitions
    \fi
  }%<<<
\newcommand\only@grab@columndefinitions[1]%>>>
  {%
    \edef\only@columndefinitions
      {\unexpanded\expandafter{\only@columndefinitions&#1}}%
    \edef\only@columntypes
      {%
        \unexpanded\expandafter{\only@columntypes}%
        \unexpanded\expandafter{\only@columntype}|%
      }%
    \advance\only@columns-1
    \ifnum\only@columns>0
      \edef\only@end@rowdefinition
        {\unexpanded\expandafter{\only@end@rowdefinition&}}%
      \expandafter\only@grab@columndefinitions
    \else
      \edef\only@end@rowdefinition
        {\unexpanded\expandafter{\only@end@rowdefinition\\\hline}}%
      \expandafter\expandafter\expandafter\only@shipout\expandafter
        {\only@columntypes}%
    \fi
  }%<<<
\newcommand\only@shipout[1]%>>>
  {%
    \begin{table}%
      \centering
      \expandafter\caption\expandafter{\only@caption}%
      \begin{tabularx}{\linewidth}{ | l | #1 }%
        \cline{2-\numexpr\only@columns@save+1\relax}%
        \multicolumn{1}{l|}{} \only@columndefinitions\\
        \hline
        \only@rowdefinitions
      \end{tabularx}%
    \end{table}%
    \endgroup
  }%<<<
\makeatother

\begin{document}
\only{Reading}[30][8]{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{A}{B}{C}{a}{b}{c}{d}{e}{f}{g}{h}
\end{document}

Example output using only 3 rows and 3 columns:

enter image description here

EDIT: Alternative input method, because nobody loves counting :) Just put a \EndRows after the row names and an \EndColumns after the column names.

\documentclass[]{article}

\usepackage{tabularx}
\usepackage{pdftexcmds}% to make \pdf@strcmp available for other engines

\makeatletter
\@ifdefinable\only@columns{\newcount\only@columns}
\newcommand\only@caption{}
\newcommand\only@rowdefinitions{}
\newcommand\only@columndefinitions{}
\newcommand\only@end@row{}
\newcommand\only@columntypes{}
\newcommand\only[1]%>>>
  {%
    \begingroup
    \def\only@caption{#1}%
    \expandafter\only@grab@rows\expandafter{\detokenize{\EndRows}}%
  }%<<<
\newcommand\only@grab@rows[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \expandafter\@firstoftwo
    \else
      \edef\only@rowdefinitions
        {\unexpanded\expandafter{\only@rowdefinitions#2\only@end@row}}%
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@grab@columns\expandafter{\detokenize{\EndColumns}}}
    {\only@grab@rows{#1}}%
  }%<<<
\newcommand\only@grab@columns[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row\\\hline}}%
      \expandafter\@firstoftwo
    \else
      \edef\only@columndefinitions
        {\unexpanded\expandafter{\only@columndefinitions&#2}}%
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row&}}%
      \edef\only@columntypes{\unexpanded\expandafter{\only@columntypes X |}}%
      \advance\only@columns1
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@shipout\expandafter{\only@columntypes}}
    {\only@grab@columns{#1}}%
  }%<<<
\newcommand\only@shipout[1]%>>>
  {%
    \begin{table}%
      \centering
      \expandafter\caption\expandafter{\only@caption}%
      \begin{tabularx}{\linewidth}{ | l | #1 }%
        \cline{2-\numexpr\only@columns+1\relax}%
        \multicolumn{1}{l|}{} \only@columndefinitions\\
        \hline
        \only@rowdefinitions
      \end{tabularx}%
    \end{table}%
    \endgroup
  }%<<<
\makeatother

\begin{document}
\only{Caption}{A}{B}{C}\EndRows{a}{b}{c}\EndColumns
\only{Caption}
{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{M}{N}{O}{P}{Q}{R}{S}{T}{U}{V}{W}{X}{Y}{Z}
\EndRows
{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k}{l}{m}
\EndColumns
\end{document}

(Output looks the same)

EDIT2:

Centred cell contents in every column:

\documentclass[]{article}

\usepackage{tabularx}
\usepackage{pdftexcmds}% to make \pdf@strcmp available for other engines

\makeatletter
\newcolumntype{C}{>{\centering\arraybackslash}X}
\@ifdefinable\only@columns{\newcount\only@columns}
\newcommand\only@caption{}
\newcommand\only@rowdefinitions{}
\newcommand\only@columndefinitions{}
\newcommand\only@end@row{}
\newcommand\only@columntypes{}
\newcommand\only[1]%>>>
  {%
    \begingroup
    \def\only@caption{#1}%
    \expandafter\only@grab@rows\expandafter{\detokenize{\EndRows}}%
  }%<<<
\newcommand\only@grab@rows[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \expandafter\@firstoftwo
    \else
      \edef\only@rowdefinitions
        {\unexpanded\expandafter{\only@rowdefinitions#2\only@end@row}}%
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@grab@columns\expandafter{\detokenize{\EndColumns}}}
    {\only@grab@rows{#1}}%
  }%<<<
\newcommand\only@grab@columns[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row\\\hline}}%
      \expandafter\@firstoftwo
    \else
      \edef\only@columndefinitions
        {\unexpanded\expandafter{\only@columndefinitions&#2}}%
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row&}}%
      \edef\only@columntypes{\unexpanded\expandafter{\only@columntypes C |}}%
      \advance\only@columns1
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@shipout\expandafter{\only@columntypes}}
    {\only@grab@columns{#1}}%
  }%<<<
\newcommand\only@shipout[1]%>>>
  {%
    \begin{table}%
      \centering
      \expandafter\caption\expandafter{\only@caption}%
      \begin{tabularx}{\linewidth}{ | c | #1 }%
        \cline{2-\numexpr\only@columns+1\relax}%
        \multicolumn{1}{l|}{} \only@columndefinitions\\
        \hline
        \only@rowdefinitions
      \end{tabularx}%
    \end{table}%
    \endgroup
  }%<<<
\makeatother

\begin{document}
\only{Caption}{A}{B}{C}\EndRows{a}{b}{c}\EndColumns
\only{Caption}
{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{M}{N}{O}{P}{Q}{R}{S}{T}{U}{V}{W}{X}{Y}{Z}
\EndRows
{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k}{l}{m}
\EndColumns
\end{document}

Output:

enter image description here

EDIT3: Now there is a starred and an unstarred version of the macro. The one with a star would put the first row-argument in the top row next to the column arguments. Also, if you specify an empty caption argument, no caption will be used (it will still be put inside of a float though).

\documentclass[]{article}

\usepackage{tabularx}
\usepackage{pdftexcmds}% to make \pdf@strcmp available for other engines

\makeatletter
\newcolumntype{C}{>{\centering\arraybackslash}X}
\@ifdefinable\only@columns{\newcount\only@columns}
\newcommand\only@caption{}
\newcommand\only@rowdefinitions{}
\newcommand\only@columndefinitions{}
\newcommand\only@end@row{}
\newcommand\only@columntypes{}
\newcommand\only@upper@border{}
\newcommand\only@first@row@first@cell{}
\newcommand\only%>>>
  {%
    \begingroup
    \@ifstar{\only@starred}{\only@unstarred}%
  }%<<<
\newcommand\only@starred%>>>
  {%
    \def\only@upper@border{\hline}%
    \only@grab@caption
      {%
        \expandafter\only@grab@row@starred\expandafter{\detokenize{\EndRows}}%
      }%
  }%<<<
\newcommand\only@unstarred%>>>
  {%
    \def\only@upper@border{\cline{2-\numexpr\only@columns+1\relax}}%
    \def\only@first@row@first@cell{\multicolumn{1}{c|}{}}%
    \only@grab@caption
      {%
        \expandafter\only@grab@rows\expandafter{\detokenize{\EndRows}}%
      }%
  }%<<<
\newcommand\only@grab@caption[2]%>>>
  {%
    \def\only@caption{#2}%
    #1%
  }%<<<
\newcommand\only@grab@row@starred[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \def\only@first@row@first@cell{\multicolumn{1}{c|}{}}%
      \expandafter\@firstoftwo
    \else
      \def\only@first@row@first@cell{#2}%
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@grab@columns\expandafter{\detokenize{\EndColumns}}}
    {\only@grab@rows{#1}}%
  }%<<<
\newcommand\only@grab@rows[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \expandafter\@firstoftwo
    \else
      \edef\only@rowdefinitions
        {\unexpanded\expandafter{\only@rowdefinitions#2\only@end@row}}%
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@grab@columns\expandafter{\detokenize{\EndColumns}}}
    {\only@grab@rows{#1}}%
  }%<<<
\newcommand\only@grab@columns[2]%>>>
  {%
    \expandafter\ifnum\expandafter\pdf@strcmp\expandafter{\detokenize{#2}}{#1}=0
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row\\\hline}}%
      \expandafter\@firstoftwo
    \else
      \edef\only@columndefinitions
        {\unexpanded\expandafter{\only@columndefinitions&#2}}%
      \edef\only@end@row{\unexpanded\expandafter{\only@end@row&}}%
      \edef\only@columntypes{\unexpanded\expandafter{\only@columntypes C |}}%
      \advance\only@columns1
      \expandafter\@secondoftwo
    \fi
    {\expandafter\only@shipout\expandafter{\only@columntypes}}
    {\only@grab@columns{#1}}%
  }%<<<
\newcommand\only@shipout[1]%>>>
  {%
    \begin{table}%
      \centering
      \expandafter\if\expandafter
        \relax\expandafter\detokenize\expandafter{\only@caption}\relax
      \else
        \expandafter\caption\expandafter{\only@caption}%
      \fi
      \begin{tabularx}{\linewidth}{ | c | #1 }%
        \only@upper@border
        \only@first@row@first@cell
        \only@columndefinitions\\
        \hline
        \only@rowdefinitions
      \end{tabularx}%
    \end{table}%
    \endgroup
  }%<<<
\makeatother

\begin{document}
\only*{Caption}{A}{B}{C}\EndRows{a}{b}{c}\EndColumns
\only{}
{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{M}{N}{O}{P}{Q}{R}{S}{T}{U}{V}{W}{X}{Y}{Z}
\EndRows
{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k}{l}{m}
\EndColumns
\end{document}

enter image description here

  • It is good working. – Özgür Aug 12 '18 at 12:13
  • @Özgür wait for an edit, the input obviously has drawbacks... – Skillmon Aug 12 '18 at 12:13
  • @Özgür imho, better syntax in the edit. – Skillmon Aug 12 '18 at 12:33
  • It is perfect working. – Özgür Aug 12 '18 at 13:01
  • Now I do not know if it would be right to ask a question. But one last question; If some tables require it, how do I change the code to write to the upper left empty cell? So to shift the text in the left column up. – Özgür Aug 12 '18 at 17:56
4

I have defined a macro \mytable that takes five arguments, with the second and third arguments being optional. The arguments are:

  • #1 is the table caption
  • #2 generates a label for the table of the form tab:#2. By default, #2 is #1.
  • #3, which is delimited by brackets, is character in the first column. It defaults to R.
  • #4 is the number of non-header rows
  • #5 is a comma separated list of column headers

Using this macro, the lines

  \mytable{Reading}{3}{Colors,Value,Tolerance,Power}

  \bigskip

  \mytable{Writing}[write](S){2}{Colors,Value,Power}

produce

enter image description here

Here is the full code:

\documentclass{article}
\usepackage{xparse}
\usepackage{tabularx}

\ExplSyntaxOn
\seq_new:N \l_headers_seq
\int_new:N \g_table_int
\int_new:N \g_columns_int
% \mytable{caption}[label](R){#rows}{column headers}
\NewDocumentCommand\mytable{ m O{#1} D(){R} mm}{
  \seq_set_from_clist:Nn \l_headers_seq {#5}
  \int_set:Nn \g_columns_int {\seq_count:N \l_headers_seq }
  \begin{table}[h!]
    \caption{#1}\label{tab:#2}
    \begin{tabularx}{\linewidth}{|l *{\int_use:N \g_columns_int}{|X}|}
      \hline
      \seq_map_inline:Nn \l_headers_seq { &##1} \\\hline
      \int_zero:N \g_table_int
      \prg_replicate:nn {#4}
      {
         \int_gincr:N \g_table_int
         $#3\sb{\int_use:N \g_table_int}$
         \prg_replicate:nn {\int_use:N \g_columns_int} {&} \\\hline
      }
    \end{tabularx}
  \end{table}
}
\ExplSyntaxOff

\begin{document}

  \mytable{Reading}{3}{Colors,Value,Tolerance,Power}

  \bigskip

  \mytable{Writing}[write](S){2}{Colors,Value,Power}

\end{document}

The macro uses expl3 package.

Edit

In the comment the OP asks for variable row headers as well. The following modification of the code above achieves this.

The new \mytable macro now takes 4 arguments:

  • #1 is the table caption
  • #2 generates a label for the table of the form tab:#2. By default, #2 is #1.
  • #3 is a comma separated list of column headers
  • #4 is a comma separated list of row headers

Now the input

  \mytable{Reading}{Colors,Value,Tolerance,Power}{Row 1, Row 2, Row 3}

  \bigskip

  \mytable{Writing}[write]
       {Colors,Value,Power}
       {$A_1$, $D_2$, $R_1$, $S_3$}

  See Table~\ref{tab:Reading} and Table~\ref{tab:write}

produces:

enter image description here

The modified code:

\documentclass{article}
\usepackage{xparse}
\usepackage{tabularx}

\ExplSyntaxOn
\seq_new:N \l_header_seq
\seq_new:N \l_row_seq
\int_new:N \l_columns_int
\tl_new:N \l_ampersands_tl
\tl_new:N \l_table_row_tl
% \mytable{caption}[label]{column headers}{row headers}
\NewDocumentCommand\mytable{ m O{#1} mm}{
  \seq_set_from_clist:Nn \l_header_seq {#3}
  \tl_clear:N \l_ampersands_tl
  \seq_map_inline:Nn \l_header_seq 
      {\tl_put_right:Nn \l_ampersands_tl {&}}
  % now construct the table rows
  \seq_set_from_clist:Nn \l_row_seq {#4}
  \tl_clear:N \l_table_row_tl
  \seq_map_inline:Nn \l_row_seq {
     \tl_put_right:Nn \l_table_row_tl 
         {##1 \tl_use:N \l_ampersands_tl \\ \hline}
  }

  \int_set:Nn \l_columns_int {\seq_count:N \l_header_seq }
  \begin{table}[h!]
    \caption{#1}\label{tab:#2}
    \begin{tabularx}{\linewidth}{|l *{\l_columns_int}{|X}|}
      \cline{2-\int_eval:n{ \l_columns_int+1} }
      \multicolumn{1}{c|}{}\tl_use:N \l_ampersands_tl \\\hline
      \tl_use:N \l_table_row_tl
    \end{tabularx}
  \end{table}
}
\cs_generate_variant:Nn \tl_set:Nn {Nx}
\ExplSyntaxOff

\begin{document}

  \mytable{Reading}{Colors,Value,Tolerance,Power}{Row 1, Row 2, Row 3}

  \bigskip

  \mytable{Writing}[write]
       {Colors,Value,Power}
       {$A_1$, $D_2$, $R_1$, $S_3$}

  See Table~\ref{tab:Reading} and Table~\ref{tab:write}
\end{document}
  • Good working. But can [R] be replaced with variable letters? A_1, D_2, R_1 like Reading Measuring ... How do I eliminate the borders of the upper left cell? – Özgür Aug 12 '18 at 8:46
  • @Özgür See my edit -- almost... – Andrew Aug 12 '18 at 13:37
  • So, I'm waiting your edit. – Özgür Aug 12 '18 at 13:40
  • @Özgür Not sure what is causing the issue with the last row, Will look at this tomorrow. – Andrew Aug 12 '18 at 13:42
  • 2
    @Andrew Look at the \seq_map_inline:Nn \l_row_seq { ##1 \seq_map_inline:Nn \l_header_seq { & } \\\hline }-loop. Putting something behind the \\\hline that catches 3 arguments and shows them and puts them back yields that there is a not-vanishing sequence \__prg_break_point:Nn \seq_map_break: \__seq_pop_item_def: behind the \\\hline belonging to the last row-item. This non-vanishing sequence which seems to serve for terminating the loop yields an additional unwanted table-row. I suggest using a loop that works fully expandable. – Ulrich Diez Aug 13 '18 at 1:25
2

Your code looks good. Just add & for the missing column and a few % here and there and define a columntype Y and everything turns out nicely. :-)

\documentclass[a4paper,twoside,openright,12pt]{book}
\usepackage[left=1.5cm,right=1cm,top=2.5cm,bottom=2.5cm,marginparwidth=0cm,marginparsep=0cm,outer=1cm]{geometry}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{tabularx,colortbl}
\usepackage{showframe}

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

\newcommand{\only}[6]{% 
\begin{table}[h!]%
\caption{#1}%
\centering
\begin{tabularx}%
{\linewidth}{ l | Y | Y | Y | Y |}%
\cline{2-5}%
&  #2 &  #3 &  #4 &  #5 \\\hline
\multicolumn{1}{|l|}{$R_1$} &  &  &  & \\ \hline
\multicolumn{1}{|l|}{$R_2$} &  &  &  & \\ \hline
\multicolumn{1}{|l|}{$R_3$} &  &  &  & \\ \hline
\multicolumn{1}{|l|}{$R_4$} &  &  &  & \\ \hline 
\multicolumn{1}{|l|}{$R_5$} &  &  &  & \\ \hline        
\end{tabularx}%
\end{table}%
}

\begin{document}
\twocolumn

\only{Reading\label{tab:read}}{Colors}{Value}{Tolerance}{Power}

Table \ref{tab:read} is very important.
\end{document}

enter image description here


Off the cuff I can offer some nested looping for automatizing the creation of the tables.

\documentclass[a4paper,twoside,openright,12pt]{book}

\usepackage[left=1.5cm,right=1cm,top=2.5cm,%
            bottom=2.5cm,marginparwidth=0cm,%
            marginparsep=0cm,outer=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
%\usepackage{lmodern}
\usepackage{tabularx,colortbl}
%\usepackage{showframe}

\makeatletter
%%-------------------------------------------------------------------------
%% Paraphernalia:
%%.........................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@bracestripexchange[2]{#2#1}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% \UD@ActOnFirstListElement{<action>}%
%%                       {<action when no (more) arguments are in list>}%
%%                       {<preset>}%
%%                       {{<e_k>}{<e_(k+1)>}..{<e_n>}}%
%% yields either: <action when no (more) arguments are in list><preset>
%%            or: <action>{<e_k>}<preset>{{<e_(k+1)>}..{<e_n>}}
%%
%%   (   The "list" in question is {<e_k>}{<e_(k+1)>}..{<e_n>}   )
%%.............................................................................
\newcommand\UD@KeepFirstTillSelDOM{}%
\long\def\UD@KeepFirstTillSelDOM#1#2\UD@SelDOM{{#1}}%
\newcommand\UD@ActOnFirstListElement[4]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#4.{}}%
  {#2#3}%
  {%
    \expandafter\expandafter
    \expandafter            \UD@ExtractFirstListElementLoop
    \expandafter\UD@bracestripexchange
    \expandafter{%
    \expandafter{%
    \UD@firstoftwo{}#4}}{{#4\UD@SelDOM}{#1}{#3}}%
  }%
}%
\newcommand\UD@ExtractFirstListElementLoop[3]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
  {#2#1#3}%
  {%
    \expandafter\UD@ExtractFirstListElementLoop
    \expandafter{%
    \UD@KeepFirstTillSelDOM#1}{#2}{#3}%
  }%
}%
%%-------------------------------------------------------------------------
%% David Kastrup's \replicate:
%%.........................................................................
%% <http://www.gust.org.pl/projects/pearls/2005p/david-kastrup/bachotex2005-david-kastrup-pearl3.pdf>
\newcommand\DK@recur[1]{\csname DK@rn#1\DK@recur}%
\newcommand\DK@rnm[1]{\endcsname{#1}#1}%
\newcommand\DK@rn[1]{}%
\newcommand\DK@replicate[1]{\csname DK@rn\expandafter\DK@recur
\romannumeral\number\number#1 000\endcsname\endcsname}%
%%-----------------------------------------------------------------------------
%% \CreateTable[<caption>]{<columns>}{<rows>}
%%     a caption will be placed only in case the optional
%%     <caption> is neither empty nor holding only a space token.
%%.............................................................................
\newcolumntype{Y}{>{\centering\arraybackslash}X}
\newcommand*\CreateTable[3][]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#2.{}}{%
    \@latex@error{No table-columns specified}{Specify at least one table-column.}%
  }{%
    \expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#3.{}}{%
      \@latex@error{No table-rows specified}{Specify at least one table-row.}%
    }{%
      \UD@ActOnFirstListElement{\@CreateTableHead}
                               {\@CreateTableRows{#3}{#1}}%
                               {%
                                  {1}{0}{}{l|}%
                                  {\@CreateTableHead}{\@CreateTableRows{#3}{#1}}%
                               }%
                               {#2}%
    }%
  }%
}%
\newcommand\@CreateTableHead[7]{%
  \begingroup
  \@tempcnta=#2\relax
  \advance\@tempcnta by 1\relax
  \expandafter\UD@bracestripexchange
  \expandafter{\expandafter{\expandafter{\the\@tempcnta}%
  %{#2}{#4&#1}{#5X|}{#6}{#7}}}%
  {#2}{#4&#1}{#5Y|}{#6}{#7}}}%
  {\endgroup\UD@ActOnFirstListElement{#6}{#7}}%
}%
%
\newcommand\@CreateTableRows[8]{%
  \begin{table}[h!]%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#2.{}}%
    {}{\caption{#2}}%
  \centering
  \begin{tabularx}{\linewidth}{#6}%
  \cline{2-#3}%
  #5\\\hline
  \UD@ActOnFirstListElement{\@CreateTableRow}%
                           {\expandafter\@gobbletwo\@gobble}%
                           {{#4}{\@CreateTableRow}{\expandafter\@gobbletwo\@gobble}}%
                           {#1}%
  \end{tabularx}%
  \end{table}%
}%
\newcommand\@CreateTableRow[4]{%
  \multicolumn{1}{|l|}{#1}\DK@replicate{#2}{&}\\\hline
  \UD@ActOnFirstListElement{#3}{#4}{{#2}{#3}{#4}}%
}%
\makeatother

\begin{document}

\CreateTable[Reading\label{tab:read}]%
            {{Colors}{Value}{Tolerance}{Power}}%
            {{$R_1$}{$R_2$}{$R_3$}{$R_4$}{$R_5$}}%

\CreateTable[AnotherReading\label{tab:anotherread}]%
            {%
              {Col 1}{Col 2}{Col 3}{Col 4}{Col 5}{Col 6}%
              {Col 7}{Col 8}{Col 9}{Col 10}{Col 11}{Col 12}%
            }%
            {%
              {$R_1$}{$R_2$}{$R_3$}{$R_4$}{$R_5$}%
              {$R_6$}{$R_7$}{$R_8$}{$R_9$}{$R_{10}$}%
            }%

\end{document}

enter image description here


An approach using expl3-Syntax could be:

\documentclass[a4paper,twoside,openright,12pt]{book}
\usepackage[left=1.5cm,right=1cm,top=2.5cm,%
            bottom=2.5cm,marginparwidth=0cm,%
            marginparsep=0cm,outer=1cm]{geometry}
\usepackage{xparse}
\usepackage{tabularx}

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

\ExplSyntaxOn
\seq_new:N \l_header_seq
\seq_new:N \l_row_seq
\int_new:N \l_columns_int
\cs_new:Npn \row_add_mc:n #1
{
  #1\seq_map_function:NN \l_header_seq \emptycell_add_mc:n\\\hline
}

\cs_new:Npn \emptycell_add_mc:n #1
{
  & 
}

\cs_new:Npn \headcell_add_mc:n #1
{
  & #1
}

% \mytable{caption}[label]{column headers}{row headers}
\NewDocumentCommand\CreateTable{ m O{#1} mm}{
  \seq_set_from_clist:Nn \l_header_seq {#3}
  \seq_set_from_clist:Nn \l_row_seq {#4}
  \int_set:Nn \l_columns_int {\seq_count:N \l_header_seq }
  \begin{table}[h!]
    \centering
    \caption{#1}\label{tab:#2}%
    \begin{tabularx}{\linewidth}{|l *{\l_columns_int}{|Y}|}%
      \cline{2-\int_eval:n{ \l_columns_int+1} }%
      \multicolumn{1}{c|}{}\seq_map_function:NN \l_header_seq \headcell_add_mc:n\\\hline
      \seq_map_function:NN \l_row_seq \row_add_mc:n
    \end{tabularx}%
  \end{table}%
}
\ExplSyntaxOff

\begin{document}

\CreateTable{Reading}[read]{Colors,Value,Tolerance,Power}{$R_1$,$R_2$,$R_3$,$R_4$,$R_5$}

\bigskip

\CreateTable{Another Reading}[anotherread]
        {Col 1,Col 2,Col 3,Col 4,Col 5,Col 6, Col 7,Col 8,Col 9,Col 10,Col 11,Col 12 }
        {$R_1$, $R_2$, $R_3$, $R_4$, $R_5$, $R_6$, $R_7$, $R_8$, $R_9$, $R_{10}$}

See Table~\ref{tab:read} and Table~\ref{tab:anotherread}
\end{document}
  • Your code is good working. Also I will consider your warnings. – Özgür Aug 12 '18 at 18:33
  • It is important to me to get 'warnings' from knowledgeable and experienced people like you. Please warn me always. ;-) Have a good day. – Özgür Aug 12 '18 at 18:47

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.