循环中的表格对齐问题

循环中的表格对齐问题

我在构建的表格中遇到了一些奇怪的表格对齐问题\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

使用您现有的设置,这里出现了两处错误:

  1. 未对齐是由于\maketabular调用 时传递给 的一个空格造成的\stepcounter{nada}。请删除这个空格。
  2. 通过调用 开始一个新单元格\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}

表格循环

相关内容