[Roxygen-commits] r92 - in pkg: . R sandbox tests/runit

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Jul 26 05:19:39 CEST 2008


Author: pcd
Date: 2008-07-26 05:19:39 +0200 (Sat, 26 Jul 2008)
New Revision: 92

Modified:
   pkg/DESCRIPTION
   pkg/R/Rd.R
   pkg/R/list.R
   pkg/R/parse.R
   pkg/R/roclet.R
   pkg/R/roxygenize.R
   pkg/R/string.R
   pkg/README
   pkg/sandbox/Rd.R
   pkg/tests/runit/runit.Rd.R
Log:
add roxygenize to collation; fix infelicitous tags; de-TeXed, first-sentence titles; @method for S3; fix argument docs; BUGS


Modified: pkg/DESCRIPTION
===================================================================
--- pkg/DESCRIPTION	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/DESCRIPTION	2008-07-26 03:19:39 UTC (rev 92)
@@ -7,4 +7,5 @@
         Manuel Eugster <Manuel.Eugster at stat.uni-muenchen.de>
 Maintainer: Peter Danenberg <pcd at roxygen.org>
 URL: http://roxygen.org
-Collate: 'functional.R' 'string.R' 'parse.R' 'collate.R' 'list.R' 'roclet.R' 'namespace.R' 'Rd.R'
+Collate: 'functional.R' 'string.R' 'parse.R' 'collate.R' 'list.R' 'roclet.R' 'namespace.R' 'Rd.R' 'roxygenize.R'
+Suggests: R.utils

Modified: pkg/R/Rd.R
===================================================================
--- pkg/R/Rd.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/Rd.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -6,12 +6,15 @@
 
 #' Make an Rd roclet which parses the given files and writes the Rd
 #' format to standard out (TODO: write to the file designated by
-#' \code{@@name}). Tries to guess \name and \usage unless explicitly
-#' given.
+#' \code{@@name}). Tries to guess \code{@@name} and \code{@@usage} unless
+#' explicitly given.
 #'
 #' Contains the member function \code{parse} which parses the result
 #' of \code{parse.files}.
 #'
+#' If \code{@@title} isn't present, substitutes \code{@@name} or
+#' equivalent.
+#'
 #' @param subdir directory into which to place the Rd files; if
 #' \code{NULL}, standard out.
 #' @return Rd roclet
@@ -36,7 +39,7 @@
   #' @param \dots the arguments
   #' @return \code{NULL}
   parse.expression <- function(key, ...)
-    cat(Rd.expression(key, c(...)), file=filename, append=T)
+    cat(Rd.expression(key, c(...)), file=filename, append=TRUE)
 
   filename <- ''
 
@@ -49,11 +52,58 @@
     getSrcLines(srcfile, first.line, first.line)
   }
 
-  NULL.STATEMENT <- 'roxygen()'
+  #' What does the noop look like?
+  NULL.STATEMENT <- 'roxygen[[:space:]]*()'
 
+  #' Does the statement contain a noop-like?
+  #' @param source.line the line of source code
+  #' @return Whether the statement contains a noop
   is.null.statement <- function(source.line)
     length(grep(NULL.STATEMENT, source.line) > 0)
 
+  de.tex <- function(string)
+    gsub('\\\\[^{]*\\{([^}]*)(}|)',
+         '\\1',
+         string,
+         perl=T)
+
+  #' First sentence of a string, defined as first
+  #' period, question mark or newline.
+  #' @param description the string to be first-sentenced
+  #' @return The first sentence
+  first.sentence <- function(description) {
+    description <- de.tex(description)
+    r <- regexpr('[^.?\n]*(\\.(?!\\w)|\\?|\n|)',
+                 description,
+                 perl=T)
+    sentence <- substr(description, r, attr(r, 'match.length'))
+    if (is.null.string(sentence))
+      NULL
+    else {
+      chars <- nchar(sentence)
+      last.char <- substr(sentence, chars, chars)
+      if (last.char == '.' || last.char == '?')
+        sentence
+      else
+        paste(trim(sentence), '\\dots', sep='')
+    }
+  }
+
+  #' If \code{@@title} is specified, use it; or
+  #' take the first sentence of the description;
+  #' or, lastly, take the name.
+  #' @param partitum the parsed elements
+  #' @param name the calculated name-fallback
+  #' @return The parsed title
+  parse.title <- function(partitum, name) {
+    if (!is.null(partitum$title))
+      partitum$title
+    else if (!is.null(partitum$description))
+      first.sentence(partitum$description)
+    else
+      name
+  }
+  
   #' Reconstruct the \name directive from amongst
   #' \code{@@name}, \code{@@setMethod}, \code{@@setClass},
   #' \code{@@setGeneric}, \code{@@assignee}, etc.
