creating Rd documentation files for R6 classes not in a package
Asked Answered
G

1

5

I am trying to create the documentation of a few scripts that have some R6 classes in it. As an example I use the R6Class named "Person" from here: https://www.tidyverse.org/blog/2019/11/roxygen2-7-0-0/

I am using this function https://mcmap.net/q/552205/-possible-to-create-rd-help-files-for-objects-not-in-a-package to create the documentation without the need of creating a package. Is it also possible to use this for R6Classes or is there maybe another way to achieve this? With the mentioned function I always get an Error R6 Class (Person) without source references.

The solution of the official tidyverse blog https://www.tidyverse.org/blog/2019/11/roxygen2-7-0-0/ to write Roxygen: list(r6 = FALSE) in the DESCRIPTION file does not work because I don't have a package and so no DESCRIPTION file.

Grissel answered 1/10, 2020 at 10:3 Comment(0)
H
8

One way to do this is to hijack some of roxygen2's unexported functions to create the block object for the documented R6 class and write an Rd file. This can then be parsed and written to html using the tools package.

This is a very rough proof-of-concept, requiring your R6 definition to be in a standalone file, and not taking any arguments to allow saving to specific locations, etc, but it could be adapted and expanded to suit:

document_R6 <- function(R_file)
{
  blocks  <- lapply(roxygen2:::tokenize_file(R_file), roxygen2:::block_set_env,
                    env = .GlobalEnv)
  blocks  <- roxygen2:::order_blocks(blocks)
  roclet  <- roxygen2:::roclet("rd")
  my_rd   <- suppressWarnings(roxygen2:::roclet_process(roclet, blocks))
  my_rd   <- my_rd[[1]]$format()
  rd_file <- tempfile()
  writeLines(my_rd, rd_file)
  tools::Rd2HTML(tools::parse_Rd(rd_file), 
                 gsub("\\.R$", ".html", R_file))
}

So if we have the following file, taken from your link:

Person.R

#' R6 Class representing a person
#'
#' A person has a name and a hair color.
Person <- R6::R6Class("Person",
  public = list(
    #' @field name First or full name of the person.
    name = NULL,

    #' @field hair Hair color of the person.
    hair = NULL,

    #' @description
    #' Create a new person object.
    #' @param name Name.
    #' @param hair Hair color.
    #' @return A new `Person` object.
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
      self$greet()
    },

    #' @description
    #' Change hair color.
    #' @param val New hair color.
    #' @examples
    #' P <- Person("Ann", "black")
    #' P$hair
    #' P$set_hair("red")
    #' P$hair
    set_hair = function(val) {
      self$hair <- val
    },

    #' @description
    #' Say hi.
    greet = function() {
      cat(paste0("Hello, my name is ", self$name, ".\n"))
    }
  )
)

Then we can do:

document_R6("Person.R")

The following is a screenshot of the resulting rendered "Person.html" file, found in the same directory as "Person.R":


enter image description here

Heflin answered 4/10, 2020 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.