表格/数组中的选择性对齐选项卡?

表格/数组中的选择性对齐选项卡?

一段时间以来,我一直在考虑一个array/tabular功能,如果能有的话会很不错。据我所知,它似乎还不存在。不幸的是,我现在没有时间自己开发它。

如果它存在,请告诉我。否则,也许有人会受到启发去研究它。如果你受到启发,我会给你一个300-500 点赏金当您编写出可行的解决方案时。请看下文。

功能描述

它涉及一种指示内容对齐的新方法。&所有列分隔符都分配有一个数字(或名称),而不是使用 跳转到下一列,并且您必须引用一个特定的数字来与其对齐,例如使用&1&2、... 并且\\始终与表格的右边框对齐。

所有这些的结果是,它为我们提供了\multicolumn类似行为的非常简单的语法。

\begin{tabular}{|l|l|l|}                     \hline
    Cell One  &1  Cell Two  &2  Cell Three \\\hline
    Cell One and Two        &2  Cell Three \\\hline
    Cell One  &1  Cell Two and Three       \\\hline
\end{tabular}

缩写为

\begin{tabular}{|l|l|l|}                                    \hline
    Cell One  &  Cell Two                   &  Cell Three \\\hline
    \multicolumn{2}{|l|}{Cell One and Two}  &  Cell Three \\\hline
    Cell One  &  \multicolumn{2}{l|}{Cell Two and Three}  \\\hline
\end{tabular}

tabbing它给我们美好的现代环境带来了tabular一些感觉array,但tabbing它本身太简单了,在大多数情况下没有用。

就我个人而言,我会更多地使用它array。作为一个完美主义者,我习惯于对齐公式中最小的部分,然后\multicolumn在所有应该通过这种对齐的公式中使用。这对最终文档的可读性有积极贡献……但对源代码的可读性没有帮助。这个功能会有很大帮助。

一些评论:

  • 不同的语法也可以。但应该是不引人注目(即短)。David Carlisle 的观点是:一个简单的 & 符号后跟一个裸数字可能会有很多兼容性问题。类似&'1或的东西&[1]可能会更好。(除非您可以强制在 & 符号和索引之间不出现空格。但这可能会带来一些巨大的 catcode 麻烦。)

  • 默认情况下,出现的列说明符\multicolumn应以某种合理的方式从主列说明中继承。但我们可以想出一些不错的语法来覆盖它。

  • 我认为无序使用对齐标签应该是一个错误。

  • 它至少应该与tabulararray环境的所有标准功能兼容。最好还与流行的软件包(如)兼容array

可能的额外功能

  • 能够创建新的临时标签位置。与 不同tabbing,这些应该是命名并且它们的位置应该由最右边的约束决定 - 而不是固定在它们的声明上。

  • 简单的语法可以跳转到相对于当前标签位置的(非临时)标签位置。例如,使用 good-old&跳转到下一个标签位置。例如,&>2向前跳 2 个标签位置。

300-500 点赏金

作为额外的奖励,我为编写上述软件包的人提供 300 到 500 点声望点的赏金。赏金的具体价值取决于软件包的质量。

我还没有在网站上“正式”发布悬赏,因为我不想设定一个星期的期限。当我看到并尝试解决方案后,我会发布并授予悬赏。

如果我不这样做的话,版主可能会打倒我。


对 David Carlisle 的回答的反馈

干得好!而且很快。但还是有一些错误。

版本 0.1

以下示例中有两个不同之处:

\begin{tabular}{|ll|l|l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three  \>4  Cell Four  \<\hline
    Cell One and Two         \>3  Cell Three and Four         \<\hline
    Cell One  \>2  Cell Two, Three and Four                   \<\hline
\end{tabular}
  1. 我删除了可见的\>2分隔符,但此更改也适用\>3于第二行。
  2. 奇怪的是,第四列根本不想被跨越。

(3)下面的真实示例根本无法编译:

\[
    \begin{array}{l@{{} = {}}l}
        a + (b + c)  \>2  (a + b) + c  \<
        a + b        \>2  b + a        \<
        0 + a = a = a + 0
    \end{array}
\]

版本 0.2

我看到您修复了上面的第 2 点和第 3 点。看起来不错!我找不到任何方法再打破它了(现在)。

但如果您能修复 1 号问题,我将不胜感激。这是我目前还不能将它用于实际文档的最后一个原因。(之后只剩下“会更好”的补充。)它需要更好地处理列分隔符。目前,它使用第一列前一个单元格,而应该使用最后一栏前一个单元格。例如:

\begin{tabular}{|l||l|l|l|}\hline
    One \>2 Two \>3 Three \>4 Four \<\hline
    One and Two \>3 Three and Four \<\hline
    One and Two and Three \>4 Four \<\hline
    One and Two and Three and Four \<\hline
\end{tabular}

array由于我的误解,这个错误在你的例子中是不可见的。我\<想象默示在最后一行的末尾。但我不认为这是需要修复的问题。当前的行为很好。)

