Automatisches Generieren einer Tabelle mit \multido

Automatisches Generieren einer Tabelle mit \multido

Erstens: Diese Frage ist ähnlichGenerieren Sie Zeilen in der Tabelle mit \multido (oder etwas Ähnlichem)..

Betrachten Sie den folgenden Code:

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

Ausgabe

Ich möchte die Spalten mit den Zeilen vertauschen, um folgendes zu erhalten:

gesucht

Wie mache ich das?

Antwort1

Komplizierterer Code, aber viel einfachere Syntax:

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

Bildbeschreibung hier eingeben

Die Tabelleneinträge werden berechnet und in einer Eigenschaftenliste gespeichert, indiziert durch row,column.

Anschließend wird die Tabelle spaltenweise (kein *) oder zeilenweise ausgedruckt, wobei der entsprechende Index aus der Eigenschaftenliste entnommen wird.

Das erste Argument ist die Nummer der Iteration, das zweite Argument ist die durch Kommas getrennte Liste der Spalten- oder Zeilenüberschriften (wird zum Bestimmen der Anzahl der Spalten/Zeilen verwendet), das dritte Argument ist die Tabellenpräambel; schließlich kommen die Spezifizierer, die #1für die aktuelle Ganzzahl verwendet werden.

Antwort2

Ich zeige die einfache TeX-ähnliche Lösung, aber sie funktioniert auch in LaTeX, da nur eTeX-Grundelemente und \newcountMakros verwendet werden. Wir benötigen keine LaTeX-Pakete.

\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

Antwort3

Die Transposition ist nicht ganz so einfach. Sie müssen jede Zeile einzeln durchgehen:

Bildbeschreibung hier eingeben

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

verwandte Informationen