Skip to content

Commit

Permalink
close #1929: mention the lazy registration of S3method() in NAMESPACE…
Browse files Browse the repository at this point in the history
… in the knit_print vignette so that package authors don't have to make knitr a hard dependency
  • Loading branch information
yihui committed Aug 31, 2023
1 parent 0901218 commit 360176b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- `write_bib()` has a new argument `packageURL` to control whether to use a URL from the `DESCRIPTION` file or the one generated by `utils::citation()` (thanks, @dmurdoch, #2264).

- Updated the package vignette `vignette('knit_print', 'knitr')` to mention that package authors no longer have to make **knitr** a hard dependency if they want to define S3 methods for `knitr::knit_print` with R >= 3.6.0 (thanks, @cderv, #1929).

## BUG FIXES

- Fixed a bug in `spin(format = 'Rnw')` reported by @Tarious14 at https://github.com/yihui/yihui.org/discussions/769#discussioncomment-6587927
Expand Down
17 changes: 14 additions & 3 deletions vignettes/knit_print.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,24 @@ str(knit_meta()) # empty now, because clean = TRUE by default

If you are implementing a custom print method in your own package, here are two tips:

1. Normally you need to import `knit_print` in your package namespace via `importFrom(knitr, knit_print)` (or roxygen: `#' @importFrom knitr knit_print`) (see [the **printr** package](https://github.com/yihui/printr) for an example). If you don't want to import **knitr**, you can call `registerS3method()` in your `.onLoad()` hook (see [rstudio/htmltools#108](https://github.com/rstudio/htmltools/pull/108/files) for an example);
1. `asis_output()` is simply a function that marks an object with the class `knit_asis`, and you do not have to import this function to your package, either -- just let your print method return `structure(x, class = 'knit_asis')`, and if there are additional metadata, just put it in the `knit_meta` attribute; here is the source code of this function:
1. With R >= 3.6.0 (2019-04-26), you can declare the S3 method in the package `NAMESPACE` with `S3method(knitr::knit_print, class)`. If you use **roxygen2** package, that means a roxygen comment like this:

```r
#' @exportS3Method knitr::knit_print
knit_print.class <-
```

With this method, you do not need to import **knitr** to your package, i.e., **knitr** can be listed in `Suggests` and not necessarily `Imports` in the package `DESCRIPTION`. The S3 methods will be automatically registered when **knitr** is actually loaded.

For R < 3.6.0, you need to import `knit_print` in your package namespace via `importFrom(knitr, knit_print)` (or roxygen: `#' @importFrom knitr knit_print`) (see [the **printr** package](https://github.com/yihui/printr) for an example).

1. `asis_output()` is simply a function that marks an object with the class `knit_asis`, and you do not have to import this function to your package, either---just let your print method return `structure(x, class = 'knit_asis')`, and if there are additional metadata, just put it in the `knit_meta` attribute; here is the source code of this function:

```{r}
knitr::asis_output
```

Note that you can actually put **knitr** in the `Suggests` field in DESCRIPTION, and use `knitr::asis_output()`, so that you can avoid the "hard" dependency on **knitr**.
You may put **knitr** in the `Suggests` field in `DESCRIPTION`, and use `knitr::asis_output()`, so that you can avoid the "hard" dependency on **knitr**.

```{r clean-up, include=FALSE}
# R compiles all vignettes in the same session, which can be bad
Expand Down

0 comments on commit 360176b

Please sign in to comment.