]> git.donarmstrong.com Git - r/CairoHacks.git/commitdiff
add start of CairoHacks package
authorDon Armstrong <don@donarmstrong.com>
Fri, 1 Jul 2016 18:36:02 +0000 (13:36 -0500)
committerDon Armstrong <don@donarmstrong.com>
Fri, 1 Jul 2016 18:36:02 +0000 (13:36 -0500)
12 files changed:
DESCRIPTION [new file with mode: 0644]
Makefile [new file with mode: 0644]
NAMESPACE [new file with mode: 0644]
R/CairoHacks.R [new file with mode: 0644]
R/bookmarks.R [new file with mode: 0644]
R/raster_plots.R [new file with mode: 0644]
man/CairoHacks.Rd [new file with mode: 0644]
man/make.pdf.bookmark.Rd [new file with mode: 0644]
man/plus-.CairoHacks_bookmark.Rd [new file with mode: 0644]
man/start_rasterplot.Rd [new file with mode: 0644]
man/stop_rasterplot.Rd [new file with mode: 0644]
man/write.pdf.bookmarks.Rd [new file with mode: 0644]

diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644 (file)
index 0000000..48e7bad
--- /dev/null
@@ -0,0 +1,20 @@
+Package: CairoHacks
+Type: Package
+Title: Various hacks for Cairo devices including PDF bookmarks and raster plots in PDFs
+Version: 1.0
+Date: 2016-06-20
+Authors@R: person("Don","Armstrong",email="don@donarmstrong.com",role=c("aut","cre"))
+Maintainer: Don Armstrong <don@donarmstrong.com>
+Depends: Cairo, grid
+Description: Routines which enable the addition of PDF bookmarks
+ (table of contents) to PDFs and methods to plot raster plots in the
+ middle of PDF plots.
+ .
+ Bookmarks enable the easy browsing of PDFs by table of contents/index
+ using pdftk.
+ .
+ Raster plots enable the inclusion of plots with millions of points or
+ lines in a vector format (such as a PDF) without making the PDF file
+ megabytes in size, while still allowing other plot components to be
+ presented in their original vector format.
+License: GPL (>=3)
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..b119c24
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+#!/usr/bin/make -f
+
+R ?= R
+ROPTS=-q --no-save --no-restore-data
+
+update_docs:
+       $(R) $(ROPTS) -e "devtools::document()"
+
+check:
+       $(R) $(ROPTS) -e "devtools::check(manual=TRUE)"
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644 (file)
index 0000000..4132a5e
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,9 @@
+# Generated by roxygen2 (4.1.1): do not edit by hand
+
+S3method("+",CairoHacks_bookmark)
+export(make.pdf.bookmark)
+export(start_rasterplot)
+export(stop_rasterplot)
+export(write.pdf.bookmarks)
+import(Cairo)
+import(grid)
diff --git a/R/CairoHacks.R b/R/CairoHacks.R
new file mode 100644 (file)
index 0000000..ea84fbe
--- /dev/null
@@ -0,0 +1,25 @@
+#' CairoHacks: Various hacks for Cairo devices including PDF bookmarks and raster plots in PDFs
+#'
+#' CairoHacks contains routines to allow you to include PDF bookmarks
+#' and raster plots inside of your PDFs.
+#'
+#' @section Bookmarks:
+#' 
+#' Bookmarks enable the easy browsing of PDFs by table of contents/index
+#' using pdftk.
+#'
+#' @seealso make.pdf.bookmark, write.pdf.bookmark
+#' 
+#' @section Raster Plots:
+#' 
+#' Raster plots enable the inclusion of plots with millions of points or
+#' lines in a vector format (such as a PDF) without making the PDF file
+#' megabytes in size, while still allowing other plot components to be
+#' presented in their original vector format.
+#'
+#' @seealso start_rasterplot, stop_rasterplot
+#'
+#' @docType package
+#' @name CairoHacks
+#' @author Don Armstrong <don@@donarmstrong.com>
+NULL
diff --git a/R/bookmarks.R b/R/bookmarks.R
new file mode 100644 (file)
index 0000000..4ced5a3
--- /dev/null
@@ -0,0 +1,99 @@
+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)
+}
diff --git a/R/raster_plots.R b/R/raster_plots.R
new file mode 100644 (file)
index 0000000..2e831a9
--- /dev/null
@@ -0,0 +1,74 @@
+##' Start a raster plot with indicated width or height in pixels
+##'
+##' This creates a Cairo device with output to /dev/null of width or
+##' height given (defaulting to a width of 1024)
+##' @title start_rasterplot
+##' @param width Width in pixels of raster image
+##' @param height Height in pixels of raster image. In general only
+##' one of \code{width} or \code{height} should be provided.
+##' @return NULL
+##' @author Don Armstrong
+##' @export
+##' @import Cairo grid
+##' @examples
+##' \dontrun{
+##' ### plot a raster plot in a PDF
+##' pdf()
+##' start_rasterplot()
+##' print(xyplot(y~x,
+##'      data=data.frame(y=rnorm(1E8),x=rnorm(1E8))))
+##' stop_rasterplot()
+##' dev.off()
+##' }
+##'
+##' ### plot a raster plot using grid.raster
+##' start_rasterplot(width=100)
+##' print(plot(y~x,
+##'             data=data.frame(y=rnorm(1E4),
+##'                             x=rnorm(1E4))))
+##' raster.image <- stop_rasterplot(plot=FALSE)
+##' grid.raster(raster.image)
+start_rasterplot <- function(width=NULL,height=NULL) {
+    x.y.ratio <- grid::convertX(grid::unit(1,"npc"),"mm",valueOnly=TRUE)/
+        grid::convertY(grid::unit(1,"npc"),"mm",valueOnly=TRUE)
+    width.points <- as.numeric(grid::convertX(grid::unit(1,"npc"),"points"))
+    dpi <- as.numeric(grid::convertX(grid::unit(1,"inch"),"point"))
+    if (is.null(width) && is.null(height)) {
+        width <- 1024
+    }
+    if (is.null(width)) {
+        width <- height*x.y.ratio
+    }
+    else if (is.null(height)) {
+        height <- width/x.y.ratio
+    } else {
+        if (height != width/x.y.ratio) {
+            warning(paste0("You've provided both width and height, ",
+                           "but they do not match the actual ratio ",
+                           "of the plot. Consider only providing one ",
+                           "if the results look bad."))
+        }
+    }
+        
+    Cairo::Cairo(width=width,height=height,dpi=width/width.points*dpi,file="/dev/null")
+    NULL
+}
+##' Stops a raster plot and returns the results and optionally plots them
+##'
+##' This stops a raster plot created with start_rasterplot and plots
+##' the result.
+##' @title stop_rasterplot
+##' @param plot Boolean indicating whether the captured raster image
+##' should be plotted or not
+##' @return raster image suitable for plotting with \code{grid.raster()}
+##' @author Don Armstrong
+##' @export
+##' @seealso start_rasterplot
+stop_rasterplot <- function(plot=TRUE) {
+    raster.image <- dev.capture(native=TRUE)
+    dev.off()
+    if (plot) {
+        grid::grid.raster(raster.image,width=grid::unit(1,"npc"),height=grid::unit(1,"npc"))
+    }
+    invisible(raster.image)
+}
diff --git a/man/CairoHacks.Rd b/man/CairoHacks.Rd
new file mode 100644 (file)
index 0000000..aa944a6
--- /dev/null
@@ -0,0 +1,35 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/CairoHacks.R
+\docType{package}
+\name{CairoHacks}
+\alias{CairoHacks}
+\alias{CairoHacks-package}
+\title{CairoHacks: Various hacks for Cairo devices including PDF bookmarks and raster plots in PDFs}
+\description{
+CairoHacks contains routines to allow you to include PDF bookmarks
+and raster plots inside of your PDFs.
+}
+\section{Bookmarks}{
+
+
+Bookmarks enable the easy browsing of PDFs by table of contents/index
+using pdftk.
+}
+
+\section{Raster Plots}{
+
+
+Raster plots enable the inclusion of plots with millions of points or
+lines in a vector format (such as a PDF) without making the PDF file
+megabytes in size, while still allowing other plot components to be
+presented in their original vector format.
+}
+\author{
+Don Armstrong <don@donarmstrong.com>
+}
+\seealso{
+make.pdf.bookmark, write.pdf.bookmark
+
+start_rasterplot, stop_rasterplot
+}
+
diff --git a/man/make.pdf.bookmark.Rd b/man/make.pdf.bookmark.Rd
new file mode 100644 (file)
index 0000000..0621ab6
--- /dev/null
@@ -0,0 +1,40 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/bookmarks.R
+\name{make.pdf.bookmark}
+\alias{make.pdf.bookmark}
+\title{make.bookmark}
+\usage{
+make.pdf.bookmark(text, level = 1, page = NULL)
+}
+\arguments{
+\item{text}{Text of bookmark to create}
+
+\item{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.}
+
+\item{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.}
+}
+\value{
+list of bookmarks to be passed to write.bookmarks or
+further calls to save.bookmark
+}
+\description{
+Make a bookmark for a PDF for later saving to the pdf with
+\code{write.pdf.bookmarks}
+}
+\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)
+}
+\author{
+Don Armstrong <don@donarmstrong.com>
+}
+
diff --git a/man/plus-.CairoHacks_bookmark.Rd b/man/plus-.CairoHacks_bookmark.Rd
new file mode 100644 (file)
index 0000000..22920e1
--- /dev/null
@@ -0,0 +1,24 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/bookmarks.R
+\name{+.CairoHacks_bookmark}
+\alias{+.CairoHacks_bookmark}
+\title{+ CairoHacks_bookmark}
+\usage{
+\method{+}{CairoHacks_bookmark}(b1, b2)
+}
+\arguments{
+\item{b1}{An object of class CairoHacks_bookmark.}
+
+\item{b2}{An object of class CairoHacks_bookmark}
+}
+\description{
+Add additional bookmarks to a bookmark
+}
+\details{
+Given a bookmarks object created with make.pdf.bookmark, add more
+bookmarks to it.
+}
+\author{
+Don Armstrong <don@donarmstrong.com>
+}
+
diff --git a/man/start_rasterplot.Rd b/man/start_rasterplot.Rd
new file mode 100644 (file)
index 0000000..b14e5a1
--- /dev/null
@@ -0,0 +1,44 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/raster_plots.R
+\name{start_rasterplot}
+\alias{start_rasterplot}
+\title{start_rasterplot}
+\usage{
+start_rasterplot(width = NULL, height = NULL)
+}
+\arguments{
+\item{width}{Width in pixels of raster image}
+
+\item{height}{Height in pixels of raster image. In general only
+one of \code{width} or \code{height} should be provided.}
+}
+\description{
+Start a raster plot with indicated width or height in pixels
+}
+\details{
+This creates a Cairo device with output to /dev/null of width or
+height given (defaulting to a width of 1024)
+}
+\examples{
+\dontrun{
+### plot a raster plot in a PDF
+pdf()
+start_rasterplot()
+print(xyplot(y~x,
+     data=data.frame(y=rnorm(1E8),x=rnorm(1E8))))
+stop_rasterplot()
+dev.off()
+}
+
+### plot a raster plot using grid.raster
+start_rasterplot(width=100)
+print(plot(y~x,
+            data=data.frame(y=rnorm(1E4),
+                            x=rnorm(1E4))))
+raster.image <- stop_rasterplot(plot=FALSE)
+grid.raster(raster.image)
+}
+\author{
+Don Armstrong
+}
+
diff --git a/man/stop_rasterplot.Rd b/man/stop_rasterplot.Rd
new file mode 100644 (file)
index 0000000..1cee08b
--- /dev/null
@@ -0,0 +1,29 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/raster_plots.R
+\name{stop_rasterplot}
+\alias{stop_rasterplot}
+\title{stop_rasterplot}
+\usage{
+stop_rasterplot(plot = TRUE)
+}
+\arguments{
+\item{plot}{Boolean indicating whether the captured raster image
+should be plotted or not}
+}
+\value{
+raster image suitable for plotting with \code{grid.raster()}
+}
+\description{
+Stops a raster plot and returns the results and optionally plots them
+}
+\details{
+This stops a raster plot created with start_rasterplot and plots
+the result.
+}
+\author{
+Don Armstrong
+}
+\seealso{
+start_rasterplot
+}
+
diff --git a/man/write.pdf.bookmarks.Rd b/man/write.pdf.bookmarks.Rd
new file mode 100644 (file)
index 0000000..69367f8
--- /dev/null
@@ -0,0 +1,27 @@
+% Generated by roxygen2 (4.1.1): do not edit by hand
+% Please edit documentation in R/bookmarks.R
+\name{write.pdf.bookmarks}
+\alias{write.pdf.bookmarks}
+\title{write.pdf.bookmarks}
+\usage{
+write.pdf.bookmarks(file, bookmarks)
+}
+\arguments{
+\item{file}{file name of pdf which was saved to disk}
+
+\item{bookmarks}{list of bookmarks}
+}
+\value{
+list of bookmarks
+}
+\description{
+Write saved bookmarks to the PDF file which was generated
+}
+\details{
+Given a set of bookmarks generated with make.pdf.bookmark, write
+them out to a PDF file using pdftk.
+}
+\author{
+Don Armstrong <don@donarmstrong.com>
+}
+