有没有办法自己定义列的顺序?
说我有
\begin{tabular}{ l l l }
A1 & C1 & B1 \\
A2 & C2 & B2 \\
A3 & C3 & B3 \\
\end{tabular}
但真的想要
\begin{tabular}{ l l l }
A1 & B1 & C1 \\
A2 & B2 & C2 \\
A3 & B3 & C3 \\
\end{tabular}
并希望避免移动所有内容。
答案1
使用@MartinScharrer 的相当新的collcell
包,我们可以收集每个单元格的主体并将其保存为给定的标签,然后以不同的顺序排版单元格,调用每个标签。也就是说,下面的代码定义了两种列类型:(s{<label>}
用于保存)和o{<label>}
(用于输出)。
&
一个缺点是,你需要在每行末尾放置一大堆才能进行排版(&
与列数一样多)。这也可以用于例如将一列翻倍或删除一列。
\documentclass{article}
\usepackage{collcell}
\usepackage{array}
\newcommand{\newcelltoksifnew}[1]{%
\expandafter\ifx\csname cell@toks@#1\endcsname\relax
\expandafter\newtoks\csname cell@toks@#1\endcsname
\fi}
\newcolumntype{s}[1]{%
>{\unskip\newcelltoksifnew{#1}%
\collectcell{\global\csname cell@toks@#1\endcsname}}%
c%
<{\endcollectcell}%
@{}%
}
\newcolumntype{o}[1]{%
>{\the\csname cell@toks@#1\endcsname}%
c%
}
\begin{document}
\begin{table}\centering
\begin{tabular}{|c|c|c|}
a & c & b \\
AAAAA&CCCCC&BBBBB
\end{tabular}
\begin{tabular}{s{A}s{B}s{C}|o{A}|o{C}|o{B}|}
a & b & c &&&\\
AAAAA&BBBBB&CCCCC&&&
\end{tabular}
\caption{Comparing two tables to see that the spacing is not affected.}
\end{table}
\end{document}
答案2
另一种方法是使用字符串操作包来交换列,比如说xstring
;)。当然,交换 2 列并不是重新排序所有列!
\swapcol 命令必须写在要交换 2 个单元格内容的每一行的开头。最后一行必须以 结尾\\
。
以下是棘手的代码:
\documentclass[a4paper]{article}
\usepackage{xstring}
\usepackage{array}
\def\expaddtocs#1#2{%
\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
#1\expandafter\expandafter\expandafter{\expandafter#1#2}}
\def\swapcol#1#2#3\\{%
\ifnum#1>#2 \def\colinf{#2}\def\colsup{#1}%
\else \def\colinf{#1}\def\colsup{#2}\fi
\noexpandarg \let\swaprow\empty \iffalse{\fi\ifnum0=`}\fi
\expandafter\StrBefore\expandafter[\number\numexpr\colinf-1]{#3&}&[\beforecol]%
\ifx\beforecol\empty\else\expaddtocs\swaprow{\beforecol&}\fi
\StrBehind[\colinf]{&}&[\aftercol]%
\expandafter\StrBefore\expandafter{\aftercol}&[\colA]%
\expandafter\StrBehind\expandafter{\aftercol}&[\aftercol]%
\expandafter\StrBefore\expandafter[\number\numexpr\colsup-\colinf-1\expandafter]\expandafter{\aftercol}&[\intercol]%
\StrBehind[\colsup]{}&[\aftercol]%
\expandafter\StrBefore\expandafter{\aftercol&}&[\colB]%
\expandafter\StrBehind\expandafter{\aftercol}&[\aftercol]%
\expaddtocs\swaprow{\colB&}%
\ifx\intercol\empty\else\expaddtocs\swaprow{\intercol&}\fi
\expaddtocs\swaprow{\colA}%
\ifx\aftercol\empty\else\expaddtocs\swaprow{\noexpand&}\fi
\expaddtocs\swaprow{\aftercol\\}%
\ifnum0=`{\fi\iffalse}\fi \swaprow}
\begin{document}
\begin{tabular}{ccccc}
1 & 2 & 3 & 4 & 5 \\
1 & 2 & 3 & 4 & 5 \\
1 & 2 & 3 & 4 & 5 \\
\end{tabular}
\qquad
\begin{tabular}{ccccc}
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\swapcol{2}{5}1 & 2 & 3 & 4 & 5 \\
\end{tabular}
\begin{tabular}{|c|c|c|}
a & c & b \\
AAAAA&CCCCC&BBBBB
\end{tabular}
\qquad
\begin{tabular}{|c|c|c|}
\swapcol{1}{2} a & c & b \\
\swapcol{1}{2}AAAAA&CCCCC&BBBBB\\
\end{tabular}
\end{document}
答案3
使用第一个解决方案中的想法,但不使用胶原细胞:
\def\CollectArg#1\EndCollectArg{\def\StoredContent{#1}}
\newcolumntype{s}[1]{>{\unskip\CollectArg}c%
<{\EndCollectArg\expandafter\global\expandafter\let\csname StoredColumn#1\endcsname\StoredContent}%
@{}}
\newcolumntype{o}[1]{>{\csname StoredColumn#1\endcsname}c}
(当然,这需要包大批, 否则新列类型没有定义)。排版本身和第一个解决方案相同。