R/make_pdf.R

Defines functions make_pdf

Documented in make_pdf

#' Write a printable PDF file.
#'
#' A utility to generate a PDF file ready for printing labels.
#'
#' This function generates a PDF document that can be printed directly to sheets
#' of labels/stickers for the easy and clear identification of experimental
#' samples. The default behaviour is to print the same ID across all labels in a
#' row, with a different ID for each row.
#'
#'
#' @param ids A character vector of IDs as generated by
#'   \code{\link[idLabelR]{make_ids}}.
#' @param layout A \code{\link{list}} object describing the layout of labels on
#'   the sheet to be printed. See Details to learn how to customise this.
#' @param byRow By default (\code{byRow = TRUE}), IDs are repeated for all
#'   labels in a row. If \code{byRow = FALSE}, then IDs are repeated for all
#'   labels in a column. It is also possible to set \code{byRow = NULL}, which
#'   will print each ID on one label only.
#' @param sublabel An optional character vector that will be printed under the
#'   ID. This allows the replicate label (for the same ID) to be distinguished
#'   (to label, for example, different samples, tissues, replicate numbers,
#'   collection sites or dates). When \code{byRow} is TRUE, then this vector
#'   should be the same length as the number of columns in the label layout; or
#'   the length of the number of rows if \code{byRow} is FALSE. If \code{byRow}
#'   is NULL, then specify only one sublabel (if a vector is supplied, only the
#'   first element will be used).
#' @param printing An optional character to identify multiple copies of the same
#'   label sheet. Default is to ignore this feature.
#' @param file The name of the file to be written to. The default is
#'   \code{"Labels.pdf"} in the current working directory.
#' @param ... Additional parameters passed to \code{\link[grDevices]{pdf}}.
#'
#' @seealso \code{\link[idLabelR]{make_ids}}. Also see
#'   \code{\link[grDevices]{pdf}} for detail on additional PDF printing
#'   parameters.
#'
#' @examples
#' require(idLabelR)

