我如何检测自己是否位于列的顶部?

我如何检测自己是否位于列的顶部?

我有一系列采用 2 列布局的文本块,使用multicol。每个文本块都包裹在一个minipage环境中,以确保所有包含的文本都显示在同一列中。我想用水平线或其他装饰将这些小页面分开,但如果它位于列的顶部,我不希望规则出现。

显然,我可以添加一个参数来手动抑制该规则,但我正在寻找一种自动检测情况并适当格式化的方法。对于下面的 MWE,这意味着该行应该只出现在最后两段之间。

\documentclass{article}
\usepackage{multicol}
\usepackage{lipsum}

\newenvironment{segmented}{%
\begin{minipage}{\linewidth}
\hrule\bigskip
}{\bigskip
\end{minipage}}

\begin{document}
    \begin{multicols}{2}
    \begin{segmented}
        \lipsum[1]  
    \end{segmented}
    \begin{segmented}
        \lipsum[2]  
    \end{segmented}
    \begin{segmented}
        \lipsum[3]  
    \end{segmented}
    \end{multicols}
\end{document}

答案1

这是你想要得到的吗?

\documentclass{article}
\usepackage[latin]{babel}% for avoiding too many underfull boxes
\usepackage{multicol}
\usepackage{lipsum}

\newenvironment{segmented}
 {%
  \noindent\begin{minipage}{\linewidth}
 }
 {%
  \end{minipage}\par
  \bigskip
  \cleaders\vbox{\hrule width\linewidth}\vskip0.4pt
  \bigskip
 }

\begin{document}

\begin{multicols}{2}
\begin{segmented}
\lipsum[1]  
\end{segmented}
\begin{segmented}
\lipsum[2]  
\end{segmented}
\begin{segmented}
\lipsum[3]  
\end{segmented}
\end{multicols}

\end{document}

在此处输入图片描述

答案2

可能有更好的方法可以做到这一点,但是@Werner 的链接给了我这个想法。它依赖于colaction以下功能multicol

\documentclass{article}
\usepackage[colaction]{multicol}
\usepackage{etoolbox}
\usepackage{lipsum}

\numdef{\columnnumber}{0}
\newcommand{\conditionalrule}[1]{
    \ifnumequal{#1}{\columnnumber}{\hrule}{}
    \global\numdef{\columnnumber}{#1}
    }

\newenvironment{segmented}{%
\noindent\begin{minipage}{\linewidth}
    \docolaction{\conditionalrule{1}}{}{\conditionalrule{2}}\bigskip
}{\bigskip
\end{minipage}}

\begin{document}
    \begin{multicols}{2}
        \begin{segmented}
            \lipsum[1]  
        \end{segmented}
        \begin{segmented}
            \lipsum[2]  
        \end{segmented}
        \begin{segmented}
            \lipsum[3]  
        \end{segmented}
    \end{multicols}
\end{document}

多列线

如果有人有更优雅/高效的解决方案,我很乐意接受他们的答案,所以我暂时不会接受我自己的答案。

答案3

您可以让 TeX 确定位置(在 multicol 之内或之外起作用):

\documentclass[]{article}
\usepackage{multicol,lipsum}

\usepackage{xparse}

\ExplSyntaxOn

\dim_new:N \l__condline_dim
\box_new:N \l__condline_box

% #1 skip produced
% #2 vertical correction of material
% #3 material 
% #4 break penalty after (if forbidden the only place to break is before

\cs_new:Npn \condline:nn #1#2#3#4 
  {
    \par
    \hbox_set_to_wd:Nnn \l__condline_box \columnwidth {\hfil #3 \hfil}
%
    \dim_set:Nn \l__condline_dim
        { \box_ht:N \l__condline_box +
          \box_dp:N \l__condline_box }
%
    \skip_vertical:n { #1 / 2 - \prevdepth + #2 - \l__condline_dim / 2 }
    \nobreak    
%
    \cleaders \copy \l__condline_box \vskip \l__condline_dim
    \nobreak    
%
    \skip_vertical:n { #1 / 2 - \parskip  - #2 - \l__condline_dim / 2 }
    \penalty #4 \relax 
%
    \dim_set:Nn \prevdepth { 0pt }
  }

% document level command
%
% \condline * < correction > [ skip ] { material }
%
% all arguments optional

\DeclareDocumentCommand\condline 
  { s  D<>{3pt} O{\baselineskip} G{$*\quad*\quad*$} }
  { \IfBooleanTF #1
      { \condline:nn {#3} {#2} {#4} {10000} }
      { \condline:nn {#3} {#2} {#4} {0} }
  }

\ExplSyntaxOff

\begin{document}
\begin{multicols}{3}
  \lipsum[1]
  \condline{...........}
  line1\\  line2\\  line3\\  line4\\ line5\\  
  add two extra lines
  and the stars below will vanish!\\
 % line9\\  line10\\
  LAST LAST LAST
  \condline{$* \quad * \quad * $}
  \lipsum[2]
\end{multicols}

  \condline<-5pt>{\hrulefill}

\begin{multicols}{2}
  \lipsum[3]
  \condline{\hrulefill}
  \lipsum[4]
  \condline[2\baselineskip]{---With star this line would vanish }
  \lipsum[5]
  \condline{\dotfill}
  \lipsum[6]
\end{multicols}

\end{document} 

(该代码有点像 expl3 + 普通 LaTeX 的混合,因为 expl3 尚未具备所有文本处理工具(如处理处罚))

结果是:

在此处输入图片描述

\condline如果我们在第一个多列中添加 2 行,并在第二个多列中使用星号形式,我们将得到:

在此处输入图片描述

现在,右下角的列似乎太短了,但这是可以理解的,因为现在唯一的中断是在之前,\condline并且如果在那里中断,该线就会消失(就像第一个多列中带有星号的线在中断处消失一样)。

答案4

一份提案:

\documentclass{article}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{zref-savepos}%

\newcount\myy\newcount\ymax
\newcounter{myx}\setcounter{myx}{1}

\typeout{\themyx}
\newcommand\donotruleattop{%
    \stepcounter{myx}
    \zsaveposy{\themyx}%
    \typeout{y position of \themyx: \zposy{\themyx}}
    \myy=\numexpr\zposy{\themyx}\relax
    \ifnum\myy>\ymax\relax\else\hrule\bigskip\fi
}%
\newcommand{\gaugeymax}{%
\stepcounter{myx}
\zsaveposy{\themyx}
\ymax=\numexpr\zposy{\themyx}-256\relax
}

\newenvironment{segmented}{%
\noindent\begin{minipage}{\linewidth}\donotruleattop
}{\bigskip
\end{minipage}}

\begin{document}\gaugeymax 
    \begin{multicols}{2}
    \begin{segmented}
        \lipsum[1] 
    \end{segmented}
    \begin{segmented}
        \lipsum[2] 
    \end{segmented}
    \begin{segmented}
        \lipsum[3] 
    \end{segmented}
    \end{multicols}
\end{document}

在此处输入图片描述

有一个缺点:定义中出现的数字256是硬编码的,如果您更改文档的布局,可能需要进行调整。

尽管如此,这可能是一个更顺利的解决方案的起点。它既是@Werner 陈述的反例,也是对它的确认,这取决于你所说的“容易”是什么意思。

显然,这种构造并不是多列所特有的。

相关内容