[Rd] Lightweight 'package' idea.
Keith Jewell
k.jewell at campden.co.uk
Wed Jan 20 13:44:39 CET 2010
Following up on my own post of 13th,
Someone pointed out that I was MS Windows dependent. I've tried to correct
that, but I'm in a Windows only environment so I can't check.
I've also tried to make a few other "improvements". The result is below.
No guarantees or warranties of any kind, but perhaps people will find it
useful.
It now reasonably meets my needs so I'm not planning to do any more work on
it. I'm sure real R experts will be able to improve it..
Regards,
Keith J
============================
"Keith Jewell" <k.jewell at campden.co.uk> wrote in message
news:hikudu$373$1 at ger.gmane.org...
> Going back a few months....
> I also thought "it would be nice if R had built into it some way of
> running code in source packages possibly with degraded functionality to
> ease development"
> so building on Barry Rowlingsons start I came up with this:
> ---------------------------
<snip previous version>
## R code starts <<<<<<<<<<<<<<<<<<<<<<<
require(tools, quietly=TRUE) # for Rd2HTML
require(tcltk, quietly=TRUE) # for tk_choose.dir and tk_choose.files
# load an unbuilt package
loadDir <- function(Root = tk_choose.dir(getwd())){
Package = basename(Root) # package name defined by directory name
while(sum(search()==Package)>0) detach(pos=which(search()==Package)[1])
# if already attached, detach
attach(NULL, name=Package) # attach empty environment
assign(".Root.loadDir", Root, pos=Package) # insert Root into Package
assign(".Package.loadDir", Package, pos=Package) # insert package name
# use the reloadDir function to populate the environment
reloadDir(Package)
invisible(Package) # invisibly return .Package name
}
# reload a previously loaded package (by default the most recently loaded)
reloadDir <- function(Package = .GlobalEnv) {
Root <- get(".Root.loadDir", envir=as.environment(Package),
mode="character") # retrieve Root
Package <- get(".Package.loadDir", envir=as.environment(Package),
mode="character") # and package name
for (f in list.files(path=file.path(Root , "R"), # path is
.Root.loadDir/R/
pattern=".R$",full.names=TRUE,recursive=TRUE,ignore.case=TRUE)) #
file type = .R
sys.source(f, envir=as.environment(Package)) # source all such
files into .Package
invisible(Package)} # invisibly return package
# display help from previously loaded package (by default most recently
loaded)
help.loadDir <- function(subj="", Package=.GlobalEnv){ # default subject
is blank, package is first found
.Root <- get(".Root.loadDir", envir=as.environment(Package),
mode="character") # get file path
.Package <- get(".Package.loadDir", envir=as.environment(Package),
mode="character") # get package name
if (substitute(subj)=="") subj = "*" else subj <- substitute(subj) # get
*subj*' as character
hfile <- list.files(path=file.path(.Root, "man"), # path is .Root/man/
pattern=paste(subj,"Rd$", sep="."), # file = subj.Rd
full.names=TRUE,recursive=TRUE,ignore.case=TRUE) # list of matching
files
if (length(hfile) != 1) # if not exactly one file, choose one
hfile <- tk_choose.files(file.path(.Root, "man", paste(subj,"Rd",
sep=".")), multi=FALSE)
if(hfile != "") { # if exactly one file, open it
if(length(grep(".Rd$", hfile, ignore.case=TRUE)) ==1) { # if it's an Rd
file,
outfile <- sub("Rd$", "html", hfile, ignore.case=TRUE) # name of
corresponding html
out.mod <- file.info(outfile)[,"mtime"] # if html absent or needs
updating
if (is.na(out.mod)||file.info(hfile)[,"mtime"] > out.mod)
tools::Rd2HTML(hfile, outfile, .Package) # do it
hfile <- outfile} # point to html
hfile <- file.path(dirname(hfile), basename(hfile)) # needed to handle
"//server" syntax on Windows
shell.exec(shQuote(hfile))} # use operating system to open file of any
type
invisible(hfile)} # invisibly return displayed file name
## R code ends >>>>>>>>>>>>>>>>>>>>>>>>>>
% File loadDir.Rd begins <<<<<<<<<<<<<<<<<<<<<
\name{loadDir}
\title{Load an unbuilt package}
\description{Loads code from a packages \file{\\R} subdirectory}
\usage{loadDir(Root = tk_choose.dir(getwd())}
\arguments{
\item{Root}{character, scalar. The package directory (containing
subdirectories \file{\\R} and \file{\\man}). The package name
(\code{.Package.loadDir}) is taken as \code{basename(Root)}.}
}
\details{Attaches an environment at the second position on the search list
with name \code{basename(Root)} (after detaching any existing
entries with that name). Into that environment it sources all \file{.R}
files in the \file{\\R} subdirectory, searching recursively.
In that environment it also places \code{.Root.loadDir <- Root} and
\code{.Package.loadDir <- basename(Root)} so that
\code{get(".Root.loadDir", pos=Package_name_as_character)} can be used to
retrieve the original file path. }
\value{\code{invisible()}; scalar, character. Name of loaded package}
\references{
%% ~put references to the literature/web site here ~
}
\author{
%% ~~who you are~~
}
\note{
%% ~~further notes~~
}
%% ~Make other sections like Warning with \section{Warning }{....} ~
\seealso{
%% ~~objects to See Also as \code{\link{help}}, ~~~
}
\examples{
\dontrun{
loadDir() navigating to '\\\\Server02\\stats\\R\\CBRIutils' adds the
package CBRIutils}}
% Add one or more standard keywords, see file 'KEYWORDS' in the
% R documentation directory.
\keyword{ ~kwd1 }
\keyword{ ~kwd2 }% __ONLY ONE__ keyword per line
% File loadDir.Rd ends >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
% File reloadDir.Rd begins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\name{reloadDir}
\title{Refresh an unbuilt package previously loaded by loadDir}
\description{Re-load code from a packages \file{\\R} subdirectory previously
loaded by loadDir}
\usage{reloadDir(Package = .GlobalEnv)}
\arguments{\item{Package}{package name to be reloaded specified as either
\itemize{
\item{character, scalar. Name of entry on search list}
\item{environment}}}}
\details{The environment specified by \code{Package} is searched for
character variables \code{.Root.loadDir} and \code{.Package.loadDir}. Then
all .R files in \file{.Root.loadDir\\R} (searching recursively) are sourced
into \code{as.environment(.Package.loadDir)}
By default (\code{Package = .GlobalEnv}) the global environment is searched
and then the search list. This means that if \code{Package} is not specified
the package most recently loaded by loadDir is reloaded}
\value{\code{invisible()}; scalar, character. Name of reloaded package}
\references{
%% ~put references to the literature/web site here ~
}
\author{
%% ~~who you are~~
}
\note{
%% ~~further notes~~
}
%% ~Make other sections like Warning with \section{Warning }{....} ~
\seealso{
%% ~~objects to See Also as \code{\link{help}}, ~~~
}
\examples{
\dontrun{
loadDir() navigating to '\\\\Server02\\stats\\R\\CBRIutils' adds the
package CBRIutils
then
reload("CBRIutils") or just reload() re-sources all '\\R\\*.R' files in
package CBRIutils. }}
% Add one or more standard keywords, see file 'KEYWORDS' in the
% R documentation directory.
\keyword{ ~kwd1 }
\keyword{ ~kwd2 }% __ONLY ONE__ keyword per line
% File reloadDir.Rd ends >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%File help.loadDir.Rd begins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
\name{help.loadDir}
\title{Show help from an unbuilt package loaded by loadDir}
\description{ Gives access to help files in the packages \file{\\man}
subdirectory, converting \file{.Rd} files to \file{.html} as appropriate.}
\usage{help.loadDir(subj="", Package=.GlobalEnv)}
\arguments{
\item{subj}{character or name, scalar. File name to be searched for in
\file{\\man} subdirectory}
\item{.Package}{package name specified as either \itemize{
\item{character, scalar. Name of entry on search list}
\item{environment}}}}
\details{The environment specified by \code{Package} is searched for
character variables \code{.Root.loadDir} and \code{.Package.loadDir}; these
provide the context for the search for help files. By default (\code{Package
= .GlobalEnv}) the global environment is searched and then the search list.
This means that if \code{Package} is not specified the package most recently
loaded by loadDir is searched.
The packages \file{\\man} subdirectory is recursively searched for files
named \code{subj}, initially searching for files of type \file{.Rd}.
If there is not exactly one such file it opens a \code{tk_file.choose}
dialog to choose a single file of any type.
If the single specified file is of type \file{.Rd} then the target file is a
correspondingly named \file{.html} file with a later modification date. If
this target file does not exist (no such \file{.html} file, or earlier
modification) it is produced from the \file{.Rd} file using
\code{tools::Rd2HTML}.
The target file is opened by the operating system's file associations.}
\value{ \code{invisible}, scalar, character; file opened (the \file{.html}
file if a \file{.Rd} file was chosen)}
\references{
%% ~put references to the literature/web site here ~
}
\author{
%% ~~who you are~~
}
\note{
%% ~~further notes~~
}
%% ~Make other sections like Warning with \section{Warning }{....} ~
\seealso{
%% ~~objects to See Also as \code{\link{help}}, ~~~
}
\examples{
\dontrun{
loadDir() navigating to '\\\\Server02\\stats\\R\\CBRIutils' adds the
package CBRIutils
then
help.loadDir(item, "CBRIutils") or just help.loadDir(item)
if required, converts '\\man\\item.Rd' to '\\man\\item.html'
opens '\\man\\item.html' the default web browser.}}
% Add one or more standard keywords, see file 'KEYWORDS' in the
% R documentation directory.
\keyword{ ~kwd1 }
\keyword{ ~kwd2 }% __ONLY ONE__ keyword per line
%File help.loadDir.Rd ends
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
More information about the R-devel
mailing list