0

I have code that generates multiple lists of data in the form of XeLaTeX source. Because the lines of data are very short, I'm presenting it in a multicols environment. Each list has a few headings in it. Occasionally the list of data is very short – just a single heading and one line of data – and in this case, I'm struggling to prevent the heading and following line from being split across columns. Here's a MWE showing the problem and my attempt to fix it using \needspace:

\documentclass[a4paper]{article}
\usepackage{multicol}
\usepackage{needspace}
\newcommand{\tblheading}[1]{\needspace{2\baselineskip}\textbf{#1}\newline}
\begin{document}
\begin{multicols}{3}
\tblheading{Heading}
Entry
\end{multicols}
\end{document}

I've tried using \Needspace* instead of \needspace, I've also tried adding \raggedcolumns, increasing the requested space from 2\baselineskip, and using \par, \\ or \\* instead of \newline, but whatever I try, I cannot prevent these two lines from being split between two columns. Can anyone help?

(I know that in principle I could use a minipage or perhaps samepage environment, but I don't think that's possible here because I really need to keep the special handling within the \tblheading macro due to the way the data is generated.)

4
  • why don't you define a real heading command? Sep 11, 2020 at 11:53
  • @UlrikeFischer – what do you mean? I can't use \section, \subsection, etc., as they're already in use in the document.
    – richard
    Sep 11, 2020 at 11:57
  • well \subsection doesn't fall from the sky, it is defined in your class, and you can define more such commands if you want. Or you could use scrartcl as class and \minisec{Heading}. Sep 11, 2020 at 12:01
  • Changing to scrartcl breaks far too much, so that's not an option, though it does fix this particular problem. I've no idea what you mean when you say I can define more commands line \subsection. Isn't that what I've done? Presumably I've missed something relevant from my definition of \tblheading, but I don't know what – that's why I've posted the question.
    – richard
    Sep 11, 2020 at 12:05

2 Answers 2

1

The \minisec command of KOMA does more or less this:

\documentclass[a4paper]{article}
\usepackage{multicol}
\makeatletter
\newcommand\minisec[1]{%
    \if@noskipsec \leavevmode \fi
    \par
    \@afterindentfalse
    \if@nobreak
      \everypar{}%
    \else
      \addpenalty\@secpenalty\addvspace{1.5ex}% space before, adjust if needed
    \fi
  {\parindent \z@
   \setlength{\parfillskip}{\z@ plus 1fil}
    \normalfont\bfseries
    \nobreak\interlinepenalty \@M #1\par\nobreak%
  }\nobreak
  \@afterheading
}                              
\makeatother
\begin{document}
\begin{multicols}{3}
\minisec{Heading}
Entry
\end{multicols}
\end{document}
2
  • Unfortunately this seems to break inside the hangpara environment – or rather, the column breaking continues to work correctly, but hangpara stops working. I'm not going to be able to fix this myself because I haven't the faintest idea what your answer is doing or how it does it.
    – richard
    Sep 11, 2020 at 13:36
  • it does nothing much different to a \subsection command. Try if it works if you comment the \everypar{}. Sep 11, 2020 at 13:47
0

Multicol actually formats the entire page as a single column, then splits it into two or more equal lengths. It turns out that \@afterheading will not prevent this split from taking place, so \subsection* etc won't work either. My old version of \needspace will work, fortunately.

\documentclass[a4paper]{article}
\usepackage{multicol}
\setlength\columnseprule{.4pt}
\usepackage{lipsum}

\makeatletter
\newcommand{\tblheading}[1]{\par\rule{0pt}{\dimexpr 2\baselineskip-\dp\strutbox}\vspace{-2\baselineskip}\newline
  \indent\textbf{#1}\newline}
\makeatother

\begin{document}
\begin{multicols}{3}
\noindent\rule{\columnwidth}{49\baselineskip}% 48 will go in first column

\tblheading{Heading}
Entry

\lipsum[1-4]
\end{multicols}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .