Precisa de uma macro para tabelas - independente do tamanho da linha e da coluna

Precisa de uma macro para tabelas - independente do tamanho da linha e da coluna

Eu criei a seguinte macro para Tabela:

\newcommand{\createtable}[7]{
\begin{table}[htbp]
\begin{tabular}{|p{8cm}||p{8cm}|}
\hline
\begin{center}\textbf{\cellcolor{Orchid!25}{#1}}\end{center} &
\begin{center}\textbf{\cellcolor{Orchid!25}{#2}}\end{center} \\
\hline\hline
 {#3} 
 & {#4}\\
 \hline
 {#5}
 & {#6}\\ 
\hline
    \end{tabular}%
 \centering
 \caption{#7}
\end{table}
}

Uso:

\createtable
    {Label1} 
    {Label2}
    {Text1-1}
    {Text2-1}
    {Text1-2}
    {Text2-2}
    {Table Title}

Saída:

insira a descrição da imagem aqui

Problema:

Referência: \newcommand com argumento multilinha opcional e ambiente de itemização implícito

Aqui, podemos criar uma lista dinâmica com marcadores, sem nenhum conhecimento prévio da quantidade de itens.

Preciso de uma macro semelhante para tabelas, para que se eu escrever:

\createtable
  {Label1}
  {Label2}
  {Label3}
  {Text1-Label1
   \&
   Text1-Label2
   \&
   Text1-Label3
   \\
   Text2-Label1
   \&
   Text2-Label2
   \& 
   Text2-Label3
}   

A macro deve ser inteligente o suficiente para descobrir que:

[1] Table has 3 columns -- Label1, Label2 and Label3
[2] Distribute the text-input separated by \& among these columns, i.e. 
   Text1-Label1 under Label1, Text1-Label2 under Label2 and Text1-Label3 under Label3

[3] Identify the end of row marker as "//"
    and add further entries (using the procedure described in 
    point [2]) to the next row. 

Alguém pode fornecer algumas dicas.

Isto é o que tentei inicialmente:

\ExplSyntaxOn
\NewDocumentCommand{\testtable}{ m o }
{
  % split the \\ separated list of items
  \seq_set_split:Nnn \l_egreg_outline_items_seq { \\ } { #1 }
\begin{tabular}{|p{8cm}||p{8cm}|}
\hline
\begin{center}\textbf{\cellcolor{Orchid!25}{Column1}}\end{center} &
\begin{center}\textbf{\cellcolor{Orchid!25}{Column2}}\end{center} \\
\hline\hline
  \seq_map_inline:Nn \l_egreg_outline_items_seq
   {
    ##1 %\hline
   }
    \end{tabular}%
}
\ExplSyntaxOff

Se não pudermos fornecer o número de colunas em tempo de execução, tudo bem, mas o número de linhas deve ser adicionado dinamicamente.

Responder1

Sugiro o uso da \createtableseguinte forma:

\createtable 3 {3cm}
  {Label1}        {Label2}       {Label3}
  {Text1-Label1 | Text1-Label2 | Text1-Label3 |
   Text2-Label1 | Text2-Label2 | Text2-Label3 }
  {Table title}

Você pode ver que deve especificar o número de colunas (3 no exemplo) e a largura das colunas (3cm no exemplo). Você está usando uma largura de coluna fixa em seu exemplo, portanto há um bom motivo para especificá-la.

A implementação deverá ser:

\newcount\tmpnum   
\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}

\def\createtable#1#2{\def\tabcols{#1}\def\colwidth{#2}%
   \def\tabdata{}\def\tabdataA{}\tmpnum=0 \createtableA}
\def\createtableA#1{\advance\tmpnum by1
   \addto\tabdata{\begin{center}\textbf{\cellcolor{red!25}{#1}}\end{center}}%
   \addto\tabdataA{|p{\colwidth}|}%
   \ifnum\tabcols>\tmpnum
      \addto\tabdata{&}\expandafter\createtableA
   \else
      \addto\tabdata{\\ \hline\hline}\expandafter\createtableB
   \fi
}
\def\createtableB#1{\tmpnum=0 \createtableC#1||}
\def\createtableC#1|{\ifx|#1|\expandafter\createtableD\else   
   \advance\tmpnum by1
   \ifnum\tabcols=\tmpnum \addto\tabdata{{#1}\\ \hline}\tmpnum=0
   \else \addto\tabdata{{#1}&}%
   \fi
   \expandafter\createtableC \fi
}
\def\createtableD#1{%
   \begin{table}[htbp]
   \edef\tmp{\noexpand\begin{tabular}{\tabdataA}}\tmp
   \hline
   \tabdata
   \end{tabular}
   \centering\caption{#1}
   \end{table}
}

Responder2

Se você inserir os rótulos em um argumento único, será fácil descobrir o número de colunas.

\documentclass{article}
\usepackage{xparse}
\usepackage[table]{xcolor}
\usepackage{tabularx}
\usepackage{booktabs}

\ExplSyntaxOn
\NewDocumentCommand{\createtable}{mm}
 {
  \sandeep_ct_create_table:nn { #1 } { #2 }
 }

\int_new:N \l_sandeep_ct_cols_int
\seq_new:N \l_sandeep_ct_head_input_seq
\seq_new:N \l_sandeep_ct_head_output_seq
\seq_new:N \l_sandeep_ct_table_body_seq

\cs_new_protected:Npn \sandeep_ct_create_table:nn #1 #2
 {
  \seq_set_split:Nnn \l_sandeep_ct_head_input_seq { & } { #1 }
  \int_set:Nn \l_sandeep_ct_cols_int
   {
    \seq_count:N \l_sandeep_ct_head_input_seq
   }
  \seq_set_map:NNn \l_sandeep_ct_head_output_seq \l_sandeep_ct_head_input_seq
   {
    \exp_not:n { \multicolumn{1}{c}{\ctbigstrut\bfseries ##1} }
   }
  \seq_set_split:Nnn \l_sandeep_ct_table_body_seq { \\ } { #2 }
  \begin{tabularx}{\columnwidth}{*{\l_sandeep_ct_cols_int}{X}}
  \toprule
  \addlinespace[0pt]
  \rowcolor{orchid}
  \seq_use:Nn \l_sandeep_ct_head_output_seq { & } \\
  \addlinespace[0pt]
  \midrule
  \seq_use:Nn \l_sandeep_ct_table_body_seq { \\ \addlinespace }
  \\
  \bottomrule
  \end{tabularx}
 }

\ExplSyntaxOff

\newcommand{\ctbigstrut}{%
  \vrule height .8cm
         depth \dimexpr.8cm-\ht\strutbox\relax
         width 0pt
}

\definecolor{orchid}{RGB}{242,213,230}

\begin{document}

\noindent
\createtable
 {
  Label 1 & Label 2
 }
 {
  Text1-Label1
  &
  Text1-Label2
  \\
  Text2-Label1
  &
  Text2-Label2
}   

\bigskip

\noindent
\createtable
 {
  Label 1 & Label 2 & Label 3
 }
 {
  Text1-Label1
  &
  Text1-Label2
  &
  Text1-Label3
  \\
  Text2-Label1
  &
  Text2-Label2
  & 
  Text2-Label3
 }

\end{document}

O primeiro argumento é dividido em &para contar o número de colunas; os itens são então colocados como argumento de \multicolumn.

Em seguida, dividimos o corpo da tabela \\para poder adicionar \addlinespaceentre as linhas.

insira a descrição da imagem aqui

informação relacionada