在 plainTeX / LaTeX / Context 等中垂直对齐表格

在 plainTeX / LaTeX / Context 等中垂直对齐表格

我最后一次关于垂直对齐表格的答案启发了我在这个网站上写下我的第一个问题。如何使用各种 TeX 方法创建下表:plainTeX、LaTeX、Context、eplain、OPmac 等?欢迎进行比较。

表格具有给定的列宽,每个数据项垂直居中,一些数据项可以垂直跨越并在其空间中垂直居中。数据项有两种类型:列或段落中的单行居中。列之间和行之间都有单行。表格如下所示:

对齐2

将代码分成两部分是可以的:第一部分将标记为由 % macro code宏程序员和/或排版设计师创建。第二部分将标记为,% document并且应该是文本的作者编写的。

我将给出 plainTeX 的答案(这是我的领域)。我期待其他方法。

作为奖励,你可以尝试根据我的书创建表格 TeXbook 彻底 (全文可查阅这里) 来自第 142 页。垂直对齐也在这里:倒数第二行垂直居中,最后一行顶部对齐。

编辑我仍在等待 LaTeX 解决方案。一位用户在评论中提到,从印刷角度来看,这是更糟糕的方面。但我没有评估 tex.stackexchange 上呈现的许多示例的印刷质量。为什么要对这种特殊情况进行评估?例如,我的客户要求我创建以下类似 excel 的表格:

表 v

这不是用于书籍印刷,而只是作为打印在纸张上的工具,使数据更加透明。这是典型的\valign使用示例。

有没有 LaTeX 方法可以做到这一点?98% 的帖子都提到了 LaTeX。我们能找到人从 LaTeX 的角度解释一下吗?或者 LaTeX 无法做到这一点(不吸收普通的 TeX 解决方案)?

注意:vertical-alignment 标签包含 1030 个线程。\valign对于这样的请求,还有什么比原始更自然的呢……

今天,非常相似的问题 多行不同的垂直对齐方式

答案1

使用 ConTeXt:

\def\blah{blah blah blah blah }
\switchtobodyfont[10pt]
\starttext
\bTABLE
  \setupTABLE[offset=1em]
  \setupTABLE[column][each][align={middle, lohi}]
  \setupTABLE[column][3][align=right, width=.3\textwidth]
  \bTABLEhead
    \bTR\bTH Type\eTH         \bTH Specs\eTH   \bTH[align=middle] Uses\eTH\eTR
  \eTABLEhead
  \bTABLEbody
    \bTR\bTD\eTD              \bTD Model 1\eTD \bTD \blah\blah \eTD\eTR
    \bTR\bTD[nr=3] Spring\eTD \bTD Model 2\eTD \bTD \blah\blah\blah\blah\blah\blah blah blah blah \eTD\eTR
    \bTR                      \bTD Model 3\eTD \bTD \blah\blah \eTD\eTR
    \bTR                      \bTD Model 4\eTD \bTD \blah\blah blah blah blah \eTD\eTR
  \eTABLEbody
\eTABLE
\stoptext

看起来像

在此处输入图片描述

答案2

我将展示基于 OPmac 的解决方案。此宏包提供了 \table创建表的命令。当然,它使用\halign原始的。以下解决方案定义了基于原始的\vtable替代方案。它在本地重新定义了来自 OPmac 的一些内部宏。这是在宏中完成的。A等 更改在此处执行。\table\valign\vtabledefs\vrule <-> \hrule\vfil <-> \hfil

代码的(部分)用户% document可以享受 OPmac 表的功能,例如不相交的双线。

% macros:
\input opmac

