How can I detect when I'm at the top of column?

Is it what you'd like to get?

\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}

enter image description here


There's probably a better way to do this, but @Werner's link gave me this idea. It relies on the colaction feature of 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}

multicol line

If anyone has a more elegant/efficient solution, I'd be happy to accept their answer, so I'm holding off on accepting my own answer for a little while.


You can let TeX determine the position (which works within or outside 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} 

(the code is a bit of a mixture of expl3 + ordinary LaTeX as expl3 doesn't yet have all tools for text processing (like handling penalties))

The result is:

enter image description here

And if we add 2 lines in the first multicol and use the star form of \condline in the second one we will get:

enter image description here

The right bottom column now appears to be too short but that is understandable as now the only break is before the \condline and the line vanishes if the break is taken there (just like the line with asterisks in the first multicol vanished at the break.

Tags:

Multicol