Author: Andreas Dominik Cullmann

# An Introduction to document

#### Andreas Dominik Cullmann

#### 2022-08-17, 09:21:00

# Teaser

Have you ever been tempted to create roxygen2-style documentation comments for one of your functions that was not part of one of your packages (yet)?

This is exactly what this package is about: running roxygen2 on (chunks of) a single code file.

## Features

This package enables you to

- create function documentation with roxygen2
- detect code/documentation mismatches
- save the documentation to disk
- view the documentation in your interactive R session

It does so by creating a temporary package from (the chunks of) your single code file. It runs R CMD check to see if your code and documentation match. For the sake of cpu time on CRAN, I have disabled that check in all examples below by setting `check_package = FALSE`. You should always stick with the default. This is what this package is about!

# Writing Documentation Files to Disk

## A Minimal Example

Suppose you have a script

    path <- system.file("files", "minimal.R", package = "document")
    cat(readLines(path), sep = "\n")

    #' Nothing Good For
    #'
    #' Just prints "foo!".
    #' @author Your Name <you@@somewhe.re>
    #' @param x Not needed.
    #' @return NULL
    #' @export
    #' @examples
    #' foo(x = 2)
    foo <- function(x) {
        print("foo!")
        return(invisible(NULL))
    }

    #' Uhh
    #'
    #' Just prints "bar!".
    #' @author Your Name <you@@somewhe.re>
    #' @return NULL
    #' @export
    #' @examples
    #' bar()
    bar <- function() {
        print("bar!")
        return(invisible(NULL))
    }

Then

    d <- document::document(file_name = path, check_package = FALSE)

creates a Portable Document Format (pdf) file, an Hypertext Markup Language (html) file and a plain text file. The plain text reads

    cat(readLines(d[["txt_path"]]), sep = "\n")

    Uhh

    Description:

         Just prints "bar!".

    Usage:

         bar()

    Author(s):

         Your Name <you@somewhe.re>

    Examples:

         bar()

    Nothing Good For

    Description:

         Just prints "foo!".

    Usage:

         foo(x)

    Arguments:

           x: Not needed.

    Author(s):

         Your Name <you@somewhe.re>

    Examples:

         foo(x = 2)

You can view a copy of the html file here. The pdf file resembles a package’s documentation pdf file.

### Checking the code with R CMD check

By default, `document` checks the temporary package it creates from your code file using R CMD check. The corresponding call would be:

    res <- document(file_name = system.file("files", "minimal.R",
                                            package = "document"),
                    check_package = TRUE)

After that you could display the check results with:

    cat(res[["check_result"]][["output"]][["stdout"]], sep = "\n")
    cat(res[["check_result"]][["output"]][["stderr"]], sep = "\n")

## A Simple Example

Suppose you have a script

    path <- system.file("files", "simple.R", package = "document")
    cat(readLines(path), sep = "\n")

    #!/usr/bin/Rscript --vanilla
    #' \emph{File} simple.R
    #'
    #' Provide a simple example of a file using roxygen and standard R comments.
    #'
    #' @note This header will show up in the documentation, but it's got nothing to
    #' do with the R statements below. Usually this is not intended.
    #' @section Warning: DO NOT CHANGE THE FOLLWOWING THREE LINES.
    #' @docType data
    #' @name A Header for
    NULL
    # ROXYGEN_STOP

    #% Front Matter
    ##% load packages
    library("methods") # load an example package from the standard library

    ##% load local code
    # This would usually be functions defined and stored away in files.

    ##% define local functions
    # ROXYGEN_START

    #' a first function example XXX
    #'
    #' This really is just an example, the function prints \code{utils::head()} and
    #' \code{utils::str()} of the given \code{data.frame}.
    #' @param df Name of a data.frame to ... do whatever needs to be done.
    #' @return NULL. This is no good.
    #' @export
    #' @examples
    #' data(iris, package = "datasets")
    #' a_first_function(iris)
    a_first_function <- function(df) {
        message(paste("# Structure of", deparse(substitute(df)), ":"))
        utils::str(df)
        message(paste("# Head of", deparse(substitute(df)), ":"))
        print(utils::head(df))
        return(invisible(NULL))
    }
    # ROXYGEN_STOP

    ##% set "global" options
    options(warn = 1)

    #% Body Matter
    ##% Load data
    data(iris, package = "datasets")

    ##% Analysize the data
    a_first_function(iris)

    #% Back Matter

Then you can write documentation using:

    d <- document::document(file_name = path, check_package = FALSE)

    cat(readLines(d[["txt_path"]]), sep = "\n")

    _File_ simple.R

    Description:

         Provide a simple example of a file using roxygen and standard R
         comments.

    Warning:

         DO NOT CHANGE THE FOLLWOWING THREE LINES.

    Note:

         This header will show up in the documentation, but it's got
         nothing to do with the R statements below. Usually this is not
         intended.

    a first function example XXX

    Description:

         This really is just an example, the function prints
         'utils::head()' and 'utils::str()' of the given 'data.frame'.

    Usage:

         a_first_function(df)

    Arguments:

          df: Name of a data.frame to ... do whatever needs to be done.

    Value:

         NULL. This is no good.

    Examples:

         data(iris, package = "datasets")
         a_first_function(iris)

# Displaying Temporary Help Files

You can display the help page for one of the documented functions using

    path <- system.file("files", "minimal.R", package = "document")
    document::man(x = path, topic = "foo")

    Nothing Good For

    Description:

         Just prints "foo!".

    Usage:

         foo(x)

    Arguments:

           x: Not needed.

    Author(s):

         Your Name <you@somewhe.re>

    Examples:

         foo(x = 2)