我在构建的表格中遇到了一些奇怪的表格对齐问题\whileboolexpr
。
该.tex
文件内容如下:
\documentclass{article}
\usepackage{etoolbox}
\newcounter{pcnt}
\setcounter{pcnt}{0}
\newenvironment{defineperson}[1]
{\csgdef{person\thepcnt}{#1}}
{\stepcounter{pcnt}}
\newcommand\persontitle[1]{\csgdef{persontitle\thepcnt}{#1}}
\newcommand\personmail[1]{\csgdef{personmail\thepcnt}{#1}}
\newcommand\showperson[1]{\textbf{#1}}
\newcommand\maketabular[1]{\begin{tabular}{| l | l | l |} \hline #1 \end{tabular}}
\newcounter{nada}
\newcommand\makepersonrtable{%
\setcounter{nada}{0}%
\maketabular{%
\whileboolexpr
{ test {\ifnumcomp{\value{nada}}{<}{\value{pcnt}}} }%
{\showperson{\csuse{person\thenada}} & \csuse{persontitle\thenada} & \csuse{personmail\thenada} \\ \hline \stepcounter{nada} }
}}
\begin{defineperson}{Mr.}
\persontitle{Wall Eye}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mrs.}
\persontitle{Perch}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mr.}
\persontitle{Brook Trout}
\personmail{[email protected]}
\end{defineperson}
\begin{document}
\makepersonrtable
\end{document}
这确实会生成一个我预期的表格,但是对齐不正确 - 例如,
请注意,第一个“Mr.”没有与第二行对齐。还请注意底部的额外垂直线。
知道这是怎么回事吗?我知道还有其他制作表格的方法,但这次我尝试了一些替代方法作为学习练习。
答案1
不对齐是由于虚假的空间造成的;多余的条是由于当\whileboolexpr
决定循环结束时,一个tabular
单元已经开始了。
通常的方法是准备整个表主体然后传递它。在这种情况下,传递的变量数据使这个过程变得复杂,因此在附加到先前收集的主体之前必须扩展行。
\documentclass{article}
\usepackage{etoolbox}
\newcounter{pcnt}
\newenvironment{defineperson}[1]
{\csgdef{person\thepcnt}{#1}}
{\stepcounter{pcnt}}
\newcommand\persontitle[1]{\csgdef{persontitle\thepcnt}{#1}}
\newcommand\personmail[1]{\csgdef{personmail\thepcnt}{#1}}
\newcommand\showperson[1]{\textbf{#1}}
\newcommand\maketabular[1]{\begin{tabular}{| l | l | l |} \hline #1 \end{tabular}}
\newcommand{\personrtablebody}{} % initialization
\newcounter{nada}
\makeatletter
\newcommand\makepersonrtable{%
\renewcommand\personrtablebody{}%
\setcounter{nada}{0}%
\maketabular{%
\whileboolexpr
{ test {\ifnumcomp{\value{nada}}{<}{\value{pcnt}}} }%
{%
\begingroup\protected@edef\x{\endgroup
\noexpand\appto{\noexpand\personrtablebody}{%
\showperson{\csuse{person\thenada}} &
\csuse{persontitle\thenada} &
\csuse{personmail\thenada} \noexpand\\
\noexpand\hline
}%
}\x
\stepcounter{nada}%
}%
\personrtablebody
}}
\makeatother
\begin{defineperson}{Mr.}
\persontitle{Wall Eye}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mrs.}
\persontitle{Perch}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mr.}
\persontitle{Brook Trout}
\personmail{[email protected]}
\end{defineperson}
\begin{document}
\makepersonrtable
\end{document}
答案2
使用您现有的设置,这里出现了两处错误:
- 未对齐是由于
\maketabular
调用 时传递给 的一个空格造成的\stepcounter{nada}
。请删除这个空格。 - 通过调用 开始一个新单元格
\whileboolexpr
,导致在底部插入最后一行。为了解决这个问题,我改变了一些命令,强制固定第一行(当 时\value{nada}=0
)。在每行的最后一个单元格中执行反向步进和测试\whileboolexpr
,避免开始新行。
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcounter{pcnt}\setcounter{pcnt}{0}
\newenvironment{defineperson}[1]
{\csgdef{person\thepcnt}{#1}}
{\stepcounter{pcnt}}
\newcommand\persontitle[1]{\csgdef{persontitle\thepcnt}{#1}}
\newcommand\personmail[1]{\csgdef{personmail\thepcnt}{#1}}
\newcommand\showperson[1]{\textbf{#1}}
\newcommand\maketabular[1]{\begin{tabular}{| l | l | l |} \hline #1 \\ \hline \end{tabular}}
\newcounter{nada}
\newcommand\makepersonrtable{%
\setcounter{nada}{1}%
\maketabular{%
\showperson{\csuse{person0}} & \csuse{persontitle0} & \csuse{personmail0}
\whileboolexpr
{ test {\ifnumcomp{\value{nada}}{<}{\value{pcnt}}} }%
{ \\ \hline \showperson{\csuse{person\thenada}} & \csuse{persontitle\thenada} & \csuse{personmail\thenada}\stepcounter{nada}}%
}}
\begin{defineperson}{Mr.}
\persontitle{Wall Eye}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mrs.}
\persontitle{Perch}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mr.}
\persontitle{Brook Trout}
\personmail{[email protected]}
\end{defineperson}
\begin{document}
\makepersonrtable
\end{document}
答案3
您的代码中存在的问题已经得到解释,这里的工作是\xintFor*
由新工具. 无需柜台nada
。
\documentclass{article}
\usepackage{etoolbox}
\usepackage{xinttools}
\expandafter\chardef\csname xint_c_i\endcsname 1
% the line above to circumvent a bug with a missing definition in xinttools v1.09k.
\newcounter{pcnt}
\setcounter{pcnt}{0}
\newenvironment{defineperson}[1]
{\csgdef{person\thepcnt}{#1}}
{\stepcounter{pcnt}}
\newcommand\persontitle[1]{\csgdef{persontitle\thepcnt}{#1}}
\newcommand\personmail [1]{\csgdef{personmail\thepcnt}{#1}}
\newcommand\showperson [1]{\textbf{#1}}
\newcommand\maketabular[1]
{\begin{tabular}{| l | l | l |}\hline #1\end{tabular}}
% Let's use \xintFor to generate an alignment
% \xintSeq{0}{\value{pcnt}-1} generates {0}{1}{2}...{N-1} with N=value of pcnt counter.
% \xintFor* is for such "braced" lists, \xintFor for comma separated lists.
\newcommand\makepersonrtable{%
\maketabular{%
\xintFor* ##1 in {\xintSeq{0}{\value{pcnt}-1}}
\do
{\showperson{\csuse{person##1}} &
\csuse{persontitle##1} &
\csuse{personmail##1} \\ \hline }
}}
\begin{defineperson}{Mr.}
\persontitle{Wall Eye}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mrs.}
\persontitle{Perch}
\personmail{[email protected]}
\end{defineperson}
\begin{defineperson}{Mr.}
\persontitle{Brook Trout}
\personmail{[email protected]}
\end{defineperson}
\begin{document}
\makepersonrtable
\end{document}