parse_pairlist <- function(x){ is.missing.arg <- function(arg) typeof(arg) == "symbol" && deparse(arg) == "" # x == NULL corresponds to functions with no arguments (also # length(NULL) is 0) also, NULL is a pairlist with length 0. # Is this function used with x other than pairlist? if(is.null(x) || length(x) == 0) # If not, the test of length(x) is redundant. return(list(argnames = character(0), defaults = character(0))) nonmis <- x[ !sapply(x, is.missing.arg) ] wrk <- character(length(nonmis)) names(wrk) <- names(nonmis) for(s in names(nonmis)){ wrk[[s]] <- paste(deparse(nonmis[[s]], backtick = TRUE, width.cutoff = 500L) , collapse = "\n") } list(argnames = names(x), defaults = wrk ) } # 2012-10-03 new arg. infix pairlist2f_usage1 <- function(x, name, S3class = "", S4sig = "", infix = FALSE, fu = TRUE){ structure(c(list(name=name, S3class=S3class, S4sig=S4sig, infix=infix, fu = fu), parse_pairlist(x)), class="f_usage") } print.f_usage <- function(x, ...){ tab <- max(nchar(names(x))) for(nam in names(x)){ if(is.null(nam)) next if(nam != "defaults") cat(nam, strrep(" ", tab - nchar(nam)), "=", x[[nam]], "\n") else{ defnams <- names(x$defaults) for(i in seq_along(defnams)){ if(i == 1) cat(nam, strrep(" ", tab - nchar(nam[i])), ":", defnams[i], "=", x$defaults[i], "\n") else cat(strrep(" ", tab + 3), defnams[i] , "=", x$defaults[i], "\n") } } } cat("\n") } format_funusage <- function(x, name = "", width = 72, realname){ res <- paste(name, "(", paste(x, collapse = ", "), ")", sep="") if(is.numeric(width) && nchar(res, type="width") > width){ delim <- c("(", rep(", ", length(x) - 1), ")") wrk <- paste(c(name, x), delim, sep="") lens <- nchar(wrk, type="width") if(!missing(realname)) lens[1] <- nchar(realname, type="width") + 1 indent <- paste(rep(" ", lens[1]), collapse="") res <- character(0) curlen <- 0 for(i in seq_along(wrk)){ if(curlen + lens[i] > width){ res <- paste(res, "\n", indent, sep="") curlen <- lens[1] # = number of chars in `indent' } res <- paste(res, wrk[i], sep="") curlen <- curlen + lens[i] } } res } deparse_usage1 <- function(x, width = 72){ if(!x$fu) # a variable, not function return( structure( x$name, names = x$name ) ) # todo: maybe x$name tryabva da e character, as.character here should not be needed. if(as.character(x$name) %in% c("[","[[", "$", "@", "[<-", "[[<-", "$<-", "@<-", "!")) "dummy" else if(x$infix){ # infix operator if(grepl(".+<-$", x$name)){ # name end is "<-" but is not equal to it name2 <- sub("^(.+)<-$", "\\1", x$name) m <- length(x$argnames) res <- paste(name2, "(", paste(x$argnames[-m], collapse=", "), ")", "<-", x$argnames[m]) }else # todo: make sure that the name is not in quotes! res <- paste(x$argnames, collapse = paste0(" ", x$name, " ")) return(res) } res <- x$argnames names(res) <- x$argnames nams <- names(x$defaults) res[nams] <- paste(res[nams], "=", x$defaults) assop <- grepl(".+<-$", x$name) # name end is "<-" but is not equal to it name <- x$name if(assop){ name <- sub("<-$", "", x$name) value <- res[length(res)] res <- res[-length(res)] } res <- if(!identical(x$S3class, "")) format_funusage(res, paste("\\method{", name, "}{", x$S3class, "}", sep=""), realname = name ) else if(!identical(x$S4sig, "")) format_funusage(res, paste("\\S4method{", name, "}{", paste0(x$S4sig, collapse = ", "), "}", sep=""), realname = name ) else switch(name, "$" =, "@" = paste0(res[1], name, res[2]), "[" =, "[[" = paste0(res[1], name, paste0(res[-1], collapse = ", "), .closeOp[name]), "!" = paste0("!", res[1]), ## default format_funusage(res, name) ) if(assop) # if assignment, add to the last line, usually the only one res[length(res)] <- paste0(res[length(res)], " <- ", value) # "[<-" = paste0(res[1], "[", paste0(res[c(-1,-length(res))], # collapse = ", "), "]", " <- ", res[length(res)]), # "[[<-" = paste0(res[1], "[[", paste0(res[c(-1,-length(res))], # collapse = ", "), "]]", " <- ", res[length(res)]), # "$<-" = paste0(res[1], "$", res[2], " <- ", res[3]), # "@<-" = paste0(res[1], "@", res[2], " <- ", res[3]), res <- gsub("...", "\\dots", res, fixed=TRUE) structure( paste(res, collapse = ""), names=x$name ) } as.character.f_usage <- function(x,...){ deparse_usage1(x) } deparse_usage <- function (x){ if(class(x) == "f_usage") return(deparse_usage1(x)) nams <- names(x) if(!is.null(nams)) # remove names since sapply merges them with the names of names(x) <- NULL # the list obtained by lapply() res <- sapply(x, deparse_usage1) if(is.null(names(res))) # in most cases names(res) will be the same as nams names(res) <- nams # but give preference to the ones returned by # deparse_usage1 which takes names from the objects. # This `if' will hardly ever kick in... res } .closeOp <- list("[" = "]", "[[" = "]]", "(" = ")", "{" = "}")