![表格/数组中的选择性对齐选项卡?](https://linux22.com/image/270094/%E8%A1%A8%E6%A0%BC%2F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E9%80%89%E6%8B%A9%E6%80%A7%E5%AF%B9%E9%BD%90%E9%80%89%E9%A1%B9%E5%8D%A1%EF%BC%9F.png)
一段时间以来,我一直在考虑一个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
应以某种合理的方式从主列说明中继承。但我们可以想出一些不错的语法来覆盖它。我认为无序使用对齐标签应该是一个错误。
它至少应该与
tabular
和array
环境的所有标准功能兼容。最好还与流行的软件包(如)兼容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}
- 我删除了可见的
\>2
分隔符,但此更改也适用\>3
于第二行。 - 奇怪的是,第四列根本不想被跨越。
(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