my.pdf.stamp <- function(stamp.text="Stamp", pos=c(0.4, 0.9), pdf.in.file, pdf.out.file)
{
## Purpose: Apply a stamp (text string) to each page of a PDF file.
## Requires Linux program "pdftk".
## Arguments:
## pdf.in.file: Input PDF file.
## stamp.text: a vector of strings (stamps). Each value will be stamped on the corresponding page of the PDF file.
## Its values will be recycled to match the total number of pages in the input PDF file.
## pos: position of the stamp text (located between [0,1] X [0,1])
## pdf.out.file: Output PDF file with the stamps.
## Return: PDF file with the stamps.
## Author: Feiming Chen, Date: 25 Apr 2017, 10:42
## ________________________________________________
p1 <- pdf.file.page.number(pdf.in.file)
p2 <- length(stamp.text)
if (p1 != p2) stamp.text <- rep(stamp.text, length.out = p1)
## burst the PDF file into single page PDF's
f <- "page_%05d.pdf"
fs <- "stamp_%05d"
fs2 <- "stamp_%05d-Plot.pdf"
fo <- "out_%05d.pdf"
system(paste("pdftk", pdf.in.file, "burst output", f))
for (i in 1:p1) {
X(text.in.plot(stamp.text[i], cex = 2, pos = pos), file = sprintf(fs, i), open.pdf=F)
system(paste("pdftk", sprintf(f, i), "stamp", sprintf(fs2, i), "output", sprintf(fo, i)))
}
merge.file.list <- paste(sapply(1:p1, function(i) sprintf(fo, i)), collapse = " ")
system(paste("pdftk", merge.file.list, "cat output", pdf.out.file))
}
if (F) { # Unit Test
dir.create("tmp"); setwd("tmp")
pdf("test.pdf"); replicate(3, plot(rnorm(100))); dev.off()
pdf.in.file <- "test.pdf"
pdf.out.file <- "result.pdf"
stamp.text <- LETTERS[1:3]
pos <- c(0.4, 0.9)
my.pdf.stamp(stamp.text, pos=pos, pdf.in.file, pdf.out.file)
}
pdf.file.page.number <- function(fname) {
## Return the total number of pages in a PDF file.
## Require Linux program "pdfinfo"
a <- pipe(paste0("pdfinfo '", fname, "' | grep Pages | cut -d: -f2"))
page.number <- as.numeric(readLines(a))
close(a)
page.number
}
if (F) {
## pdf.file.page.number("ALL-Plots.pdf")
}
text.in.plot <- function(x, cex=1, pos=c(0.5, 0.5)) {
## "x" is a string. Put "x" in the center of a plot. For putting
## text summary in a PDF file that is mostly plots.
## "pos" is the position of the text string
## "cex" is the expansion ratio of the text string
plot(c(0, 1), c(0, 1), type = "n", main = "", xlab = "", ylab = "", xaxt="n", yaxt="n", axes = F, mar=c(0,0,0,0), oma=c(0,0,0,0))
text(pos[1], pos[2], x, cex=cex)
}
if (F) {
text.in.plot("good", cex=5)
text.in.plot("bad", pos=c(0.1, 0.1))
}
X <- function(expr, file="test", open.pdf = TRUE) {
## USED IN UNIX!
## Generate a PDF file based on evaluation of expr and open it
## Put multiple plot commands like "{ cmd1; cmd2; cmd3; cmd4 }".
## USAGE: xpdf(plot(sig1))
graphics.off()
## png("~/tmp/plot.png", width=600, height=600)
r <- my.pdf(file)
ans <- eval(expr)
dev.off()
## system("convert ~/tmp/plot.pdf ~/tmp/plot.png")
if (open.pdf) open.pdf(r$plot)
invisible(ans)
}
if (F) {
X(plot(rnorm(100)))
a <- X({plot(a <- rnorm(100)); a})
X({plot(a <- rnorm(100)); hist(a); boxplot(a); dotchart(a); qqnorm(a); plot(lm(a~seq(a)))})
}
open.pdf <- function(file) {
## Open a PDF file.
system(paste("evince ", file, " &", sep=""))
cat("See Plot In: ", file, "\n")
}