我想要让美国城市的那两行填充蓝色,日本的城市是白色,俄罗斯又是蓝色。即想以国家那一列的单元格为标准来判定行数奇偶,这样就能自动给单元格填间隔的背景色了。
用的是Windows10,安装的发行版是TEXlive2022,使用的编辑器是vscord,使用的编译命令是xelatex。
\documentclass[]{ctexbook}
\usepackage{tabularray}
\UseTblrLibrary{booktabs}
\usepackage[]{xcolor}
\begin{document}
{\small
\begin{longtblr}[
caption = {国家与城市}
]{
width = \textwidth,
colspec = {X[1,l,h] X[1,l,h] X[3,l,h]},
rowhead = 1, rowfoot = 0, % 每个分页里表头表尾的数量
row{even} = {azure9},
}
\toprule
\textbf{城市} & \textbf{国家} & \textbf{性质}\\
\midrule
华盛顿 & \SetCell[r=2]{h}美国 & 首都\\
洛杉矶 & & a\\
东京 & 日本 & 首都\\
莫斯科 & 俄罗斯 & 首都\\
\bottomrule
\end{longtblr}
}
\end{document}
多看看文档,做到“真”样式和内容分离。
\documentclass{ctexbook}
\usepackage{xcolor}
\usepackage{tabularray}
\begin{document}
\SetTblrStyle{caption}{font=\small}
\begin{longtblr}[caption={国家与城市}]
{
width=\textwidth,
colspec={X[1,l,h]X[1,l,h]X[3,l,h]},
rows={font=\small},
row{1}={font=\small\bfseries},
rowhead=1,
rowfoot=0,
hline{2}={.05em},
hline{1,Z}={.08em},
row{even}={azure9},
}
城市 & 国家 & 性质 \\
{华盛顿\\洛杉矶} & 美国 & {首都\\a} \\
东京 & 日本 & 首都 \\
莫斯科 & 俄罗斯 & 首都 \\
{华盛顿\\洛杉矶} & 美国 & {首都\\a} \\
东京 & 日本 & 首都 \\
莫斯科 & 俄罗斯 & 首都 \\
\end{longtblr}
\end{document}
可以换一个思路,用 csvsimple
结合 tabularray
来完成这个任务。本来你这种长表格就不会自己手动敲入内容,更多是从文件读取,不妨在 csv
文件里加一列指定相应颜色。代码示例如下:
\documentclass{ctexart}
\begin{filecontents*}{temp.csv}
cellcolor,city,country,property
azure9,华盛顿,美国,首都
azure9,洛杉矶,美国,大城市
white,东京,日本,首都
azure9,莫斯科,俄罗斯,首都
\end{filecontents*}
\usepackage{tabularray}
\usepackage{csvsimple-l3}
\usepackage{xcolor}
\begin{document}
\begin{table}
\caption{测试表}\label{tab:temp}
\csvreader[
head to column names,
tabularray={
colspec = {X[1,l,h] X[1,l,h] X[3,l,h]},
hline{1,Z}=1.2pt,
hline{2}=0.8pt,
cell{2}{2}={r=2}{m,l}
},
table head={\textbf{城市} & \textbf{国家} & \textbf{性质}\\}
]{temp.csv}{}{
\SetRow{\cellcolor}
\city & \country & \property
}
\end{table}
\end{document}
效果:
如果颜色那一列你想操作得简单一点,那么就用个简单字符,然后用 csvsimple
做判断,具体要看csvsimple
的手册。
我细看了你的例子,就这个例子而言,还需要用些权宜之计,主要问题在于:
csvsimple
没有给 longtblr
的 [<option>]
参数的接口,表格标题要自己处理。,
字符,标准的 csv
是将单元格字符串用 ""
包裹,但 csvsimple
不支持,可能会导致列错误,因此要用其他不包含的字符作为分隔符,比如 |
,但这样的 csv
在 Microsoft Excel 中修改处理就比较麻烦了。tipa
的音标字符通过 csvsimple
处理会出错,这里用了\newsavebox
\sbox
和 \usebox
处理(没去深究,权宜之计)。这一段的代码如下:
\documentclass{ctexart}
\usepackage{tabularray}
\usepackage{csvsimple-l3}
\usepackage{xcolor}
\usepackage{tipa}
%%% 因为你这里用到了 comma 作为标点符号,如果是严格的 csv 将用 "" 包裹含 comma 的字符串
%%% 但 csvsimple 并不支持这样的用法,所以这里文件用 | 作为分隔符
%%% 不过这样 Microsoft Excel 就不支持了。这些细节上的困难要自己去克服。
\begin{filecontents*}{PfN.csv}
ccolor|Meaning|Prefixes|Example
azure9|{a half \\ $\frac{1}{2}$} |semi- |{semilunar valve 半月瓣\\ (lun/o: moon; -ar: pertaining to)}
azure9| |hemi- |{hemisphere \\ hemiplegia 半瘫\\ (-plegia/\usebox{\plegia}/: paralysis)}
white |{one,single \\ 1} |mono- |{monocyte 单核细胞}
white | |uni- |{unicellular 单细胞的}
azure9|{two \\ 2} |bi- |{bicuspid 二尖瓣的 \\ (cusp/i: point)}
azure9| |di- |{dioxide 二氧化物 \\ diplegia 双侧瘫痪}
white |double |dipl/o|{diploid n.【生】二倍体;(结晶)偏方24面体 adj.二倍体的(含有两套染色体)}
azure9|{three \\ 3} |tri- |{triplet \\ triceps 三头肌 \\ (-ceps: head)}
white |{four \\ 4} |quadr-|quadrant
white | |tetra-|tetracycline/\usebox{\tetracycline}/ 四环素
azure9|many |multi-|{multipara /\usebox{\multipara}/ 经产妇 \\ (-para: to bring forth to, bear)}
azure9| |poly- |polycystic kidney 多囊肾
\end{filecontents*}
%%% 有几个 tipa 字符好像没法通过 csvsimple 中处理,这里用了权宜之计
\newsavebox\plegia
\sbox\plegia{\textipa{"pli:\textdyoghlig I@}}
\newsavebox\multipara
\sbox\multipara{\textipa{m2l"tIp@r@}}
\newsavebox\tetracycline
\sbox\tetracycline{\textipa{""tetr@"saIklm}}
\begin{document}
%%% 由于 csvsimple 没有给 longtblr 的 option 参数的接口
%%% 长表格的标题要用这种黑科技处理一下,用完好像要恢复成 normal
\DefTblrTemplate{caption-text}{empty}{Prefixes for Numbers}
\SetTblrTemplate{caption-text}{empty}
%%% 下面使用 csvsimple
\csvreader[
head to column names,
separator=pipe,
long tabularray={
colspec = {X[1,l,h] X[1,l,h] X[3,l,h]},
rowhead = 1, rowfoot = 0,
column{2}={font=\bfseries},
hline{1,Z}=1.2pt,
hline{2}=0.8pt,
cell{2,4,6,10,12}{1,1,1,1,1}={r=2}{m,l}
},
table head={\textbf{Meaning} & \textbf{Prefixes} & \textbf{Example}\\}
]{PfN.csv}{}{
\SetRow{\ccolor}
{\Meaning} & \Prefixes & {\Example}
}
%%% 恢复
\SetTblrTemplate{caption-text}{normal}
\end{document}
效果:
如果只是要按某一列内各行合并单元格后的情况来交替颜色,思路是可以写一小段逻辑来控制新的行索引,这样就能根据这个新的索引来交替行的颜色。
tabularray
提供了inner key process
接口,可以通过\UseTblrLibrary{functional}
提供的类l3
风格函数,构造出符合要求的 hook。
在tabularray
中,SetCell
会设置合并行的首个原始单元格的rowspan
属性为x
,x
视合并的行数而定。如果能够拿到这个值,就可以确定每一组的边界,再重新定义行索引就很容易了。
不过tabularray
并没有直接暴露获取rowspan
数据的接口,目前只提供了获取单元格内容的接口cellGetText
。当然也可以选择魔改tabularray
,仿照cellGetText
添一个cellGetSpan
。
这里选择一个讨巧的方法,在确定某一列为key
的情况下,一般来说,合并的单元格中,首个原始的单元格必定不是空,剩下的一定是空,这样就可以区分出哪些是被合并的行,只需要将这些行的新索引默认与首行的索引相同即可。
\documentclass[]{ctexbook}
\usepackage{tabularray}
\UseTblrLibrary{booktabs}
\UseTblrLibrary{functional}
\usepackage[]{xcolor}
\usepackage[]{amsmath}
\usepackage[]{tipa}
\begin{document}
\IgnoreSpacesOn
\prgNewFunction \groupByCol { m } {
\intZero \lTmpaInt
\intStepOneInline {2} {\arabic{rowcount}} {% ignore head
\tlSet \lTmpaTl {\cellGetText {##1} {#1}}
\tlVarIfEmptyF \lTmpaTl
{ \intIncr \lTmpaInt }
\intCompareT {\intMathMod {\lTmpaInt-1} {2}} = {0}
{ \rowSetStyle {##1} {bg=azure9} }
}
}
\IgnoreSpacesOff
{\small
\begin{longtblr}[
caption = {国家与城市}
]{
width = \textwidth,
colspec = {X[1,l,h] X[1,l,h] X[3,l,h]},
rowhead = 1, rowfoot = 0, % 每个分页里表头表尾的数量
process = \groupByCol{2}
}
\toprule
\textbf{城市} & \textbf{国家} & \textbf{性质}\\
\midrule
华盛顿 & \SetCell[r=2]{h}美国 & 首都\\
洛杉矶 & & a\\
东京 & 日本 & 首都\\
莫斯科 & 俄罗斯 & 首都\\
\bottomrule
\end{longtblr}
\begin{longtblr}[
caption = {Prefixes for Numbers},
]{
width = \textwidth,
colspec = {X[1,c,h] X[1,l,h] X[3,l,h]},
rowhead = 1, rowfoot = 0, % 每个分页里表头表尾的数量
% row{even} = {azure9},
process = \groupByCol{1},
}
\toprule
\textbf{Meaning} & \textbf{Prefixes} & \textbf{example} \\ \midrule
\SetCell[r=2]{c} {a half \\ $\frac{1}{2}$} & \textbf{semi-} & {semilunar valve 半月瓣\\ \hspace*{1em}(lun/o: moon; -ar: pertaining to)}\\
& \textbf{hemi-} & {hemisphere \\ hemiplegia 半瘫\\ \hspace*{1em}(-plegia/\textipa{"pli:\textdyoghlig I@}/: paralysis)}\\
\SetCell[r=2]{c} {one, single \\ 1} & \textbf{mono-} & monocyte 单核细胞\\
& \textbf{uni-} & unicellular 单细胞的\\
\SetCell[r=2]{c} {two \\ 2} & \textbf{bi-} & {bicuspid 二尖瓣的 \\ \hspace*{1em}(cusp/i: point)}\\
& \textbf{di-} & {dioxide 二氧化物 \\ diplegia 双侧瘫痪}\\
double & \textbf{dipl/o} & diploid n.【生】二倍体;(结晶)偏方24面体
adj.二倍体的(含有两套染色体)\\
{three \\ 3} & \textbf{tri-} & {triplet \\ triceps 三头肌 \\ \hspace*{1em}(-ceps: head)}\\
\SetCell[r=2]{c} {four \\ 4} & \textbf{quadr-} & quadrant\\
& \textbf{tetra-} & tetracycline/\textipa{""tetr@"saIklm}/ 四环素\\
\SetCell[r=2]{c} many & \textbf{multi-} & {multipara/\textipa{m2l"tIp@r@}/ 经产妇 \\ \hspace*{1em}(-para: to bring forth, to bear)}\\
& \textbf{poly-} & polycystic kidney 多囊肾\\
\bottomrule
\end{longtblr}
}
\end{document}
效果:
十分感谢您的回答。
这个方法我之前有考虑过,但是碰到以下红框内的布局(MWE如下)就需要在第三列嵌套多层大括号,同时在第二列手动加入
\\ ~
或垂直间距来创造空行。如果像是下图所示的布局,我可能就分不清嵌套关系了。而且这还不是我笔记中嵌套最多的表格。
所以我只好沿用目前的代码写法,并暂时将填充颜色的命令注释掉(如下图所示)。但是没有颜色填充,也没有分隔线(我不太想用它),有时候就会看花眼。所以我更倾向于寻找其他方法来解决颜色填充的问题。
附件
如有需要,上述表格的完整代码如下所示:
建议你去 https://github.com/lvjr/tabularray/discussions 咨询作者吧,看有没有更好的解决办法。