blob: 61eb09facb3b61753a0d364ec4767222d9fe74b2 [file] [log] [blame]
#=============================================================================#
# Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================#
## StatET help
.getHelpFile <- function(file) {
path <- dirname(file)
dirpath <- dirname(path)
if(!file.exists(dirpath))
stop(gettextf("invalid '%s' argument", "file"), domain= NA)
pkgname <- basename(dirpath)
RdDB <- file.path(path, pkgname)
if(!file.exists(paste(RdDB, "rdx", sep= ".")))
stop(gettextf("package %s exists but was not installed under R >= 2.10.0 so help cannot be accessed", sQuote(pkgname)), domain= NA)
tools:::fetchRdDB(RdDB, basename(file))
}
#' Creates rhelp url, mostly compatible to \code{help}
#'
#' @param topic
#' @param package
#' @param ... for compatibility
#' @returnType character
#' @return URL in rhelp schema
.getRHelpUrl <- function(helpObj) {
if (inherits(helpObj, "packageInfo")) {
return (paste("rhelp:///page", helpObj$name, "", sep= "/"))
}
if (inherits(helpObj, "help_files_with_topic")) {
topic <- attr(helpObj, "topic", exact= TRUE)
if (is.null(topic)) {
topic <- "help"
package <- "utils"
}
else {
package <- attr(helpObj, "call", exact= TRUE)[["package"]]
}
if (is.name(y <- substitute(package))) {
package <- as.character(y)
}
if (is.character(package)
&& length(package) == 1 && !is.na(package)) {
return (paste("rhelp:///page", package, topic, sep= "/"))
}
else {
return (paste("rhelp:///topic", topic, sep= "/"))
}
}
stop("Unexpected help information.")
}
#' Creates HTML help page for the given help page(s).
#'
#' @param x vector of help pages (as returns by original \code{help}
#' @return HTML page for a single page, otherwise \code{NULL}
#' @returnType character
.getLiveHelp <- function(x) {
paths <- as.character(x)
if(!length(paths)) {
writeLines(c(gettextf("No documentation for '%s' in specified packages and libraries:",
topic),
gettextf("you could try '??%s'",
topic)))
return (invisible(NULL))
}
if (attr(x, "tried_all_packages", exact= TRUE)) {
paths <- unique(dirname(dirname(paths)))
msg <- gettextf("Help for topic '%s' is not in any loaded package but can be found in the following packages:",
topic)
writeLines(c(strwrap(msg), "",
paste(" ", formatDL(c(gettext("Package"), basename(paths)),
c(gettext("Library"), dirname(paths)),
indent= 22))))
return (invisible(NULL))
}
file <- NULL
if (length(paths) > 1L) {
p <- paths
msg <- gettextf("Help on topic '%s' was found in the following packages:",
topic)
paths <- dirname(dirname(paths))
txt <- formatDL(c("Package", basename(paths)),
c("Library", dirname(paths)),
indent= 22L)
writeLines(c(strwrap(msg), "", paste(" ", txt), ""))
if (interactive()) {
fp <- file.path(paths, "Meta", "Rd.rds")
tp <- basename(p)
titles <- tp
if(type == "html" || type == "latex")
tp <- tools::file_path_sans_ext(tp)
for (i in seq_along(fp)) {
tmp <- try(.readRDS(fp[i]))
titles[i] <- if(inherits(tmp, "try-error"))
"unknown title" else
tmp[tools::file_path_sans_ext(tmp$File) == tp[i], "Title"]
}
txt <- paste(titles, " {", basename(paths), "}", sep= "")
## the default on menu() is currtently graphics = FALSE
res <- menu(txt, title= gettext("Choose one"),
graphics= getOption("menu.graphics"))
if (res > 0) {
file <- p[res]
} else {
file <- NULL
}
} else {
file <- paths[1L]
writeLines(gettext("\nUsing the first match ..."))
}
} else {
file <- paths
}
if (is.null(file)) {
return (invisible(NULL))
}
file <- sub("/html/([^/]*)\\.html$", "/help/\\1", file)
if (getRversion() < "2.11.0") {
rd <- .getHelpFile(file)
}
else {
rd <- utils:::.getHelpFile(file)
}
renderRd(rd, basename(dirname(dirname(file))))
}
.showHelp <- function(url) {
if (missing(url) || !is.character(url) || length(url) != 1) {
stop("Illegal argument: url")
}
.rj_ui.execCommand("r/showHelp", list(
url= url ), wait= FALSE)
}
#' Shows R help in StatET. This is a console command for R help in StatET
#' mainly compatible to the original \code{help}.
#'
#' @seealso help
#' @export
statet.help <- function(topic, package= NULL, lib.loc= NULL,
verbose= getOption("verbose"),
try.all.packages= getOption("help.try.all.packages"), ...,
live= FALSE ) {
nextCall <- match.call(expand.dots= TRUE)
callName <- nextCall[[1]]
if (is.null(nextCall$topic) && !is.null(nextCall$package)) {
packageInfo <- list(name= nextCall$package)
class(packageInfo) <- "packageInfo"
result <- list(value= packageInfo, visible= TRUE)
}
else {
nextCall[[1]] <- substitute(utils::help)
nextCall$live <- NULL
nextCall$help_type <- "html"
result <- withVisible(eval(nextCall, envir= parent.frame()))
result.call <- attr(result$value, "call", exact= TRUE)
if (!is.null(result.call)) {
result.call[[1]] <- callName
attr(result$value, "call") <- result.call
}
}
if (live) {
help.statet <- .getLiveHelp(result$value)
if (!is.null(help.statet)) {
help.statet <- paste(help.statet, collapse= "\n")
help.statet <- paste("html:///", help.statet, sep= "")
}
}
else if (is.null(.rj.tmp$help)
|| inherits(result$value, "packageInfo") ) {
help.statet <- .getRHelpUrl(result$value)
}
else {
return (resolveVisible(result))
}
if (is.character(help.statet) && !is.na(help.statet)) {
.showHelp(help.statet)
}
return (invisible())
}
#' Shows the R help start page in StatET. This is a console command for R help in StatET
#' mainly compatible to the original \code{help.start}.
#'
#' At moment no argument functionality is supported.
#'
#' @param ... for compatibility
#' @seealso help.start
#' @export
statet.help.start <- function(...) {
.showHelp("rhelp:///")
return (invisible())
}
statet.print.help <- function(x, ...) {
type <- attr(x, "type", exact= TRUE)
if (length(x) == 0
|| (!is.null(type) && type != "html")
|| is.null(.rj.tmp$help) ) {
# NextMethod ?
return (utils:::print.help_files_with_topic(x, ...))
}
help.statet <- .getRHelpUrl(x)
if (is.character(help.statet)
&& length(help.statet) == 1 && !is.na(help.statet)) {
.showHelp(help.statet)
}
return (invisible(x))
}