首先:这个问题类似于使用 \multido (或类似方法)生成表中的行。
考虑以下代码:
\documentclass{article}
\usepackage{siunitx}
\usepackage{multido}
\usepackage{booktabs}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\newcommand*\nederst[1]{\calc{#1*(#1+1)/2}}
\newcommand*\iAlt[1]{\calc{#1*(#1+1)*(#1+2)/6}}
\begin{document}
\makeatletter
\newcommand*\skyIDtable{}
\multido{\i = 1+1}{6}{%
\protected@xdef\skyIDtable{\skyIDtable \i & \i & \i & \nederst{\i} & \iAlt{\i}\\}
}
\makeatother
\begin{table}
\centering
\begin{tabular}{
*{3}{S[table-format = 1]}
*{2}{S[table-format = 2]}
}
\toprule
{Long text~A} & {Long text~B} & {Long text~C} & {Long text~D} & {Long text~E} \\
\midrule
\skyIDtable
\bottomrule
\end{tabular}
\end{table}
\end{document}
我想交换列和行以获得以下内容:
我怎么做?
答案1
代码更复杂,但语法更简单:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[danish]{babel}
\usepackage{xparse,siunitx,booktabs}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\nederst}{m}
{
\fp_eval:n { #1 * (#1+1)/2 }
}
\DeclareExpandableDocumentCommand{\iAlt}{m}
{
\fp_eval:n { #1 * ( #1 + 1 ) * ( #1 + 2 ) / 6 }
}
\NewDocumentCommand{\printtable}{smmmm}
{% * = transpose
% #2 = number of iterations
% #3 = column/row headers
% #4 = table preamble
% #5 = entry specs
\svend_preparetable:nnn { #2 } { #3 } { #5 }
\IfBooleanTF{#1}
{ \__svend_make_table_rows:nn { #3 } { #4 } }
{ \__svend_make_table_columns:nn { #3 } { #4 } }
}
\tl_new:N \l_svend_tablebody_tl
\prop_new:N \l_svend_entries_prop
\int_new:N \l_svend_rows_int
\int_new:N \l_svend_columns_int
\cs_new:Npn \svend_prop_item:Nnn #1 #2 #3
{
\prop_item:Nn #1 { #2, #3 }
}
\cs_generate_variant:Nn \svend_prop_item:Nnn { Nnf , Nfn }
\cs_new_protected:Npn \svend_preparetable:nnn #1 #2 #3
{% #1=iterations; #2=column/row headers; #3=specs
\int_set:Nn \l_svend_columns_int { \clist_count:n { #2 } }
\int_set:Nn \l_svend_rows_int { #1 }
\prop_clear:N \l_svend_entries_prop
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\prop_put:Nnf \l_svend_entries_prop { ##1,####1 }
{
\clist_item:nn { #3 } { ####1 }
}
}
}
}
\cs_generate_variant:Nn \prop_put:Nnn { Nnf }
\cs_new_protected:Npn \__svend_make_table_columns:nn #1 #2
{
% start making the table body
\tl_set:Nn \l_svend_tablebody_tl
{
\begin{tabular}{ #2 }\toprule
}
% the header row
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ##1 == 1 } { & }
{ \clist_item:nn { #1 } { ##1 } }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ \midrule } % finish the row
% the table body proper
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ####1 == 1 } { & }
\svend_prop_item:Nnn \l_svend_entries_prop { ##1 } { ####1 }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ }
}
% finish up the table body
\tl_put_right:Nn \l_svend_tablebody_tl { \bottomrule \end{tabular} }
% produce the table
\tl_use:N \l_svend_tablebody_tl
}
\cs_new_protected:Npn \__svend_make_table_rows:nn #1 #2
{
% start building the table body
\tl_set:Nn \l_svend_tablebody_tl
{
\begin{tabular}{ #2 }\toprule
}
% the table body proper
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\clist_item:nn { #1 } { ##1 } &
}
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ####1 == 1 } { & }
\svend_prop_item:Nnn \l_svend_entries_prop { ####1 } { ##1 }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ }
}
% finish up the table body
\tl_put_right:Nn \l_svend_tablebody_tl { \bottomrule \end{tabular} }
% produce the table
\tl_use:N \l_svend_tablebody_tl
}
\cs_generate_variant:Nn \prop_item:Nn { Nx }
\ExplSyntaxOff
\begin{document}
\printtable
{6}
{ Long text A, Long text B, Long text C, Long text D, Long text E }
{ *{3}{S[table-format = 1]} *{2}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable*
{6}
{ Opstillingsnummer, Antal lag, Antal bægre i bundes side,
Antal bægre i nederste lag, Antal bægre i optillingen }
{ l *{6}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable
{7}
{ Long text A, Long text B, Long text C, Long text D, Long text E }
{ *{3}{S[table-format = 1]} *{2}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable*
{7}
{ Opstillingsnummer, Antal lag, Antal bægre i bundes side,
Antal bægre i nederste lag, Antal bægre i optillingen }
{ l *{7}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\end{document}
表条目经过计算并存储在属性列表中,由 索引row,column
。
然后按列(无*)或按行打印表,从属性列表中收集适当的索引。
第一个参数是迭代次数,第二个参数是列或行标题的逗号分隔列表(用于确定列/行的数量),第三个参数是表格前言;最后是说明符,其中#1
用于当前整数。
答案2
我展示了普通的 TeX 类解决方案,但它在 LaTeX 中也有效,因为只\newcount
使用了 eTeX 基元和宏。我们不需要任何 LaTeX 包。
\def\nederst#1{\the\numexpr #1*(#1+1)/2 \relax}
\def\iAlt#1{\the\numexpr #1*(#1+1)*(#1+2)/6 \relax}
\newcount\i \i=1
\def\skyIDtable{
\the\i & \the\i & \the\i & \hbox to1em{\hss\nederst\i} & \hbox to1em{\hss\iAlt\i}
\global\advance\i by 1
\ifnum\i<7 \global\let\next=\skyIDtable \else \global\let\next=\empty \global\i=1 \fi
\cr \next
}
\def\trline#1{#11 & #12 & #13 & #14 & #15 & #16 \cr}
\def\skyIDtableT{
Opstillingsnummer & \trline\relax
Antal lag & \trline\relax
Antal bægre i bundes side & \trline\relax
Antal bægre i nederste lag & \trline\nederst
Antal bægre i optillingen & \trline\iAlt
}
\def\toprule{\noalign{\smallskip\hrule height1pt\smallskip}}\let\botrule=\toprule
\def\midrule{\noalign{\smallskip\hrule\smallskip}}
Normal table:
\hfil\vbox{\halign{&\enspace\hfil#\unskip\hfil\enspace \cr
\toprule
Long text A & Long text B & Long text C & Long text D & Long text E \cr
\midrule
\skyIDtable
\botrule
}}
Transposed table:
\hfil\vbox{\halign{\enspace #\unskip\enspace\hfil&&\enspace\hfil#\unskip\enspace\cr
\toprule
\skyIDtableT
\botrule
}}
\bye
答案3
转置并不那么简单。你必须逐行循环:
\documentclass{article}
\usepackage{siunitx,multido,booktabs}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\newcommand*\nederst[1]{\calc{#1*(#1+1)/2}}
\newcommand*\iAlt[1]{\calc{#1*(#1+1)*(#1+2)/6}}
\begin{document}
\centering
\makeatletter
\newcommand\skyIDtable{}
\multido{\i=1+1}{6}{% Construct 6 rows
\protected@xdef\skyIDtable{\skyIDtable \i & \i & \i & \nederst{\i} & \iAlt{\i}\protect\\}%
}
\makeatother
\begin{tabular}{
*{3}{S[table-format = 1]}
*{2}{S[table-format = 2]}
}
\toprule
{Long text~A} & {Long text~B} & {Long text~C} & {Long text~D} & {Long text~E} \\
\midrule
\skyIDtable
\bottomrule
\end{tabular}
\bigskip
% Transposed table
\makeatletter
\newcommand\skyIDtableT{Long text A}% First column ID
\multido{\i = 1+1}{6}{\protected@xdef\skyIDtableT{\skyIDtableT & \i}}% Add first row entries
\g@addto@macro{\skyIDtableT}{\protect\\ Long text B}% Add another first column ID
\multido{\i = 1+1}{6}{\protected@xdef\skyIDtableT{\skyIDtableT & \i}}% Add second row entries
\g@addto@macro{\skyIDtableT}{\protect\\ Long text C}% Add another first column ID
\multido{\i = 1+1}{6}{\protected@xdef\skyIDtableT{\skyIDtableT & \i}}% Add third row entries
\g@addto@macro{\skyIDtableT}{\protect\\ Long text D}% Add another first column ID
\multido{\i = 1+1}{6}{\protected@xdef\skyIDtableT{\skyIDtableT & \nederst{\i}}}% Add fourth row entries
\g@addto@macro{\skyIDtableT}{\protect\\ Long text E}% Add another first column ID
\multido{\i = 1+1}{6}{\protected@xdef\skyIDtableT{\skyIDtableT & \iAlt{\i}}}% Add fifth row entries
\makeatother
\begin{tabular}{
l
*{6}{S[table-format = 2]}
}
\toprule
\skyIDtableT \\% Insert constructed table
\bottomrule
\end{tabular}
\end{document}