There was a discussion on r-help of getting the output from print.packageInfo into a file. Spencer and I have added a fileargument to print.packageInfo for consideration in R. Had this been available it would have simplified the answer to that thread. If the file= argument is used then the packageInfo information is sent to the file specified rather than displayed using file.show . print.packageInfo <- function (x, ..., file = NULL) { if (!inherits(x, "packageInfo")) stop("wrong class") outFile <- if (is.null(file)) tempfile("RpackageInfo") else file outConn <- file(outFile, open = "w") vignetteMsg <- paste("Further information is available in the following ", "vignettes in directory ", sQuote(file.path(x$path, "doc")), ":", sep = "") headers <- c("", "Description:\n\n", "Index:\n\n", paste(paste(strwrap (vignetteMsg), collapse = "\n"), "\n\n", sep = "")) footers <- c("\n", "\n", "\n", "") formatDocEntry <- function(entry) { if (is.list(entry) || is.matrix(entry)) formatDL(entry, style = "list") else entry } for (i in which(!sapply(x$info, is.null))) { writeLines(headers[i], outConn, sep = "") writeLines(formatDocEntry(x$info[[i]]), outConn) writeLines(footers[i], outConn, sep = "") } close(outConn) if (is.null(file)) file.show(outFile, delete.file = TRUE, title = paste ("Documentation for package", sQuote(x$name))) invisible(x) }
>>>>> Gabor Grothendieck writes:> There was a discussion on r-help of getting the output from > print.packageInfo into a file. Spencer and I have added a file> argument to print.packageInfo for consideration in R. Had this > been available it would have simplified the answer to that > thread. If the file= argument is used then the packageInfo > information is sent to the file specified rather than displayed > using file.show .What is wrong with capture.output(print.packageInfo(x, ...), file = NULL) for what you want? -k> print.packageInfo <- function (x, ..., file = NULL) > { > if (!inherits(x, "packageInfo")) > stop("wrong class") > outFile <- if (is.null(file)) > tempfile("RpackageInfo") > else > file > outConn <- file(outFile, open = "w") > vignetteMsg <- paste("Further information is available in the following ", > "vignettes in directory ", sQuote(file.path(x$path, "doc")), > ":", sep = "") > headers <- c("", "Description:\n\n", "Index:\n\n", paste(paste(strwrap > (vignetteMsg), > collapse = "\n"), "\n\n", sep = "")) > footers <- c("\n", "\n", "\n", "") > formatDocEntry <- function(entry) { > if (is.list(entry) || is.matrix(entry)) > formatDL(entry, style = "list") > else entry > } > for (i in which(!sapply(x$info, is.null))) { > writeLines(headers[i], outConn, sep = "") > writeLines(formatDocEntry(x$info[[i]]), outConn) > writeLines(footers[i], outConn, sep = "") > } > close(outConn) > if (is.null(file)) > file.show(outFile, delete.file = TRUE, title = paste > ("Documentation for package", > sQuote(x$name))) > invisible(x) > }> ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-devel
print.packageInfo does not print to the console, it uses file.show. For example, on R 1.9.1 patched on Windows XP:> require(chron)[1] TRUE> capture.output(print.packageInfo(help(package = chron)), file = "/abc.txt")NULL> length(readLines("/abc.txt"))[1] 0 Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> writes:>>>>> Gabor Grothendieck writes:> There was a discussion on r-help of getting the output from > print.packageInfo into a file. Spencer and I have added a file> argument to print.packageInfo for consideration in R. Had this > been available it would have simplified the answer to that > thread. If the file= argument is used then the packageInfo > information is sent to the file specified rather than displayed > using file.show .What is wrong with capture.output(print.packageInfo(x, ...), file = NULL) for what you want? -k> print.packageInfo <- function (x, ..., file = NULL) > { > if (!inherits(x, "packageInfo")) > stop("wrong class") > outFile <- if (is.null(file)) > tempfile("RpackageInfo") > else > file > outConn <- file(outFile, open = "w") > vignetteMsg <- paste("Further information is available in the following ", > "vignettes in directory ", sQuote(file.path(x$path, "doc")), > ":", sep = "") > headers <- c("", "Description:\n\n", "Index:\n\n", paste(paste(strwrap > (vignetteMsg), > collapse = "\n"), "\n\n", sep = "")) > footers <- c("\n", "\n", "\n", "") > formatDocEntry <- function(entry) { > if (is.list(entry) || is.matrix(entry)) > formatDL(entry, style = "list") > else entry > } > for (i in which(!sapply(x$info, is.null))) { > writeLines(headers[i], outConn, sep = "") > writeLines(formatDocEntry(x$info[[i]]), outConn) > writeLines(footers[i], outConn, sep = "") > } > close(outConn) > if (is.null(file)) > file.show(outFile, delete.file = TRUE, title = paste > ("Documentation for package", > sQuote(x$name))) > invisible(x) > }
>>>>> Gabor Grothendieck writes:> > print.packageInfo does not print to the console, it uses file.show. > For example, on R 1.9.1 patched on Windows XP: > >> require(chron) > [1] TRUE >> capture.output(print.packageInfo(help(package = chron)), file = "/abc.txt") > NULL >> length(readLines("/abc.txt")) > [1] 0But file.show() can be tuned by playing with options(pager). In your case, something like oop <- options(pager = function(file, ...) writeLines(readLines(file))) capture.output(print.packageInfo(help(package = "stats")), file = "abc.txt") options(oop) gives R> length(readLines("abc.txt")) [1] 345 Hth -k> > > Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> writes: > >>>>> Gabor Grothendieck writes: > >> There was a discussion on r-help of getting the output from >> print.packageInfo into a file. Spencer and I have added a file>> argument to print.packageInfo for consideration in R. Had this >> been available it would have simplified the answer to that >> thread. If the file= argument is used then the packageInfo >> information is sent to the file specified rather than displayed >> using file.show . > > What is wrong with > > capture.output(print.packageInfo(x, ...), file = NULL) > > for what you want? > > -k > >> print.packageInfo <- function (x, ..., file = NULL) >> { >> if (!inherits(x, "packageInfo")) >> stop("wrong class") >> outFile <- if (is.null(file)) >> tempfile("RpackageInfo") >> else >> file >> outConn <- file(outFile, open = "w") >> vignetteMsg <- paste("Further information is available in the following ", >> "vignettes in directory ", sQuote(file.path(x$path, "doc")), >> ":", sep = "") >> headers <- c("", "Description:\n\n", "Index:\n\n", paste(paste(strwrap >> (vignetteMsg), >> collapse = "\n"), "\n\n", sep = "")) >> footers <- c("\n", "\n", "\n", "") >> formatDocEntry <- function(entry) { >> if (is.list(entry) || is.matrix(entry)) >> formatDL(entry, style = "list") >> else entry >> } >> for (i in which(!sapply(x$info, is.null))) { >> writeLines(headers[i], outConn, sep = "") >> writeLines(formatDocEntry(x$info[[i]]), outConn) >> writeLines(footers[i], outConn, sep = "") >> } >> close(outConn) >> if (is.null(file)) >> file.show(outFile, delete.file = TRUE, title = paste >> ("Documentation for package", >> sQuote(x$name))) >> invisible(x) >> } >> _______________________________________________ > No banners. No pop-ups. No kidding.
On Mon, 2 Aug 2004, Kurt Hornik wrote:> >>>>> Gabor Grothendieck writes: > > > > > print.packageInfo does not print to the console, it uses file.show. > > For example, on R 1.9.1 patched on Windows XP: > > > >> require(chron) > > [1] TRUE > >> capture.output(print.packageInfo(help(package = chron)), file = "/abc.txt") > > NULL > >> length(readLines("/abc.txt")) > > [1] 0 > > But file.show() can be tuned by playing with options(pager). > > In your case, something like > > oop <- options(pager = function(file, ...) writeLines(readLines(file))) > capture.output(print.packageInfo(help(package = "stats")), > file = "abc.txt") > options(oop) > > gives > > R> length(readLines("abc.txt")) > [1] 345or even oop <- options(pager="console") an internal version of the same thing under R for Windows. -- Brian D. Ripley, ripley@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
I already suggested using the pager as a workaround in the original thread although your pager workaround has the advantage of being 100% in R while mine used a batch file which defined a new pager. Note that R already supports options(pager = "console") but if you do this then it seems that capture.output still won't capture it. Thus one alternative solution would be to get capture.output to work with pager = "console" and modify print.packageInfo to take a pager= argument which it would pass down to file.show. (file.show already has a pager argument.) Then one could write: capture.output( print.packageInfo(help(package = chron), pager = "console"), file = "myfile.txt") That gets it down to one line although it still seems unnecessarily indirect when one could just write: print.packageInfo(help(package = chron), file = "myfile.txt") if print.packageInfo just had a file= argument. Furthermore, print.packageInfo ALREADY creates the file as a temporary file to hand over to file.show so its not much of a stretch to give the user access to what it is already creating anyway. From: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>>>>>> Gabor Grothendieck writes:> > print.packageInfo does not print to the console, it uses file.show. > For example, on R 1.9.1 patched on Windows XP: > >> require(chron) > [1] TRUE >> capture.output(print.packageInfo(help(package = chron)), file = "/abc.txt") > NULL >> length(readLines("/abc.txt")) > [1] 0But file.show() can be tuned by playing with options(pager). In your case, something like oop <- options(pager = function(file, ...) writeLines(readLines(file))) capture.output(print.packageInfo(help(package = "stats")), file = "abc.txt") options(oop) gives R> length(readLines("abc.txt")) [1] 345 Hth -k> > > Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> writes: > >>>>> Gabor Grothendieck writes: > >> There was a discussion on r-help of getting the output from >> print.packageInfo into a file. Spencer and I have added a file>> argument to print.packageInfo for consideration in R. Had this >> been available it would have simplified the answer to that >> thread. If the file= argument is used then the packageInfo >> information is sent to the file specified rather than displayed >> using file.show . > > What is wrong with > > capture.output(print.packageInfo(x, ...), file = NULL) > > for what you want? > > -k > >> print.packageInfo <- function (x, ..., file = NULL) >> { >> if (!inherits(x, "packageInfo")) >> stop("wrong class") >> outFile <- if (is.null(file)) >> tempfile("RpackageInfo") >> else >> file >> outConn <- file(outFile, open = "w") >> vignetteMsg <- paste("Further information is available in the following ", >> "vignettes in directory ", sQuote(file.path(x$path, "doc")), >> ":", sep = "") >> headers <- c("", "Description:\n\n", "Index:\n\n", paste(paste(strwrap >> (vignetteMsg), >> collapse = "\n"), "\n\n", sep = "")) >> footers <- c("\n", "\n", "\n", "") >> formatDocEntry <- function(entry) { >> if (is.list(entry) || is.matrix(entry)) >> formatDL(entry, style = "list") >> else entry >> } >> for (i in which(!sapply(x$info, is.null))) { >> writeLines(headers[i], outConn, sep = "") >> writeLines(formatDocEntry(x$info[[i]]), outConn) >> writeLines(footers[i], outConn, sep = "") >> } >> close(outConn) >> if (is.null(file)) >> file.show(outFile, delete.file = TRUE, title = paste >> ("Documentation for package", >> sQuote(x$name))) >> invisible(x) >> } >
From: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>>>>>> Gabor Grothendieck writes:> > I already suggested using the pager as a workaround > in the original thread although your pager workaround > has the advantage of being 100% in R while mine used > a batch file which defined a new pager. > > Note that R already supports > > options(pager = "console") > > but if you do this then it seems that capture.output > still won't capture it. Thus one alternative solution > would be to get capture.output to work with > pager = "console" and modify print.packageInfo to > take a pager= argument which it would pass down to file.show. > (file.show already has a pager argument.) > > Then one could write: > > capture.output( print.packageInfo(help(package = chron), > pager = "console"), file = "myfile.txt") > > That gets it down to one line although it still seems > unnecessarily indirect when one could just write: > > print.packageInfo(help(package = chron), file = "myfile.txt") > > if print.packageInfo just had a file= argument. > Furthermore, print.packageInfo ALREADY creates the file as a > temporary file to hand over to file.show so its not much of > a stretch to give the user access to what it is already > creating anyway.The point about the proferred solution is that it works generally when is is desired to capture output that is "printed" via file.show(). If we start adding extra arguments to print.packageIQR (which is documented to be internal, btw), we would need to do the same for print.libraryIQR and print.hsearch and ..., i.e. for all print() methods which in fact display something using file.show() as a "side effect". That seems suboptimal to me, when one can wrap the above in a very simple and generally applicable function (and just calling the print() generic rather than some method, btw). --- That's a good point but if a command _already_ produces a file I think its logical that access to that file be given directly, even if that means having to add a file= argument in many commands. In my opinion, both our pager workarounds are too complex/geeky for a simple task. I think this whole thing could be streamlined by extending the pager= option to accept a connection, e.g. options(pager = file("a.txt")) and then modifying the args of file.show to: function (..., header = rep("", nfiles), title = "R Information", delete.file = FALSE, file, pager = if (missing(file)) getOption("pager")) else base:file(file)) Now passing down the ... arguments from print.packageInfo to file.show only involves a one line change, namely, just add three dots at the end of the call to file.show within print.packageInfo: file.show(outFile, delete.file = TRUE, title = paste("Documentation for package", sQuote(x$name)), ...) and this automatically gives pager= and file= support to it. (Note that currently the three dots are already in the arg list to print.packageInfo but are not used anywhere in the body of that function.) Modifying the other functions might be just as easy. Also, while we are at it we could add pager= arguments to sink and to capture.output. With the above any of the following would work: print.packageInfo(help(package = chron), file = "a.txt") print.packageInfo(help(package = chron), pager = file("a.txt")) capture.output(help(package = chron), pager = file("a.txt")) sink(pager = file("a.txt")) help(package = chron) sink() oop <- options(pager = file("a.txt")) help(package = chron)) options(oop)