我可以使用它来生成一个简单的表格:
\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}