@@ -77,7 +127,7 @@
                         filename,
                         first.line,
                         first.source.line),
-                immediate.=T)
+                immediate.=TRUE)
     } else if (!is.null(name)) {
       name <- trim(name)
       if (!is.null(subdir)) {
@@ -87,10 +137,22 @@
         cat(sprintf('Writing %s to %s\n', name, filename))
         unlink(filename)
       }
+      parse.expression('title', parse.title(partitum, name))
       parse.expression('name', name)
+      if (is.null(partitum$aliases))
+        parse.expression('alias', name)
     }
   }
   
+  parse.function.name <- function(partitum) {
+    if (!is.null(partitum$method))
+      Rd.expression('method',
+          car(partitum$method),
+          cadr(partitum$method))
+    else
+      partitum$assignee
+  }
+
   #' Turn a list of formal arguments into a human-readable
   #' function-like.
   #' @param partitum the pre-parsed elements
@@ -112,10 +174,11 @@
                          sep=', '))
       parse.expression('usage',
           do.call(paste,
-                  c(as.list(strwrap(sprintf('%s(%s)',
-                                            partitum$assignee,
-                                            args),
-                                    exdent=4)),
+                  c(as.list(strwrap
+                            (sprintf('%s(%s)',
+                                     parse.function.name(partitum),
+                                     args),
+                             exdent=4)),
                     sep='\n')))
     }
   }

Modified: pkg/R/list.R
===================================================================
--- pkg/R/list.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/list.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -86,7 +86,7 @@
 #' Zip \emph{n} lists together into tuplets of
 #' length \emph{n}.
 #' @param zipper the zipping function
-#' @param dots the lists to be zipped
+#' @param \dots the lists to be zipped
 #' @return A list of tuplets
 zip <- function(zipper, ...) {
   m <- mapply(zipper, ...)

Modified: pkg/R/parse.R
===================================================================
--- pkg/R/parse.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/parse.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -1,7 +1,12 @@
 #' @include string.R
 #' @include list.R
 #' @include functional.R
+NULL
+
+#' Sequence that distinguishes roxygen comment from normal comment.
 LINE.DELIMITER <- '#\''
+
+#' Symbol that delimits tags.
 TAG.DELIMITER <- '@'
 
 #' No-op for sourceless files
@@ -218,7 +223,8 @@
 #' @aliases slot param
 register.preref.parsers(parse.name.description,
                         'slot',
-                        'param')
+                        'param',
+                        'method')
 
 #' Parse an element containing a single name and only a name;
 #' extra material will be ignored and a warning issued.
@@ -315,12 +321,15 @@
 
 #' Parse either srcrefs, prerefs or pairs of the same.
 #' @param ref the srcref, preref or pair of the same
+#' @param \dots ignored
 #' @return List containing the parsed srcref/preref
 parse.ref <- function(ref, ...)
   UseMethod('parse.ref')
 
 #' Parse a preref/srcrefs pair
+#' @method parse.ref list
 #' @param ref the preref/srcref pair
