Нужен макрос для таблиц — независимо от размера строк и столбцов

Нужен макрос для таблиц — независимо от размера строк и столбцов

Я создал следующий макрос для таблицы:

\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}
}

Использование:

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

Выход:

введите описание изображения здесь

Проблема:

Ссылка: \newcommand с необязательным многострочным аргументом и неявной средой itemize

Здесь мы можем создать динамический маркированный список, не имея никаких предварительных сведений о количестве элементов.

Мне нужен аналогичный макрос для таблиц, чтобы если я напишу:

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

Макрос должен быть достаточно интеллектуальным, чтобы понять, что:

[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. 

Может ли кто-нибудь дать какие-нибудь указания?

Вот что я попробовал изначально:

\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

Если мы не можем указать количество столбцов во время выполнения, это нормально, но количество строк следует добавлять динамически.

решение1

Я предлагаю использовать его \createtableследующим образом:

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

Вы видите, что вам необходимо указать количество столбцов (3 в примере) и ширину столбцов (3 см в примере). Вы используете фиксированную ширину столбца в своем примере, поэтому есть веская причина указать ее.

Реализация должна быть:

\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}
}

решение2

Если ввести метки в уникальный аргумент, то легко подсчитать количество столбцов.

\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}

Первый аргумент разделяется для &подсчета количества столбцов; затем элементы помещаются в качестве аргумента \multicolumn.

Затем мы разделяем тело таблицы, \\чтобы иметь возможность добавлять данные \addlinespaceмежду строками.

введите описание изображения здесь

Связанный контент