无论如何,我现在就给你赏金(虽然我猜你这样做不是为了“积分”)。不过,如果能解决最后一个问题就更好了。

编辑:呵呵。看来你得等到明天了。愚蠢的网站。提供“奖励现有答案”作为悬赏的正当理由,然后强制执行 24 小时的等待期。

答案1

在此处输入图片描述

\documentclass{article}
\usepackage{array}
\newcount\tc
\makeatletter

\def\x@multispan#1{%
  \begingroup
  \@multicnt#1\relax
  \def\xtmp{}%
  \let\sp@n\relax
  \loop\ifnum\@multicnt>\@ne
   \xdef\xtmp{\xtmp\span\omit}\advance\@multicnt\m@ne\repeat
  \endgroup
  \xtmp}


\protected\def\>#1{%
\ifnum#1>\numexpr\tc+\@ne\relax
\x@multispan{\numexpr#1-\tc}%
\fi
&}

\protected\def\<{%
\ifnum\tabcolnum>\tc\relax
\x@multispan{\numexpr\tabcolnum+\@ne-\tc\relax}%
\fi\\}


\def\@addamp{%
   \ifx\tabcolnum\@undefined
    \tc\@ne
    \edef\@preamble{\@preamble\tc\@ne}%
     \else
    \advance\tc\@ne
     \fi
    \xdef\tabcolnum{\the\tc}%
  \if@firstamp
    \@firstampfalse
    \edef\@preamble{\@preamble\tc\the\tc\relax}%
  \else
    \edef\@preamble{\@preamble &\tc\the\tc\relax}%
  \fi}

\makeatother


\begin{document}



