是否有可能在多列输出的上方和下方放置一条水平线(使用multicol
包裹) 使得水平线multicol
恰好在列分隔符的边界处接触?
从图形上看,它应该如下所示:
----------------
|
|
|
----------------
答案1
以下是通过新环境的一个选项multicolumns
。它接受一个参数,性质上与环境类似multicol
:
\begin{multicolumns}{<colnum>}
%...
\end{multicolumns}
\documentclass{article}
\usepackage{multicol}% http://ctan.org/pkg/multicol
\usepackage{xcolor}% http://ctan.org/pkg/xcolor
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\makeatletter
\patchcmd{\endmulticols}{\par}{\par\xdef\@@tpd{\the\prevdepth}}{}{}
\newenvironment{multicolumns}[1]
{% \begin{multicolumns}{<cols>}
\par\nobreak % don't break a page here
\kern\dimexpr\the\prevdepth+\multicolsep\relax % don't take into account the depth of the preceding line + #2
{\columnseprulecolor\hrule height \columnseprule} % the rule, same width as \columnseprule
\kern-\multicolsep % space after the rule
\nointerlineskip % no additional space after the rule
\begin{multicols}{#1}
}
{% \end{multicolumns}
\end{multicols}%
\par\nobreak % don't break a page here
\kern\dimexpr\@@tpd-\multicolsep\relax % don't take into account the depth of the preceding line + #2
{\columnseprulecolor\hrule height \columnseprule} % the rule, same width as \columnseprule
\kern\multicolsep % space after the rule
\nointerlineskip % no additional space after the rule
}
\makeatother
\setlength{\columnseprule}{.4pt}% Column separator rule width
\begin{document}
\lipsum[1]
\begin{multicolumns}{2}
\lipsum[2-3]
\end{multicolumns}
\lipsum[4]
\end{document}
在 处\begin{multicolumns}
,根据跳跃 ( \multicolsep
) 进行垂直校正,并添加multicol
包裹。这也在 中得到了纠正\end{multicolumns}
。但是,\prevdepth
还需要捕获,从而导致使用etoolbox
修补\endmulticol
。
已\hrule
使 匹配\columnseprule
。如有必要,可以更改。要查看效果,请使用 之类的命令\setlength{\columnseprule}{1pt}
。此外,由于xcolor
加载后,您可以修改列分隔线的颜色\columnseprulecolor
,这将转换为顶部/底部水平线。例如,使用\renewcommand{\columnseprulecolor}{\color{orange}}
以查看效果。
需要注意的是: 的使用\prevdepth
依赖于环境中的最后一行multicolumn
。因此,如果最后一行(最右边的列)没有降行(如 j、p、q、g 或 y),则对齐将不准确。例如:
% same preamble as above
\begin{document}
\lipsum[1]
\begin{multicolumns}{2}
\lipsum*[2-3] Here is some more filler text to fill the line.
\end{multicolumns}
\lipsum[4]
\end{document}
这应该手动更正,要么用一些\vphantom{<descender>}
(比如说),要么用结尾\strut
。或者,也可以将其包含在补丁中,\endmulticol
以便更广泛地使用。后者是首选,因为它还在下降部和之间留下了更好的垂直间隙\hrule
。例如,考虑
% same preamble above
\patchcmd{\endmulticols}{\par}{\strut\par\xdef\@@tpd{\the\prevdepth}}{}{}
% same preamble below and entire document
答案2
我的简短回答是“是的,但要小心你得到的东西。” 较长的回答是:该包具有一个名为(默认值:)multicol
的长度参数,它控制在环境的开头和结尾插入的垂直空间量。包执行的插入此垂直空间的代码是。有人可能会认为执行就是您的问题的答案,但这并不完全正确。具体来说,虽然上部水平规则和列间垂直规则会恰好接触,这是所希望的,但下部水平规则并非如此。FMi(multicol 包的作者)似乎没有考虑到任何人都希望设置为的可能性,因为存在(小!)故障,如以下 MWE 所示:\multicolsep
12pt plus 4pt minus 3pt
multicols
\addvspace\multicolsep
\setlength\multicolsep{0pt}
\mulicolsep
0pt
\documentclass{article}
\usepackage{multicol,lipsum}
\setlength{\columnseprule}{0.4pt} % 0.4pt-wide vertical rule between columns
\setlength{\multicolsep}{0pt}
\begin{document}
\hrule % horizontal rule, 0.4pt wide
\begin{multicols}{2}
\lipsum[3]
\end{multicols}
\hrule % horizontal rule, 0.4pt wide
\end{document}
由于分辨率较低,很难注意到上图中的问题,但如果您在自己的系统上运行 MWE 并研究输出,您会发现下部水平线“附着”在最低基线,因此平分字母g
、p
和q
(甚至逗号)的下行部分以及列分隔符规则。可能不是您想要的...问题似乎是由程序包计算多列“框”下边界的方式引起的。具体来说,程序包的代码似乎将此下边界设置为框的最底基线,而没有考虑到最底行文本的内容可能包含下行部分到达基线以下的字母。
此时,您可能会决定忍受这个故障(我不会......),深入研究包的代码以确定如何添加一点点额外的垂直空间来纠正这个问题(我不会这样做......),或者得出结论,设置\multicolsep
为 0pt 并在环境\hrule
上方和下方立即绘制 smulticol
可能不是一个好主意。:-(
附录multicol
:我刚刚注意到 Werner 发布了一个答案,解决了该包计算环境下限的方式中固有的棘手的小问题multicols
。:-)