使用宏构建表格元素

使用宏构建表格元素

1.小例子

考虑以下两个表:

\documentclass{article}
\usepackage{multirow}
\usepackage{hyperref}
\begin{document}
\begin{tabular}{c | c c | c}
\multirow{4}{*}{First}  & First(     & \hypertarget{firststuff.<third argument>}{}Some      & \multirow{4}{*}{\hyperlink{secondstuff.<third argument>}{$\rightarrow$}}    \tabularnewline
                    & Example      & more      &                       \tabularnewline
                    & of a & elements      &                       \tabularnewline
                    & table        & in the third      & \tabularnewline
\hline
\multirow{4}{*}{First}  & First(     & \hypertarget{firststuff.<third argument>}{}Some      & \multirow{4}{*}{\hyperlink{secondstuff.<third argument>}{$\rightarrow$}}    \tabularnewline
                    & Example      & more      &                       \tabularnewline
                    & of a & elements      &                       \tabularnewline
                    & table        & in the third      &
\end{tabular}
\vspace{\parindent}

The above table has two elements and four rows. The one down below has one element and five rows.

\vspace{\parindent}
\begin{tabular}{c | c c | c}
\multirow{5}{*}{Second}                    & Second(     & \hypertarget{firststuff.<third argument>}{}Some & \multirow{5}{*}{\hyperlink{stuff.<third argument>}{$\rightarrow$}}     &                       \tabularnewline
                    & example      & more      &                       \tabularnewline
                    & of this & elements      &             \tabularnewline
                    & table        & in the third      &                       \tabularnewline
                    & \textbf{Woah} & \textbf{an}   & 
\end{tabular}
\end{document}

2. 条款与措辞

为了消除请求中的歧义,对所使用的术语进行一些解释:

  • \mymacro{#1}- 有一个争论
  • \mymacro{one,two,three}- 此宏具有论点和三部分的论点(将被命名“部分”在请求中)。
  • 表格元素由组成一份由宏创建。

看:

\documentclass{article}
\usepackage{multirow}
\usepackage{hyperref}
\begin{document}
\begin{tabular}{c | c c | c}
\multirow{4}{*}{First}  & First(     & \hypertarget{firststuff.<third argument>}{}Some      & \multirow{4}{*}{\hyperlink{stuff.<third argument>}{$\rightarrow$}}    \tabularnewline
                    & Example      & more      &                       \tabularnewline
                    & of a & elements      &                       \tabularnewline
                    & table        & in the third      & \tabularnewline
\hline
\multirow{4}{*}{First}  & First(     & Some      & \multirow{4}{*}{\hyperlink{stuff.<third argument>}{$\rightarrow$}}    \tabularnewline
                    & Example      & more      &                       \tabularnewline
                    & of a & elements      &                       \tabularnewline
                    & table        & in the third      &
\end{tabular}
\end{document}
  • 上表有两个元素和四行。元素本质上是每次使用宏时迭代过程的产物。这可以通过\multirow{4}{*}{...}本例中使用的时间轻松识别。

3. 预期效果

我希望通过使用一个类似于这样的宏来自动完成这些表格元素的制作过程:\mymacro{#1}{#2}{#3}并且与 非常相似。\newcommand{\mymacro}[3]{#1&#2&#3}该宏应该制作整个“元素”(由多行组成)。该宏的参数可能看起来不直观。

  • 论点#1#2包含多个部分,以逗号分隔(与宏评估参数数量不受限制例子\mymacro{I,love,cake,and,pie}{You,hate,cake,and,pie}{...}这两个元素中“部分”的数量将决定第二列和第三列的行数(如示例中所概述)。
  • 表格中的第一列将包含第一个参数(介于{和 之间,)的#1。(见额外的以下)
  • #2其行为非常类似#1,因此我可以输入与在 中使用的部分数量相同的部分#1
  • 第四列与第一列的对齐方式相同。为了实现这一点,\multirow{n}{*}{...}n行数应该足够了。
  • 表元素用于保存像这样的逐字命令\mintinline{Python}{#1}或其他fancrVrb相关命令\lstinline
  • #3将持有超链接和超目标的论点,如上例所示。
  • 最后一列(数字 4)将是静态的并显示$\rightarrow$或某些内容。

为了澄清起见,这里有一张图片:

http://i.imgur.com/Hrpz2Zl.png


4. 分页

一个元素应作为一个整体出现在一个页面上。如果使用,最好不要在页面中间元素处中断longtable。当然,这可以通过使用轻松规避\\*,如下所述:

\documentclass{article}
\usepackage{geometry}
\usepackage{longtable}
\usepackage{array}
\begin{document}
{\renewcommand*\arraystretch{3}
\begin{longtable}{c c c c c}
some & serious & stuff\\
\hline
\endhead
& stuff \\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
& is \\*
& one \\*
\textbf{\Large This} & of \\*
& those \\*
& elements \\
\end{longtable}
}
\end{document}

删除星号将使表格中间的分页符成为“元素”。


5. 宏的使用

该宏将作为表中的“独立”元素多次使用。例子一个表应该能够容纳mymacro多个这样的时间:

\documentclass{article}
\usepackage{multirow}
\begin{document}
\begin{tabular}{c c c c c}
\mymacro{dummy,elements,in the second, column}{some,more,elements,in the third}{hyperlinkinfourthcolumn}
\mymacro{dummy,elements,in the second, column}{some,more,elements,in the third}{hyperlinkinfourthcolumn}
\end{document}

重要的是宏仅有的创建要使用的元素里面一张桌子(代替实际的Some text & more text & text text text \tabularnewline每个实际的表格单元格,但此宏将执行多行和(部分)列。)。我希望创建一个包含这些元素的大表。


6. #1 的第一部分将在表格的第一列中重复使用(选修的)

  • 在我的例子中,的第一个参数#1看起来有点像<stuff>(
  • (我)在表格第一列的单个单元格中(其中“第一个例子”和“第二个例子”位于从上面的例子编译的表格中),我希望显示<stuff>
  • (二)我想要将参数1n包括我已在第一列中打印的参数)打印在第二列中。在此列中,我只想看到<stuff>(,包括括号。

到目前为止我所拥有的是这样的:

\documentclass{article}
\usepackage{xparse}
\usepackage{longtable}
\usepackage{multirow}
\usepackage{hyperref}

\ExplSyntaxOn
\NewDocumentCommand{\mymacro}{ m m }
 {
  \ioiooiioio_setargs:nn { #1 } { #2 }
  \ioiooiioio_print: 
 }

\seq_new:N \l__ioiooiioio_first_col_seq
\seq_new:N \l__ioiooiioio_second_col_seq
\tl_new:N \l__ioiooiioio_table_body_tl
\int_new:N \l__ioiooiioio_step_int
\int_new:N \l__ioiooiioio_args_int

\cs_new_protected:Npn \ioiooiioio_setargs:nn #1 #2
 {
  \seq_set_split:Nnn \l__ioiooiioio_first_col_seq { , } { #1 }
  \seq_set_split:Nnn \l__ioiooiioio_second_col_seq { , } { #2 }
  \tl_clear:N \l__ioiooiioio_table_body_tl
  \int_zero:N \l__ioiooiioio_step_int
  \int_set:Nn \l__ioiooiioio_args_int { \seq_count:N \l__ioiooiioio_first_col_seq }
  \seq_mapthread_function:NNN
     \l__ioiooiioio_first_col_seq
     \l__ioiooiioio_second_col_seq
     \__ioiooiioio_fill_body:nn
 }

\cs_new_protected:Npn \__ioiooiioio_fill_body:nn #1 #2
  {
    \int_incr:N \l__ioiooiioio_step_int
    \tl_put_right:Nn \l__ioiooiioio_table_body_tl { & #1 & #2 & }
    \int_compare:nT { \l__ioiooiioio_step_int = 1}
      {
         \tl_put_right:Nn \l__ioiooiioio_table_body_tl 
           { 
           \multirow{ \l__ioiooiioio_args_int }{*}{
             \hyperlink { #1 } { $ \rightarrow $ }
             }
           }
      }
     \int_compare:nTF { \l__ioiooiioio_step_int = \l__ioiooiioio_args_int}
       {
         \tl_put_right:Nn \l__ioiooiioio_table_body_tl
           { \\ }
       }
       {
       \tl_put_right:Nn \l__ioiooiioio_table_body_tl
           { \\* }
       }
   }

\cs_new_protected:Npn \ioiooiioio_print:
 {
 \multirow{ \l__ioiooiioio_args_int }{*}{ \seq_item:Nn \l__ioiooiioio_first_col_seq { 1 } } \l__ioiooiioio_table_body_tl
   }
\ExplSyntaxOff

\begin{document}
\begin{longtable}{cccc}
\mymacro{this is a test,this,is a,test}{now its,not a,test,anymore}
\end{longtable}
\end{document}

然而我遇到了两个问题:

第一件事:所以我查看了文档interface3\seq_mapthread_function我强烈怀疑它支持两个参数和仅两个参数。我希望使用第三个参数,它只会打印第一行的超链接。(@egreg 的答案只是将其粘贴到右侧,我希望将其嵌入表格中,参见示例。)我必须在这里使用另一个序列吗?第三个参数只会#3打印一次,因此是静态的,目前#1由于没有更好的替代方案,该参数显示。我也无法想象\seq_mapthread_function使用第三个参数如何按预期工作。预期效果是有一个带有任意参数的超链接\hyperlink{<whatever I can think of>}{$\rightarrow$}

第二件事:\multirow关于超链接的使用会产生 。我无法解释此错误,与此和overfull vbox相关的唯一问题是 的一个“实际”案例,它是由元素过大引起的:vbox\multirowoverfull vbox删除嵌套表格导致的“Overfull \vbox”消息。我很难找到该线程中的解决方案与我的情况之间的关系。我该如何处理这个错误?预期效果是使此$\rightarrow$(当然还有超链接)与表格的第一列对齐,这将由使用 的参数总数决定\multirow{ \l__ioiooiioio_args_int }{*}{...}

答案1

很明显,第一项和最后一项不是表格的列,而只是要设置在真实表格旁边的项目。

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\mymacro}{ m m m }
 {
  \ioiooiioio_setargs:nn { #1 } { #2 }
  \mbox { \ioiooiioio_print:n { #3 } }
 }

\seq_new:N \l__ioiooiioio_first_col_seq
\seq_new:N \l__ioiooiioio_second_col_seq
\tl_new:N \l__ioiooiioio_table_body_tl

\cs_new_protected:Npn \ioiooiioio_setargs:nn #1 #2
 {
  \seq_set_split:Nnn \l__ioiooiioio_first_col_seq { , } { #1 }
  \seq_set_split:Nnn \l__ioiooiioio_second_col_seq { , } { #2 }
  \tl_clear:N \l__ioiooiioio_table_body_tl
  \seq_mapthread_function:NNN
     \l__ioiooiioio_first_col_seq
     \l__ioiooiioio_second_col_seq
     \__ioiooiioio_fill_body:nn
 }

\cs_new_protected:Npn \__ioiooiioio_fill_body:nn #1 #2
 {
  \tl_put_right:Nn \l__ioiooiioio_table_body_tl { #1 & #2 \\ }
 }

\cs_new_protected:Npn \ioiooiioio_print:n #1
 {
  \seq_item:Nn \l__ioiooiioio_first_col_seq { 1 }
  \hspace{\tabcolsep}
  \begin{tabular}{|cc|}
  \l__ioiooiioio_table_body_tl
  \end{tabular}
  \hspace{\tabcolsep}
  #1
 }

\ExplSyntaxOff

\begin{document}

\mymacro{dummy,elements,in the second, column}{some,more,elements,in the third}{fourth column}

\end{document}

在此处输入图片描述

答案2

尽管进行了所有编辑,但仍然不太清楚您想要什么,而且我不明白为什么第一列应该是逗号列表的一部分,因此我将其作为一个单独的参数。也许是这样的: 在此处输入图片描述

\documentclass{article}

\def\mymacro#1#2#3#4{%
\par
#1%
\begin{tabular}{|c|c|}
\zz#2,\zzend\yy#3,\relax\qq
\end{tabular}%
#4%
\par}

\def\zzend#1\qq{}

\def\zz#1,#2\yy#3,#4\qq{#1&#3\\
\ifx\zzend#2\expandafter\zzend\fi
\zz#2\yy#4\qq
}

\begin{document}

\mymacro{first}{dummy,elements,in the second, column}{some,more,elements,in the third}{fourth column}
\mymacro{first}{dummy,elements,in the second, column}{some,more,elements,in the third}{fourth column}

\end{document}

答案3

#1如果包含的元素多于#2或反之亦然,我不确定该怎么办。在这里,如果出现这种情况,我只是截断。此外,(第二列顶部单元格中添加的 看起来很奇怪。

这次的最终更新采用了一种更好的方法:没有包,只使用计数器并利用使用\multirow负第一个参数的可能性。

更好的动态表格

\documentclass[a4paper,12pt]{article}
\usepackage{multirow}
\usepackage{hyperref}

\makeatletter

\newcounter{rowcnt}

\newcommand\mymacro [3]{%
    \mymacro@next@a #1,\@nnil #2,\@nnil\@nil {#3}%
}

\def\mymacro@next@a #1,#2\@nnil #3,#4\@nil #5{%
    \setcounter{rowcnt}{-\tw@}
          & #1 ( & #3 & \\
    \mymacro@next@b #2\@nnil #4\@nil {#1}{#5}}

\def\mymacro@next@b #1,#2\@nnil #3,#4\@nnil\@nil #5#6{%
    \ifx\@nnil#2\@nnil\expandafter\@thirdofthree
    \else\ifx\@nnil#4\@nnil
        \expandafter\expandafter\expandafter\@thirdofthree
    \fi\fi
    \@firstoftwo {\addtocounter{rowcnt}{\m@ne}& #1 & #3 & \\
                  \mymacro@next@b #2\@nnil #4\@nnil\@nil {#5}{#6}}
    {\multirow {\value{rowcnt}}{*}{#5}& #1 & #3 &
     \multirow {\value{rowcnt}}{*}{\hyperlink{stuff.#6}{$\rightarrow$}}\\}%
}


\makeatother

\begin{document}

{\centering\begin{tabular}{c|cc|c}
\hline\hline
\multirow{4}{1cm}{First\\(literal input)} & First ( 
                       & Some 
                       & \multirow{4}{*}{
                         \hyperlink{stuff.}{$\rightarrow$}} 
                       \tabularnewline
  & Example & more &   \tabularnewline
  & of a & elements &  \tabularnewline
  & table & in the third & \\
\hline
\mymacro {First,Example,of a,table}{Some,more,elements,in the third}{A}
\hline
\mymacro {Second,Example,of a,table,with,more,elements}
         {Some,elements,in the,third,column}{B}
\hline
\mymacro {Third,Example,with,less,elements}
         {Too,many,elements,in,the,third,column}{C}
\hline
\mymacro {Fourth,Example,with,many,many,many,many,elements}
         {Many,many,elements,in,the,third,column,isn't it?}{D}
\hline\hline
\end{tabular}\par }

\hypertarget{stuff.}{Top target}

\hypertarget{stuff.A}{Second target}

\hypertarget{stuff.B}{Third target}

\hypertarget{stuff.C}{Fourth target}

\hypertarget{stuff.D}{Fifth target}

\end{document}

早先的提议。

\documentclass[a4paper,12pt]{article}
\usepackage{multirow}
\usepackage{hyperref}
\usepackage{xinttools}

\makeatletter

\newcommand\mymacro [3]{%
    \mymacro@next@a #1,\@nnil #2,\@nnil\mymacro@next@e
    {\multirow {\xintNthElt{0}{\xintCSVtoListNonStrippedNoExpand{#1}}}{*}}{#3}%
%
% OR IN CASE #1 AND #2 MAY HAVE DISTINCT NUMBERS OF ITEMS
% do \usepackage{xint} and use: (not efficient, but did not know if really needed; if really needed then was can aslo do without xint)
%    {\multirow {\xintiMin{\xintNthElt{0}{\xintCSVtoListNonStrippedNoExpand{#1}}}
%                         {\xintNthElt{0}{\xintCSVtoListNonStrippedNoExpand{#2}}}}{*}}{#3}%
}
\def\mymacro@next@a #1,#2\@nnil #3,#4\mymacro@next@e #5#6{%
    #5{#1}& #1 ( & #3 & #5{\hyperlink{stuff.#6}{$\rightarrow$}}\\
    \mymacro@next@b #2\@nnil #4\mymacro@next@e }

\def\mymacro@next@b #1,#2\@nnil #3,#4\@nnil\mymacro@next@e {%
    & #1 & #3 & \\
    \ifx\@nnil#2\@nnil\expandafter\mymacro@next@e
    \else\ifx\@nnil#4\@nnil
        \expandafter\expandafter\expandafter\mymacro@next@e
    \fi\fi
    \mymacro@next@b #2\@nnil #4\@nnil\mymacro@next@e }

\def\mymacro@next@e #1\mymacro@next@e {}

\makeatother

\begin{document}\pagestyle{empty}

{\centering
\begin{tabular}{c|cc|c}
\hline\hline
\multirow{4}{1cm}{First\\(literal input)} & First( 
                       & Some 
                       & \multirow{4}{*}{
                         \hyperlink{stuff.}{$\rightarrow$}} 
                       \tabularnewline
  & Example & more &   \tabularnewline
  & of a & elements &  \tabularnewline
  & table & in the third & \\
\hline
\mymacro {First,Example,of a,table}{Some,more,elements,in the third}{A}
\hline
\mymacro {Second,Example,of a,table,with,more,elements}
         {Some,elements,in the,third,column}{B}
\hline
\mymacro {Third,Example,with,less,elements}
         {Too,many,elements,in,the,third,column}{C}
\hline\hline
\end{tabular}\par }

\hypertarget{stuff.}{Top target}

\hypertarget{stuff.A}{Second target}

\hypertarget{stuff.B}{Third target}

\hypertarget{stuff.C}{Fourth target}

\end{document}

相关内容