\begin{tabular}{|l|l|l|l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three  \>4  Cell Four  \\\hline
    Cell One and Two         \>3  Cell Three and Four         \<\hline
    Cell One  \>2  Cell Two, Three and Four                  \<\hline %hmph
    Cell One  \>2  Cell Two, Three and Four                  \<\hline %ditto
\end{tabular}


\bigskip

\begin{tabular}{|l|l|l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three \<\hline
    Cell One and Two       \>3 Cell Three    \<\hline
    Cell One  \>2  Cell Two and Three       \<\hline
\end{tabular}

\bigskip

\[
    \begin{array}{@{}l@{{}={}}l}% The @{} at the start is _required_ for tonight.
        a + (b + c)  \>2  (a + b) + c  \<
        a + b        \>2  b + a        \<
        0 + a = a = a + 0
    \end{array}
\]


\bigskip
\begin{tabular}{|l|>{\bfseries}l|>{\itshape}l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three \<\hline
    Cell One and Two       \>3 Cell Three    \<\hline
    Cell One  \>2  Cell Two and Three       \<\hline
\end{tabular}


\bigskip

As discussed in comments you can not omit just the left or just
the right part of the preamble, but by adding dummy columns ypu
can separate the inter-column material from \texttt{@} or \texttt{|}
into a separate column so it is available for spanning cells.

\newcolumntype{^}[1]{@{}l@{#1}}
\begin{tabular}{
@{[A] }
l^{ [B] }
>{\bfseries}l^{ [C] }
l^{[ D] }
l^{ [E]}
}\hline
    Cell One  \>2&  Cell Two  \>4&  Cell Three  \>6&  Cell Four \>8\<\hline
    Cell One and Two         \>4& Cell Three and Four          \>8\<\hline
    Cell One  \>2&  Cell Two, Three and Four                   \>8\<\hline
\end{tabular}

\end{document}

早期版本

在此处输入图片描述

因此我用\>{col number}代替你的&colnumber\<代替\\。我还从 1 开始对列进行编号。

我添加了一些array包格式,以便您(和我:-)可以知道哪个单元格正在拾取哪个列规范。正如所写,它可能需要数组包。

\documentclass{article}
\usepackage{array}
\newcount\tc
\makeatletter

\def\x@multispan#1{%
  \begingroup
  \@multicnt#1\relax
  \def\xtmp{}%
  \let\sp@n\relax
  \loop\ifnum\@multicnt>\@ne
   \xdef\xtmp{\xtmp\span\omit}\advance\@multicnt\m@ne\repeat
  \endgroup
  \xtmp}


\protected\def\>#1{%
\ifnum#1>\numexpr\tc+\@ne\relax
\x@multispan{\numexpr#1-\tc}%
\fi
&}

\protected\def\<{%
\ifnum\tabcolnum>\tc\relax
\x@multispan{\numexpr\tabcolnum+\@ne-\tc\relax}%
\fi\\}


\def\@addamp{%
  \if@firstamp
    \@firstampfalse
    \tc\@ne
    \edef\@preamble{\@preamble\tc\@ne}%
  \else
    \advance\tc\@ne
    \xdef\tabcolnum{\the\tc}%
    \edef\@preamble{\@preamble &\tc\the\tc\relax}%
  \fi}

\makeatother

\begin{document}


\begin{tabular}{|l|l|l|l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three  \>4  Cell Four  \\\hline
    Cell One and Two         \>3  Cell Three and Four         \<\hline
    Cell One  \>2  Cell Two, Three and Four                  \<\hline %hmph
    Cell One  \>2  Cell Two, Three and Four                  \<\hline %ditto
\end{tabular}


\bigskip

\begin{tabular}{|l|l|l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three \<\hline
    Cell One and Two       \>3 Cell Three    \<\hline
    Cell One  \>2  Cell Two and Three       \<\hline
\end{tabular}

\bigskip

\[
    \begin{array}{@{}l@{{}={}}l}% The @{} at the start is _required_ for tonight.
        a + (b + c)  \>2  (a + b) + c  \<
        a + b        \>2  b + a        \<
        0 + a = a = a + 0
    \end{array}
\]


\bigskip
\begin{tabular}{|l|>{\bfseries}l|>{\itshape}l|}\hline
    Cell One  \>2  Cell Two  \>3  Cell Three \<\hline
    Cell One and Two       \>3 Cell Three    \<\hline
    Cell One  \>2  Cell Two and Three       \<\hline
\end{tabular}

\end{document}

答案2

如果您不介意稍微不同的语法和使用 luatex,那么您可以使用 Lua 表:

\alignedtable 
  { 
    {
      [1] = "Cell one and two",
      [3] = "Cell three and four"
    },
    { [1] = "Cell One",
      [2] = "Cell Two",
      [3] = "Cell Three",
      [4] = "Cell Four"
     },
     {
      [1] = "Cell one",
      [2] = "Cell two, three, and four"
     }
  }

并将排版委托给 lua。例如,这是一个 ConTeXt 实现(应该很容易将其转换为 LaTeX):

\def\alignedtable#1%
    {\ctxcommand{alignedtable({ #1 })}}

\startluacode
  function commands.alignedtable( t ) 
    local max_cols = 0;
    for row = 1,#t do
      for col,value in pairs(t[row]) do
        if col > max_cols then
          max_cols = col
        end
      end
    end
    context.bTABLE() -- Settings can be passed here
      for row = 1, #t do
        context.bTR()
        for col = 1, max_cols do
           if t[row][col] ~= nil then
              local n = max_cols - col + 1
              for m = col + 1, max_cols do
                if t[row][m] ~= nil then
                    n = m - col
                    break
                end
              end
             context.bTD{ nc = n }
             context(t[row][col])
             context.eTD()
            end
        end
        context.eTR()
      end
    context.eTABLE()
  end
\stopluacode

\starttext

\alignedtable 
  { 
    {
      [1] = "Cell one and two",
      [3] = "Cell three and four"
    },
    { [1] = "Cell One",
      [2] = "Cell Two",
      [3] = "Cell Three",
      [4] = "Cell Four"
     },
     {
      [1] = "Cell one",
      [2] = "Cell two, three, and four"
     }
  }

\stoptext

在此处输入图片描述

相关内容