From k.jewell at campden.co.uk  Wed Jan 20 13:44:39 2010
From: k.jewell at campden.co.uk (Keith Jewell)
Date: Wed, 20 Jan 2010 12:44:39 -0000
Subject: [Rd] Lightweight 'package' idea.
References: <d8ad40b50908210503xf67354fhfd5f3beede550df0@mail.gmail.com><971536df0908210532k1152976al404b94a230f9858e@mail.gmail.com>
	<hikudu$373$1@ger.gmane.org>
Message-ID: <hj6trp$meb$1@ger.gmane.org>

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 
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>



[Rd] Lightweight 'package' idea.
Keith Jewell