+CairoHacks.env <- new.env()
+CairoHacks.env$device_set_up <- FALSE
+CairoHacks.env$current_page <- 0
+
+##' Make a bookmark for a PDF for later saving to the pdf with
+##' \code{write.pdf.bookmarks}
+##'
+##'
+##' @title make.bookmark
+##' @param text Text of bookmark to create
+##' @param level Optional bookmark level which defaults to 1. This
+##' enables you to have headings and sub-headings and so forth, simply
+##' by increasing the number passed.
+##' @param page Optional page number to write the bookmark to. If you
+##' are using a Cairo device, this is automatically set for you to be
+##' the page which you are currently writing to.
+##' @return list of bookmarks to be passed to write.bookmarks or
+##' further calls to save.bookmark
+##' @author Don Armstrong <don@@donarmstrong.com>
+##' @export
+##' @examples
+##' CairoPDF(file="example.pdf",onefile=TRUE)
+##' plot(y~x,data.frame(x=1:5,y=1:5))
+##' bookmarks <- make.pdf.bookmark("First plot")
+##' plot(y~x,data.frame(x=1:5,y=1:5))
+##' bookmarks <- bookmarks + make.pdf.bookmark("Second plot")
+##' dev.off()
+##' write.pdf.bookmarks(file="example.pdf",bookmarks)
+make.pdf.bookmark <- function(text,level=1,page=NULL) {
+ if (!CairoHacks.env$device_set_up) {
+ Cairo.onSave(device = dev.cur(),
+ onSave=function(device,page){
+ ch <- getNamespace("CairoHacks")
+ print(ls(envir=ch))
+ assign("current_page",
+ page,
+ envir=ch[["CairoHacks.env"]])
+ })
+ CairoHacks.env$device_set_up <- TRUE
+ }
+ if (missing(page)|| is.null(page)) {
+ page <- CairoHacks.env$current_page
+ }
+ p <- structure(list(
+ bookmarks=list(
+ list(text=text,
+ level=level,
+ page=page))
+ ), class = c("CairoHacks_bookmark"))
+ return(p)
+}
+##' Add additional bookmarks to a bookmark
+##'
+##' Given a bookmarks object created with make.pdf.bookmark, add more
+##' bookmarks to it.
+##' @title + CairoHacks_bookmark
+##' @param b1 An object of class CairoHacks_bookmark.
+##' @param b2 An object of class CairoHacks_bookmark
+##' @export
+##' @method + CairoHacks_bookmark
+##' @author Don Armstrong <don@@donarmstrong.com>
+"+.CairoHacks_bookmark" <- function(b1,b2) {
+ b1[["bookmarks"]] <-
+ c(b1[["bookmarks"]],
+ b2[["bookmarks"]])
+ b1
+}
+##' Write saved bookmarks to the PDF file which was generated
+##'
+##' Given a set of bookmarks generated with make.pdf.bookmark, write
+##' them out to a PDF file using pdftk.
+##' @title write.pdf.bookmarks
+##' @param file file name of pdf which was saved to disk
+##' @param bookmarks list of bookmarks
+##' @return list of bookmarks
+##' @author Don Armstrong <don@@donarmstrong.com>
+##' @export
+write.pdf.bookmarks <- function(file,bookmarks) {
+ pdf.bookmarks <- ""
+ print(bookmarks[["bookmarks"]])
+ for (bookmark in 1:length(bookmarks[["bookmarks"]])) {
+ pdf.bookmarks <-
+ paste0(pdf.bookmarks,
+ "BookmarkBegin\n",
+ "BookmarkTitle: ",bookmarks[["bookmarks"]][[bookmark]][["text"]],"\n",
+ "BookmarkLevel: ",bookmarks[["bookmarks"]][[bookmark]][["level"]],"\n",
+ "BookmarkPageNumber: ",bookmarks[["bookmarks"]][[bookmark]][["page"]],"\n")
+ }
+ temp.pdf <- tempfile(pattern=basename(file))
+ temp.pdf.info <- tempfile(pattern=paste0(basename(file),"info_utf8"))
+ cat(file=temp.pdf.info,pdf.bookmarks)
+ system2("pdftk",c(file,'update_info_utf8',temp.pdf.info,'output',temp.pdf))
+ if (file.exists(temp.pdf)) {
+ file.rename(temp.pdf,file)
+ } else {
+ stop("unable to properly create bookmarks")
+ }
+ invisible(bookmarks)
+}