Rather than making use of the user's clipboard, here's a solution that uses Shiny and a little JavaScript to use the last submission from an exercise to populate the code in another exercise.
---
title: "Tutorial"
output: learnr::tutorial
runtime: shiny_prerendered
---
```{r setup, include=FALSE}
library(learnr)
knitr::opts_chunk$set(echo = FALSE)
```
```{js echo=FALSE}
//
// A custom Shiny message handler that updates the code in any exercise
// From R you'll send a list(label = "exercise-chunk-label", code = "new code for editor"))
//
Shiny.addCustomMessageHandler('set-exercise-code', function(x) {
var el = $(`.tutorial-exercise[data-label="${x.label}"] .tutorial-exercise-code-editor`)
var exerciseInput = Shiny.inputBindings.bindingNames["tutorial.exerciseInput"].binding
exerciseInput.setValue(el, {code: x.code})
})
```
## Topic 1
### Exercise
*Here's a simple exercise with an empty code chunk provided for entering the answer.*
Write the R code required to add two plus two:
```{r two-plus-two, exercise=TRUE}
```
### Exercise with Code
*Here's an exercise with some prepopulated code as well as `exercise.lines = 5` to provide a bit more initial room to work.*
Now write a function that adds any two numbers and then call it:
```{r use-two-plus-two-button}
actionButton("use-two-plus-two", "Use your answer to the previous exercise")
```
```{r handle-use-two-plus-two-button, context="server"}
observeEvent(input[["use-two-plus-two"]], {
# get last submission for the "two-plus-two" exercise
code <- learnr:::get_exercise_submission(session, "two-plus-two")$data$code
# use last submission in template
code <- paste("add <- function() {\n", trimws(code), "\n}\n\nadd()")
# send a custom message to our handler (see js chunk above)
# updates the "add-function" exercise with the new code
session$sendCustomMessage("set-exercise-code", list(label = "add-function", code = code))
})
```
```{r add-function, exercise=TRUE, exercise.lines = 5}
add <- function() {
}
```
Notes
This approach requires that the use clicks "Run Code" (or "Submit Answer") at least once, but I think it's worth it. First, because the trigger of the code updating is a button, so the user is in control. If you instead use the clipboard, you're overwriting whatever the use has on the clipboard and it would be hard to add feedback to let the user know you did this. Also, as a user of a clipboard manager, I'd be frustrated personally if the tutorial added many things to my clipboard stack.