\def\vtable{\hbox\bgroup \catcode`\|=12 \vtabledefs \tableB}
\def\tableB#1#2{\offinterlineskip \def\tmpa{}\tabdata={}\scantabdata#1\relax
   \valign\expandafter{\the\tabdata\tabstrutA\cr#2\crcr}\egroup}
\def\vtabledefs{%
   \let\dopar=\hfilneg  % the items of paragraph format are prefixed by \dopar
   \def\setrowparams{\hsize=\dimen\tmpnum \leftskip=.5em \rightskip=\leftskip
      \normalbaselines \hsize=\tmpdim
      \emergencystretch=2em \noindent\hfil}%
   \def\topstrut{\vbox to3ex{}}\def\botstrut{\vtop to2ex{}}%
   \def\tabstrut{}%
   \def\multirow##1##2{\multispan{##1}\vfil\vbox{\setrowparams\topstrut##2\botstrut}\vfil\hrule}%
   \def\crl{\crcr\noalign{\vrule}}%
   \def\colw=##1 {\noalign{\global\tmpdim=##1}}%
   \def\addtabvrule{\ifx\tmpa\vrule \addtabdata{\kern\hhkern}%
      \ifnum\colnum=0\def\vvleft{\vvitem}\else\addto\ddlinedata{\vvitem}\fi\fi
      \let\tmpa=\vrule \addtabdata{\hrule}}%
   \def\crli{\crcr \omit \gdef\dditem{\omit\tablinefil}\gdef\vvitem{\tabvvline}%
      \vvleft\tablinefil\ddlinedata\cr}%
   \def\tablinefil{\leaders\vrule\vfil}%
   \def\tabvvline{\hrule\kern\hhkern\hrule}%
   \def\crlli{\crli\noalign{\kern\vvkern}\crli}%
   \tmpdim=100pt
   \def\tabdeclarec{\medskip\vfil\vbox{\setrowparams\topstrut####\unskip\botstrut}\vfil\medskip}%
}   
\def\vvkern{2pt} \def\hhkern{2pt}

% document:

\def\blah{blah blah blah blah blah blah blah blah}
\def\blahh{\blah\ \blah\ \blah\  blah blah blah}

\frame{\vtable{|c||c||c|c|c|}{\crli 
   \colw=20mm Type  & & \multirow3{Spring} \crlli
   \colw=20mm Specs & Model 1 & Model 2 & Model 3 & Model 4 \crlli
   \colw=40mm Uses  & \dopar\blah & \dopar\blahh & \dopar\blah & \dopar\blah\ blah \crli
}}
\bye

valign opmac 双线

OPmac 也提供颜色。然后第二个示例使用此功能。 \vtabledefs与上面的类似,但添加了用于项目着色背景的新宏。使用pdftex它来处理它。

% macros:
\input opmac

\def\vtable{\hbox\bgroup \catcode`\|=12 \vtabledefs \tableB}
\def\tableB#1#2{\offinterlineskip \def\tmpa{}\tabdata={}\scantabdata#1\relax
   \valign\expandafter{\the\tabdata\tabstrutA\cr#2\crcr}\egroup}
\def\vtabledefs{%
   \let\dopar=\hfilneg  % the items of paragraph format are prefixed by \dopar
   \def\setrowparams{\hsize=\dimen\tmpnum \leftskip=.5em \rightskip=\leftskip 
      \normalbaselines \hsize=\tmpdim
      \emergencystretch=2em \noindent\hfil}%
   \def\topstrut{\vbox to3ex{}}\def\botstrut{\vtop to2ex{}}%
   \def\tabstrut{}%
   \def\crl{\crcr\noalign{\vrule}}%
   \def\colw=##1 {\noalign{\global\tmpdim=##1}}%
   \def\addtabvrule{\ifx\tmpa\vrule \addtabdata{\kern\hhkern}%
      \ifnum\colnum=0\def\vvleft{\vvitem}\else\addto\ddlinedata{\vvitem}\fi\fi
      \let\tmpa=\vrule \addtabdata{\hrule}}%
   \def\crli{\crcr \omit \gdef\dditem{\omit\tablinefil}\gdef\vvitem{\tabvvline}%
      \vvleft\tablinefil\ddlinedata\cr}%
   \def\tablinefil{\leaders\vrule\vfil}%
   \def\tabvvline{\hrule\kern\hhkern\hrule}%
   \def\crlli{\crli\noalign{\kern\vvkern}\crli}%
   \tmpdim=100pt
   \def\tabdeclarec{\medskip\vfil\vbox{\setrowparams\topstrut####\unskip\botstrut}\vfil\medskip}%
}
\def\vvkern{2pt} \def\hhkern{4pt}

\def\spancolor#1#2{\multispan{#1}{\localcolor#2\kern\vvkern\leaders\hrule width\tmpdim \vfil\kern\vvkern}}
\def\multirow#1#2{\multispan{#1}\vfil\vbox{\setrowparams\topstrut#2\botstrut}\vfil}%

\def\colitem#1{\omit{\localcolor#1\kern\vvkern\leaders\hrule width\tmpdim \vfil\kern\vvkern}}
\def\crc{\crcr\noalign{\global\advance\tmpdim by-\hhkern \hskip-\tmpdim \global\advance\tmpdim by-\hhkern}}
\def\crx{\crcr\noalign{\hskip\hhkern\hskip\hhkern}}

% document:

\def\blah{blah blah blah blah blah blah blah blah}
\def\blahh{\blah\ \blah\ \blah\  blah blah blah}  

\def\itemcolors#1#2#3#4#5{\colitem#1&\colitem#2&\colitem#3&\colitem#4&\colitem#5\crc}

\def\liRed{\setcmykcolor{0 .5 .5 0}}
\def\liBlue{\setcmykcolor{.3 .3 0 0}}
\def\liGreen{\setcmykcolor{.5 0 .5 0}}
\def\liOrange{\setcmykcolor{0 0.2 0.5 0}}
\def\liCyan{\setcmykcolor{.3 0 0 0}}

\vtable{ccccc}{
   \colw=20mm \colitem\liGreen & \colitem\liGreen & \spancolor3\liOrange \crc
   Type  & & \multirow3{Spring} \crx
   \colw=20mm \itemcolors\liRed\liBlue\liRed\liBlue\liRed
   Specs & Model 1 & Model 2 & Model 3 & Model 4 \crx
   \colw=40mm \itemcolors\liCyan\Yellow\liCyan\Yellow\liCyan
   Uses  & \dopar\blah & \dopar\blahh & \dopar\blah & \dopar\blah\ blah \crx
}
\bye

在此处输入图片描述

答案3

plainTeX 方法在这里。这是我的回答这里略有改进。这里有两个新功能:

  • 代码分为宏部分(由宏程序员完成)和文档部分(由作者完成)。
  • 作者可以设置表格中使用的每列的宽度。

代码

% Macro code (by programator and designer)
\newcount\tmpnum
\def\setcolumnsA #1,{\if,#1,\else \advance\tmpnum by1 \dimen\tmpnum=#1 
   \expandafter \setcolumnsA \fi
}
\def\vtable #1#2{\vbox{\hbox{%
   \tmpnum=180 \setcolumnsA #1,,\tmpnum=180
   \everycr={\noalign{\vrule \global\advance\tmpnum by1}}% 
   \valign{&\hrule\vfil\vbox{\setrowparams\topstrut##\unskip\botstrut}\vfil\crcr
   #2\crcr}}\hrule}%
}
\def\multirow#1#2{\multispan{#1}\hrule\vfil\vbox{\setrowparams\topstrut#2\botstrut}\vfil}
\def\topstrut{\vbox to3ex{}} \def\botstrut{\vtop to2ex{}}
\def\setrowparams{\hsize=\dimen\tmpnum \leftskip=.5em \rightskip=\leftskip
   \ifdim\hsize=0pt \hsize=100pt \message{WARNING: the columnwidth is not set.}\fi
   \emergencystretch=2em \noindent\hfil}
\let\dopar=\hfilneg  % the items of paragraph format are prefixed by \dopar

% document (by author):
\def\blah{blah blah blah blah blah blah blah blah}
\def\blahh{\blah\ \blah\ \blah\  blah blah blah}

\vtable{25mm,25mm,40mm}{
   Type   & & \multirow3{Spring} \cr
   Specs  & Model 1 & Model 2 & Model 3 & Model 4 \cr
   Uses   & \dopar\blah & \dopar\blahh & \dopar\blah & \dopar blah blah \blah\ blah \cr
}

\end

tex document你可以用或来处理pdftex document。结果和问题给出的表格一样。

答案4

tblr利用新 LaTeX 包环境轻松解决tabularray

\documentclass{article}

\usepackage{tabularray}

\newcommand*\blah{blah blah blah blah }

\NewColumnType{z}[1]{Q[m,c,#1]}% a centered m-type column

\begin{document}

\begin{tblr}{
  colspec ={|z{2cm}|z{2cm}|m{0.3\linewidth}|},
  row{1} = {c,font=\bfseries},
  cell{3}{1} = {r=3}{m,c}, % multirow
  hlines,
}
  Type   & Specs   & Uses \\
         & Model 1 & \blah\blah \\
  Spring & Model 2 & \blah\blah\blah\blah\blah blah blah blah \\
         & Model 3 & \blah\blah \\
         & Model 4 & \blah\blah blah blah blah \\
\end{tblr}

\end{document}

在此处输入图片描述

相关内容