6

EDIT: To clarify my question: I am not looking for an index that will start without a page break; I, rather, want an index where I manually would take care of the page break.

Say you've inserted a ton of \clearpages, to make sure that the "next" page starts on pg 37. Now you want to insert the index "here", at page 37 - so you type \printindex[names] there - and, surprise - the index now starts at page 38, because the index decided to enter one more \clearpage :/ And that means now you have to go back, and re-enter ammount of \clearpages, so they match to page N-1; so that along with the extra pagebreak, the index will start where at page N. This I'd see as an unnecessary complication.

Second, let's say you don't want to use the default section title of \printindex; you'd rather use \section*. The easiest thing to think of (without knowing any better), is to suppress the default index heading (in this case, since the example is for \printindex from index package, that would be in \newindex command):

\newindex{names}{ndx}{nnd}{}  % instead of: {names}{ndx}{nnd}{Name Index}

... (which does indeed suppress the default index heading) - and then, instead of that heading, one would type \section*{Name Index} followed by a \printindex[names]. Obviously, if \printindex inserts its own pagebreak, then this approach won't work, since the section title and the first page of the index will be on different pages - which is precisely what the MWE in this question demonstrates....


Damn it, I'm really starting to hate Latex :/ naah... :)

Take a look at the following MWE:

\documentclass[a4paper,twoside,11pt]{book}


% must load index before hyperref, else no hyperlinks!
\usepackage{index}
\usepackage{hyperref}
\usepackage{trace}

% declare new index files
\newindex{names}{ndx}{nnd}{Name Index}
\newindex{titles}{tdx}{tnd}{Title Index}

\usepackage{forloop}
\usepackage{trace}

% expandable modulo operation
\def\truncdiv#1#2{((#1-(#2-1)/2)/#2)}
\def\moduloop#1#2{(#1-\truncdiv{#1}{#2}*#2)}
\def\modulo#1#2{\number\numexpr\moduloop{#1}{#2}\relax}


% needed to generate index files
\newcounter{ct}
\def\modme{10}

% generate names (.nnd) index file
\newwrite\tempnnd
\immediate\openout\tempnnd=\jobname.nnd
\immediate\write\tempnnd{\protect\noexpand\begin{theindex}}

\forLoop[1]{0}{255}{ct}{
    \immediate\write\tempnnd{%
      \protect\noexpand\item Surname\thect, Name\thect, %
      %\protect\noexpand\hyperpage{\thect}
      % hyperlink all to page 1, 
      % to avoid Latex complaining:
      \protect\noexpand\hyperpage{1} %
    }
    \ifnum\modulo\thect\modme=0
      \immediate\write\tempnnd{}
      \immediate\write\tempnnd{\protect\noexpand\indexspace}
      \immediate\write\tempnnd{}
    \else
    \fi
}
\immediate\write\tempnnd{\protect\noexpand\end{theindex}}
\immediate\closeout\tempnnd

% generate titles (.tnd) index file
\newwrite\temptnd
\immediate\openout\temptnd=\jobname.tnd
\immediate\write\temptnd{\protect\noexpand\begin{theindex}}

\forLoop{0}{255}{ct}{
    \immediate\write\temptnd{%
      \protect\noexpand\item \noexpand\emph {Title of Work\thect}, %
      %\protect\noexpand\hyperpage{\thect}
      % hyperlink all to page 1, 
      % to avoid Latex complaining:
      \protect\noexpand\hyperpage{1} %
    }
    \ifnum\modulo\thect\modme=0
      \immediate\write\temptnd{}
      \immediate\write\temptnd{\protect\noexpand\indexspace}
      \immediate\write\temptnd{}
    \else
    \fi
}
\immediate\write\temptnd{\protect\noexpand\end{theindex}}
\immediate\closeout\temptnd


\begin{document}

\clearpage

\section*{Test 1}
\addcontentsline{toc}{section}{Test 1}

\phantomsection % NOTE NO PAGEBREAK PRESENT AROUND HERE!
\addcontentsline{toc}{chapter}{Name Index} \traceon
\printindex[names] \traceoff

\phantomsection
\addcontentsline{toc}{chapter}{Title Index} % master TOC and PDF bookmark
\printindex[titles] % the title index

\end{document}

