16

I am writing my indices with imakeidx and I want to use sub-entries as well. As you can see on my image, I am getting a column break which I think is making it more difficult to understand. Can I control that somehow? Should I?

enter image description here

Edit If I would have "gap", "axial", and "radial" a separation between the last two would not disturb very much. But the split directly after "gap" looks strange.


MWE for play-around:

% arara: lualatex
% arara: makeindex
% arara: lualatex

\documentclass{article}
\usepackage{imakeidx}
% we don't want a page break before THE FIRST subitem
\makeatletter\renewcommand\subitem{\nobreak\@idxitem\hspace*{20\p@}}\makeatother
\makeindex
\begin{document}
\index{gap!radial}\index{gap!axial}
\index{gapa!radial}\index{gapa!axial}
\index{gapb!radial}\index{gapb!axial}
\index{gapc!radial}\index{gapc!axial}
\index{gapd!radial}\index{gapd!axial}
\index{gap1!radial}\index{gap1!axial}
\index{gapa1!radial}\index{gapa1!axial}
\index{gapb1!radial}\index{gapb1!axial}
\index{gapc1!radial}\index{gapc1!axial}
\index{gapd1!radial}\index{gapd1!axial}
\index{gap2!radial}\index{gap2!axial}
\index{gapa2!radial}\index{gapa2!axial}
\index{gapb2!radial}\index{gapb2!axial}
\index{gapc2!radial}\index{gapc2!axial}
\index{gapd2!radial111}\index{gapd2!axial111}
\printindex
\end{document}

The column break should appear before gapd2 or after axial111.

LaRiFaRi
  • 43,807

2 Answers2

20

The solution is to move \nobreak after \@idxitem:

% arara: lualatex
% arara: makeindex
% arara: lualatex

\documentclass{article}
\usepackage{makeidx}

\makeatletter
% we don't want a page break before a subitem
\renewcommand\subitem{\@idxitem\nobreak\hspace*{20\p@}}
\makeatother

\makeindex
\begin{document}
\index{gap!radial}\index{gap!axial}
\index{gapa!radial}\index{gapa!axial}
\index{gapb!radial}\index{gapb!axial}
\index{gapc!radial}\index{gapc!axial}
\index{gapd!radial}\index{gapd!axial}
\index{gap1!radial}\index{gap1!axial}
\index{gapa1!radial}\index{gapa1!axial}
\index{gapb1!radial}\index{gapb1!axial}
\index{gapc1!radial}\index{gapc1!axial}
\index{gapd1!radial}\index{gapd1!axial}
\index{gap2!radial}\index{gap2!axial}
\index{gapa2!radial}\index{gapa2!axial}
\index{gapb2!radial}\index{gapb2!axial}
\index{gapc2!radial}\index{gapc2!axial}
\index{gapd2!radial}\index{gapd2!axial}
\printindex
\end{document}

enter image description here

The standard definition of \subitem is without \nobreak; the command \@idxitem just does a \par and sets \hangindent, so if we add the penalty (\nobreak is \penalty 10000) after it, TeX will not break a page at this point.


If you just want that the first subitem remains attached to the main entry, then change the code between \makeatletter and \makeatother into

\makeatletter
% we don't want a page break before the first subitem
\newif\iffirst@subitem
\def\@idxitem{%
  \par\hangindent40\p@ % original
  \first@subitemtrue   % added
}
\def\subitem{%
  \par\hangindent40\p@
  \iffirst@subitem
    \nobreak
    \first@subitemfalse
  \fi
  \hspace*{20\p@}}
\makeatother

This will add the penalty only between a main item and the first subitem.

egreg
  • 1,121,712
2

I'm working with lengthy index for a textbook. I found it useful implement egreg's suggestion using LaTeX's renewcommand, which I could drop into the preamble. This code also suppresses breaks before first subsubitem and keeps \see entries on the same page. (The \see fix is somewhat experimental, as I'm not sure it will be appropriate for longer entries, but it does eliminate widows...)

    \newif\iffirst@subitem
    \newif\iffirst@subsubitem\first@subsubitemfalse
    \renewcommand\@idxitem{\par\hangindent 40\p@ \first@subitemtrue}
    \renewcommand\subitem{\par\hangindent 
           40\p@\iffirst@subitem\nobreak\first@subitemfalse\fi 
           \hspace*{20\p@}\first@subsubitemtrue}
    \renewcommand\subsubitem{\par\hangindent 
           40\p@\iffirst@subsubitem\nobreak\first@subsubitemfalse\fi 
           \hspace*{30\p@}}
    \renewcommand\see[2]{\samepage\emph{\seename} #1}
John
  • 2,400