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 = "" . $entry->text . "\t" . $entry->page . ""; $toc_tf_text .= $entry_text; } $toc_tf_text .= "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)); } ?>