The first two pages of the output are:

test.png

Generated with:

montage -bordercolor LimeGreen -border 1 -density 100 test.pdf[0] test.pdf[1] -geometry +2+2 -tile 2x1 test.png

My question is:

Can someone explain to me why there a pagebreak before the Name Index section - and how do I remove it?

 

As seen in the MWE, I even tried tracing for it:

$ grep -C10 'Surname0' b.log
{into \Hy@temp=macro:->}
{\ifx}
{true}
{\else}
{blank space  }
{\relax}

\item ->\par \hangindent 40\p@                 <= \item
{\par}                                         <= \par (?)
@firstpass
[]\OT1/cmr/m/n/10.95 Surname0, Name0, []0[]    <= typeset Surname0
@\par via @@0 b=0 p=-10000 d=100
@@1: line 1.2- t=100 -> @@0

{changing \hangindent=40.0pt}
{into \hangindent=0.0pt}
%% goal height=476.5225, max depth=5.5         <= pagebreak?!
% t=0.0 g=476.5225 b=10000 p=0 c=100000#       <=    WHERE FROM??
{vertical mode: \hangindent}
{changing \hangindent=0.0pt}
{into \hangindent=40.0pt}

... but I simply don't understand which command would cause a new page after the first name is typeset ?! And if the pagebreak happened after Surname0 got typeset, why isn't Surname0 on first page ??!

2
  • 3
    An index in the book documentclass is set as a chapter and issues \clearpage before creating the heading. To see this, search for the definitions of theindex in book.cls and \twocolumn (called by the theindex environment) in latex.ltx.
    – Werner
    Jun 25, 2012 at 5:35
  • Many thanks for that, @Werner - not knowing any better, I started by hacking \renewenvironment{theindex} and \def\@showidx from index.sty; that could have been quite a dead end for me without your pointer! I managed to remove the pagebreak (post below) - however, that also messes up the twocolumn layout of the index :) Still, great to know where the pagebreak was initiated from (I just wish I could debug myself to those kinds of conclusions). Many thanks again - cheers!
    – sdaau
    Jun 25, 2012 at 6:02

3 Answers 3

6

The problem seems quite abstract, because it's quite rare to have an index start without a page break. However, here is a possibility. Since you don't want page breaks, it's necessary to avoid any automatism in index generation.

\documentclass[a4paper,twoside,11pt]{book}

\usepackage[noautomatic,nonewpage]{imakeidx}
\usepackage{hyperref}

% declare new index files
\makeindex[name=names,title=Name Index,intoc]
\makeindex[name=titles,title=Title Index,intoc]
\indexsetup{level=\section*} % no page break with sections

\begin{document}

\tableofcontents

% generate fake index entries
\count255=0
\loop\ifnum\count255<200
  \index[names]{Surname\number\count255, Name\number\count255}
  \index[titles]{Title of Work\number\count255}
  \advance\count255 1
\repeat

\clearpage

\phantomsection
\section*{Test 1}
\addcontentsline{toc}{section}{Test 1}

\printindex[names]
\printindex[titles]

\end{document}
5
  • Thank you for the answer, @egreg - I'm never keen on switching packages; however your answer code works fine, and behaves as I expect it to - so I'll be switching from package index to package imakeidx :) Btw, I appreciate this example a lot - it was nearly impossible for me to find examples that would compare code for index and code for imakeidx (so fx. one can see that \newindex from index corresponds to \makeindex from imakeidx). Many thanks again - cheers!
    – sdaau
    Jun 25, 2012 at 11:44
  • Why is it necessary to avoid the automation, though? Either texindy is ran via \write18 and the resulting .ind is included into the page immediately, or I run texindy manually and the resulting .ind is included into the page in the next run. I don't see the difference, but there has to be one, doesn't there?
    – Witiko
    Nov 25, 2015 at 22:38
  • @Witiko If there's no page break, entries defined in the last page won't appear in the index.
    – egreg
    Nov 25, 2015 at 23:04
  • Wouldn't making the \writes in the definition of \index \immediate fix this?
    – Witiko
    Nov 26, 2015 at 8:29
  • @Witiko No, the page numbers are known only during the output routine.
    – egreg
    Nov 26, 2015 at 8:32
3