#' example_spreadsheet = system.file("extdata", "Example.txt", package = "idLabelR")
#' ids = make_ids(file = example_spreadsheet)
#' layout = get_layout("cryobabies_LCRY_1700_A4")
#' make_pdf(ids, layout)
#'
#' # Additionally prints a timestamp and identifier
#' # to distinguish repeated printings of the same page.
#' make_pdf(ids, layout, printing = "a")
#'
#' # 17 rows of 5 labels for each ID.
#' make_pdf(ids, layout, byRow = TRUE, file = "Labels_by_row.pdf")
#' # 5 columns of 17 labels for each ID.
#' make_pdf(ids, layout, byRow = FALSE, file = "Labels_by_col.pdf")
#'
#' @importFrom grDevices pdf dev.off
#' @importFrom graphics par text
#' @importFrom tools file_path_sans_ext
#'
#' @export
make_pdf = function(ids, layout, byRow = TRUE, sublabel = NULL, printing = NULL, file = "Labels.pdf", ...){
	if(layout$units == "mm"){
			layout$page.width = layout$page.width / 25.4
			layout$page.height = layout$page.height / 25.4
			layout$label.x = layout$label.x / 25.4
			layout$label.y = layout$label.y / 25.4
			layout$timestamp.x = layout$timestamp.x / 25.4
			layout$timestamp.y = layout$timestamp.y / 25.4
	}

	# Format sublabel.
	if(is.null(byRow)){ # Print one copy only of each label.
		sublabel = as.character(sublabel)[1] # Only one value used, and repeated for all labels.
	}else if(byRow){
		sublabel = paste0(rep("", length(layout$label.x)), as.character(sublabel))[seq_along(layout$label.x)]
	}else{
		sublabel = paste0(rep("", length(layout$label.y)), as.character(sublabel))[seq_along(layout$label.y)]
	}

	if(!is.null(printing)) printing = paste0("_", printing)

	split.vector = function(v, n){
	  ncols = floor(length(v)/n)
	  remainder = NULL
	  if(ceiling(length(v)/n) > ncols) remainder = list(v[(n * ncols + 1):length(v)])
	  if(ncols > 0){
	  	return(unname(c(split(v[1:(n * ncols)], rep(1:ncols, each=n)), remainder)))
	  }else{
	  	return(unname(list(v[(n * ncols + 1):length(v)])))
	  }
	}

	if(is.null(byRow)){
		pages = split.vector(ids, n = length(layout$label.x) * length(layout$label.y))
		grDevices::pdf(file = paste0(tools::file_path_sans_ext(file), printing, ".pdf"), width = layout$page.width, height = layout$page.height)
		graphics::par(mar = c(0, 0, 0, 0))
		for(p in seq_along(pages)){
			n = 1
			plot(0, xlim=c(0, layout$page.width), ylim=c(layout$page.height, 0), ann=F, bty="n", type="n", xaxt = "n", yaxt = "n", xaxs = "i", yaxs = "i")
			for(y in layout$label.y){
				for(xi in seq_along(layout$label.x)){
					text = pages[[p]][n]
					x = layout$label.x[xi]
					graphics::text(x, y, text, adj = c(0.5, NA), cex = layout$text.size, font = layout$text.font)
					graphics::text(x, y, as.character(sublabel), adj = c(0.5, layout$sublabel.offset), cex = layout$sublabel.size, font = layout$sublabel.font)
					n = n + 1
				}
			}
			# Add vertical date and sheet stamp.
			if(!is.null(printing) & !is.null(layout$timestamp.x) & !is.null(layout$timestamp.y) & !is.null(layout$timestamp.size)){
				graphics::text(layout$timestamp.x, layout$timestamp.y, paste0("Page  ", p, printing, "  ", Sys.Date()), adj = c(0, 0), cex = layout$timestamp.size, srt = -90)
			}
		}
	}else if(byRow){
		pages = split.vector(ids, n = length(layout$label.y))
		grDevices::pdf(file = paste0(tools::file_path_sans_ext(file), printing, ".pdf"), width = layout$page.width, height = layout$page.height)
		graphics::par(mar = c(0, 0, 0, 0))
		for(p in seq_along(pages)){
			n = 1
			plot(0, xlim=c(0, layout$page.width), ylim=c(layout$page.height, 0), ann=F, bty="n", type="n", xaxt = "n", yaxt = "n", xaxs = "i", yaxs = "i")
			for(y in layout$label.y){
				text = pages[[p]][n]
				for(xi in seq_along(layout$label.x)){
					x = layout$label.x[xi]
					graphics::text(x, y, text, adj = c(0.5, NA), cex = layout$text.size, font = layout$text.font)
					graphics::text(x, y, as.character(sublabel[xi]), adj = c(0.5, layout$sublabel.offset), cex = layout$sublabel.size, font = layout$sublabel.font)
				}
				n = n + 1
			}
			# Add vertical date and sheet stamp.
			if(!is.null(printing) & !is.null(layout$timestamp.x) & !is.null(layout$timestamp.y) & !is.null(layout$timestamp.size)){
				graphics::text(layout$timestamp.x, layout$timestamp.y, paste0("Page  ", p, printing, "  ", Sys.Date()), adj = c(0, 0), cex = layout$timestamp.size, srt = -90)
			}
		}
	}else{
		pages = split.vector(ids, n = length(layout$label.x))
		grDevices::pdf(file = paste0(tools::file_path_sans_ext(file), printing, ".pdf"), width = layout$page.width, height = layout$page.height)
		graphics::par(mar = c(0, 0, 0, 0))
		for(p in seq_along(pages)){
			n = 1
			plot(0, xlim=c(0, layout$page.width), ylim=c(layout$page.height, 0), ann=F, bty="n", type="n", xaxt = "n", yaxt = "n", xaxs = "i", yaxs = "i")
			for(x in layout$label.x){
				text = pages[[p]][n]
				for(yi in seq_along(layout$label.y)){
					y = layout$label.y[yi]
					graphics::text(x, y, text, adj = c(0.5, NA), cex = layout$text.size, font = layout$text.font)
					graphics::text(x, y, as.character(sublabel[yi]), adj = c(0.5, layout$sublabel.offset), cex = layout$sublabel.size, font = layout$sublabel.font)
				}
				n = n + 1
			}
			# Add vertical date and sheet stamp.
			if(!is.null(printing) & !is.null(layout$timestamp.x) & !is.null(layout$timestamp.y) & !is.null(layout$timestamp.size)){
				graphics::text(layout$timestamp.x, layout$timestamp.y, paste0("Page  ", p, printing, "  ", Sys.Date()), adj = c(0, 0), cex = layout$timestamp.size, srt = -90)
			}
		}
	}


	grDevices::dev.off()
}

##########
rupertoverall/idLabelR documentation built on Aug. 27, 2023, 12:39 p.m.