\newcommand 带有多个参数,用于生成表

\newcommand 带有多个参数,用于生成表

我想创建一个可以生成如下表格的宏:

\documentclass{minimal}

\begin{document}

\begin{tabular}{c|c|c}
  A & 1 & 2 & 3 \\
  B & 0 & 1 & 1 \\
  C & 0 & 0 & 1
\end{tabular}

\end{document}

我希望能够定义一个\columns{1,2,3}包含每列标题的列表,以及一个\rows{A,B,C}包含每行第一个元素的列表。

对于其余的条目,也许是类似的\entries{011,001},我不确定最好的方法是什么。

最终,我想要一个具有类似语法的宏

\mymacro{\columns}{\rows}{\entries}

我最近才开始编写自己的宏,但我还没有找到任何能满足我要求的东西,也不知道该如何进行。

谢谢!

答案1

有趣的问题,但是真的有好处吗?

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
% user interface
\NewDocumentCommand{\mymacro}{mmm}
 {% #1 = column headers, #2 = row headers, #3 = entries
  \gabriel_mymacro:nnn { #1 } { #2 } { #3 }
 }

% variables
\tl_new:N \l__gabriel_mymacro_body_tl
\tl_new:N \l__gabriel_mymacro_row_tl
\seq_new:N \l__gabriel_mymacro_entries_seq

% functions
\cs_new_protected:Nn \gabriel_mymacro:nnn
 {
  % clear the tl containing the body and collect the entries
  \tl_clear:N \l__gabriel_mymacro_body_tl
  \seq_set_split:Nnn \l__gabriel_mymacro_entries_seq { , } { #3 }
  % make the first row
  \tl_put_right:Nx \l__gabriel_mymacro_body_tl
   {
    \clist_item:nn { #2 } { 1 }
   }
  \clist_map_function:nN { #1 } \__gabriel_mymacro_add_entry:n
  \tl_put_right:Nn \l__gabriel_mymacro_body_tl { \\ \hline }
  % build the following rows
  \int_step_inline:nn { \clist_count:n { #2 } - 1 }
   {
    \tl_put_right:Nx \l__gabriel_mymacro_body_tl
     {
      \clist_item:nn { #2 } { ##1 + 1 }
     }
    \seq_pop_left:NN \l__gabriel_mymacro_entries_seq \l__gabriel_mymacro_row_tl
    \tl_map_function:NN \l__gabriel_mymacro_row_tl \__gabriel_mymacro_add_entry:n
    \tl_put_right:Nn \l__gabriel_mymacro_body_tl { \\ }
   }
  % typeset the table
  \begin{tabular}{c *{ \clist_count:n { #1 } } { |c } }
  \tl_use:N \l__gabriel_mymacro_body_tl
  \end{tabular}
 }

\cs_new_protected:Nn \__gabriel_mymacro_add_entry:n
 {
  \tl_put_right:Nn \l__gabriel_mymacro_body_tl { & #1 }
 }

\ExplSyntaxOff

\begin{document}

\mymacro{1,2,3}{A,B,C}{011,001}

\bigskip

\mymacro{Apple,Banana,Cherry,Date}{X,Apple,Banana,Cherry,Date}{
 0000,0101,1111,1010
}

\end{document}

在此处输入图片描述

带有可选参数的变体,用于指定列对齐。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
% user interface
\NewDocumentCommand{\mymacro}{ommm}
 {% #2 = column headers, #3 = row headers, #4 = entries
  \IfNoValueTF { #1 }
   {
    \gabriel_mymacro:nnnn { c *{ \clist_count:n { #2 } } { |c } } { #2 } { #3 } { #4 }
   }
   {
    \gabriel_mymacro:nnnn { #1 } { #2 } { #3 } { #4 }
   }
 }

% variables
\tl_new:N \l__gabriel_mymacro_body_tl
\tl_new:N \l__gabriel_mymacro_row_tl
\seq_new:N \l__gabriel_mymacro_entries_seq

% functions
\cs_new_protected:Nn \gabriel_mymacro:nnnn
 {
  % clear the tl containing the body and collect the entries
  \tl_clear:N \l__gabriel_mymacro_body_tl
  \seq_set_split:Nnn \l__gabriel_mymacro_entries_seq { , } { #4 }
  % make the first row
  \tl_put_right:Nx \l__gabriel_mymacro_body_tl
   {
    \clist_item:nn { #3 } { 1 }
   }
  \clist_map_function:nN { #2 } \__gabriel_mymacro_add_entry:n
  \tl_put_right:Nn \l__gabriel_mymacro_body_tl { \\ \hline }
  % build the following rows
  \int_step_inline:nn { \clist_count:n { #3 } - 1 }
   {
    \tl_put_right:Nx \l__gabriel_mymacro_body_tl
     {
      \clist_item:nn { #3 } { ##1 + 1 }
     }
    \seq_pop_left:NN \l__gabriel_mymacro_entries_seq \l__gabriel_mymacro_row_tl
    \tl_map_function:NN \l__gabriel_mymacro_row_tl \__gabriel_mymacro_add_entry:n
    \tl_put_right:Nn \l__gabriel_mymacro_body_tl { \\ }
   }
  % typeset the table
  \begin{tabular}{#1}
  \tl_use:N \l__gabriel_mymacro_body_tl
  \end{tabular}
 }

\cs_new_protected:Nn \__gabriel_mymacro_add_entry:n
 {
  \tl_put_right:Nn \l__gabriel_mymacro_body_tl { & #1 }
 }

\ExplSyntaxOff

\begin{document}

\mymacro{1,2,3}{A,B,C}{011,001}

\bigskip

\mymacro{Apple,Banana,Cherry,Date}{X,Apple,Banana,Cherry,Date}{
 0000,0101,1111,1010
}

\bigskip

\mymacro[l|cccc]{Apple,Banana,Cherry,Date}{X,Apple,Banana,Cherry,Date}{
 0000,0101,1111,1010
}

\end{document}

在此处输入图片描述

相关内容