我正在尝试编写一个 key:value 环境,它允许我创建一个双列表,其中的列由冒号分隔。
通常,我在自己的类文件中使用 parbox 实现此功能:
\makeatletter
\newenvironment{keylist}{\global\setlength{\parindent}{0pt}}{}
\newlength{\@keyvalueXposition}
\setlength{\@keyvalueXposition}{0.5\textwidth}
\newcommand{\keyvalue}[2]{
\parbox[t]{\@keyvalueXposition}{#1}
:
\parbox[t]{\@keyvalueXposition}{#2}
\\
}
\makeatother
在用户端通常这样使用:
\begin{keylist}
\keyvalue{Foo que lorem ipsum } {Foofoo }
\keyvalue{Bar foobar } {Bar bar ipsum }\\
\keyvalue{Baz norf } {Bazbaz }
\keyvalue{Qux lorem ipsum } {Qux lorem qux }
\end{keylist}
很快,我意识到我的实现缺少这个用例:允许行只有一个元素而不打印冒号。此外,我开始在类文件中使用,tabularx
以便booktabs
在表格中使用大间距行。
\begin{tabularx}{\textwidth}{ X@{ : }X }\toprule
Foo que lorem ipsum & Foofoo\\\midrule
Bar foobar & Bar bar ipsum\\[\baselineskip]
Baz norf & Bazbaz\\
Qux lorem ipsum & Qux lorem qux\\\bottomrule
\end{tabularx}
* 其中[\baselineskip]
用于模拟换行,\\
使用 parbox 的前面的实现中简单实现。
虽然到目前为止效果很好,但使用起来相当麻烦。我决定用环境别名替换上述解决方案,定义如下:
\newenvironment{keylisting}
{\tabularx{\textwidth}{ X@{ : }X }}
{\endtabularx}
这会给我
\begin{keylisting}\toprule
Foo que lorem ipsum & Foofoo\\\midrule
Bar foobar & Bar bar ipsum\\[\baselineskip]
Baz norf & Bazbaz\\
Qux lorem ipsum & Qux lorem qux\\\bottomrule
\end{keylisting}
如果一行只有一个项目,我们需要为第二列创建一个空项目,如下所示
Foo bar &\\
但是,两列之间打印了一个冒号。根据我在文档中找到的内容,使用 \multicolumn{2}{l}{Foo bar}\\
是解决方案。但是,由于我不知道的原因,当我们在该语句前面加上 时[\baselineskip]
,后者不会被 LaTeX 内核解释。如果您使用以下示例,您将看到两行之间的差异[\baselineskip]]
:第一行不会被解释。我在语句前面加上 以10
清楚地看到它不会被解释。
\documentclass{report}
\usepackage[margin=2cm]{geometry}
\linespread{1.2}
\usepackage{tabularx}
\usepackage{booktabs}
\usepackage{float}
\newenvironment{keyval}
{ \tabularx{\textwidth}{ X@{ : }X } }
{ \endtabularx }
\begin{document}
\begin{keyvalue}
Foo bar lorem ipsum & Lorem ipusm que \\
Some number & 12 3456 789 8 \\
\multicolumn{2}{l}{This is some comment} \\[10\baselineskip]
Yet some number & 987 65432 1 \\
Foo bar & 163883495778 \\[\baselineskip]
Bar lorem ipsum & 2013-04-12 \\
\end{keyvalue}
\end{document}
感谢您的帮助。
答案1
你需要
\\[10\normalbaselineskip]
就像\baselineskip
表格环境中的 0pt 一样,这样行(特别是垂直规则)就没有间隙。
p
如果最后一列是(或此处为)列,则它会偶然起作用X
,因为在该列内,基线会重置为正常排版。请注意,但是您正在选择该本地设置,如果单元格中的文本是,\small
您将选择一个较小的 值\baselineskip
。
我很想这么说
Foo bar & 163883495778 \\[\baselineskip]
增加空间是乳胶的一个错误(在这种情况下它从一开始就存在并且有 30 年左右没有报告过......)
答案2
我对您的混合问题的方法有些不同。下面我使用列表式的表格设置并利用array
的功能是将内容插入到列的开头- 就像一个列分隔机制。后一种方法仅在使用该列时>{<stuff>}
设置,如果未使用该列,则不设置。<stuff>
<stuff>
\documentclass{article}
\usepackage{tabularx,booktabs,environ}
\NewEnviron{keylisting}{%
\let\olditem\item% Save \item
\par\noindent
\begin{tabularx}{\textwidth}{ X @{\hspace{\tabcolsep}} >{\leavevmode\llap{: }}X }
\toprule
% https://tex.stackexchange.com/q/227142/5764
\ifdim\hfuzz=\maxdimen % During tabularx trial
\gdef\item{\\}
\else% During tabularx final
\gdef\item{\gdef\item{\\\midrule\gdef\item{\\}}}
\gdef\bigskip{\gdef\item{\\[\normalbaselineskip]\gdef\item{\\}}}
\fi
\BODY \\
\bottomrule
\end{tabularx}
\let\item\olditem% Restore \item
}
\begin{document}
\begin{keylisting}
\item Foo que lorem ipsum & Foofoo
\item Bar foobar & Bar bar ipsum \bigskip
\item Baz norf & Bazbaz
\item Something with only one column
\item Qux lorem ipsum & Qux lorem qux
\end{keylisting}
\end{document}
上述 的定义\item
假定第一行将是标题行。因此,第一个\item
被定义为不执行任何操作。第二个\item
插入\midrule
,而后续\item
插入传统的\\
。\bigskip
也被重新定义为 的别名\\[\normalbaselineskip]
(实际上是通过再次重新定义\item
),以方便使用。如果需要,可以定义其他跳过以类似的方式执行。