A bit of warning from the OP: this code locked-up my Mathematica session, so be sure to save everything before you try this. Update: Problem seems to be related to a problem MMA has with paginating a particular notebook of mine (see comments).
This code creates a separate TOC for a notebook saved at the location bookUrl
. It works by iterating over all the cells in the book. If a cell is encountered whose type is in typeList
, a tag is added to the cell and a line is written to the TOC notebook. We use CounterBox["Page", {bookUrl, tag}]
to print the appropriate page number.
Note that due to the nature of CounterBox
, the page numbers are only shown in the TOC is the notebook of the book is open and ShowPageBreaks -> True
is set, but you should be able to print the TOC to a pdf.
createToc[bookUrl_, typeList_] :=
Module[{toc, book, createCell, counter, cell, type, tag},
(*create TOC file and open book*)
toc = CreateDocument[];
book = NotebookOpen[bookUrl];
SetOptions[book, ShowPageBreaks -> True];
(* helper file for creating cell *)
createCell[text_, tag_, level_] := Cell[BoxData[
TagBox[GridBox[{{"", text, CounterBox["Page", {bookUrl, tag}]}},
GridBoxAlignment -> {"Columns" -> {Left, Left, Right}},
GridBoxItemSize -> {"Columns" -> {2 level - 1, 35 - 2 level, 5}}],
"Grid"]], "Text"];
(* iterate over cells to set tags and write lines to TOC *)
Scan[(counter[#] = 0) &, typeList];
SelectionMove[book, Before, Notebook];
SelectionMove[book, Next, Cell];
While[(cell = NotebookRead[book]) =!= {},
If[Length[cell] >= 2,
type = cell[[2]];
If[MemberQ[typeList, type],
counter[type] += 1;
tag = type <> ToString[counter[type]];
SetOptions[NotebookSelection[book],
CellTags -> Union[Flatten[{Options[NotebookSelection[book],
CellTags][[1, 2]], tag}]]];
SelectionMove[book, All, CellContents];
NotebookWrite[toc,
createCell[NotebookRead[book], tag,
Position[typeList, type][[1, 1]]]]];
SelectionMove[book, Next, Cell]]];
SetSelectedNotebook[toc]];
To see the code in action, lets create a very simple document with 2 sections and 3 subsections on 3 pages
book = CreateDocument[];
NotebookWrite[book, Cell["This is section 1", "Section"]];
NotebookWrite[book, Cell["This is a subsection", "Subsection"]];
NotebookWrite[book, Cell["This is some text", "Text"]];
NotebookWrite[book,
Cell["Another section which begins on a new page", "Section",
PageBreakAbove -> True]];
NotebookWrite[book,
Cell["Subsection 2.1", "Subsection", PageBreakBelow -> True]];
NotebookWrite[book, Cell["Subsection 2.2", "Subsection"]];
bookUrl = ExpandFileName["book1.nb"];
NotebookSave[book, bookUrl];
Then createToc[bookUrl, {"Section", "Subsection"}]
creates something like this

File>Printing settings>Page Setup
. Mathematica is aware of the page breaks because you can have them shown using the optionFile>Printing settings>Show page breaks
. And indeed, I'm looking for an automatic method. It used to be possible, and it looks like all MMA books written in MMA have there TOC made up with MMA. So, how do they do it? $\endgroup$AuthorTools
code to see if you can update the bits you need? I hope Wolfram are reading this and will give us a workingAuthorTools
in version 9. $\endgroup$