如何定义这个快速表宏?

如何定义这个快速表宏?

我可以使用它来生成一个简单的表格:

\documentclass{article}
\begin{document}
\begin{tabular}{|p{.25\textwidth}|p{.25\textwidth}|p{.5\textwidth}|}\hline
&&\\\hline
&&\\\hline
\end{tabular}
\end{document}

我需要一个\newcommand\quicktable{........},并且可以像这样使用它:

\quicktable{1:1:2}{
&&\\\hline
&&\\\hline
}

答案1

xparse下面是使用和的实现expl3

其思路是先将“多比率”中的项相加,从而确定模数。然后构建一个合适的前言,将每一项乘以模数,再减去两倍\tabcolsep

我已经设置好了一些东西,所以你不需要输入\hline

可选参数默认为\columnwidth,但你可以尝试

\quicktable[10cm]{1:2:1}{&&\\&&}

并查看结果。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\quicktable}{ O{\columnwidth} m m }
 {
  \zenoshuai_quicktable:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l__zenoshuai_quicktable_header_seq
\seq_new:N \l__zenoshuai_quicktable_body_seq
\tl_new:N \l__zenoshuai_quicktable_header_tl
\dim_new:N \l__zenoshuai_quicktable_modulus_dim

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }

\cs_new_protected:Nn \zenoshuai_quicktable:nnn
 {
  \seq_set_split:NVn \l__zenoshuai_quicktable_header_seq \c_colon_str { #2 }
  \dim_set:Nn \l__zenoshuai_quicktable_modulus_dim
   {
    #1/(\seq_use:Nn \l__zenoshuai_quicktable_header_seq { + })
   }
  \tl_set:Nx \l__zenoshuai_quicktable_header_tl
   {
    |\seq_map_function:NN \l__zenoshuai_quicktable_header_seq \__zenoshuai_quicktable_col:n
   }
  \__zenoshuai_quicktable_body:Vn \l__zenoshuai_quicktable_header_tl { #3 }
 }

\cs_new:Nn \__zenoshuai_quicktable_col:n
 {
  p { \dim_eval:n { #1\l__zenoshuai_quicktable_modulus_dim - 2\tabcolsep } }|
 }

\cs_new_protected:Nn \__zenoshuai_quicktable_body:nn
 {
  \seq_set_split:Nnn \l__zenoshuai_quicktable_body_seq { \\ } { #2 }
  \begin{tabular}{#1}
  \hline
  \seq_use:Nn \l__zenoshuai_quicktable_body_seq { \\ \hline } \\
  \hline
  \end{tabular}
 }
\cs_generate_variant:Nn \__zenoshuai_quicktable_body:nn { V }

\ExplSyntaxOff

\begin{document}

\noindent X\hrulefill X

\bigskip

\noindent
\quicktable{1:1:2}{
&&\\
&&
}

\bigskip

\noindent
\quicktable{2:2:6}{
&&\\
&&
}

\bigskip

\noindent
\quicktable{1:1:1:1}{
&&&\\
&&&
}

\end{document}

在此处输入图片描述

稍微复杂一点的版本在array加载时也可以工作。

\documentclass{article}
\usepackage{xparse,array}

% important: code should go after \usepackage{array} or any package that loads it
\ExplSyntaxOn

\bool_new:N \g_zenoshuai_quicktable_array_bool
\use:c { @ifpackageloaded } { array }
 {
  \bool_gset_true:N \g_zenoshuai_quicktable_array_bool
 }
 {
  \bool_gset_false:N \g_zenoshuai_quicktable_array_bool
 }

\NewDocumentCommand{\quicktable}{ O{\columnwidth} m m }
 {
  \zenoshuai_quicktable:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l__zenoshuai_quicktable_header_seq
\seq_new:N \l__zenoshuai_quicktable_body_seq
\tl_new:N \l__zenoshuai_quicktable_header_tl
\dim_new:N \l__zenoshuai_quicktable_modulus_dim

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }

\cs_new_protected:Nn \zenoshuai_quicktable:nnn
 {
  \seq_set_split:NVn \l__zenoshuai_quicktable_header_seq \c_colon_str { #2 }
  \dim_set:Nn \l__zenoshuai_quicktable_modulus_dim
   {
    \bool_if:NTF \g_zenoshuai_quicktable_array_bool
     {(#1 - \int_eval:n { \seq_count:N \l__zenoshuai_quicktable_header_seq +1 }\arrayrulewidth) }
     { #1 }
    /(\seq_use:Nn \l__zenoshuai_quicktable_header_seq { + })
   }
  \tl_set:Nx \l__zenoshuai_quicktable_header_tl
   {
    |\seq_map_function:NN \l__zenoshuai_quicktable_header_seq \__zenoshuai_quicktable_col:n
   }
  \__zenoshuai_quicktable_body:Vn \l__zenoshuai_quicktable_header_tl { #3 }
 }

\cs_new:Nn \__zenoshuai_quicktable_col:n
 {
  p { \dim_eval:n { #1\l__zenoshuai_quicktable_modulus_dim - 2\tabcolsep } }|
 }

\cs_new_protected:Nn \__zenoshuai_quicktable_body:nn
 {
  \seq_set_split:Nnn \l__zenoshuai_quicktable_body_seq { \\ } { #2 }
  \begin{tabular}{#1}
  \hline
  \seq_use:Nn \l__zenoshuai_quicktable_body_seq { \\ \hline } \\
  \hline
  \end{tabular}
 }
\cs_generate_variant:Nn \__zenoshuai_quicktable_body:nn { V }

\ExplSyntaxOff

\begin{document}

\noindent X\hrulefill X

\bigskip

\noindent
\quicktable{1:1:2}{
&&\\
&&
}

\bigskip

\noindent
\quicktable{2:2:6}{
&&\\
&&
}

\bigskip

\noindent
\quicktable{1:1:1:1}{
&&&\\
&&&
}

\end{document}

答案2

以下使用tabularx及其X-type 列(尽管这不是必需的)。它的工作方式与@Werner 的答案类似,即对比率求和,然后再次使用序列的条目来设置每列的宽度。它\hline在表格内容的前后添加。

\documentclass[]{article}

\usepackage{xparse}
\usepackage{tabularx}

\ExplSyntaxOn
\seq_new:N \l__zeno_shuai_columnratios_seq
\int_new:N \l__zeno_shuai_column_count_int
\tl_new:N \l__zeno_shuai_columns_tl
\cs_new_protected:Npn \__zeno_shuai_set_columns:n #1
  {
    \tl_put_right:Nx \l__zeno_shuai_columns_tl
      {
        >{
        \exp_not:n { \hsize = }
        \fp_eval:n
          { #1 * \l__zeno_shuai_column_count_int / \l__zeno_shuai_ratio_sum_fp }
        \exp_not:n { \hsize \linewidth = \hsize }
        }X|
      }
  }
\cs_new_protected:Npn \__zeno_shuai_sum_ratios:n #1
  {
    \fp_add:Nn \l__zeno_shuai_ratio_sum_fp { #1 } 
  }
\cs_new_protected:Npx \__zeno_shuai_parse_widths:n #1
  {
    \exp_not:n
      {
        \tl_set:Nn \l__zeno_shuai_columns_tl { | }
        \seq_set_split:Nnn \l__zeno_shuai_columnratios_seq
      }
      { \c_colon_str } { #1 }
    \exp_not:n
      {
        \int_set:Nn \l__zeno_shuai_column_count_int
          { \seq_count:N \l__zeno_shuai_columnratios_seq }
        \fp_zero:N \l__zeno_shuai_ratio_sum_fp
        \seq_map_function:NN \l__zeno_shuai_columnratios_seq
          \__zeno_shuai_sum_ratios:n
        \seq_map_function:NN \l__zeno_shuai_columnratios_seq
          \__zeno_shuai_set_columns:n
      }
  }
\cs_new_protected:Npn \__zeno_shuai_start_tabularx:nn #1 #2
  {
  }
\cs_generate_variant:Nn \__zeno_shuai_start_tabularx:nn { nV }
\NewDocumentCommand \quicktable { O{\linewidth} m +m }
  {
    \__zeno_shuai_parse_widths:n { #2 }
    \exp_args:NnnV
    \begin { tabularx } { #1 } \l__zeno_shuai_columns_tl
      \hline
      #3
      \crcr
      \hline
    \end { tabularx }
  }
\ExplSyntaxOff

\begin{document}
\quicktable{1:1:2}{a&b&c\\}
\end{document}

答案3

以下版本的\quicktable{<colspec ratio>}{<table>}处理第一个参数 - <colspec ratio>- 两次。第一次它将“比率”加起来得到一个总数。在第二次运行期间,它将每列的列宽指定为 的比率\linewidth(减去 提供的双列填充\tabcolsep)。最后,它使用新定义的列规范以及第二个参数 来设置表格<table>

在此处输入图片描述

\documentclass{article}

\usepackage{xfp}

\newcounter{colnums}
\newcommand{\sumcols}[1]{\setcounter{colnums}{\numexpr\value{colnums}+#1}}
\newcommand{\coldims}[1]{%
  \edef\colspec{\colspec p{\dimexpr\fpeval{#1/\value{colnums}}\linewidth-2\tabcolsep} |}%
}

% \quicktable{<colspec ratio>}{<table>}
\NewDocumentCommand{\quicktable}{>{\SplitList{:}}m m}{%
  \setcounter{colnums}{0}\ProcessList{#1}{\sumcols}% Identify total column ratio
  \def\colspec{|}% Initialize column specification
  \ProcessList{#1}{\coldims}% Update column specification with column widths/dimensions
  \noindent
  \begin{tabular}{\colspec}
    \hline
    #2
  \end{tabular}\par
}

\begin{document}

\quicktable{2:1:4:5}{%
  2 & 1 & 4 & 5 \\
  \hline
}

\quicktable{1:1:2}{
  1 & 1 & 2 \\
  \hline
}

\quicktable{1}{%
  1 \\
  \hline
}

\quicktable{1:2:3:4:5}{%
  1 & 2 & 3 & 4 & 5 \\
  \hline
}

\end{document}

相关内容