
Я создал следующий макрос для таблицы:
\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
между строками.