diff --git a/R/parse_url.R b/R/parse_url.R index dfe3904..67b6f04 100644 --- a/R/parse_url.R +++ b/R/parse_url.R @@ -1,9 +1,12 @@ -#' Creates Shinylive url for the app code. +#' Creates Shinylive url based on app code. #' #' @importFrom jsonlite unbox toJSON #' @importFrom lzstring compressToEncodedURIComponent #' #' @param code (`character(1)`) A string with app code. +#' @param mode (`character(1)`) A string with mode. One of "app" or "editor". Default is "app". +#' @param header (`logical(1)`) A logical value indicating whether to include header. +#' Ignored if `mode` is "editor". #' @return (`character(1)`) Shinylive app url. #' #' @export @@ -11,8 +14,12 @@ #' @examples #' code <- "this is your app code as a string" #' create_shinylive_url(code) -create_shinylive_url <- function(code) { +#' create_shinylive_url(code, header = FALSE) +#' create_shinylive_url(code, mode = "editor") +create_shinylive_url <- function(code, mode = c("app", "editor"), header = TRUE) { stopifnot(is.character(code) && length(code) == 1) + mode <- match.arg(mode) + stopifnot(is.logical(header) && length(header) == 1) # implementation based on "Create ShinyLive Link" feature of Shiny VSCode extension # https://github.com/posit-dev/shiny-vscode/blob/80560bf36d516ff89dffe88bd9a28cee9edd4d43/src/shinylive.ts#L499 @@ -23,5 +30,8 @@ create_shinylive_url <- function(code) { files_json <- jsonlite::toJSON(list(files)) files_lz <- lzstring::compressToEncodedURIComponent(as.character(files_json)) files_lz <- gsub("/", "-", files_lz) - sprintf("https://shinylive.io/r/app/#code=%s", files_lz) + + header_param <- ifelse(mode == "app" && isFALSE(header), "h=0&", "") + + sprintf("https://shinylive.io/r/%s/#%scode=%s", mode, header_param, files_lz) } diff --git a/R/tag_examplesShinylive.R b/R/tag_examplesShinylive.R index 75ee6cd..c278dab 100644 --- a/R/tag_examplesShinylive.R +++ b/R/tag_examplesShinylive.R @@ -1,7 +1,7 @@ -#' Custom `examplesShinylive` tag. +#' Custom `@examplesShinylive` tag. #' -#' This function generates a new "Examples in Shinylive" section in the documentation. This section contains URL to -#' the application in Shinylive as well as an iframe with the application. +#' This function generates a new "Examples in Shinylive" section in the documentation. +#' This section contains URL to the application in Shinylive and for HTML outputs: an iframe with the application. #' If no code is provided then the code is taken from the following `@examples` or `@examplesIf` tag. #' #' The application code must be executable inside Shinylive. If the application code includes functions from your @@ -206,7 +206,7 @@ format.rd_section_examplesShinylive <- function(x, ...) { $(function() { var if_pkgdown = [...document.scripts].filter(x => x.src.includes(\"pkgdown.js\")).length > 0; if (if_pkgdown) { - $(\"iframe.iframe_shinylive\").css(\"width\", \"140\\%\"); + $(\"iframe.iframe_shinylive\").css(\"width\", \"150\\%\"); } });" paste0( diff --git a/README.md b/README.md index f829102..5618306 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,29 @@ This package provides a `roxygen2` extension that automatically takes the code f ## Install ```r +# install.packages("pak") pak::pak("insightsengineering/roxy.shinylive") ``` ## Usage +### Creating a URL manually + +```r +code <- "\"Hello World\"" +roxy.shinylive::create_shinylive_url(code, mode = "editor") +``` + +This returns the following URL: + + + +### In the roxygen2 documentation + In your `DESCRIPTION` file, add the following: ```yaml -Roxygen: list(markdown = TRUE, packages = c("roxy.shinylive")) +Roxygen: list(..., packages = c(..., "roxy.shinylive")) ``` Then in your package documentation: @@ -47,4 +61,39 @@ Which would produce a following output in your documentation: } ``` +![example of function](inst/function.gif) + +### In the vignettes + +In your `DESCRIPTION` file, add the following: + +```yaml +Suggests: + roxy.shinylive +``` + +Then in your vignette: + +````Rmd +```{r shinylive_url, echo = FALSE, results = 'asis'} +# extract the code from knitr code chunks by ID +code <- paste0(c( + ... # add more IDs if needed + knitr::knit_code$get("app"), + knitr::knit_code$get("shinyapp") +), collapse = "\n") + +url <- roxy.shinylive::create_shinylive_url(code) +cat(sprintf("[Open in Shinylive](%s)\n\n", url)) +``` + +```{r shinylive_iframe, echo = FALSE, out.width = '150%', out.extra = 'style = "position: relative; z-index:1"', eval = knitr::is_html_output() && identical(Sys.getenv("IN_PKGDOWN"), "true")} +knitr::include_url(url, height = "800px") +``` +```` + +![example of vignette](inst/vignette.gif) + See the package documentation for more details. + +See the example implementation in the [`teal.modules.general`](https://insightsengineering.github.io/teal.modules.general/) or [`teal.modules.clinical`](https://insightsengineering.github.io/teal.modules.clinical/) packages. diff --git a/inst/function.gif b/inst/function.gif new file mode 100644 index 0000000..5302f41 Binary files /dev/null and b/inst/function.gif differ diff --git a/inst/vignette.gif b/inst/vignette.gif new file mode 100644 index 0000000..dcac716 Binary files /dev/null and b/inst/vignette.gif differ diff --git a/man/create_shinylive_url.Rd b/man/create_shinylive_url.Rd index 8b312cb..19ca61e 100644 --- a/man/create_shinylive_url.Rd +++ b/man/create_shinylive_url.Rd @@ -2,20 +2,27 @@ % Please edit documentation in R/parse_url.R \name{create_shinylive_url} \alias{create_shinylive_url} -\title{Creates Shinylive url for the app code.} +\title{Creates Shinylive url based on app code.} \usage{ -create_shinylive_url(code) +create_shinylive_url(code, mode = c("app", "editor"), header = TRUE) } \arguments{ \item{code}{(\code{character(1)}) A string with app code.} + +\item{mode}{(\code{character(1)}) A string with mode. One of "app" or "editor". Default is "app".} + +\item{header}{(\code{logical(1)}) A logical value indicating whether to include header. +Ignored if \code{mode} is "editor".} } \value{ (\code{character(1)}) Shinylive app url. } \description{ -Creates Shinylive url for the app code. +Creates Shinylive url based on app code. } \examples{ code <- "this is your app code as a string" create_shinylive_url(code) +create_shinylive_url(code, header = FALSE) +create_shinylive_url(code, mode = "editor") } diff --git a/man/tag-examplesShinylive.Rd b/man/tag-examplesShinylive.Rd index aa14bdd..5f2f9fb 100644 --- a/man/tag-examplesShinylive.Rd +++ b/man/tag-examplesShinylive.Rd @@ -2,13 +2,13 @@ % Please edit documentation in R/tag_examplesShinylive.R \name{tag-examplesShinylive} \alias{tag-examplesShinylive} -\title{Custom \code{examplesShinylive} tag.} +\title{Custom \verb{@examplesShinylive} tag.} \usage{ #' @examplesShinylive${1:# example code (optional)} } \description{ -This function generates a new "Examples in Shinylive" section in the documentation. This section contains URL to -the application in Shinylive as well as an iframe with the application. +This function generates a new "Examples in Shinylive" section in the documentation. +This section contains URL to the application in Shinylive and for HTML outputs: an iframe with the application. If no code is provided then the code is taken from the following \verb{@examples} or \verb{@examplesIf} tag. } \details{