fun1 {topichelp}R Documentation

Help system links

Description

Examples of help system links that need to be handled carefully if we change the current lookup order.

Usage

fun1(x, ...)
fun2(x, ...)

Arguments

x

An object.

...

Extra arguments.

Details

This file documents a proposed change to the lookup rule in R's dynamic HTML help system, and identifies existing links on CRAN that will need to be updated to continue working as intended. It is also meant to serve as a source of test cases for the proposed change.

The source of this documentation can be found at https://github.com/deepayan/misc/blob/master/helptopic/man/funs.Rd

Current status

The R help system includes a concept of hyperlinks to other help pages. Such hyperlinks are supported to a limited extent in PDF (e.g., within-package links in the manual) and to a greater extent in HTML help.

For potential problems with within-package links, see fun3. This discussion is limited to links to other packages. These come in two forms:

Here pkg is the target package, and foo has historically been documented to be interpreted as a file link; i.e., both links above are supposed to go to the file corresponding to pkg/man/foo.Rd. The explicit file specification is needed because R manual pages often document multiple objects; e.g., grid/man/grid.rect.Rd documents both grid.rect and rectGrob, so

In R 2.10.0 or thereabouts, a new dynamic help system was introduced to enable features not possible in static HTML files, such as the ability to include content generated dynamically at the time of rendering the page. This new system also modified the interpretation for \link[pkg:foo]{link-text}:

Note that this means that the link to be embedded in the HTML file being rendered does not need to know anything about the target package pkg, and in particular, whether the link will at all be resolved. The actual lookup will happen only when the user clicks on the link, and may fail if the target package is not installed or the file / topic does not exist in it.

This also means that the links in the generated HTML is the same for both static and dynamic help, but in the latter case a foo.html link is resolved to first display the help page generated by man/foo.Rd if it exists, and then to display the help page generated by man/bar.Rd if man/bar.Rd contains \alias{foo}.

This can be verified by following the grid links above and checking the URL shown (through dynamic help).

It is possible, in principle, for multiple help pages, say man/bar.Rd and man/baz.Rd, to contain \alias{foo}. Such packages can be installed (e.g., fun1 is an alias both in this page and in fun3), but R CMD check will produce a WARNING, so such packages will not get on CRAN. Such a link will resolve to one of the two pages, but we do not really care which one.

Fixing static pages

In the current setup, one infelicity is that non-file links do not work with static HTML pages. To solve this without changing the generated HTML in any way, we must have a topic.html file available for every topic (alias) in a package. This can be done easily by creating small one-line HTTP redirect files pointing to the actual target file while processing the package man files.

To ensure that filenames get priority over topics, we only need to ensure that

Going further — prefer topic over filename

Although file links are natural with traditional hyperlinks, for the R help system it is more natural to link to topics rather than filenames. There is a general consensus that we should move to a system where \link[pkg:foo]{link-text} should be interpreted as a link to the topic foo in package pkg, regardless of whether there is a file called man/foo.Rd in it. In fact, there are many instances of packages on CRAN where this interpretation has been assumed, because of the support for topic links in the dynamic help system (such links do not currently work with static HTML).

Implementing this should not be difficult, but unfortunately, switching completely to a topic-only lookup rule would be unfair to careful package authors who have intentionally linked to files. So the proposal is only to prefer topics and fall back to files when the topic does not exist.

This still leaves open the possibility of penalizing careful package authors under certain special circumstances; namely, the package pkg has a file foo.Rd, as well as a topic \alias{foo} but in a different file bar.Rd. In such cases, a link like \link[pkg:foo]{link-text} would change meaning; from being a link to foo.Rd it will become a link to bar.Rd.

The example code below finds instances of such occurrences on CRAN (yielding 79 such packages). Fortunately, in all these cases, the name of the file (bar.Rd) is not an alias in the package (i.e., there is no \alias{bar}), so links of the form \link[pkg:bar]{link-text} would unambiguously link to bar.Rd.

