3

I can use this to generate a simple table:

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

I need a \newcommand\quicktable{........}, and can use it like:

\quicktable{1:1:2}{
&&\\\hline
&&\\\hline
}
8
  • 1
    With the current column types, your table will be wider than the textwidth, since they do not take into account the \tabcolsep and the \arrayrulewidth.
    – leandriis
    Oct 17, 2019 at 13:52
  • A precise definition is that I want further more
    – Zeno Shuai
    Oct 17, 2019 at 14:00
  • @leandriis in the MWE array isn't loaded, so \arrayrulewidth won't contribute to the overall width.
    – Skillmon
    Oct 17, 2019 at 14:22
  • Better to use \begin{tabularx}{\linewidth}{|*2{>{\hsize=.75\hsize\linewidth=\hsize}X|}>{\hsize=1.5\hsize\linewidth=\hsize}X|}.
    – Skillmon
    Oct 17, 2019 at 14:26
  • 1
    Is the number of columns fixed at 3? What does the 1:1:2 represent? Oct 17, 2019 at 15:05

3 Answers 3

4

Here's an implementation with xparse and expl3.

The idea is to first sum the items in the “multiratio” so as to establish the modulus. Then a suitable preamble is built, multiplying each item by the modulus and subtracting twice the \tabcolsep.

I set up things so you don't need to type \hline.

The optional argument defaults to \columnwidth, but you can try

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

and see the result.

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

enter image description here

A slightly more complicated version that also works when array is loaded.

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

The following uses tabularx and its X-type column (though this won't be necessary). It works in a similar manner as @Werner's answer in that it sums the ratios and then uses the entries of the sequence again to set the widths of each column. It adds a \hline before and after the contents of your table.

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

The following version of \quicktable{<colspec ratio>}{<table>} processes the first argument - <colspec ratio> - twice. The first time it adds up the "ratios" into some total. During the second run it specifies the column width of each column as a ratio of \linewidth (minus the dual column padding provided by \tabcolsep). Finally, it sets the table with the newly-defined column specification, together with the second argument <table>.

enter image description here

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .