我如何创建一个表,其中每一行确切地常数的倍数(在这个例子中是 3cm)?
一行内的文字可以换行多行,但如果换行后的行高超过3cm,则应增加到下一个3cm的倍数。
我不知道每个条目占用多少行。tex 文件是动态生成的。高度必须在 TeX 中动态生成。目前,我正在使用 Python 根据字符数估计每行占用多少行,并以此方式设置高度。
我尝试过使用tabularx
和调整,arraystretch
但没有成功:
\renewcommand{\arraystretch}{2.5}
\begin{tabularx}{\textwidth}{|p{3cm}|p{5cm}|}
\hline
Row 1 & Content of row 1. This might be a long text that needs to wrap onto the next line. \\
\hline
Row 2 & Content of row 2. \\
\hline
\end{tabularx}
我也尝试过用与/vbox
的高度相关的表达式计算高度,尽管我无法让它工作甚至编译:strutbox
parbox
\newcommand{\dynamicrow}[1]{\vbox to \dimexpr2cm * \ceil*{(\ht\strutbox+#1)/2cm}\relax{\vfil\parbox[t][\dimexpr2cm * \ceil*{(\ht\strutbox+#1)/2cm}\relax][c]{\linewidth}{#1}\vfil}}
然后表格条目将被插入为
\dynamicrow{Content of row 1. This might be a long text that needs to wrap onto the next line.} & Example text \\
答案1
这是另一个基于保存的框的示例——获取多个多行段落的当前高度的方法。
longtblr
我使用了一种略有不同的方法,基于from包构建了一个长表tabularray
。固定高度通过以下方式获得:计算常数的下一个最接近倍数;并创建一个大小为 0 的垂直规则的不可见项。顺便说一句,我之所以应用它,是longtblr
因为 中的表格tabularray
有一种更简化的方法来为选定的单元格应用宏,并且格式化也更容易。
目前,存在一个限制,即受影响的单元格(\processcell{}
申请的单元格)中的文本需要在\processcell
中的宏内进行内部格式化\parbox
。
下面是一个单元格示例,其高度固定为 2 厘米的倍数,但可以通过修改宏来更改\mtplconst
:
\documentclass{article}
\usepackage{tabularray}
\UseTblrLibrary{booktabs}
\usepackage[nopar]{kantlipsum}
\newcommand\mtplconst{2} % Multiple of 2cm
\NewDocumentCommand\processcell{m}{%
\sbox1{\parbox[t]{\linewidth}{#1}}%
\dimen0 = \fpeval{
ceil((\ht1+\dp1)/\mtplconst/72.27*2.54)*\mtplconst*72.27/2.54
}pt%
\rule[-\dimexpr\dimen0-0.7\baselineskip]{0pt}{\dimen0}\usebox1}
\begin{document}
\begin{longtblr}[
caption = {Test},
label = {tab:test},
]{
width = \linewidth,
colspec = {Q[2cm,l] X Q[2cm,l]},
row{1} = {font=\bfseries},
cell{2-Z}{2} = {cmd=\processcell},
hline{3-Y} = {wd=\cmidrulewidth},
rowhead = 1,
}
\toprule
Head & Column & Column \\
\midrule
Row 1 & \kant[2][1] & Short sentence. \\
Row 2 & \kant[1][1-3] & Short sentence. \\
Row 3 & \kant[3][1-2] & Short sentence. \\
Row 4 & \kant[3][3] & Short sentence. \\
Row 5 & \kant[3][4] & Short sentence. \\
Row 6 & \kant[1][4] & Short sentence. \\
\bottomrule
\end{longtblr}
\end{document}
答案2
由于您没有展示 MWE,我将仅包含一些代码,从原则上展示您可以做什么。基本思想是将每个表条目放入一个迷你页面中,其高度是动态计算的。
\documentclass{article}
\newlength\threecm
\setlength\threecm{3cm}
\newsavebox{\innertextbox}
\newcommand{\scaletothreecm}[1]{\sbox{\innertextbox}%
{\begin{minipage}[b]{5cm} \raggedright #1\end{minipage}}%
\fbox{\begin{minipage}[t][\dimexpr \numexpr (\ht\innertextbox + \threecm/2)/\threecm * \threecm \relax sp\relax][t]{5cm}%
\usebox{\innertextbox}\end{minipage}}}
\begin{document}
\scaletothreecm{Short text} \the\ht\innertextbox
\scaletothreecm{Explanation: \begin{enumerate}
\item We first build a box with the specified width (5cm chosen arbitrarily) and the given material. This box is saved and not used.
\item We then build a new minipage with a specified height. This height is computed from the height of the original material. Since the division operation rounds to the nearest integer, to make it round \emph{up} instead, we first add to the measured height half of the unit.
\item Inside the minipage we use the saved material.
\item For illustration we wrap the whole thing in a fbox so you can see the extra space reserved.\end{enumerate}}
\the\ht\innertextbox
\end{document}
评论。请注意,在第二个示例中,框的基线设置在内框文本的底部。这是我们用来\usebox
打印内容的神器。或者,您也可以将 替换为\usebox
,\raggedright #1
并在现有规范下,相邻文本的基线(即 302.94444pt 量)将与文本的顶行对齐。