How to get roxygen2 to interpret backticks as code formatting? - r

The standard way of writing documentation with code formatting is by using \code{}.
That is, #' #param foo value passed on to \code{bar()} becomes
Arguments
foo    value passed on to bar()
However, I've seen some packages (i.e. dplyr) using backticks instead of \code{} to the same effect. This is much better, since it's less clunky and allows for very nice syntax highlighting.
However, if I try that on my own package, the backticks get interpreted as... just backticks, like any other character.
The documentation for dplyr::across(), for example, starts with:
#' #description
#' `across()` makes it easy to apply the same transformation to multiple [...]
which gets compiled and displayed in the man page as:
Description
across() makes it easy to apply the same transformation to multiple [...]
But if I try something similar on my package, I get:
Description
`across()` makes it easy to apply the same transformation to multiple [...]
Weirdly, I've forked the package glue (which also manages to use backticks for code formatting) for a simple PR, and if I build the package locally, the backticks work (I get code formatting). Can't for the life of me figure out why it works there but not for my package.
So, is there some setting I need to modify to get this to work? I checked the dplyr.Rproj but found nothing relevant. I also glanced at the Doxyfile, but didn't know what it did or what I'd even be looking for there.

All credit goes to #rawr's comment to the question, just formalizing it with an answer:
The secret is in the roxygen2 documentation: just add the following to the end of the package DESCRIPTION file:
# DESCRIPTION file
# [... rest of file ...]
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.2 # actually works since 6.0.0
As that code would imply, this sets roxygen2 to interpret the commands as good ol' Markdown like we're used to using here on SO and elsewhere. This also implies all the other standard Markdown commands such as **bold** and *italics*, as well as [text](http://www.url.com), code blocks defined by ```, itemized and enumerated lists, etc. It's a huge improvement across the board.
Though be careful and take a look at the documentation, since there are a few gotchas. For instance, an empty line isn't necessary to start lists, so don't start any lines with #' 1. [...] or #' * [...] or you'll accidentally create a list!). There's also a few things which don't work yet, but they're pretty minor.

Related

How to export S3method both as method and normal function using roxygen2

There are similar, older questions out there, but since roxygen2 version 3.0.0 things have changed a bit (as I understand from other Q&A here on SO).
I have written an alternative function format.Date, which I want to export, both as method and as function.
Using the #export tag means roxygen2 recognises it as an S3-method for print, and registers it accordingly. And when I load my package, and print a date object, my method gets called. So far, so good.
But, when I then call format.Date, I still get the normal base-method. This also happens when I use debugonce(format.Date), the 'debug-mark' gets set on base::format.Date, so if my method gets called, nothing happens. Or if I want to inspect the source-code: very hard for a user to understand that what he sees with View(format.Date) is NOT what is executed.
And if a user looks into my package what functions I have provided, format.Date is not there.
So I want format.Date to be exported as both an S3-method, and as a normal function called format.Date. In order to do so, I expect my NAMESPACE file to contain both following lines:
S3method(format,Date)
export(format.Date)
Is this possible in roxygen2? I get the impression you could do this in earlier versions (as you could supply both #S3method/#method and #export), but I can't get it to work now.
Background-info: roxygen2 version 6.1.1 with R 3.5.1, run under Rstudio 1.1.453/MacOS 10.13.6
The ways I found are
#exportS3Method and an explicit #export line. Since roxygen2 changes often, this might change in the future:
#' #exportS3Method fortify
#' #export fortify.Date
Manually spelling out the NAMESPACE content (add no other #export or #method directives)
#' #rawNamespace S3method(fortify,Date)
#' export(fortify.Date)
Both will result in the NAMESPACE file containing the following lines, with the first one resulting in roxygen2 ordering things for you.
S3method(fortify,Date)
export(fortify.Date)

Using an R Markdown Document as a source for functions

I'm looking into R Markdown for documenting functions I regularly use. I will put them into an R Markdown file to document them and then be able to read my thinking behind the function if i come back to it months later
My question is, if i start a new R project, Is it possible to source the r markdown file and use the library of functions i have created just by calling them similarly to if i was sourcing a regular R file. I dont really wish to maintain two sets of function files
I appreciate this may be a beginners question but any help pointing to tutorials and the like would be greatly appreciated
Thanks
As was mentioned in the comments, you should probably create a package for this purpose. But if you insist on putting function definitions in scripts and document them using RMarkdown files, using read_chunk() from the knitr package might be the way to go.
Note that this approach differs slightly from what you requested. You wanted to have the function definition in the markdown file together with the documentation. And then you wanted to somehow source that file into your R script in order to use the function. I did not find a way to do this (even though it might be possible).
The alternative that I propose puts the function definition in its own R script, say fun.R. The Rmarkdown file then reads the function definition from fun.R and adds documentation. If you want to use the function in some other script, you can simply source fun.R (and not the markdown file). This still means that you have to maintain the code for the function definition only once.
So let me show this with an example. This is fun.R:
## ---- fun
fun <- function(x) x^2
The first line is an identifier that will be used later. The markdown file is as follows:
---
title: "Documentation of fun()"
output: html_document
---
This documents the function `fun()` defined in `fun.R`.
```{r,cache = FALSE}
knitr::read_chunk("fun.R")
```
This is the function definition
```{r fun}
```
This is an example of how to use `fun()`:
```{r use_fun}
fun(3)
```
The first chunk reads in fun.R using knitr::read_chunk. Later on, you can define an empty chunk that has the identifier that was used in fun.R as its name. This will act as if the contents of fun.R were written directly in this file. As you see, you can also use fun() in later chunks. This is a screenshot of the resulting html file:
In a script where you want to use fun() you simply add source("fun.R") to source the function definition.
You could also have several functions in a single R file and still document them separately. Simply put an identifier starting with ## ---- before each function definition and then create empty chunks referring to each one of the identifiers.
This is admittedly somewhat more complicated than what you asked for, because it involves two files instead of just one. But at least there is no redundancy
The klmr/modules package has been superseded by the box package by the same author. It is on CRAN. After the cat command below run these lines to display the roxygen2 help for add2.
box::use(./test)
box::help(test$add2)
Perhaps this is close enough -- you can use the github klmr/modules package (not the CRAN modules package) to combine roxygen2 documentation and code in a single file without creating a package. For example, after installing the modules package copy this to the clipboard and then paste it into the R console to create a single file module with embedded documentation. The subsequent code then imports it, runs a function from it and invokes help. See the documentation of the modules package for more info.
Note that this has the following advantages: (1) everything is in a single file, (2) if you later decide to move to using packages you can use the very same file in your package with roxygen2 -- no need to revise anything, (3) any learning of roxygen2 applies to packages too.
# create a file with our documentation and code
Lines <- "
#' Add two numbers.
#'
#' #param x the first number.
#' #param y the second number.
#' #return The sum.
#' #note This is just a simple example.
#'
#' This function is a simple example intended to show how to use the modules
#' package with roxygen2.
add2 <- function(x, y) x + y
"
cat(Lines, file = "test.R")
# now we can import it
# devtools::install_github("klmr/modules")
library(modules)
test <- import("test") # do not include the .R extension
test$add2(1, 2)
## [1] 3
# this will cause help page to appear
?test$add2

reliably extract srclines and srcfile from a function

I need to extract the exact lines of the source that was parsed to create an R function, for use in coverage analysis. deparse is not accurate enough because in doing coverage analysis with package covr exact line numbers matter.
If there is a srcfile, I just need the filename. If there isn't, e.g. function was created in console, I need to create an equivalent temporary file that could have been, line by line, the source file for that function.
I see several function to extract src information from a function, like getsrcFilename or getSrcref, but none specifically to get the source code.
getSrclines looked promising, but doesn't take functions as arguments. I tried to use attributes to get to the srcref and get to the information that way, but it doesn't seem to be stored consistently -- clearly I am missing something.
Sometimes
attributes(body(cover.fun))$srcfile works and sometimes this attributes(attributes(cover.fun)$srcref)$srcfile) does, and in the srcref itself I found the source in srcfile$lines or srcfile$original$lines and of course these look just like experiments and not The Right Way to implement this.
I need something that takes care of functions created in a package, with source or interactively. If the filename is available, that's all I need, otherwise I need the source lines. Thanks

Pre- or post-process roxygen snippets

Is there some mechanism by which I can transform the comments that roxygen sees, preferably before it does the roxygen->rd conversion?
For example, suppose I have:
#' My function. Does stuff with numbers.
#'
#' This takes an input `x` and does something with it.
#' #param x a number.
myFunction <- function (x) {
}
Now, suppose I want to do some conversion of the comment before roxygen parses it, for example replacing all instances of things in backticks with \code{}. Ie:
preprocess <- function (txt) {
gsub('`([^ ]+)`', '\\\\code{\\1}', txt)
}
# cat(preprocess('Takes an input `x` and does something with it'.))
# Takes an input \code{x} and does something with it.
Can I feed preprocess into roxygen somehow so that it will run it on the doclets before (or after would work in this case) roxygen does its document generation?
I don't want to do a permanent find-replace in my .r files. As you might guess from my example, I'm aiming towards some rudimentary markdown support in my roxygen comments, and hence wish to keep my .r files as-is to preserve readability (and insert the \code{..} stuff programmatically).
Should I just write my own version of roxygenise that runs preprocess on all detected roxygen-style comments in my files, saves them temporarily somewhere, and then runs the actual roxygenise on those?
Revisiting this a couple of years later, it looks like Roxygen has a function register.preref.parsers that one can use to inject their own parsers into roxygen.
One such use of this is the promising maxygen package (markdown + roxygen = maxygen), which a very neat implementation of markdown processing of roxygen comments (albeit only to the CommonMark spec), and you can see how it is used in that package's macument function. I eagerly await "pandoc + roxygen = pandoxygen"... :)

Linking to an S4 method in a .rd file?

I'm writing a package with an S4 class, and I've written methods for as.POSIXct and as.POSIXlt for the class. I've written the documentation and everything looks fine, except that I would like to reference the as.POSIXct method in the documentation for as.POSIXlt, and vice versa. I tried \S4method{coerce}{abc, POSIXct}(from, to), (where 'abc' is the S4 class), but that is only supposed to be put in the \usage section, which isn't where I want it. Is there a way to do this? It seems odd to me that it would not be allowed.
I realize that it is possible to combine these .rd files and avoid this issue, but I'm trying to learn as much as possible about classes and packages in R, so this is of interest to me anyway.
Here is the skeleton of one of the .Rd files:
\name{as.POSIXct-methods}
\docType{methods}
\alias{as.POSIXct-methods}
\alias{as.POSIXct,ANY-method}
\alias{as.POSIXct,abc-method}
\title{\code{abc} Method for Function \code{as.POSIXct}}
\description{
\code{as.POSIXct} method to coerce timestamps in \code{abc} objects into
\code{POSIXct} format.
}
\section{Methods}{
\describe{
~~description here~~
\item{\code{signature(x = "ANY")}}{
default implementation (from base)
}
\item{\code{signature(x = "abc")}}{
implementation for \code{\link{abc}} objects.
~~more description of function~~
See \code{\linkS4class{abc}} for more about abc objects.
See also \code{\link[abc]{as.POSIXlt}} for the corresponding \code{POSIXlt} method.
}
}}
\keyword{methods}
The line fourth from the bottom is the one that is causing problems.
The basic format for a link is
\link{foo}
where foo appears in some help page (in the same package) as \alias{foo}. So if your other package has \alias{as.POSIXlt,abc-method} (pay attention to the absence of spaces) then
\link{as.POSIXlt,abc-method}
Adding [abc] is only necessary when linking to other packages, and then the semantics are confusing (in \link[abc]{foo}, foo is the name of the HTML help page, rather than, e.g., an alias). Adding \code{} is mark-up, so not directly relevant to establishing a link. The link above inserts "as.POSIXlt,abc-method" into the help page, which might be more informative (or not) than an arbitrary \alias tag that might be present.
Per the Cross-references section of Writing R extensions, you can create links to other help pages like this:
\code{\link[base]{as.POSIXct}}
Where "base" is the name of the package (I don't think [base] is necessary, but if it were another package, it would be)

Resources