Include "All other functions" in a pkgdown reference yaml

713 Views Asked by At

I have a pkgdown site in which I group a number of functions into categories in the reference .yml file. I'm wondering if there is a way to put all of the functions which I didn't explicitly categorize into their own category. The only thought I had was to use the matches function like so:

reference:
- title: "someCategory"
  contents:
  - myFunction
- title: "other"
  contents:
  - matches(".*")

But this puts myFunction in both the "someCategory" and "other" categories. What I'd like to do is match all functions which aren't in a category.

Thanks!

3

There are 3 best solutions below

1
On BEST ANSWER

If you don't mind running a function to update your yaml, running this from the root of your package should work (use "overwrite = FALSE" for testing: it will create a _pkgdown_new.yaml file.):

update_yaml <- function(mypkg, overwrite = FALSE) {
  require(yaml)
  #   _____________________________________________________________________
  #   Find currently missing functions in yaml file                    ####
  curr_yaml     <- yaml.load_file("_pkgdown.yaml")
  curr_yaml_ref <- curr_yaml[["reference"]]
  curr_funcs <- unlist(lapply(curr_yaml_ref,
                              FUN = function(x) (x$contents))) %>%
    gsub('`', "", .)
  all_pkgfuncs <- ls(paste0("package:", mypkg))
  miss_funcs   <- setdiff(pkg_funcs, curr_funcs)

  if (length(miss_funcs) == 0) {
    message("All functions are already in _pkgdown.yaml")
  } else {

    #   _________________________________________________________________
    #   Look if an "Other" section already exists                     ####

    titles     <- unlist(lapply(curr_yaml_ref, FUN = function(x) (x$title)))
    other_sect <- which(titles == "Other")

    if (!length(other_sect) == 0) {
      #   _________________________________________________________________
      #   If the "Other" sect already exists, append missing functions ####

      message(strwrap(paste(
        "Adding ", paste0("`", miss_funcs, "` ", collapse = ""),
        "to _pkgdown.yaml")))
      curr_yaml_ref[[other_sect]] = list(
        title = "Other",
        desc  = "Other Functions",
        contents = c(curr_yaml_ref[[other_sect]]$contents,
                     paste0("`", miss_funcs, "`"))
      )

    } else {

      #   _____________________________________________________________
      #   Otherwise, create the "other" section and add            ####

      message("Creating the \"Others\" section")
      message(strwrap(paste(
        "Adding ", paste0("`", miss_funcs, "` ", collapse = ""),
        "to _pkgdown.yaml")))
      curr_yaml_ref[[length(curr_yaml_ref) + 1]] = list(
        title = "Other",
        desc  = "Other Functions",
        contents = paste0("`", miss_funcs, "`"))
    }
    curr_yaml[["reference"]] <- curr_yaml_ref
    if (overwrite) {
      write(as.yaml(curr_yaml), "_pkgdown.yaml")
    } else {
      write(as.yaml(curr_yaml), "_pkgdown_new.yaml")
    }
  }
}

> update_yaml("sprawl", overwrite = F)

Creating the "Others" section
Adding er_crop_object er_getbands er_points er_polygons reproj_rast setClasses``setinfo_rast sprawl_scalebar to _pkgdown.yaml

The function browses the current .yaml file and finds the currently missing functions. If any are found, they are added to the "Others" section of the .yaml (which is automatically created if not already present).

I did a quick test and it seems to work properly.

HTH !

2
On

I'm not familiar with pkgdown, but for a limited case like this it might be feasible to use matches with regex for does not equal any of these

Regex negations are not efficient, and you will have to retype the names of your categorized functions, so again this might work in your limited case but is not a best practice.

Would something like this work? (test here)

- title: "other"
  contents:
  - matches('^(?!.*(myFunction|myOtherFunction|yetAnotherFunction)).*$')
1
On

In pkgdown, there is already a feature to warn you about the topics that are missing in your yaml file. You can see the code by typing pkgdown:::data_reference_index.

So, basically, if you just modify this code a little, you can return the names of the functions that are missing from the index.

library(purrr)
data_reference_index_missing <- function(pkg = ".", depth = 1L) {
  pkg <- pkgdown:::as_pkgdown(pkg)

  meta <- pkg$meta[["reference"]] %||% default_reference_index(pkg)
  if (length(meta) == 0) {
    return(list())
  }

  # Cross-reference complete list of topics vs. topics found in index page
  all_topics <- meta %>%
    map(~ pkgdown:::select_topics(.$contents, pkg$topics)) %>%
    reduce(union)
  in_index <- seq_along(pkg$topics$name) %in% all_topics

  missing <- !in_index & !pkg$topics$internal
  pkg$topics$name[missing]
}