pagination/insert_toc
Create some pages, assign labels to them and insert a table of contents at the beginning of the document.
Download PHP Code Switch to Java Code Show Output
<?php
/*
* Insert table of contents:
*
* Create some pages, assign labels to them and insert a table of contents at
* the beginning of the document.
*
* Pages are created in a different chronological order than the order in
* which they appear in the document. Using page groups create several pages
* and provide them with page labels. After creating the last page, go back
* to the start of the document and insert the pages for the table of contents.
*
* The table of contents is created twice, once using Textlines
* and once using Textflows.
*
* The entries on the table of contents pages can be clicked to jump to
* the corresponding page. This is implemented with matchboxes for the titles
* and with destinations.
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: none
*/
class toc_entry {
function __construct($text, $page, $destination) {
$this->text = $text;
$this->page = $page;
$this->destination = $destination;
}
}
/* This is where the data files are. Adjust as necessary. */
$searchpath = dirname(__FILE__,3)."/input";
$title = "Insert Table of Contents";
$docsize = 0;
/*
* Using the "groups" option, define several page groups for the title
* (title), the table of contents (toc), the individual chapters (body),
* and the index (index). List them in the order they will appear in the
* document. Using the "labels" option, assign a page label to each page
* group.
*/
$optlist = "groups={title toc content index} " .
"labels={{group=title prefix=title} " .
"{group=toc prefix={toc } start=1 style=r} " .
"{group=content start=1 style=D} " .
"{group=index prefix={index } start=1 style=r}} " .
"destination={type=fitwindow}";
try {
$p = new pdflib();
$toc_entries = array();
$p->set_option("searchpath={" . $searchpath . "}");
/* This means we must check return values of load_font() etc. */
$p->set_option("errorpolicy=return");
if ($p->begin_document("", $optlist) == 0)
throw new Exception("Error: " . $p->get_errmsg());
$p->set_info("Creator", "PDFlib Cookbook");
$p->set_info("Title", $title);
/* Create a page in the page group "title" */
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group title");
$docsize += 1;
$p->fit_textline("Title", 50, 700, "fontname=NotoSerif-Bold fontsize=36");
$p->end_page_ext("");
/* Counter for all destinations */
$destno = 0;
/* Loop over all pages in the page group "content" */
for($pageno = 1; $pageno <= 5; $pageno ++) {
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group content");
$docsize += 1;
$headline = "Chapter " . $pageno;
$destname = "dest" . $destno;
$p->fit_textline($headline, 50, 700,
"fontname=NotoSerif-Bold fontsize=36 " .
"matchbox={name=" . $destname . "}");
$p->end_page_ext("");
add_toc_entry_from_matchbox($p, $toc_entries, $pageno, $headline,
$destname);
$destno += 1;
}
/* Insert two pages in the page group "index" */
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group index");
$docsize += 1;
$headline = "Index I";
$destname = "dest" . $destno;
$p->fit_textline($headline, 50, 700,
"fontname=NotoSerif-Bold fontsize=36 " .
"matchbox={name=" . $destname . "}");
add_toc_entry_from_matchbox($p, $toc_entries, $pageno, $headline, $destname);
$destno += 1;
$pageno += 1;
$p->end_page_ext("");
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group index");
$docsize += 1;
$headline = "Index II";
$destname = "dest" . $destno;
$p->fit_textline($headline, 50, 700,
"fontname=NotoSerif-Bold fontsize=36 " .
"matchbox={name=" . $destname . "}");
add_toc_entry_from_matchbox($p, $toc_entries, $pageno, $headline, $destname);
$destno += 1;
$pageno += 1;
$p->end_page_ext("");
$xoff = 50;
/*
* Insert two pages in the page group "toc" for a table of contents
*/
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group toc");
$docsize += 1;
$p->fit_textline("Table of Contents I", $xoff, 700,
"fontname=NotoSerif-Bold fontsize=36");
/* Create table of contents entries with textlines */
$toc_textboxwidth = 400;
$yoff = 20;
$textfontopts = "fontname=NotoSerif-Regular fontsize=14";
$textopts = $textfontopts . " boxsize={" . $toc_textboxwidth . " 30} " .
"leader={alignment=right}";
$numopts = "fontname=NotoSerif-Bold fontsize=14";
$y = 660;
for($i = 0; $i < count($toc_entries); $i += 1, $y -= $yoff) {
$entry = $toc_entries[$i];
$text_entry_matchbox = "temb" . $i;
/* Place the text line */
$p->fit_textline($entry->text, $xoff, $y,
$textopts . " matchbox={name=" . $text_entry_matchbox .
"}");
$num_entry_matchbox = "nummb" . $i;
$p->fit_textline($entry->page, $xoff + $toc_textboxwidth, $y,
$numopts . " matchbox={name=" . $num_entry_matchbox . "}");
/*
* Create link annotations for both matchboxes
*/
$p->create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" . $text_entry_matchbox . "} " .
"destname={" . $entry->destination .
"} linewidth=0");
$p->create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" . $num_entry_matchbox . "} " .
"destname={" . $entry->destination .
"} linewidth=0");
}
$y -= $yoff;
$p->fit_textline("Click on TOC entry to jump to page", $xoff, $y,
$textfontopts);
$p->end_page_ext("");
/* Create table of contents with textflow */
$tf_optlist = "fontname=NotoSerif-Regular fontsize=12 " .
"leading=160% ruler=100% " .
"hortabmethod=ruler tabalignment=right";
$toc_tf_text = "";
/*
* Build the text for the whole textflow containing the TOC entries.
*/
$tf_entry_matchbox_name = "tfentmb";
for($i = 0; $i < count($toc_entries); $i++) {
$entry = $toc_entries[$i];
$tf_entry_matchbox = $tf_entry_matchbox_name . $i;
$entry_text = "<alignment=left><matchbox={name=" . $tf_entry_matchbox .
"}>" . $entry->text . "<leader={alignment={grid}}>\t" .
$entry->page . "<matchbox=end><nextline>";
$toc_tf_text .= $entry_text;
}
$toc_tf_text .= "<nextline>Click on TOC entry to jump to page";
$toc_tf = $p->create_textflow($toc_tf_text, $tf_optlist);
if ($toc_tf == 0)
throw new Exception("Error: " . $p->get_errmsg());
$p->begin_page_ext(0, 0, "width=a4.width height=a4.height group toc");
$docsize += 1;
$p->fit_textline("Table of Contents II", $xoff, 700,
"fontname=NotoSerif-Bold fontsize=36");
$p->fit_textline("for a Document of " . $docsize . " Pages.", 50, 650,
"fontname=NotoSerif-Bold fontsize=24");
/* Error handling and overflow handling omitted here */
$p->fit_textflow($toc_tf, $xoff, $xoff, $xoff + $toc_textboxwidth, 600, "");
/* Create Link annotations for matchboxes */
for($i = 0; $i < count($toc_entries); $i++) {
$tf_entry_matchbox = $tf_entry_matchbox_name . $i;
$entry = $toc_entries[$i];
$p->create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" . $tf_entry_matchbox . "} " .
"destname={" . $entry->destination .
"} linewidth=0");
}
$p->end_page_ext("");
$p->end_document("");
$buf = $p->get_buffer();
$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=insert_toc.pdf");
print $buf;
}
catch (PDFlibException $e) {
echo("PDFlib exception occurred:\n" . "[" . $e->get_errnum() . "] " .
$e->get_apiname() . ": " . $e->get_errmsg() . "\n");
exit(1);
}
catch (Throwable $e) {
echo("PHP exception occurred: " . $e->getMessage() . "\n");
exit(1);
}
$p = 0;
function add_toc_entry_from_matchbox($p, &$toc_entries, $pageno, $headline,
$matchboxname) {
/* Retrieve y coordinate of upper edge of matchbox. */
$top = $p->info_matchbox($matchboxname, 1, "y4");
$p->add_nameddest($matchboxname, "top=" . $top);
/* Create an entry in the list of TOC entries. */
array_push($toc_entries, new toc_entry($headline, $pageno, $matchboxname));
}
?>