Skip to content

Commit

Permalink
Automate R docs build from roxygen comments (#205)
Browse files Browse the repository at this point in the history
* Automate R docs build from roxygen comments

* Update docs on docs
  • Loading branch information
WardBrian authored Jan 29, 2024
1 parent 7c793e5 commit a3a1b6e
Show file tree
Hide file tree
Showing 15 changed files with 609 additions and 460 deletions.
15 changes: 14 additions & 1 deletion .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,25 @@ jobs:
- name: Set up Julia
uses: julia-actions/setup-julia@v1

- name: Install package

- name: Install R
uses: r-lib/actions/setup-r@v2.6.5

- name: Install R dependencies
uses: r-lib/actions/setup-r-dependencies@v2.6.5
with:
packages: |
any::roxygen2
github::Genentech/rd2markdown
- name: Install packages
run: |
cd python/
pip install .
cd ../julia
julia --project=./docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
cd ../R/
Rscript -e "install.packages(getwd(), repos=NULL, type=\"source\")"
- name: Calculate version
if:
Expand Down
2 changes: 1 addition & 1 deletion R/R/bridgestan.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' StanModel
#'
#' R6 Class representing a compiled BridgeStan model.
#' @description R6 Class representing a compiled BridgeStan model.
#'
#' This model exposes log density, gradient, and Hessian information
#' as well as constraining and unconstraining transforms.
Expand Down
34 changes: 19 additions & 15 deletions R/R/compile.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@ IS_WINDOWS <- isTRUE(.Platform$OS.type == "windows")
MAKE <- Sys.getenv("MAKE", ifelse(IS_WINDOWS, "mingw32-make", "make"))


#' Get the path to BridgeStan.
#'
#' By default this is set to the value of the environment
#' variable `BRIDGESTAN`.
#'
#' If there is no path set, this function will download
#' a matching version of BridgeStan to a folder called
#' `.bridgestan` in the user's home directory.
#'
#' See also `set_bridgestan_path`
verify_bridgestan_path <- function(path) {
suppressWarnings({
folder <- normalizePath(path)
Expand All @@ -26,15 +16,25 @@ verify_bridgestan_path <- function(path) {
}
}

#' Set the path to BridgeStan.
#'
#' This should point to the top-level folder of the repository.
#' @title Function `set_bridgestan_path()`
#' @description Set the path to BridgeStan.
#' @details This should point to the top-level folder of the repository.
#' @export
set_bridgestan_path <- function(path) {
verify_bridgestan_path(path)
Sys.setenv(BRIDGESTAN = normalizePath(path))
}

#' Get the path to BridgeStan.
#'
#' By default this is set to the value of the environment
#' variable `BRIDGESTAN`.
#'
#' If there is no path set, this function will download
#' a matching version of BridgeStan to a folder called
#' `.bridgestan` in the user's home directory.
#'
#' @seealso [set_bridgestan_path]
get_bridgestan_path <- function() {
# try to get from environment
path <- Sys.getenv("BRIDGESTAN", unset = "")
Expand All @@ -54,8 +54,10 @@ get_bridgestan_path <- function() {
}


#' Run BridgeStan's Makefile on a `.stan` file, creating the `.so`
#' used by the StanModel class.
#' @title Function `compile_model()`
#' @description Compiles a Stan model.
#' @details Run BridgeStan's Makefile on a `.stan` file, creating
#' the `.so` used by the StanModel class.
#' This function checks that the path to BridgeStan is valid
#' and will error if not. This can be set with `set_bridgestan_path`.
#'
Expand All @@ -67,6 +69,8 @@ get_bridgestan_path <- function() {
#' threading for the compiled model. If the same flags are defined
#' in `make/local`, the versions passed here will take precedent.
#' @return Path to the compiled model.
#'
#' @seealso [bridgestan::set_bridgestan_path()]
#' @export
compile_model <- function(stan_file, stanc_args = NULL, make_args = NULL) {
verify_bridgestan_path(get_bridgestan_path())
Expand Down
30 changes: 30 additions & 0 deletions R/convert_docs.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Converts R documentation (.Rd) files to markdown (.md) files
# for use in Sphinx.

library(rd2markdown)
library(roxygen2)

roxygen2::roxygenize()

files <- list.files("man", pattern="*.Rd")

# we only want to doc exported functions, so we need
# to read the NAMESPACE file
namespace <- paste0(readLines("NAMESPACE"), collapse="\n")

for (f in files){
name <- substr(f, 1, nchar(f)-3)

if (!grepl(name, namespace, fixed=TRUE)){
print(paste0("Skipping unexported ", name))
next
}

# read .Rd file and convert to markdown
rd <- rd2markdown::get_rd(file=file.path(".", "man", f))
md <- rd2markdown::rd2markdown(rd, fragments=c())

# write it to the docs folder
writeLines(md, file.path("..", "docs", "languages", "_r", paste0(name, ".md")))

}
5 changes: 0 additions & 5 deletions R/man/StanModel.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions R/man/compile_model.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions R/man/verify_bridgestan_path.Rd → R/man/get_bridgestan_path.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion R/man/set_bridgestan_path.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,30 @@
else:
print("Failed to build julia docs!\n", e)

try:
print("Building R doc")
subprocess.run(
["Rscript", "convert_docs.R"],
cwd=pathlib.Path(__file__).parent.parent / "R",
check=True,
)

# delete some broken links in the generated R docs
StanModel = (pathlib.Path(__file__).parent / "languages" / "_r" / "StanModel.md")
text = StanModel.read_text()
start = text.find("### Public methods")
end = text.find("### Method `")
text = text[:start] + text[end:]
StanModel.write_text(text)

except Exception as e:
# fail loudly in Github Actions
if RUNNING_IN_CI:
raise e
else:
print("Failed to build R docs!\n", e)


try:
print("Checking C++ doc availability")
import breathe
Expand Down
9 changes: 7 additions & 2 deletions docs/internals/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Documenting a mixed-language project such as BridgeStan can be tricky.

We attempt to keep documentation in the natural place for each language: C/C++
code is documented with doxygen-style comments in the source, Python documentation
appears in docstrings, etc. With the exception of the R interface, our documentation
generation (powered by `Sphinx <https://www.sphinx-doc.org/en/master/>`__) automatically
appears in docstrings, etc. Our documentation generation
(powered by `Sphinx <https://www.sphinx-doc.org/en/master/>`__) automatically
combines these together into the documentation you are reading now.

To build the documentation, you can run ``make docs`` in the top-level directory.
Expand All @@ -31,3 +31,8 @@ Similarly, the Julia documentation will only update if Julia is installed. Julia
documentation is written in :file:`julia/docs/src/julia.md`. We then build
this with `DocumenterMarkdown.jl <https://github.com/JuliaDocs/DocumenterMarkdown.jl>`__,
and the output is placed in :file:`docs/languages/julia.md`.

Finally, the R documentation is primarily written in :file:`/docs/languages/r.md`.
The API documentation for R is done by including files generated by
`rd2markdown <https://github.com/Genentech/rd2markdown>`__, which runs
on the results of the `roxygen2 package <https://roxygen2.r-lib.org/>`__.
3 changes: 3 additions & 0 deletions docs/languages/_r/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
These files are automatically generated in `conf.py` and should
not be manually edited. They are built from the documentation
comments in the R source code.
Loading

0 comments on commit a3a1b6e

Please sign in to comment.