This is still not a problem unless there are other packages that actually link to one of these ambiguous topic / file pairs. Pattern matching leads to the following extant examples, which we need to analyze. Fortunately, there are not many packages that potentially need fixing, but we do need to find a resolution that will work both in pre- and post-change versions of R.

The examples are organized by target package.

adegenet

Topic genind is documented in file new.genind.Rd. File genind.Rd documents genind-class and other related methods.

Topic genpop is documented in file new.genind.Rd. File genpop.Rd documents genpop-class and other related methods.

The following packages link to either of these (genind.Rd and genpop.Rd):

All these currently link to the class page and not the function page. This is probably as intended in several cases, although probably not in at least the last two examples. Under the new proposal, these will link to the function page.

Links of the following form should work both under the current and proposed rules:

callr

The following instances of \link[callr:rcmd_safe] both currently link to the topic rcmd_safe_env in rcmd_safe.Rd, which is likely not intended. The topic rcmd_safe is documented in file rcmd.Rd.

These will work as intended under the proposed scheme, so probably best to leave them alone. Alternatively, change \link[callr:rcmd_safe]{link-text} to \link[callr:rcmd]{link-text}.

lamW

The file lamW.Rd documents several functions, whereas the topic lamW is documented in file lamW-package.Rd. So the following links are all explicit and correct file links that will stop working in the proposed scheme.

A fix that should work under both current and proposed schemes is to change \link[lamW:lamW]{lambertW0_C} to the simpler (and more correct) \link[lamW]{lambertW0}, etc. (lambertW0_C is an internal function, not supposed to be user-callable, and not documented in lamW.Rd). Unfortunately, this will no longer work for static pages in the current scheme, but that is hopefully a minor consideration.

parsnip

The only problematic link here is topic fit which is documented in file reexports.Rd (as a rexported generic), while the file fit.Rd documents the S3 method fit.model_spec. For the links below that have the form \link[parsnip:fit]{link-text}, the intent is almost certainly to link to fit.Rd, as the links below currently do, but that will change under the proposed scheme.

A fix that would work with both current and proposed schemes would be change to links of the form \link[parsnip:fit.model_spec]{link-text}.

perm

Here the file perm.Rd documents topics permTS, permKS, etc., and the topic perm is in file perm-package.Rd.

The links (all \link[perm]{perm}) above currently link to the file, which is likely as intended. To continue this in a back-compatible manner, they should be changed to \link[perm:permTS]{perm}.

spaMM

The file Matern.corr.Rd documents topic MaternCorr, while the topic Matern.corr is an alias in spaMM-internal.Rd. The link

is likely meant to be to the file Matern.corr.Rd, and so should be changed to \link[spaMM:MaternCorr]{Matern.corr}, or probably more appropriately and simply, to \link[spaMM]{MaternCorr}.

Examples


a <- tools:::CRAN_aliases_db()
fun <- function(e) {
    files <- tools::file_path_sans_ext(names(e))
    topics <- Map(setdiff, e, files)
    intersect(files, unlist(topics))
}
z <- lapply(a, fun)
z <- Filter(length, z)

ambiguousTopics <- function(pkg)
{
    ## filenames which are also topics in a different file
    files <- z[[pkg]]
    ## which file the corresponding topic is in
    otherfiles <- character(length(files))
    for (i in seq_along(files))
    {
        otherfiles[i] <-
            names(which(sapply(a[[pkg]], function(x) files[i] %in% x)))
    }
    ## Is 'otherfile' also a topic somewhere in the package?
    also_topic <- otherfiles %in% unlist(a[[pkg]])
    data.frame(pkg = pkg, file = files, topicfile = otherfiles,
               also_topic = also_topic)
}

options(width = 120)
do.call(rbind, lapply(names(z), ambiguousTopics))


[Package topichelp version 0.0-1 Index]