Nothing
# The page template is everything except the content: page header/footer,
# titles, footnotes, etc.
# Page Template Functions ----------------------------------------------
#' Create a page template with header, titles, footnotes, and footer
#' @param rs The report spec
#' @return The page template object
#' @noRd
page_template_text <- function(rs) {
pt <- structure(list(), class = c("page_template_text", "list"))
pt$page_header <- get_page_header(rs)
pt$title_hdr <- get_title_header(rs$title_hdr, rs$line_size, rs$line_size,
rs$uchar, rs$char_width)
pt$titles <- get_titles(rs$titles, rs$line_size, rs$line_size,
rs$uchar, rs$char_width)
pt$footnotes <- c()
if (!is.null(rs$footnotes)) {
if (!is.null(rs$footnotes[[1]])) {
if (rs$footnotes[[1]]$valign == "bottom")
pt$footnotes <- get_footnotes(rs$footnotes, rs$line_size, rs$line_size,
rs$uchar, rs$char_width)
}
}
pt$page_footer <- get_page_footer(rs)
# Page by not here. Messes up line counts.
return(pt)
}
#' Get page header text strings suitable for printing
#' @param rs The report spec
#' @return A vector of strings
#' @noRd
get_page_header <- function(rs) {
if (is.null(rs$line_size)) {
stop("line_size cannot be null.")
}
phdrr <- rs$page_header_right
phdrl <- rs$page_header_left
phdr <- rs$page_header_left
if(length(phdrl) < length(phdrr))
phdr <- phdrr
ret <- c()
if (!is.null(phdr)) {
for (i in seq_along(phdr)) {
hl <- ""
hr <- ""
if (length(phdrl) >= i)
hl <- phdrl[[i]]
if (length(phdrr) >= i)
hr <- phdrr[[i]]
gp <- rs$line_size - (nchar(hl) + nchar(hr))
#print("header")
if (gp >= 0) {
lw <- rs$line_size - nchar(hr)
ln <- paste0(pad_right(hl, lw), hr)
}
else {
stop(paste0("Page header exceeds available width\n",
"Header Left: ", hl, "\n",
"Header Right: ", hr, "\n",
"Header length: ", nchar(hl) + nchar(hr), "\n",
"Line length: ", rs$line_size, "\n"))
ln <- ""
}
ret[i] <- ln
}
if (length(ret) > 0 & rs$page_header_blank_row == "below")
ret[[length(ret) + 1]] <- ""
}
return(ret)
}
#' Get title text strings suitable for printing
#' @import stringi
#' @param titles A list of title objects
#' @param width The width to set the title strings to
#' @return A vector of strings
#' @noRd
get_titles <- function(titles, content_width, page_width, uchar, char_width) {
if (is.null(content_width)) {
stop("width cannot be null.")
}
ret <- c()
if (!is.null(titles)) {
for (ttl in titles) {
if (!any(class(ttl) == "title_spec")) {
stop("titles parameter value is not a title spec.")
}
cols <- ttl$columns
if (ttl$width == "page")
width <- page_width
else if (ttl$width == "content")
width <- content_width
else if (is.numeric(ttl$width))
width <- ceiling(ttl$width / char_width)
cll <- round(width / cols)
ll <- width
algn <- ttl$align
if (algn == "centre")
algn <- "center"
if (any(ttl$blank_row %in% c("above", "both")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- ""
if (any(ttl$borders %in% c("top", "all")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- paste0(rep(uchar, ll),
collapse = "")
i <- 1
while (i <= length(ttl$titles)) {
ln <- ""
for (j in seq_len(cols)) {
# Not all cells have titles
if (i > length(ttl$titles))
t <- ""
else
t <- ttl$titles[[i]]
# Deal with column alignments
if (cols == 1) {
calgn <- algn
} else if (cols == 2) {
if (j == 1)
calgn <- "left"
else
calgn <- "right"
} else if (cols == 3) {
if (j == 1)
calgn <- "left"
else if (j == 2)
calgn <- "center"
else if (j == 3)
calgn <- "right"
}
gp <- cll - nchar(t)
#print("titles")
if (gp > 0) {
if (calgn == "left")
ln <- paste0(ln, pad_right(t, cll))
else if (calgn == "right")
ln <- paste0(ln, pad_left(t, cll))
else if (calgn == "center")
ln <- paste0(ln, pad_both(t, cll))
} else {
warning(paste0("Title exceeds available width.",
"\nTitle: ", t,
"\nTitle width: ", nchar(t),
"\nLine length: ", cll))
tgp <- cll - 3
if (tgp >= 0) {
if (ttl$align == "left") {
ln <- paste0(substr(pad_right(t, cll), 1, tgp), "...")
} else if (ttl$align == "right") {
ln <- paste0("...", substr(pad_left(t, cll), 1, tgp))
} else if (ttl$align == "center" | ttl$align == "centre") {
ln <- paste0(substr(pad_both(t, cll), 1, tgp), "...")
}
} else ln <- ""
}
i <- i + 1
}
ret[length(ret) + 1] <- ln
}
if (any(ttl$borders %in% c("bottom", "all")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- paste0(rep(uchar, ll ), collapse = "")
if (any(ttl$blank_row %in% c("below", "both")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- ""
}
}
return(ret)
}
#' Get title text strings suitable for printing
#' @import stringi
#' @param titles A list of title objects
#' @param width The width to set the title strings to
#' @return A vector of strings
#' @noRd
get_titles_back <- function(titles, content_width, page_width, uchar, char_width) {
if (is.null(content_width)) {
stop("width cannot be null.")
}
ret <- c()
if (!is.null(titles)) {
for (ttl in titles) {
if (!any(class(ttl) == "title_spec")) {
stop("titles parameter value is not a title spec.")
}
if (ttl$width == "page")
width <- page_width
else if (ttl$width == "content")
width <- content_width
else if (is.numeric(ttl$width))
width <- ceiling(ttl$width / char_width)
ll <- width
if (ttl$blank_row %in% c("above", "both") & length(ttl$titles) > 0)
ret[length(ret) + 1] <- ""
if (any(ttl$borders %in% c("top", "all")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- paste0(rep(uchar, ll),
collapse = "")
for (i in seq_along(ttl$titles)) {
t <- ttl$titles[i]
gp <- ll - nchar(t)
#print("titles")
if (gp > 0) {
if (ttl$align == "left")
ln <- pad_right(t, ll)
else if (ttl$align == "right")
ln <- pad_left(t, ll)
else if (ttl$align == "center" | ttl$align == "centre")
ln <- pad_both(t, ll)
} else {
warning(paste0("Title exceeds available width.",
"\nTitle: ", t,
"\nTitle width: ", nchar(t),
"\nLine length: ", ll))
tgp <- ll - 3
if (tgp >= 0) {
if (ttl$align == "left") {
ln <- paste0(substr(pad_right(t, ll), 1, tgp), "...")
} else if (ttl$align == "right") {
ln <- paste0("...", substr(pad_left(t, ll), 1, tgp))
} else if (ttl$align == "center" | ttl$align == "centre") {
ln <- paste0(substr(pad_both(t, ll), 1, tgp), "...")
}
} else ln <- ""
}
ret[length(ret) + 1] <- ln
}
if (any(ttl$borders %in% c("bottom", "all")) & length(ttl$titles) > 0)
ret[length(ret) + 1] <- paste0(rep(uchar, ll ),
collapse = "")
if (ttl$blank_row %in% c("below", "both") & length(ttl$titles) > 0)
ret[length(ret) + 1] <- ""
}
}
return(ret)
}
#' Get page by text strings suitable for printing
#' @import stringi
#' @param titles Page by object
#' @param width The width to set the page by strings to
#' @return A vector of strings
#' @import stringi
#' @noRd
get_page_by <- function(pgby, width, value, pgby_cnt = NULL) {
if (is.null(width)) {
stop("width cannot be null.")
}
# Set up fake values if there is no value yet.
# Needed for estimation of header line counts
if (is.null(value)) {
value <- get_pgby_value(value, pgby_cnt)
}
ll <- width
ret <- c()
if (!is.null(pgby)) {
if (!any(class(pgby) == "page_by"))
stop("pgby parameter value is not a page_by.")
if (pgby$blank_row %in% c("above", "both"))
ret[length(ret) + 1] <- ""
pb <- paste0(pgby$label, value)
lns <- unlist(stri_split_fixed(pb, "\n"))
for (pbln in lns) {
gp <- ll - nchar(pbln)
if (gp > 0) {
if (pgby$align == "left")
ln <- pad_right(pbln, ll)
else if (pgby$align == "right")
ln <- pad_left(pbln, ll)
else if (pgby$align == "center" | pgby$align == "centre")
ln <- pad_both(pbln, ll)
} else
stop("Page by exceeds available width.")
ret[length(ret) + 1] <- ln
}
if (pgby$blank_row %in% c("below", "both"))
ret[length(ret) + 1] <- ""
}
return(ret)
}
#' Get title header text strings suitable for printing
#' @import stringi
#' @param title_hdr A title_hdr object
#' @param width The width to set the title header to
#' @return A vector of strings
#' @noRd
get_title_header <- function(title_hdr, content_width, page_width,
uchar = "-", char_width) {
if (is.null(content_width)) {
stop("width cannot be null.")
}
ret <- c()
if (!is.null(title_hdr)) {
for (ttl_hdr in title_hdr) {
if (!any(class(ttl_hdr) == "title_hdr"))
stop("title header parameter value is not a title header.")
if (ttl_hdr$width == "page")
width <- page_width
else if (ttl_hdr$width == "content")
width <- content_width
else if (is.numeric(ttl_hdr$width))
width <- ceiling(ttl_hdr$width / char_width)
ll <- width
if (ttl_hdr$blank_row %in% c("above", "both") & length(ttl_hdr$titles) > 0)
ret[length(ret) + 1] <- ""
if (any(ttl_hdr$borders %in% c("top", "all")) & length(ttl_hdr$titles) > 0) {
#ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll), collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
maxlen <- length(ttl_hdr$titles)
if (length(ttl_hdr$right) > maxlen)
maxlen <- length(ttl_hdr$right)
hdr <- ttl_hdr$right
for (i in seq_len(maxlen)) {
if (i <= length(ttl_hdr$titles))
t <- ttl_hdr$titles[i]
else
t <- ""
if (i <= length(hdr))
h <- hdr[i]
else
h <- ""
gp <- ll - nchar(t) - nchar(h)
#print("titles")
if (gp >= 0) {
#ln <- paste0(pad_right(t, ll - nchar(h)), h, " ")
ln <- paste0(pad_right(t, ll - nchar(h)), h)
} else {
warning(paste0("Title header exceeds available width.\n",
"Title: ", t, "\n",
"Header: ", h, "\n",
"Title length: ", nchar(t), "\n",
"Header length: ", nchar(h), "\n",
"Line length: ", ll, "\n"))
tgp <- ll - 3
if (tgp >= 0) {
ln <- paste0(substr(paste0(pad_right(t, ll - nchar(h)), h, " "),
1, tgp), "...")
} else ln <- ""
}
ret[length(ret) + 1] <- ln
}
if (any(ttl_hdr$borders %in% c("bottom", "all")) &
length(ttl_hdr$titles) > 0) {
#ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll), collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
if (ttl_hdr$blank_row %in% c("below", "both") &
length(ttl_hdr$titles) > 0)
ret[length(ret) + 1] <- ""
}
}
return(ret)
}
#' Get footnote text strings suitable for printing
#' @param rs The report spec
#' @return A vector of strings
#' @noRd
get_footnotes <- function(footnotes, content_width, page_width,
uchar = "-", char_width) {
if (is.null(char_width)) {
stop("width cannot be null.")
}
ret <- c()
if (!is.null(footnotes)) {
for (ftn in footnotes) {
if (!any(class(ftn) == "footnote_spec"))
stop("footnotes parameter value is not a footnote spec.")
cols <- ftn$columns
if (ftn$width == "page")
width <- page_width
else if (ftn$width == "content")
width <- content_width
else if (is.numeric(ftn$width))
width <- ceiling(ftn$width / char_width)
cll <- round(width / cols)
ll <- width
algn <- ftn$align
if (algn == "centre")
algn <- "center"
if (ftn$blank_row %in% c("above", "both") & length(ftn$footnotes) > 0)
ret[length(ret) + 1] <- ""
if (any(ftn$borders %in% c("top", "all")) & length(ftn$footnotes) > 0) {
# ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll),
# collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
i <- 1
while (i <= length(ftn$footnotes)) {
ln <- ""
for (j in seq_len(cols)) {
# Not all cells have footnotes
if (i > length(ftn$footnotes))
f <- ""
else
f <- ftn$footnotes[[i]]
# Deal with column alignments
if (cols == 1) {
calgn <- algn
} else if (cols == 2) {
if (j == 1)
calgn <- "left"
else
calgn <- "right"
} else if (cols == 3) {
if (j == 1)
calgn <- "left"
else if (j == 2)
calgn <- "center"
else if (j == 3)
calgn <- "right"
}
gp <- cll - nchar(f)
#print("footnotes")
if (gp > 0) {
# if (ftn$align == "left")
# ln <- pad_right(paste0(f, " "), ll + 1)
# else if (ftn$align == "right")
# ln <- pad_left(paste0(f, " "), ll + 1)
# else if (ftn$align == "center" | ftn$align == "centre")
# ln <- pad_both(paste0(f, " "), ll + 1)
# if (ftn$align == "left")
# ln <- pad_right(f, ll)
# else if (ftn$align == "right")
# ln <- pad_left(f, ll)
# else if (ftn$align == "center" | ftn$align == "centre")
# ln <- pad_both(f, ll)
if (calgn == "left")
ln <- paste0(ln, pad_right(f, cll))
else if (calgn == "right")
ln <- paste0(ln, pad_left(f, cll))
else if (calgn == "center")
ln <- paste0(ln, pad_both(f, cll))
} else {
warning(paste0("Footnote exceeds available width.",
"\nFootnote: ", f,
"\nFootnote length: ", nchar(f),
"\nLine Length: ", ll))
tln <- cll - 3
if (tln >= 0) {
if (ftn$align == "left") {
ln <- paste0(substr(pad_right(f , cll), 1, tln), "...")
} else if (ftn$align == "right") {
ln <- paste0("...", substr(pad_left(f, cll), 1, tln))
} else if (ftn$align == "center" | ftn$align == "centre") {
ln <- paste0(substr(pad_both(f, cll), 1, tln), "...")
}
} else ln <- ""
}
i <- i + 1
}
ret[length(ret) + 1] <- ln
}
if (any(ftn$borders %in% c("bottom", "all")) & length(ftn$footnotes) > 0) {
# ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll),
# collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
if (ftn$blank_row %in% c("below", "both") & length(ftn$footnotes) > 0)
ret[length(ret) + 1] <- ""
}
}
return(ret)
}
#' Get footnote text strings suitable for printing
#' @param rs The report spec
#' @return A vector of strings
#' @noRd
get_footnotes_back <- function(footnotes, content_width, page_width,
uchar = "-", char_width) {
if (is.null(char_width)) {
stop("width cannot be null.")
}
ret <- c()
if (!is.null(footnotes)) {
for (ftn in footnotes) {
if (!any(class(ftn) == "footnote_spec"))
stop("footnotes parameter value is not a footnote spec.")
if (ftn$width == "page")
width <- page_width
else if (ftn$width == "content")
width <- content_width
else if (is.numeric(ftn$width))
width <- ceiling(ftn$width / char_width)
ll <- width
if (ftn$blank_row %in% c("above", "both") & length(ftn$footnotes) > 0)
ret[length(ret) + 1] <- ""
if (any(ftn$borders %in% c("top", "all")) & length(ftn$footnotes) > 0) {
# ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll),
# collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
for (i in seq_along(ftn$footnotes)) {
f <- ftn$footnotes[i]
gp <- ll - nchar(f)
#print("footnotes")
if (gp > 0) {
# if (ftn$align == "left")
# ln <- pad_right(paste0(f, " "), ll + 1)
# else if (ftn$align == "right")
# ln <- pad_left(paste0(f, " "), ll + 1)
# else if (ftn$align == "center" | ftn$align == "centre")
# ln <- pad_both(paste0(f, " "), ll + 1)
if (ftn$align == "left")
ln <- pad_right(f, ll)
else if (ftn$align == "right")
ln <- pad_left(f, ll)
else if (ftn$align == "center" | ftn$align == "centre")
ln <- pad_both(f, ll)
} else {
warning(paste0("Footnote exceeds available width.",
"\nFootnote: ", f,
"\nFootnote length: ", nchar(f),
"\nLine Length: ", ll))
tln <- ll - 3
if (tln >= 0) {
if (ftn$align == "left") {
ln <- paste0(substr(pad_right(f , ll), 1, tln), "...")
} else if (ftn$align == "right") {
ln <- paste0("...", substr(pad_left(f, ll), 1, tln))
} else if (ftn$align == "center" | ftn$align == "centre") {
ln <- paste0(substr(pad_both(f, ll), 1, tln), "...")
}
} else ln <- ""
}
ret[length(ret) + 1] <- ln
}
if (any(ftn$borders %in% c("bottom", "all")) & length(ftn$footnotes) > 0) {
# ret[length(ret) + 1] <- paste0(paste0(rep(uchar, ll),
# collapse = ""), " ")
ret[length(ret) + 1] <- paste0(rep(uchar, ll), collapse = "")
}
if (ftn$blank_row %in% c("below", "both") & length(ftn$footnotes) > 0)
ret[length(ret) + 1] <- ""
}
}
return(ret)
}
#' Get page footer text strings suitable for printing
#' @param rs The report spec
#' @return A vector of strings
#' @noRd
get_page_footer <- function(rs) {
if (is.null(rs$line_size)) {
stop("line_size cannot be null.")
}
pftrr <- rs$page_footer_right
pftrl <- rs$page_footer_left
pftrc <- rs$page_footer_center
mx <- max(c(length(pftrr), length(pftrl), length(pftrc)))
if (length(pftrr) < mx)
pftrr <- c(rep("", mx - length(pftrr)), pftrr)
if (length(pftrl) < mx)
pftrl <- c(rep("", mx - length(pftrl)), pftrl)
if (length(pftrc) < mx)
pftrc <- c(rep("", mx - length(pftrc)), pftrc)
# Put blank space above page footer by default
ret <- NULL
if (mx != 0) {
if (rs$page_footer_blank_row == "above")
ret <- c("")
else
ret <- c()
for (i in 1:mx) {
fl <- ""
fc <- ""
fr <- ""
if (length(pftrl) >= i)
fl <- as.character(pftrl[[i]])
if (length(pftrr) >= i)
fr <- as.character(pftrr[[i]])
if (length(pftrc) >= i)
fc <- as.character(pftrc[[i]])
l_sz <- if (is.null(fl)) 0 else nchar(fl)
r_sz <- if (is.null(fr)) 0 else nchar(fr)
c_sz <- if (is.null(fc)) 0 else nchar(fc)
gp <- rs$line_size - (l_sz + r_sz + c_sz)
#print("footer")
if (gp >= 0) {
if (l_sz > r_sz)
fr <- pad_left(fr, l_sz)
else
fl <- pad_right(fl, r_sz)
lw <- rs$line_size - nchar(fr) - nchar(fl)
ln <- paste0(fl, pad_both(fc, lw), fr)
}
else {
stop(paste0("Page footer exceeds available width\n",
"Footer Left: ", fl, "\n",
"Footer Center: ", fc, "\n",
"Footer Right: ", fr, "\n",
"Footer length: ", nchar(fl) + nchar(fc) + nchar(fr), "\n",
"Line length: ", rs$line_size, "\n"))
ln <- ""
}
ret[length(ret) + 1] <- ln
}
}
return(ret)
}
# Page Info ---------------------------------------------------------------
#' @description A internal class to collect data about a report page. This
#' object is created in create_table_pages_text and passed around to
#' different functions so they can make decisions based on the information
#' contained in this object.
#' @noRd
page_info <- function(data, keys, font_name, col_width, col_align,
label, label_align, page_by = NULL, table_align = NULL) {
ret <- structure(list(), class = c("page_info", "list"))
ret$data <- data
ret$keys <- keys
ret$font_name <- font_name
ret$col_width <- col_width
ret$col_align <- col_align
ret$label <- label
ret$label_align <- label_align
ret$total_pages <- 0
ret$page_number <- 0
ret$page_by <- page_by
ret$table_align <- table_align
return(ret)
}
# Utilities ---------------------------------------------------------------
#' @noRd
pad_right <- Vectorize(function(s, w) {
l <- w - nchar(s)
if (l < 0)
ret <- s
else
ret <- paste0(s, paste0(rep_len(" ", length.out = w - nchar(s)), collapse = ""))
return(ret)
}, USE.NAMES = FALSE)
#' @noRd
pad_left <- Vectorize(function(s, w) {
l <- w - nchar(s)
if (l < 0)
ret <- s
else
ret <- paste0(paste0(rep_len(" ", length.out =l), collapse = ""), s)
return(ret)
}, USE.NAMES = FALSE)
#' @noRd
pad_both <- Vectorize(function(s, w) {
l <- w - nchar(s)
if (l < 0)
ret <- s
else {
lp <- floor(l / 2)
rp <- ceiling(l / 2)
ret <- paste0(paste0(rep_len(" ", length.out = lp), collapse = ""),
s, paste0(rep_len(" ", length.out = rp), collapse = ""))
}
return(ret)
}, USE.NAMES = FALSE)
pad_any <- function(s, w, j) {
if (j == "left")
ret <- pad_right(s, w)
else if (j == "right")
ret <- pad_left(s, w)
else if (j %in% c("center", "centre"))
ret <- pad_both(s, w)
else
ret <- pad_right(s, w)
return(ret)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.