+#' @param \dots ignored
 #' @return List combining the parsed preref/srcref
 parse.ref.list <- function(ref, ...)
   append(parse.ref(car(ref)),
@@ -328,7 +337,9 @@
 
 
 #' Parse a preref
+#' @method parse.ref preref
 #' @param ref the preref to be parsed
+#' @param \dots ignored
 #' @return List containing the parsed preref
 parse.ref.preref <- function(ref, ...) {
   lines <- Map(trim.left, getSrcLines(attributes(ref)$srcfile,
@@ -461,7 +472,9 @@
 }
 
 #' Parse a srcref
+#' @method parse.ref srcref
 #' @param ref the srcref to be parsed
+#' @param \dots ignored
 #' @return List containing the parsed srcref
 parse.ref.srcref <- function(ref, ...) {
   srcfile <- attributes(ref)$srcfile

Modified: pkg/R/roclet.R
===================================================================
--- pkg/R/roclet.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/roclet.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -5,11 +5,11 @@
 #' Abstract roclet that serves as a rudimentary API.
 #'
 #' Contains the following member functions:
-#' \item{register.parser}{takes \code{key} and \code{parser}}
+#' \itemize{\item{register.parser}{takes \code{key} and \code{parser}}
 #' \item{register.parsers}{takes \code{parser} and \code{keys}}
 #' \item{register.default.parser}{takes a \code{key}}
 #' \item{register.default.parsers}{take \code{parsers}}
-#' \item{parse}{parses material contained in files}
+#' \item{parse}{parses material contained in files}}
 #'
 #' @param parse.default the default parser taking \code{key}
 #' and \code{value}
@@ -107,4 +107,3 @@
 #' @return The first non-null argument
 first.non.null <- function(...)
   append(NULL, c(...))[[1]]
-

Modified: pkg/R/roxygenize.R
===================================================================
--- pkg/R/roxygenize.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/roxygenize.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -1,17 +1,38 @@
 #' @include Rd.R
 #' @include namespace.R
 #' @include collate.R
+roxygen()
+
+#' Whither to copy package
 ROXYGEN.DIR <- '%s.roxygen'
+
+#' Whither to copy Rds
 MAN.DIR <- 'man'
+
+#' Whence to copy source code
 R.DIR <- 'R'
 
-roxygenize <- function(package.dir) {
+#' Process a package with the Rd, namespace and collate roclets.
+#' @param package.dir the package's top directory
+#' @param copy.package if R.utils is present, copies the package
+#' over before adding/manipulating files.
+#' @return \code{NULL}
+roxygenize <- function(package.dir,
+                       copy.package=TRUE) {
   roxygen.dir <- sprintf(ROXYGEN.DIR, package.dir)
   man.dir <- file.path(roxygen.dir, MAN.DIR)
   skeleton <- c(roxygen.dir, man.dir)
-  for (dir in skeleton) dir.create(dir, showWarnings=F)
+
+###   if (copy.package) {
+###     if (require('R.utils', quietly=T))
+###       copyDirectory(package.dir, roxygen.dir, overwrite=TRUE)
+###     else
+###       warning('`R.utils\' package not present; not copying package.')
+###   }
+
+  for (dir in skeleton) dir.create(dir, showWarnings=FALSE)
   r.dir <- file.path(package.dir, R.DIR)
-  source.files <- list.files(r.dir, recursive=T, full.names=T)
+  source.files <- list.files(r.dir, recursive=TRUE, full.names=TRUE)
   Rd <- make.Rd.roclet(man.dir)
   do.call(Rd$parse, as.list(source.files))
 }

Modified: pkg/R/string.R
===================================================================
--- pkg/R/string.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/R/string.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -1,7 +1,14 @@
 #' @include functional.R
 #' @include list.R
+NULL
+
+#' Absense of words
 SPACE <- '[[:space:]]+'
+
+#' Anti-anti-words
 MATTER <- '[^[:space:]]+'
+
+#' Analogue to the empty list
 NIL.STRING <- ''
 
 #' Trim [:space:] to the left of a string.

Modified: pkg/README
===================================================================
--- pkg/README	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/README	2008-07-26 03:19:39 UTC (rev 92)
@@ -31,8 +31,20 @@
 
 1.2. TODO
 
-Create a driver (possibly used by `R CMD roxygen') which farms out the
-results of each roclet to appropriate files in a package skeleton.
+* Create a driver (possibly used by `R CMD roxygen') which farms out
+  the results of each roclet to appropriate files in a package
+  skeleton.
 
+1.3. BUGS
+
+* parse.formals doesn't distinguish between no default argument and
+  NULL; need a special value?
+
+* Skeletal Rds are created for assignments without Roxygen-blocks;
+  desirable?
+
+* first.sentence is fooled by infix periods, whereupon it resorts to
+  \dots.
+
 -----------
 * Hail, Hephaistos! Grant skill and weal.

Modified: pkg/sandbox/Rd.R
===================================================================
--- pkg/sandbox/Rd.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/sandbox/Rd.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -13,4 +13,6 @@
 files <- if (argc > 0) as.list(argv) else FILES
 
 roclet <- make.Rd.roclet()
-do.call(roclet$parse, files)
+## do.call(roclet$parse, files)
+roclet$parse.parsed(parse.text("#' Is a number odd?
+                   a <- 2"))

Modified: pkg/tests/runit/runit.Rd.R
===================================================================
--- pkg/tests/runit/runit.Rd.R	2008-07-25 18:40:08 UTC (rev 91)
+++ pkg/tests/runit/runit.Rd.R	2008-07-26 03:19:39 UTC (rev 92)
@@ -33,29 +33,39 @@
 
 test.name.from.assignment <- function()
   check.Rd.output('a <- 2',
-                  output='\\name{a}')
+                  output=c('\\title{a}',
+                    '\\name{a}',
+                    '\\alias{a}'))
 
 test.name.overriding.assignment <- function()
   check.Rd.output("#' @name b
                    a <- 2",
-                  output='\\name{b}')
+                  output=c('\\title{b}',
+                    '\\name{b}',
+                    '\\alias{b}'))
 
 test.implicit.usage.from.formals <- function()
   check.Rd.output("a <- function(a=1) {}",
-                  output=c("\\name{a}",
+                  output=c("\\title{a}",
+                    "\\name{a}",
+                    "\\alias{a}",
                     "\\usage{a(a=1)}"))
 
 test.explicit.usage <- function()
   check.Rd.output("#' @usage a(a=2)
                    a <- function(a=1) {}",
-                  output=c("\\name{a}",
+                  output=c("\\title{a}",
+                    "\\name{a}",
+                    "\\alias{a}",
                     "\\usage{a(a=2)}"))
 
 test.params <- function()
   check.Rd.output("#' @param a an incipit letter
                    #' @param z a terminal letter
                    a <- function(a=1, z=2) {}",
-                  output=c("\\name{a}",
+                  output=c("\\title{a}",
+                    "\\name{a}",
+                    "\\alias{a}",
                     "\\usage{a(a=1, z=2)}",
                     "\\arguments{\\item{a}{an incipit letter}",
                     "\\item{z}{a terminal letter}}"))
@@ -96,3 +106,30 @@
                     "\\author{test}",
                     "\\seealso{test}",
                     "\\concept{test}"))
+
+test.title.from.description <- function()
+  check.Rd.output("#' Description with sentence. That continueth.
+                   a <- 2",
+                  output=c("\\title{Description with sentence}",
+                    "\\name{a}",
+                    "\\alias{a}",
+                    paste("\\description{Description with sentence.",
+                          "That continueth.}")))
+
+test.question.mark.end.of.sentence <- function()
+  check.Rd.output("#' Is a number odd?
+                   is.odd <- function(a) {}",
+                  output=c('\\title{Is a number odd?}',
+                    '\\name{is.odd}',
+                    '\\alias{is.odd}',
+                    '\\usage{is.odd(a)}',
+                    '\\description{Is a number odd?}'))
+
+test.ellipsis.on.no.period <- function()
+  check.Rd.output("#' Whether a number is odd
+                   is.odd <- function(a) {}",
+                  output=c('\\title{Whether a number is odd\dots}',
+                    '\\name{is.odd}',
+                    '\\alias{is.odd}',
+                    '\\usage{is.odd(a)}',
+                    '\\description{Whether a number is odd}'))



More information about the Roxygen-commits mailing list