write into the preamble:

\documentclass[a4paper,twoside,11pt]{book}

\usepackage{index}
\usepackage{multicol}
\makeatletter
\renewenvironment{theindex}
  {{\huge\indexname}\par%
   \@mkboth{\MakeUppercase\indexname}{\MakeUppercase\indexname}%
   \parindent\z@
   \parskip\z@ \@plus .3\p@\relax
   \let\item\@idxitem
   \begin{multicols}{2}}
  {\end{multicols}}
\makeatother
...
3
  • Thanks for that, @Herbert - that looked really good, but when I add that snippet to the preamble of the MWE in OP (right after the \immediate\closeout\temptnd line), I get "! LaTeX Error: \begin{theindex} on input line 1 ended by \end{multicols}." Could it be due to a typo of sorts? Cheers!
    – sdaau
    Jun 25, 2012 at 11:12
  • 1
    I edited my answer. It works for me with your MWE
    – user2478
    Jun 25, 2012 at 11:23
  • Many thanks for the edit, @Herbert - now it works great; as a bonus, the sectioning is now separate ({\huge\indexname}\par), so I can remove it and use a \section* instead... While this answer is the one matching the question more closely (it still uses index, with addition of multicol), I'll keep the accept with @egreg's answer, because it allows for comparison between packages index and imakeidx, which I thought was impossible to find. Many thanks again - cheers!
    – sdaau
    Jun 25, 2012 at 11:53
0

A big thanks to @Werner (in OP comments) for the most crucial pointer!

Unfortunately, instead of going through book.cls and latex.ltx, I - not knowing any better - tried to look at index.sty; but that doesn't reveal anything but a couple of \clearpages (which should run after, not before the index is typeset).

The definitions of theindex and \twocolumn can be easily confirmed with texdef:

$ texdef -t latex -c book -p index \theindex -f
\theindex first defined in "book.cls".

\theindex:
\long macro:->\edef \indexname {\the \@nameuse {idxtitle@\@indextype }}\if@twocolumn \@restonecolfalse \else \@restonecoltrue \fi \columnseprule \z@ \columnsep 35\p@ \twocolumn [\@makeschapterhead {\indexname }\ifx \index@prologue \@empty \else \index@prologue \bigskip \fi ]\@mkboth {\MakeUppercase \indexname }{\MakeUppercase \indexname }\thispagestyle {plain}\parindent \z@ \parskip \z@ \@plus .3\p@ \relax \let \item \@idxitem 

2$ texdef -t latex -c book -p index \twocolumn -f
\twocolumn is defined by (La)TeX.

\twocolumn:
macro:->\clearpage \global \columnwidth \textwidth \global \advance \columnwidth -\columnsep \global \divide \columnwidth \tw@ \global \hsize \columnwidth \global \linewidth \columnwidth \global \@twocolumntrue \global \@firstcolumntrue \col@number \tw@ \@ifnextchar [\@topnewpage \@floatplacement 

(NB: I was staring at \twocolumn for a couple of minutes, before realizing the \clearpage is the first token there :))

Thus, we can finally insert this redefinition before the indexes are printed:

....
\makeatletter
\def \twocolumn {%
  %\clearpage
  \global\columnwidth\textwidth
  \global\advance\columnwidth-\columnsep
  \global\divide\columnwidth\tw@
  \global\hsize\columnwidth
  \global\linewidth\columnwidth
  \global\@twocolumntrue
  \global\@firstcolumntrue
  \col@number \tw@
  \@ifnextchar [\@topnewpage\@floatplacement
}
\makeatother

\phantomsection % NOTE NO PAGEBREAK PRESENT AROUND HERE!
\addcontentsline{toc}{chapter}{Name Index} %\traceon
\printindex[names] %\traceoff

\phantomsection
\addcontentsline{toc}{chapter}{Title Index} % 
\printindex[titles] % 

\end{document}

... and indeed - finally the page break is gone! However, there is another problem now - even if you suppress the title like this:

\newindex{names}{ndx}{nnd}{}

... still the layout of the index will be messed up - given the index is typeset in two column mode - seemingly, the "\section*{Test 1}" will "push" the left column down - and so it won't look good:

test.png

... but at least the page break is gone :)

You must log in to answer this question.

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