使用 \multido 自動產生表

使用 \multido 自動產生表

第一:這個問題類似使用 \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}

相關內容