
Ich habe das folgende Makro für Table erstellt:
\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}
}
Verwendung:
\createtable
{Label1}
{Label2}
{Text1-1}
{Text2-1}
{Text1-2}
{Text2-2}
{Table Title}
Ausgabe:
Problem:
Referenz: \newcommand mit optionalem mehrzeiligem Argument und impliziter Itemize-Umgebung
Hier können wir eine dynamische Aufzählungsliste erstellen, ohne dass wir die Anzahl der Elemente im Voraus kennen.
Ich brauche ein ähnliches Makro für Tabellen, sodass, wenn ich Folgendes schreibe:
\createtable
{Label1}
{Label2}
{Label3}
{Text1-Label1
\&
Text1-Label2
\&
Text1-Label3
\\
Text2-Label1
\&
Text2-Label2
\&
Text2-Label3
}
Das Makro sollte intelligent genug sein, um Folgendes herauszufinden:
[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.
Kann mir jemand bitte ein paar Hinweise geben?
Folgendes habe ich zunächst versucht:
\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
Wenn wir die Anzahl der Spalten nicht zur Laufzeit angeben können, ist das in Ordnung, aber die Anzahl der Zeilen sollte dynamisch hinzugefügt werden.
Antwort1
\createtable
Ich schlage die folgende Verwendung vor :
\createtable 3 {3cm}
{Label1} {Label2} {Label3}
{Text1-Label1 | Text1-Label2 | Text1-Label3 |
Text2-Label1 | Text2-Label2 | Text2-Label3 }
{Table title}
Sie sehen, dass Sie die Anzahl der Spalten (im Beispiel 3) und die Breite der Spalten (im Beispiel 3 cm) angeben müssen. Sie verwenden in Ihrem Beispiel eine feste Spaltenbreite, es gibt also einen guten Grund, diese anzugeben.
Die Implementierung sollte sein:
\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}
}
Antwort2
Wenn Sie die Beschriftungen in einem eindeutigen Argument eingeben, können Sie die Anzahl der Spalten leicht ermitteln.
\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}
Das erste Argument wird bei aufgeteilt, &
um die Anzahl der Spalten zu zählen; die Elemente werden dann als Argument von eingesetzt \multicolumn
.
Anschließend teilen wir den Tabellenkörper auf, \\
um \addlinespace
zwischen den Zeilen addieren zu können.