From 5777ccd007719b29189e3fd17b1e0c20b1c01cd9 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 23 Sep 2020 17:08:34 +0200 Subject: [PATCH 01/31] update of the CSS to include the alerts --- inst/lib/tutorial/tutorial.css | 85 ++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/inst/lib/tutorial/tutorial.css b/inst/lib/tutorial/tutorial.css index 0cf6c7128..c9ec4ac22 100644 --- a/inst/lib/tutorial/tutorial.css +++ b/inst/lib/tutorial/tutorial.css @@ -1,3 +1,29 @@ +:root { + --red-back: #f2dede; + --red-color: #b94a48; + --red-border: #eed3d7; + --orange-back: #ffa0142e; + --orange-color: #b96e00; + --orange-border: #ffc10787; + --purple-back: #9c27b029; + --purple-color: #681876; + --purple-border: #9c27b01f; + --blue-back: #cce5ff; + --blue-color: #004085; + --blue-border: #b8daff; + --violet-back: #6610f214; + --violet-color: #3e246d; + --violet-border: #6610f23b; + --yellow-back: #ffc10747; + --yellow-color: #da6605; + --yellow-border: #ffc107; + --pink-back: #e83eb424; + --pink-color: #9b2158; + --pink-border: #e83e8c45; + --green-back: #dff0d8; + --green-color: #468847; + --green-border: #d6e9c6; +} .tutorial-exercise-support { display: none; @@ -132,3 +158,62 @@ margin-right: -9px; /* net 6px */ } + +.alert{ + width: 100%!important; +} + +.alert-red { + background-color: var(--red-back); + color: var(--red-color); + border-color: var(--red-border); +} + +.alert-orange { + background-color: var(--orange-back); + color: var(--orange-color); + border-color: var(--orange-border); +} + +.alert-purple { + background-color: var(--purple-back); + color: var(--purple-color); + border-color: var(--purple-border); +} + +.alert-blue { + background-color: var(--blue-back); + color: var(--blue-color); + border-color: var(--blue-border); +} + +.alert-violet { + background-color: var(--violet-back); + color: var(--violet-color); + border-color: var(--violet-border); +} + +.alert-yellow { + background-color: var(--yellow-back); + color: var(--yellow-color); + border-color: var(--yellow-border); +} + +.alert-pink { + background-color: var(--pink-back); + color: var(--pink-color); + border-color: var(--pink-border); +} + +.alert-green { + background-color: var(--green-back); + color: var(--green-color); + border-color: var(--green-border); +} + +/* Class to display pagetable inside an alert without inheriting from it*/ + +.alert > .pagedtable-wrapper { + background-color: white; + color: #555555; +} \ No newline at end of file From 7c26c172e470664aab4891b597ce9ba4e0125746 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 23 Sep 2020 17:09:36 +0200 Subject: [PATCH 02/31] refactoring of the tutorial_options function to make it easier to add new options, plus added some new options for the new alert mechanism --- R/options.R | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/R/options.R b/R/options.R index e0da519f0..ef3ba89ca 100644 --- a/R/options.R +++ b/R/options.R @@ -20,27 +20,43 @@ #' @param exercise.startover Show "Start Over" button on exercise. #' #' @export -tutorial_options <- function(exercise.cap = NULL, - exercise.eval = FALSE, - exercise.timelimit = 30, - exercise.lines = NULL, - exercise.checker = NULL, - exercise.error.check.code = NULL, - exercise.completion = TRUE, - exercise.diagnostics = TRUE, - exercise.startover = TRUE) +tutorial_options <- function( + exercise.cap = NULL, + exercise.eval = FALSE, + exercise.timelimit = 30, + exercise.lines = NULL, + exercise.checker = NULL, + exercise.error.check.code = NULL, + exercise.completion = TRUE, + exercise.diagnostics = TRUE, + exercise.startover = TRUE, + exercise.alert_color = "red", + exercise.execution_error_message = NULL, + exercise.gradethis_success_color = NULL, + exercise.gradethis_info_color = NULL, + exercise.gradethis_warning_color = NULL, + exercise.gradethis_danger_color = NULL +) { # string to evalute for setting chunk options %1$s set_option_code <- 'if (!missing(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' # set options as required - eval(parse(text = sprintf(set_option_code, "exercise.cap"))) - eval(parse(text = sprintf(set_option_code, "exercise.eval"))) - eval(parse(text = sprintf(set_option_code, "exercise.timelimit"))) - eval(parse(text = sprintf(set_option_code, "exercise.lines"))) - eval(parse(text = sprintf(set_option_code, "exercise.checker"))) - eval(parse(text = sprintf(set_option_code, "exercise.error.check.code"))) - eval(parse(text = sprintf(set_option_code, "exercise.completion"))) - eval(parse(text = sprintf(set_option_code, "exercise.diagnostics"))) - eval(parse(text = sprintf(set_option_code, "exercise.startover"))) + for (i in names(formals())){ + eval(parse(text = sprintf(set_option_code, i))) + } + # eval(parse(text = sprintf(set_option_code, "exercise.cap"))) + # eval(parse(text = sprintf(set_option_code, "exercise.eval"))) + # eval(parse(text = sprintf(set_option_code, "exercise.timelimit"))) + # eval(parse(text = sprintf(set_option_code, "exercise.lines"))) + # eval(parse(text = sprintf(set_option_code, "exercise.checker"))) + # eval(parse(text = sprintf(set_option_code, "exercise.error.check.code"))) + # eval(parse(text = sprintf(set_option_code, "exercise.completion"))) + # eval(parse(text = sprintf(set_option_code, "exercise.diagnostics"))) + # eval(parse(text = sprintf(set_option_code, "exercise.startover"))) + # eval(parse(text = sprintf(set_option_code, "exercise.alert_color"))) + # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_success_color"))) + # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_info_color"))) + # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_warning_color"))) + # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_danger_color"))) } From 0386c1a98a5ddabd38c6f150e8b16574b0c1aba4 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 23 Sep 2020 17:10:33 +0200 Subject: [PATCH 03/31] new alerts for learnr itself and for gradethis outputs --- R/exercise.R | 65 ++++++++++++++++++++++++++++++++++------------------ R/feedback.R | 50 ++++++++++++++++++++++++++++++++-------- 2 files changed, 83 insertions(+), 32 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index c46aa4aa0..b60350d9e 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -15,7 +15,6 @@ setup_exercise_handler <- function(exercise_rx, session) { # observe input observeEvent(exercise_rx(), { - # get exercise exercise <- exercise_rx() @@ -241,7 +240,8 @@ evaluate_exercise <- function(exercise, envir, evaluate_global_setup = FALSE) { # include any checker feedback with the exercise results exercise_result( feedback = checker_feedback$feedback, - html_output = rmd_results$html_output + html_output = rmd_results$html_output, + exercise = exercise ) } @@ -253,7 +253,7 @@ try_checker <- function(exercise, name, check_code, envir_result, get_checker_func(exercise, name, envir_prep), error = function(e) { message("Error occured while retrieving 'exercise.checker'. Error:\n", e) - exercise_result_error(e$message) + exercise_result_error(e$message, color = exercise$options$exercise.alert_color %||% "red") } ) # If retrieving checker_func fails, return an error result @@ -280,7 +280,7 @@ try_checker <- function(exercise, name, check_code, envir_result, name, paste(missing_args, collapse = "', '") ) message(msg) - return(exercise_result_error(msg)) + return(exercise_result_error(msg, exercise = exercise)) } # Call the check function @@ -288,8 +288,9 @@ try_checker <- function(exercise, name, check_code, envir_result, do.call(checker_func, args), error = function(e) { msg <- paste("Error occurred while evaluating", sprintf("'%s'", name)) + cli::cat_rule("./R/exercise.R#292") message(msg, ": ", conditionMessage(e)) - exercise_result_error(msg) + exercise_result_error(msg, exercise = exercise) } ) # If checker code fails, return an error result @@ -298,7 +299,7 @@ try_checker <- function(exercise, name, check_code, envir_result, } # If checker doesn't return anything, there's no exercise result to return if (length(feedback)) { - exercise_result(feedback) + exercise_result(feedback, exercise) } else { feedback } @@ -395,7 +396,7 @@ render_exercise <- function(exercise, envir, envir_prep) { # make the time limit error message a bit more friendly pattern <- gettext("reached elapsed time limit", domain = "R") if (grepl(pattern, msg, fixed = TRUE)) { - return(exercise_result_timeout()) + return(exercise_result_timeout(exercise = exercise)) } if (length(exercise$error_check)) { # Run the condition through an error checker (the exercise could be to throw an error!) @@ -409,10 +410,11 @@ render_exercise <- function(exercise, envir, envir_prep) { engine = exercise$engine ) if (is_exercise_result(checker_feedback)) { + cli::cat_rule("./R/exercise.R#414") return(checker_feedback) } } - exercise_result_error(msg) + exercise_result_error(msg, exercise = exercise) }) if (is_exercise_result(output_file)) { @@ -436,8 +438,9 @@ render_exercise <- function(exercise, envir, envir_prep) { message = "The submitted code didn't produce a visible value, so exercise checking may not work correctly.", type = "warning", correct = FALSE ) + browser() html_output <- htmltools::tagList( - feedback_as_html(invisible_feedback), + feedback_as_html(invisible_feedback, exercise), html_output ) } @@ -463,41 +466,59 @@ exercise_code_chunks <- function(exercise) { } -exercise_result_timeout <- function() { +exercise_result_timeout <- function(exercise) { exercise_result_error( "Error: Your code ran longer than the permitted timelimit for this exercise.", - timeout_exceeded = TRUE + timeout_exceeded = TRUE, + exercise = exercise ) } # @param timeout_exceeded represents whether or not the error was triggered # because the exercise exceeded the timeout. Use NA if unknown -exercise_result_error <- function(error_message, feedback = NULL, timeout_exceeded = NA) { +exercise_result_error <- function(error_message, feedback = NULL, timeout_exceeded = NA, exercise) { exercise_result( feedback = feedback, timeout_exceeded = timeout_exceeded, error_message = error_message, - html_output = error_message_html(error_message) + html_output = error_message_html(error_message, exercise) ) } exercise_result <- function(feedback = NULL, html_output = NULL, - error_message = NULL, timeout_exceeded = FALSE) { + error_message = NULL, timeout_exceeded = FALSE, + exercise = NULL) { + #browser() feedback <- feedback_validated(feedback) - feedback_html <- feedback_as_html(feedback) + feedback_html <- feedback_as_html(feedback, exercise) + + html_output <- switch( + feedback$location %||% "append", + append = { + feedback_html$children <- list( + feedback_html$children[[1]], + html_output + + ) + feedback_html + }, + prepend = { + feedback_html$children <- list( + html_output, + feedback_html$children[[1]] + ) + feedback_html + }, + replace = feedback_html, + stop("Feedback location of ", feedback$location, " not supported") + ) structure( list( feedback = feedback, error_message = error_message, timeout_exceeded = timeout_exceeded, - html_output = switch( - feedback$location %||% "append", - append = htmltools::tagList(html_output, feedback_html), - prepend = htmltools::tagList(feedback_html, html_output), - replace = feedback_html, - stop("Feedback location of ", feedback$location, " not supported") - ) + html_output = html_output ), class = "learnr_exercise_result" ) diff --git a/R/feedback.R b/R/feedback.R index 785ca4fc7..4b168bf14 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -41,7 +41,8 @@ feedback_validated <- function(feedback) { feedback } -feedback_as_html <- function(feedback) { +feedback_as_html <- function(feedback, exercise) { + if (!length(feedback)) { return(feedback) } @@ -52,17 +53,46 @@ feedback_as_html <- function(feedback) { if (feedback$type %in% "error") { feedback$type <- "danger" } - if (feedback$type %in% c("success", "info", "warning", "danger")) { - return(div( - role = "alert", - class = paste0("alert alert-", feedback$type), - feedback$message - )) + if (!feedback$type %in% c("success", "info", "warning", "danger")) { + stop("Invalid message type specified.", call. = FALSE) + } + # Applying custom colors if they exist + if (feedback$type == "success"){ + feedback$type <- exercise$options$exercise.gradethis_success_color %||% "success" + } + + if (feedback$type == "info"){ + feedback$type <- exercise$options$exercise.gradethis_info_color %||% "info" + } + + if (feedback$type == "warning"){ + feedback$type <- exercise$options$exercise.gradethis_warning_color %||% "warning" + } + + if (feedback$type == "danger"){ + feedback$type <- exercise$options$exercise.gradethis_danger_color %||% "danger" } - stop("Invalid message type specified.", call. = FALSE) + + return(div( + role = "alert", + class = paste0("alert alert-", feedback$type), + feedback$message + )) } # helper function to create tags for error message -error_message_html <- function(message) { - div(class = "alert alert-danger", role = "alert", message) +error_message_html <- function(message, exercise) { + color <- exercise$options$exercise.alert_color %||% "red" + error <- exercise$options$exercise.execution_error_message %||% "There was an error when running your code:" + div( + class = sprintf( + "alert alert-%s", + color + ), + role = "alert", + error, + tags$pre( + message + ) + ) } From 99d44eaaa8100f1bb63c96047d3fc2e90d1711d6 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 23 Sep 2020 17:10:47 +0200 Subject: [PATCH 04/31] An example Rmd with colored outputs --- sandbox/colored-output.Rmd | 191 +++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 sandbox/colored-output.Rmd diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd new file mode 100644 index 000000000..3720d1caa --- /dev/null +++ b/sandbox/colored-output.Rmd @@ -0,0 +1,191 @@ +--- +title: "Tutorial" +output: + learnr::tutorial: + progressive: true + allow_skip: true +runtime: shiny_prerendered +--- + +```{r setup, include=FALSE} +library(learnr) +library(dplyr) +options(tutorial.event_recorder = learnr:::debug_event_recorder) +tutorial_options( + exercise.eval = FALSE, + exercise.alert_color = "orange" +) +``` + + +## Using globally set color + +Done: + ++ `exercise.alert_color` in the setup chunck can be used to change the alert color. + ++ The output of the code is now inside the alert, formatted as code/table. + ++ There is a default message in the error output, it can be changed by `exercise.execution_error_message` + +To do: + ++ Add a check that the colors set by the user is valid (we have a finite set of colors) + ++ Document the colors available + +To discuss: + ++ Should we allow custom colors? For example, we could have `exercise.alert_color_background = "#f5a67d"` + +__Example__ + +The current tutorial uses the following call in the setup chunk: + +``` +tutorial_options( + exercise.eval = FALSE, + exercise.alert_color = "orange" +) +``` + +> Try typing errors in the chunks of this tutorial + +> NB: the solution to all is `mtcars` + +```{r car, exercise=TRUE, exercise.timelimit = 10} +list( +``` + +```{r car-solution} +mtcars +``` + +Example using a different `exercise.execution_error_message` + +``` +{r carbis, exercise=TRUE, exercise.execution_error_message = "Ouch!"} +``` + +```{r carbis, exercise=TRUE, exercise.execution_error_message = "Ouch!"} +list( +``` + +```{r carbis-solution} +mtcars +``` + +## Using locally set color + +Colors can also be set at the chunk level. + +### red + +``` +{r car-red, exercise.alert_color = "red"} +``` + +```{r car-red, exercise.alert_color = "red", exercise=TRUE} +list( +``` + + +```{r car-red-solution} +mtcars +``` + + +### orange + +`exercise.alert_color = "orange"` + +```{r car-orange, exercise.alert_color = "orange", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-orange-solution} +mtcars +``` + + +### purple + +`exercise.alert_color = "purple"` + +```{r car-purple, exercise.alert_color = "purple", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-purple-solution} +mtcars +``` + +### blue + +`exercise.alert_color = "blue"` + +```{r car-blue, exercise.alert_color = "blue", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-blue-solution} +mtcars +``` + + +### violet + +`exercise.alert_color = "violet"` + +```{r car-violet, exercise.alert_color = "violet", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-violet-solution} +mtcars +``` + + +### yellow + +`exercise.alert_color = "yellow"` + +```{r car-yellow, exercise.alert_color = "yellow", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-yellow-solution} +mtcars +``` + +### pink + +`exercise.alert_color = "pink"` + +```{r car-pink, exercise.alert_color = "pink", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-pink-solution} +mtcars +``` + +### green + +`exercise.alert_color = "green"` + +```{r car-green, exercise.alert_color = "green", exercise=TRUE, exercise.timelimit = 10} +list( +``` + + +```{r car-green-solution} +mtcars +``` + From 6ad4d4b4832ea34a43bf0a0248b40589e912c95c Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 23 Sep 2020 17:30:51 +0200 Subject: [PATCH 05/31] Sandbox Rmd for gradethis colored outputs --- sandbox/colored-output-gradethis.Rmd | 89 ++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 sandbox/colored-output-gradethis.Rmd diff --git a/sandbox/colored-output-gradethis.Rmd b/sandbox/colored-output-gradethis.Rmd new file mode 100644 index 000000000..4aa066e47 --- /dev/null +++ b/sandbox/colored-output-gradethis.Rmd @@ -0,0 +1,89 @@ +--- +title: "Tutorial" +output: + learnr::tutorial: + progressive: true + allow_skip: true +runtime: shiny_prerendered +--- + +```{r setup, include=FALSE} +library(learnr) +library(dplyr) +#options(tutorial.event_recorder = learnr:::debug_event_recorder) +tutorial_options( + exercise.eval = FALSE, + exercise.alert_color = "orange", + exercise.gradethis_success_color = "pink", + exercise.gradethis_info_color = "orange", + exercise.gradethis_warning_color = "violet", + exercise.gradethis_danger_color = "blue" +) +gradethis::gradethis_setup() +``` + +## Using globally set color + +Done: + ++ The gradethis colors can be set using options: `exercise.gradethis_success_color`, `exercise.gradethis_info_color`, `exercise.gradethis_warning_color` and `exercise.gradethis_danger_color` + +__Example__ + +The current tutorial uses the following call in the setup chunk: + +``` +tutorial_options( + exercise.eval = FALSE, + exercise.alert_color = "orange", + exercise.gradethis_success_color = "pink", + exercise.gradethis_info_color = "orange", + exercise.gradethis_warning_color = "violet", + exercise.gradethis_danger_color = "blue" +) +``` + +Enter `mtcars` + +```{r mtcars, exercise = TRUE} + +``` + +```{r mtcars-solution} +mtcars +``` + + +```{r mtcars-check} +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + +## Using locally set color + +With the following chunk setup: + +``` +{r mtcars2 exercise.gradethis_success_color = "red", ,exercise.gradethis_info_color = "violet", exercise.gradethis_warning_color = "blue", exercise.gradethis_danger_color = "green"} +``` + +Enter `mtcars` + +```{r mtcars2, exercise = TRUE, exercise.gradethis_success_color = "red", ,exercise.gradethis_info_color = "violet", exercise.gradethis_warning_color = "blue", exercise.gradethis_danger_color = "green"} + +``` + +```{r mtcars2-solution} +mtcars +``` + + +```{r mtcars2-check } +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + From cc3abee5f952f645bb9b903addc45e09d364210e Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 24 Sep 2020 09:07:11 +0200 Subject: [PATCH 06/31] refactor to a switch statement --- R/feedback.R | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index 4b168bf14..a7b220093 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -57,21 +57,14 @@ feedback_as_html <- function(feedback, exercise) { stop("Invalid message type specified.", call. = FALSE) } # Applying custom colors if they exist - if (feedback$type == "success"){ - feedback$type <- exercise$options$exercise.gradethis_success_color %||% "success" - } - - if (feedback$type == "info"){ - feedback$type <- exercise$options$exercise.gradethis_info_color %||% "info" - } - if (feedback$type == "warning"){ - feedback$type <- exercise$options$exercise.gradethis_warning_color %||% "warning" - } - - if (feedback$type == "danger"){ - feedback$type <- exercise$options$exercise.gradethis_danger_color %||% "danger" - } + feedback$type <- switch( + feedback$type, + success = exercise$options$exercise.gradethis_success_color %||% "success", + info = exercise$options$exercise.gradethis_info_color %||% "info", + warning = exercise$options$exercise.gradethis_warning_color %||% "warning", + danger = exercise$options$exercise.gradethis_danger_color %||% "danger" + ) return(div( role = "alert", From 43ea7228b91df8288cf83c856c580430cff6c8d6 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 24 Sep 2020 14:50:54 +0200 Subject: [PATCH 07/31] explicitely specifying argument name (was provoking a bug before) --- R/exercise.R | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index b60350d9e..c60c8fd38 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -299,7 +299,7 @@ try_checker <- function(exercise, name, check_code, envir_result, } # If checker doesn't return anything, there's no exercise result to return if (length(feedback)) { - exercise_result(feedback, exercise) + exercise_result(feedback, exercise = exercise) } else { feedback } @@ -410,7 +410,6 @@ render_exercise <- function(exercise, envir, envir_prep) { engine = exercise$engine ) if (is_exercise_result(checker_feedback)) { - cli::cat_rule("./R/exercise.R#414") return(checker_feedback) } } @@ -438,7 +437,6 @@ render_exercise <- function(exercise, envir, envir_prep) { message = "The submitted code didn't produce a visible value, so exercise checking may not work correctly.", type = "warning", correct = FALSE ) - browser() html_output <- htmltools::tagList( feedback_as_html(invisible_feedback, exercise), html_output @@ -488,7 +486,6 @@ exercise_result_error <- function(error_message, feedback = NULL, timeout_exceed exercise_result <- function(feedback = NULL, html_output = NULL, error_message = NULL, timeout_exceeded = FALSE, exercise = NULL) { - #browser() feedback <- feedback_validated(feedback) feedback_html <- feedback_as_html(feedback, exercise) From 789920ac43f5e5954cef2434e47844eedc234bb3 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 24 Sep 2020 16:17:46 +0200 Subject: [PATCH 08/31] Allow to set options for showing learnr and gradethis feedbacks or not --- R/exercise.R | 116 ++++++++++++++++++++------ R/feedback.R | 61 +++++++++++--- R/options.R | 14 +++- inst/lib/tutorial/tutorial.css | 18 +++- sandbox/colored-output-gradethis.Rmd | 119 +++++++++++++++++++++++++-- sandbox/colored-output.Rmd | 51 ++++++++++++ 6 files changed, 331 insertions(+), 48 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index c60c8fd38..8402a3a14 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -238,6 +238,7 @@ evaluate_exercise <- function(exercise, envir, evaluate_global_setup = FALSE) { } # include any checker feedback with the exercise results + exercise_result( feedback = checker_feedback$feedback, html_output = rmd_results$html_output, @@ -253,7 +254,11 @@ try_checker <- function(exercise, name, check_code, envir_result, get_checker_func(exercise, name, envir_prep), error = function(e) { message("Error occured while retrieving 'exercise.checker'. Error:\n", e) - exercise_result_error(e$message, color = exercise$options$exercise.alert_color %||% "red") + exercise_result_error( + e$message, + color = exercise$options$exercise.alert_color %||% "red", + exercise = exercise + ) } ) # If retrieving checker_func fails, return an error result @@ -437,6 +442,7 @@ render_exercise <- function(exercise, envir, envir_prep) { message = "The submitted code didn't produce a visible value, so exercise checking may not work correctly.", type = "warning", correct = FALSE ) + html_output <- htmltools::tagList( feedback_as_html(invisible_feedback, exercise), html_output @@ -474,41 +480,101 @@ exercise_result_timeout <- function(exercise) { # @param timeout_exceeded represents whether or not the error was triggered # because the exercise exceeded the timeout. Use NA if unknown -exercise_result_error <- function(error_message, feedback = NULL, timeout_exceeded = NA, exercise) { +exercise_result_error <- function( + error_message, + feedback = NULL, + timeout_exceeded = NA, + exercise = NULL +) { exercise_result( feedback = feedback, timeout_exceeded = timeout_exceeded, error_message = error_message, - html_output = error_message_html(error_message, exercise) + html_output = error_message_html(error_message, exercise), + exercise = exercise ) } -exercise_result <- function(feedback = NULL, html_output = NULL, - error_message = NULL, timeout_exceeded = FALSE, - exercise = NULL) { +exercise_result <- function( + feedback = NULL, + html_output = NULL, + error_message = NULL, + timeout_exceeded = FALSE, + exercise = NULL +) { + + # When `exercise` is empty, we return a list of NULL + # `exercise` is NULL when there was no code sent (i.e the + # student hasn't entered any code) + if (is.null(exercise)){ + return( + structure( + list( + feedback = feedback, + error_message = error_message, + timeout_exceeded = timeout_exceeded, + html_output = html_output + ), + class = "learnr_exercise_result" + ) + ) + } + feedback <- feedback_validated(feedback) feedback_html <- feedback_as_html(feedback, exercise) - html_output <- switch( - feedback$location %||% "append", - append = { - feedback_html$children <- list( - feedback_html$children[[1]], - html_output - ) - feedback_html - }, - prepend = { - feedback_html$children <- list( - html_output, - feedback_html$children[[1]] - ) - feedback_html - }, - replace = feedback_html, - stop("Feedback location of ", feedback$location, " not supported") - ) + # The trainer want feedbacks and code (the default) + if ( + exercise$options$exercise.gradethis_feedback_show & + exercise$options$exercise.gradethis_code_show + ){ + html_output <- switch( + feedback$location %||% "append", + append = { + feedback_html$children <- list( + feedback_html$children[[1]], + html_output + + ) + feedback_html + }, + prepend = { + feedback_html$children <- list( + html_output, + feedback_html$children[[1]] + ) + feedback_html + }, + replace = feedback_html, + stop("Feedback location of ", feedback$location, " not supported") + ) + } else if ( + # The trainer want feedbacks only + exercise$options$exercise.gradethis_feedback_show & + ! exercise$options$exercise.gradethis_code_show + ) { + html_output <- feedback_html + } else if ( + # The trainer wants code only + ! exercise$options$exercise.gradethis_feedback_show & + exercise$options$exercise.gradethis_code_show + ) { + html_output <- tags$div( + html_output + ) + } else if ( + # The trainer wants no feedback + ! exercise$options$exercise.gradethis_feedback_show & + ! exercise$options$exercise.gradethis_code_show + ){ + # Not sure what to do there, (i.e the trainer want neither feedback nor code) + html_output <- div( + class = "alert alert-grey", + role = "alert", + "Code submitted" + ) + } structure( list( diff --git a/R/feedback.R b/R/feedback.R index a7b220093..2c23649dc 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -41,6 +41,8 @@ feedback_validated <- function(feedback) { feedback } +# This function is called to build the html of the feedback +# provided by gradethis feedback_as_html <- function(feedback, exercise) { if (!length(feedback)) { @@ -74,18 +76,55 @@ feedback_as_html <- function(feedback, exercise) { } # helper function to create tags for error message +# It is called by learnr when clicking "Run code" & the +# code produced an error error_message_html <- function(message, exercise) { - color <- exercise$options$exercise.alert_color %||% "red" + #color <- exercise$options$exercise.alert_color %||% "red" error <- exercise$options$exercise.execution_error_message %||% "There was an error when running your code:" - div( - class = sprintf( - "alert alert-%s", - color - ), - role = "alert", - error, - tags$pre( - message - ) + class <- sprintf( + "alert alert-%s", + exercise$options$exercise.alert_color %||% "red" ) + # The trainer want feedbacks and code (the default) + if ( + exercise$options$exercise.feedback_show & + exercise$options$exercise.code_show + ){ + div( + class = class, + role = "alert", + error, + tags$pre( + message + ) + + ) + } else if ( + # The trainer want feedbacks only + exercise$options$exercise.feedback_show & + ! exercise$options$exercise.code_show + ) { + div( + class = class, + role = "alert", + error + ) + } else if ( + # The trainer wants code only + ! exercise$options$exercise.feedback_show & + exercise$options$exercise.code_show + ) { + div( + tags$pre( + message + ) + ) + } else { + # Not sure what to do there, (i.e the trainer want neither feedback nor code) + div( + class = "alert alert-grey", + role = "alert", + "Code submitted" + ) + } } diff --git a/R/options.R b/R/options.R index ef3ba89ca..97afb8b6a 100644 --- a/R/options.R +++ b/R/options.R @@ -31,20 +31,25 @@ tutorial_options <- function( exercise.diagnostics = TRUE, exercise.startover = TRUE, exercise.alert_color = "red", + exercise.feedback_show = TRUE, + exercise.code_show = TRUE, exercise.execution_error_message = NULL, exercise.gradethis_success_color = NULL, exercise.gradethis_info_color = NULL, exercise.gradethis_warning_color = NULL, - exercise.gradethis_danger_color = NULL + exercise.gradethis_danger_color = NULL, + exercise.gradethis_feedback_show = TRUE, + exercise.gradethis_code_show = TRUE ) { # string to evalute for setting chunk options %1$s - set_option_code <- 'if (!missing(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' - + set_option_code <- 'if (!is.null(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' + #browser() # set options as required for (i in names(formals())){ eval(parse(text = sprintf(set_option_code, i))) } + # browser() # eval(parse(text = sprintf(set_option_code, "exercise.cap"))) # eval(parse(text = sprintf(set_option_code, "exercise.eval"))) # eval(parse(text = sprintf(set_option_code, "exercise.timelimit"))) @@ -59,4 +64,7 @@ tutorial_options <- function( # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_info_color"))) # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_warning_color"))) # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_danger_color"))) + # for (i in names(formals())){ + # eval(parse(text = sprintf(set_option_code, i))) + # } } diff --git a/inst/lib/tutorial/tutorial.css b/inst/lib/tutorial/tutorial.css index c9ec4ac22..03d9b4ac6 100644 --- a/inst/lib/tutorial/tutorial.css +++ b/inst/lib/tutorial/tutorial.css @@ -23,6 +23,9 @@ --green-back: #dff0d8; --green-color: #468847; --green-border: #d6e9c6; + --grey-back: #f5f5f5; + --grey-color: #555555; + --grey-border: #dcdcdc; } .tutorial-exercise-support { @@ -211,9 +214,22 @@ border-color: var(--green-border); } +.alert-grey { + background-color: var(--grey-back); + color: var(--grey-color); + border-color: var(--grey-border); +} + /* Class to display pagetable inside an alert without inheriting from it*/ .alert > .pagedtable-wrapper { background-color: white; color: #555555; -} \ No newline at end of file +} + +.alert > pre { + border: none; + border-radius: 4px; + margin-top: 1em; +} + diff --git a/sandbox/colored-output-gradethis.Rmd b/sandbox/colored-output-gradethis.Rmd index 4aa066e47..3368e8a6a 100644 --- a/sandbox/colored-output-gradethis.Rmd +++ b/sandbox/colored-output-gradethis.Rmd @@ -11,7 +11,7 @@ runtime: shiny_prerendered library(learnr) library(dplyr) #options(tutorial.event_recorder = learnr:::debug_event_recorder) -tutorial_options( +gradethis::gradethis_setup( exercise.eval = FALSE, exercise.alert_color = "orange", exercise.gradethis_success_color = "pink", @@ -19,7 +19,12 @@ tutorial_options( exercise.gradethis_warning_color = "violet", exercise.gradethis_danger_color = "blue" ) -gradethis::gradethis_setup() + +tutorial_options( + exercise.gradethis_feedback_show = TRUE, + exercise.gradethis_code_show = TRUE +) + ``` ## Using globally set color @@ -34,12 +39,12 @@ The current tutorial uses the following call in the setup chunk: ``` tutorial_options( - exercise.eval = FALSE, - exercise.alert_color = "orange", - exercise.gradethis_success_color = "pink", - exercise.gradethis_info_color = "orange", - exercise.gradethis_warning_color = "violet", - exercise.gradethis_danger_color = "blue" +exercise.eval = FALSE, +exercise.alert_color = "orange", +exercise.gradethis_success_color = "pink", +exercise.gradethis_info_color = "orange", +exercise.gradethis_warning_color = "violet", +exercise.gradethis_danger_color = "blue" ) ``` @@ -87,3 +92,101 @@ grade_result( ) ``` +## Toggle Feedback or code display + +With the following chunk: + +``` +{r mtcars3, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = TRUE} +``` + +Enter `mtcars` + +```{r mtcars3, exercise = TRUE, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = TRUE} +airquality +``` + +```{r mtcars3-solution} +mtcars +``` + + +```{r mtcars3-check } +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + +With the following chunk: + +``` +{r mtcars4, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = FALSE} +``` + +Enter `mtcars` + +```{r mtcars4, exercise = TRUE, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = FALSE} +airquality +``` + +```{r mtcars4-solution} +mtcars +``` + + +```{r mtcars4-check } +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + +With the following chunk: + +``` +{r mtcars5, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = TRUE} +``` + +Enter `mtcars` + +```{r mtcars5, exercise = TRUE, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = TRUE} +airquality +``` + +```{r mtcars5-solution} +mtcars +``` + + +```{r mtcars5-check } +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + +With the following chunk: + +``` +{r mtcars6, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = FALSE} +``` + +Enter `mtcars` + +```{r mtcars6, exercise = TRUE, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = FALSE} +airquality +``` + +```{r mtcars6-solution} +mtcars +``` + + +```{r mtcars6-check } +grade_result( + fail_if(~identical(.result, cars), "This is the cars (not mtcars) dataset."), + pass_if(~identical(.result, mtcars)) +) +``` + diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd index 3720d1caa..50076c071 100644 --- a/sandbox/colored-output.Rmd +++ b/sandbox/colored-output.Rmd @@ -189,3 +189,54 @@ list( mtcars ``` +## Toggle Feedback or code display + +Done: + ++ `exercise.feedback_show` and `exercise.feedback_show` set the content of the feedbacks from learnr + +To discuss: + ++ What should we print when trainer wants neither feedback nor code? + +__Example__ + +`{r exercise.feedback_show=TRUE, exercise.code_show = TRUE}` + +```{r cara, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=TRUE, exercise.code_show = TRUE} +list( +``` + +```{r cara-solution} +mtcars +``` + +`{r exercise.feedback_show=FALSE, exercise.code_show = TRUE}` + +```{r carb, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=FALSE, exercise.code_show = TRUE} +list( +``` + +```{r carb-solution} +mtcars +``` + +`{r exercise.feedback_show=TRUE, exercise.code_show = FALSE}` + +```{r carc, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=TRUE, exercise.code_show = FALSE} +list( +``` + +```{r carc-solution} +mtcars +``` + +`{r exercise.feedback_show=FALSE, exercise.code_show = FALSE}` + +```{r card, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=FALSE, exercise.code_show = FALSE} +list( +``` + +```{r card-solution} +mtcars +``` \ No newline at end of file From 4d6b53fcc97a6cb4d0c967f20099cba8977541c0 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 15:50:58 +0200 Subject: [PATCH 09/31] Back to is.missing --- R/options.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/options.R b/R/options.R index 97afb8b6a..056d09dfa 100644 --- a/R/options.R +++ b/R/options.R @@ -43,7 +43,7 @@ tutorial_options <- function( ) { # string to evalute for setting chunk options %1$s - set_option_code <- 'if (!is.null(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' + set_option_code <- 'if (!missing(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' #browser() # set options as required for (i in names(formals())){ From 2f3a3debad552dcbdcbd31d13f1998134cbde86e Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 16:27:03 +0200 Subject: [PATCH 10/31] remove unused arg --- R/exercise.R | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index 8402a3a14..75a0e920d 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -256,7 +256,6 @@ try_checker <- function(exercise, name, check_code, envir_result, message("Error occured while retrieving 'exercise.checker'. Error:\n", e) exercise_result_error( e$message, - color = exercise$options$exercise.alert_color %||% "red", exercise = exercise ) } @@ -293,7 +292,6 @@ try_checker <- function(exercise, name, check_code, envir_result, do.call(checker_func, args), error = function(e) { msg <- paste("Error occurred while evaluating", sprintf("'%s'", name)) - cli::cat_rule("./R/exercise.R#292") message(msg, ": ", conditionMessage(e)) exercise_result_error(msg, exercise = exercise) } From ddbd09a07830887e4c9e9d4b0a75d8feaa9238a3 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 16:27:23 +0200 Subject: [PATCH 11/31] use default colors when not specified --- R/feedback.R | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index 2c23649dc..05bec360f 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -79,16 +79,20 @@ feedback_as_html <- function(feedback, exercise) { # It is called by learnr when clicking "Run code" & the # code produced an error error_message_html <- function(message, exercise) { - #color <- exercise$options$exercise.alert_color %||% "red" error <- exercise$options$exercise.execution_error_message %||% "There was an error when running your code:" class <- sprintf( "alert alert-%s", - exercise$options$exercise.alert_color %||% "red" + exercise$options$exercise.alert_class %||% "red" ) + + #Default to TRUE if the option is missing + exercise.feedback_show <- exercise$options$exercise.feedback_show %||% TRUE + exercise.code_show <- exercise$options$exercise.feedback_show %||% TRUE + # The trainer want feedbacks and code (the default) if ( - exercise$options$exercise.feedback_show & - exercise$options$exercise.code_show + exercise.feedback_show & + exercise.code_show ){ div( class = class, @@ -101,8 +105,8 @@ error_message_html <- function(message, exercise) { ) } else if ( # The trainer want feedbacks only - exercise$options$exercise.feedback_show & - ! exercise$options$exercise.code_show + exercise.feedback_show & + ! exercise.code_show ) { div( class = class, @@ -111,8 +115,8 @@ error_message_html <- function(message, exercise) { ) } else if ( # The trainer wants code only - ! exercise$options$exercise.feedback_show & - exercise$options$exercise.code_show + ! exercise.feedback_show & + exercise.code_show ) { div( tags$pre( From f9933df0b7ee3ffd640593438fcbedde3281617e Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 16:27:33 +0200 Subject: [PATCH 12/31] Documentation of options --- R/options.R | 16 +++++++++++----- man/tutorial_options.Rd | 27 ++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/R/options.R b/R/options.R index 056d09dfa..79cbbbe32 100644 --- a/R/options.R +++ b/R/options.R @@ -18,6 +18,15 @@ #' @param exercise.completion Use code completion in exercise editors. #' @param exercise.diagnostics Show diagnostics in exercise editors. #' @param exercise.startover Show "Start Over" button on exercise. +#' @param exercise.alert_class,exercise.gradethis_info_color,exercise.gradethis_success_color,exercise.gradethis_warning_color,exercise.gradethis_danger_color Slug for the CSS class for `{learnr}` and `{gradethis}` message. +#' It can be one of `red`, `orange`, `purple`, `blue`, `violet`, `yellow`, `pink`, `green`, +#' or `grey`. You can also implement your own CSS rule, in that case you need to define a +#' class that starts with `alert-` (for example `alert-rainbow`). +#' @param exercise.feedback_show Should the `{learnr}` feedback be shown? +#' @param exercise.code_show Should `{learnr}` output code be shown? +#' @param exercise.execution_error_message What message should `{learnr}` print on error? +#' @param exercise.gradethis_feedback_show Should the `{gradethis}` feedback be shown? +#' @param exercise.gradethis_code_show Should `{gradethis}` output code be shown? #' #' @export tutorial_options <- function( @@ -30,7 +39,7 @@ tutorial_options <- function( exercise.completion = TRUE, exercise.diagnostics = TRUE, exercise.startover = TRUE, - exercise.alert_color = "red", + exercise.alert_class = "red", exercise.feedback_show = TRUE, exercise.code_show = TRUE, exercise.execution_error_message = NULL, @@ -44,7 +53,7 @@ tutorial_options <- function( { # string to evalute for setting chunk options %1$s set_option_code <- 'if (!missing(%1$s)) knitr::opts_chunk$set(%1$s = %1$s)' - #browser() + # set options as required for (i in names(formals())){ eval(parse(text = sprintf(set_option_code, i))) @@ -64,7 +73,4 @@ tutorial_options <- function( # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_info_color"))) # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_warning_color"))) # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_danger_color"))) - # for (i in names(formals())){ - # eval(parse(text = sprintf(set_option_code, i))) - # } } diff --git a/man/tutorial_options.Rd b/man/tutorial_options.Rd index b9c42103b..c9ee2b352 100644 --- a/man/tutorial_options.Rd +++ b/man/tutorial_options.Rd @@ -13,7 +13,17 @@ tutorial_options( exercise.error.check.code = NULL, exercise.completion = TRUE, exercise.diagnostics = TRUE, - exercise.startover = TRUE + exercise.startover = TRUE, + exercise.alert_class = "red", + exercise.feedback_show = TRUE, + exercise.code_show = TRUE, + exercise.execution_error_message = NULL, + exercise.gradethis_success_color = NULL, + exercise.gradethis_info_color = NULL, + exercise.gradethis_warning_color = NULL, + exercise.gradethis_danger_color = NULL, + exercise.gradethis_feedback_show = TRUE, + exercise.gradethis_code_show = TRUE ) } \arguments{ @@ -39,6 +49,21 @@ code when an exercise evaluation error occurs (e.g., \code{"gradethis::grade_cod \item{exercise.diagnostics}{Show diagnostics in exercise editors.} \item{exercise.startover}{Show "Start Over" button on exercise.} + +\item{exercise.alert_class, exercise.gradethis_info_color, exercise.gradethis_success_color, exercise.gradethis_warning_color, exercise.gradethis_danger_color}{Slug for the CSS class for \code{{learnr}} and \code{{gradethis}} message. +It can be one of \code{red}, \code{orange}, \code{purple}, \code{blue}, \code{violet}, \code{yellow}, \code{pink}, \code{green}, +or \code{grey}. You can also implement your own CSS rule, in that case you need to define a +class that starts with \verb{alert-} (for example \code{alert-rainbow}).} + +\item{exercise.feedback_show}{Should the \code{{learnr}} feedback be shown?} + +\item{exercise.code_show}{Should \code{{learnr}} output code be shown?} + +\item{exercise.execution_error_message}{What message should \code{{learnr}} print on error?} + +\item{exercise.gradethis_feedback_show}{Should the \code{{gradethis}} feedback be shown?} + +\item{exercise.gradethis_code_show}{Should \code{{gradethis}} output code be shown?} } \description{ Set various tutorial options that control the display and evaluation of From 0c2b9e0b5e84f0b1a16ac84942797c6fe8a3a292 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 16:27:51 +0200 Subject: [PATCH 13/31] used correct colors for Rmd --- sandbox/colored-output-gradethis.Rmd | 4 +-- sandbox/colored-output.Rmd | 40 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/sandbox/colored-output-gradethis.Rmd b/sandbox/colored-output-gradethis.Rmd index 3368e8a6a..c1f42d83a 100644 --- a/sandbox/colored-output-gradethis.Rmd +++ b/sandbox/colored-output-gradethis.Rmd @@ -13,7 +13,7 @@ library(dplyr) #options(tutorial.event_recorder = learnr:::debug_event_recorder) gradethis::gradethis_setup( exercise.eval = FALSE, - exercise.alert_color = "orange", + exercise.alert_class = "orange", exercise.gradethis_success_color = "pink", exercise.gradethis_info_color = "orange", exercise.gradethis_warning_color = "violet", @@ -40,7 +40,7 @@ The current tutorial uses the following call in the setup chunk: ``` tutorial_options( exercise.eval = FALSE, -exercise.alert_color = "orange", +exercise.alert_class = "orange", exercise.gradethis_success_color = "pink", exercise.gradethis_info_color = "orange", exercise.gradethis_warning_color = "violet", diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd index 50076c071..f56471a8f 100644 --- a/sandbox/colored-output.Rmd +++ b/sandbox/colored-output.Rmd @@ -13,7 +13,7 @@ library(dplyr) options(tutorial.event_recorder = learnr:::debug_event_recorder) tutorial_options( exercise.eval = FALSE, - exercise.alert_color = "orange" + exercise.alert_class = "orange" ) ``` @@ -22,7 +22,7 @@ tutorial_options( Done: -+ `exercise.alert_color` in the setup chunck can be used to change the alert color. ++ `exercise.alert_class` in the setup chunck can be used to change the alert color. + The output of the code is now inside the alert, formatted as code/table. @@ -36,7 +36,7 @@ To do: To discuss: -+ Should we allow custom colors? For example, we could have `exercise.alert_color_background = "#f5a67d"` ++ Should we allow custom colors? For example, we could have `exercise.alert_class = "#f5a67d"` __Example__ @@ -45,7 +45,7 @@ The current tutorial uses the following call in the setup chunk: ``` tutorial_options( exercise.eval = FALSE, - exercise.alert_color = "orange" + exercise.alert_class = "orange" ) ``` @@ -82,10 +82,10 @@ Colors can also be set at the chunk level. ### red ``` -{r car-red, exercise.alert_color = "red"} +{r car-red, exercise.alert_class = "red"} ``` -```{r car-red, exercise.alert_color = "red", exercise=TRUE} +```{r car-red, exercise.alert_class = "red", exercise=TRUE} list( ``` @@ -97,9 +97,9 @@ mtcars ### orange -`exercise.alert_color = "orange"` +`exercise.alert_class = "orange"` -```{r car-orange, exercise.alert_color = "orange", exercise=TRUE, exercise.timelimit = 10} +```{r car-orange, exercise.alert_class = "orange", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -111,9 +111,9 @@ mtcars ### purple -`exercise.alert_color = "purple"` +`exercise.alert_class = "purple"` -```{r car-purple, exercise.alert_color = "purple", exercise=TRUE, exercise.timelimit = 10} +```{r car-purple, exercise.alert_class = "purple", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -124,9 +124,9 @@ mtcars ### blue -`exercise.alert_color = "blue"` +`exercise.alert_class = "blue"` -```{r car-blue, exercise.alert_color = "blue", exercise=TRUE, exercise.timelimit = 10} +```{r car-blue, exercise.alert_class = "blue", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -138,9 +138,9 @@ mtcars ### violet -`exercise.alert_color = "violet"` +`exercise.alert_class = "violet"` -```{r car-violet, exercise.alert_color = "violet", exercise=TRUE, exercise.timelimit = 10} +```{r car-violet, exercise.alert_class = "violet", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -152,9 +152,9 @@ mtcars ### yellow -`exercise.alert_color = "yellow"` +`exercise.alert_class = "yellow"` -```{r car-yellow, exercise.alert_color = "yellow", exercise=TRUE, exercise.timelimit = 10} +```{r car-yellow, exercise.alert_class = "yellow", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -165,9 +165,9 @@ mtcars ### pink -`exercise.alert_color = "pink"` +`exercise.alert_class = "pink"` -```{r car-pink, exercise.alert_color = "pink", exercise=TRUE, exercise.timelimit = 10} +```{r car-pink, exercise.alert_class = "pink", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -178,9 +178,9 @@ mtcars ### green -`exercise.alert_color = "green"` +`exercise.alert_class = "green"` -```{r car-green, exercise.alert_color = "green", exercise=TRUE, exercise.timelimit = 10} +```{r car-green, exercise.alert_class = "green", exercise=TRUE, exercise.timelimit = 10} list( ``` From 8d31edae3621940b5d28cd0b7d3c540528c1a4a6 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 30 Sep 2020 16:31:22 +0200 Subject: [PATCH 14/31] set default values here --- R/exercise.R | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index 75a0e920d..51c5dba32 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -521,11 +521,13 @@ exercise_result <- function( feedback <- feedback_validated(feedback) feedback_html <- feedback_as_html(feedback, exercise) + exercise.gradethis_feedback_show <- exercise$options$exercise.gradethis_feedback_show %||% TRUE + exercise.gradethis_code_show <- exercise$options$exercise.gradethis_code_show %||% TRUE # The trainer want feedbacks and code (the default) if ( - exercise$options$exercise.gradethis_feedback_show & - exercise$options$exercise.gradethis_code_show + exercise.gradethis_feedback_show & + exercise.gradethis_code_show ){ html_output <- switch( feedback$location %||% "append", @@ -549,22 +551,22 @@ exercise_result <- function( ) } else if ( # The trainer want feedbacks only - exercise$options$exercise.gradethis_feedback_show & - ! exercise$options$exercise.gradethis_code_show + exercise.gradethis_feedback_show & + ! exercise.gradethis_code_show ) { html_output <- feedback_html } else if ( # The trainer wants code only - ! exercise$options$exercise.gradethis_feedback_show & - exercise$options$exercise.gradethis_code_show + ! exercise.gradethis_feedback_show & + exercise.gradethis_code_show ) { html_output <- tags$div( html_output ) } else if ( # The trainer wants no feedback - ! exercise$options$exercise.gradethis_feedback_show & - ! exercise$options$exercise.gradethis_code_show + ! exercise.gradethis_feedback_show & + ! exercise.gradethis_code_show ){ # Not sure what to do there, (i.e the trainer want neither feedback nor code) html_output <- div( From 79e2d4183d9d2b438d7b3ce65cc51acf9797ba04 Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Thu, 1 Oct 2020 09:46:50 +0200 Subject: [PATCH 15/31] Update R/options.R Co-authored-by: Barret Schloerke --- R/options.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/options.R b/R/options.R index 79cbbbe32..8cd8f8bd9 100644 --- a/R/options.R +++ b/R/options.R @@ -25,8 +25,8 @@ #' @param exercise.feedback_show Should the `{learnr}` feedback be shown? #' @param exercise.code_show Should `{learnr}` output code be shown? #' @param exercise.execution_error_message What message should `{learnr}` print on error? -#' @param exercise.gradethis_feedback_show Should the `{gradethis}` feedback be shown? -#' @param exercise.gradethis_code_show Should `{gradethis}` output code be shown? +#' @param exercise.submitted_feedback Should submitted exercise feedback be shown? +#' @param exercise.submitted_output Should submitted exercise output be shown? #' #' @export tutorial_options <- function( From 31f3e515ebf9a9a458378147f9df0a46a2be957c Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 09:53:33 +0200 Subject: [PATCH 16/31] Renamed to submitted_feedback & submitted_output --- R/exercise.R | 20 ++++++++++---------- R/options.R | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index 51c5dba32..3e9b18317 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -521,13 +521,13 @@ exercise_result <- function( feedback <- feedback_validated(feedback) feedback_html <- feedback_as_html(feedback, exercise) - exercise.gradethis_feedback_show <- exercise$options$exercise.gradethis_feedback_show %||% TRUE - exercise.gradethis_code_show <- exercise$options$exercise.gradethis_code_show %||% TRUE + exercise.submitted_feedback <- exercise$options$exercise.submitted_feedback %||% TRUE + exercise.submitted_output <- exercise$options$exercise.submitted_output %||% TRUE # The trainer want feedbacks and code (the default) if ( - exercise.gradethis_feedback_show & - exercise.gradethis_code_show + exercise.submitted_feedback & + exercise.submitted_output ){ html_output <- switch( feedback$location %||% "append", @@ -551,22 +551,22 @@ exercise_result <- function( ) } else if ( # The trainer want feedbacks only - exercise.gradethis_feedback_show & - ! exercise.gradethis_code_show + exercise.submitted_feedback & + ! exercise.submitted_output ) { html_output <- feedback_html } else if ( # The trainer wants code only - ! exercise.gradethis_feedback_show & - exercise.gradethis_code_show + ! exercise.submitted_feedback & + exercise.submitted_output ) { html_output <- tags$div( html_output ) } else if ( # The trainer wants no feedback - ! exercise.gradethis_feedback_show & - ! exercise.gradethis_code_show + ! exercise.submitted_feedback & + ! exercise.submitted_output ){ # Not sure what to do there, (i.e the trainer want neither feedback nor code) html_output <- div( diff --git a/R/options.R b/R/options.R index 8cd8f8bd9..f2b0b2f41 100644 --- a/R/options.R +++ b/R/options.R @@ -47,8 +47,8 @@ tutorial_options <- function( exercise.gradethis_info_color = NULL, exercise.gradethis_warning_color = NULL, exercise.gradethis_danger_color = NULL, - exercise.gradethis_feedback_show = TRUE, - exercise.gradethis_code_show = TRUE + exercise.submitted_feedback = TRUE, + exercise.submitted_output = TRUE ) { # string to evalute for setting chunk options %1$s From b96eed0af306d0029483c6757fc9166551be3eb6 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 10:19:32 +0200 Subject: [PATCH 17/31] the class is now fully provided, and is not pasted with alert- --- R/feedback.R | 14 +++++++------- R/options.R | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index 05bec360f..e6098db41 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -62,15 +62,15 @@ feedback_as_html <- function(feedback, exercise) { feedback$type <- switch( feedback$type, - success = exercise$options$exercise.gradethis_success_color %||% "success", - info = exercise$options$exercise.gradethis_info_color %||% "info", - warning = exercise$options$exercise.gradethis_warning_color %||% "warning", - danger = exercise$options$exercise.gradethis_danger_color %||% "danger" + success = exercise$options$exercise.gradethis_success_color %||% "alert-success", + info = exercise$options$exercise.gradethis_info_color %||% "alert-info", + warning = exercise$options$exercise.gradethis_warning_color %||% "alert-warning", + danger = exercise$options$exercise.gradethis_danger_color %||% "alert-danger" ) return(div( role = "alert", - class = paste0("alert alert-", feedback$type), + class = paste0("alert", feedback$type), feedback$message )) } @@ -81,8 +81,8 @@ feedback_as_html <- function(feedback, exercise) { error_message_html <- function(message, exercise) { error <- exercise$options$exercise.execution_error_message %||% "There was an error when running your code:" class <- sprintf( - "alert alert-%s", - exercise$options$exercise.alert_class %||% "red" + "alert %s", + exercise$options$exercise.alert_class %||% "alert-red" ) #Default to TRUE if the option is missing diff --git a/R/options.R b/R/options.R index f2b0b2f41..14f20400e 100644 --- a/R/options.R +++ b/R/options.R @@ -18,10 +18,11 @@ #' @param exercise.completion Use code completion in exercise editors. #' @param exercise.diagnostics Show diagnostics in exercise editors. #' @param exercise.startover Show "Start Over" button on exercise. -#' @param exercise.alert_class,exercise.gradethis_info_color,exercise.gradethis_success_color,exercise.gradethis_warning_color,exercise.gradethis_danger_color Slug for the CSS class for `{learnr}` and `{gradethis}` message. -#' It can be one of `red`, `orange`, `purple`, `blue`, `violet`, `yellow`, `pink`, `green`, -#' or `grey`. You can also implement your own CSS rule, in that case you need to define a -#' class that starts with `alert-` (for example `alert-rainbow`). +#' @param exercise.alert_class,exercise.gradethis_info_color,exercise.gradethis_success_color,exercise.gradethis_warning_color,exercise.gradethis_danger_color The CSS class for `{learnr}` and `{gradethis}` message. +#' It can be one of `alert-success`, `alert-info`, `alert-warning`, `alert-danger`, +#' `alert-red`, `alert-orange`, `alert-purple`, `alert-blue`, `alert-violet`, +#' `alert-yellow`, `alert-pink`, `alert-green`, or `alert-grey`. +#' You can also use your own CSS class. #' @param exercise.feedback_show Should the `{learnr}` feedback be shown? #' @param exercise.code_show Should `{learnr}` output code be shown? #' @param exercise.execution_error_message What message should `{learnr}` print on error? @@ -39,14 +40,14 @@ tutorial_options <- function( exercise.completion = TRUE, exercise.diagnostics = TRUE, exercise.startover = TRUE, - exercise.alert_class = "red", + exercise.alert_class = "alert-red", exercise.feedback_show = TRUE, exercise.code_show = TRUE, exercise.execution_error_message = NULL, - exercise.gradethis_success_color = NULL, - exercise.gradethis_info_color = NULL, - exercise.gradethis_warning_color = NULL, - exercise.gradethis_danger_color = NULL, + exercise.gradethis_success_color = "alert-success", + exercise.gradethis_info_color = "alert-info", + exercise.gradethis_warning_color = "alert-warning", + exercise.gradethis_danger_color = "alert-danger", exercise.submitted_feedback = TRUE, exercise.submitted_output = TRUE ) From eba0811c1ad6f5b0e1b3afc37fea31814358f75e Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 10:54:27 +0200 Subject: [PATCH 18/31] exercise.feedback_show, exercise.code_show, exercise.gradethis_feedback_show and exercise.gradethis_code_show are now set to TRUE if exercise$check and exercise$code_check are NULL --- R/exercise.R | 14 ++++++++++++-- R/feedback.R | 16 +++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index 3e9b18317..b7941ec04 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -521,8 +521,18 @@ exercise_result <- function( feedback <- feedback_validated(feedback) feedback_html <- feedback_as_html(feedback, exercise) - exercise.submitted_feedback <- exercise$options$exercise.submitted_feedback %||% TRUE - exercise.submitted_output <- exercise$options$exercise.submitted_output %||% TRUE + if ( + is.null(exercise$check) && + is.null(exercise$code_check) + ){ + exercise.submitted_feedback <- TRUE + exercise.submitted_output <- TRUE + } else { + exercise.submitted_feedback <- exercise$options$exercise.submitted_feedback %||% TRUE + exercise.submitted_output <- exercise$options$exercise.submitted_output %||% TRUE + } + + # The trainer want feedbacks and code (the default) if ( diff --git a/R/feedback.R b/R/feedback.R index e6098db41..ab5193879 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -85,9 +85,19 @@ error_message_html <- function(message, exercise) { exercise$options$exercise.alert_class %||% "alert-red" ) - #Default to TRUE if the option is missing - exercise.feedback_show <- exercise$options$exercise.feedback_show %||% TRUE - exercise.code_show <- exercise$options$exercise.feedback_show %||% TRUE + if ( + is.null(exercise$check) && + is.null(exercise$code_check) + ){ + exercise.feedback_show <- TRUE + exercise.code_show <- TRUE + } else { + #Default to TRUE if the option is missing + exercise.feedback_show <- exercise$options$exercise.feedback_show %||% TRUE + exercise.code_show <- exercise$options$exercise.feedback_show %||% TRUE + } + + # The trainer want feedbacks and code (the default) if ( From aeedfc77605e3096143228fc80e19608ded93e2e Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 11:00:53 +0200 Subject: [PATCH 19/31] fully switched to class name --- R/feedback.R | 10 +++++----- R/options.R | 25 +++++-------------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index ab5193879..e442e0b67 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -58,14 +58,14 @@ feedback_as_html <- function(feedback, exercise) { if (!feedback$type %in% c("success", "info", "warning", "danger")) { stop("Invalid message type specified.", call. = FALSE) } - # Applying custom colors if they exist + # Applying custom classes if they exist feedback$type <- switch( feedback$type, - success = exercise$options$exercise.gradethis_success_color %||% "alert-success", - info = exercise$options$exercise.gradethis_info_color %||% "alert-info", - warning = exercise$options$exercise.gradethis_warning_color %||% "alert-warning", - danger = exercise$options$exercise.gradethis_danger_color %||% "alert-danger" + success = exercise$options$exercise.success_class %||% "alert-success", + info = exercise$options$exercise.info_class %||% "alert-info", + warning = exercise$options$exercise.warning_class %||% "alert-warning", + danger = exercise$options$exercise.danger_class %||% "alert-danger" ) return(div( diff --git a/R/options.R b/R/options.R index 14f20400e..88f4f15f4 100644 --- a/R/options.R +++ b/R/options.R @@ -18,7 +18,7 @@ #' @param exercise.completion Use code completion in exercise editors. #' @param exercise.diagnostics Show diagnostics in exercise editors. #' @param exercise.startover Show "Start Over" button on exercise. -#' @param exercise.alert_class,exercise.gradethis_info_color,exercise.gradethis_success_color,exercise.gradethis_warning_color,exercise.gradethis_danger_color The CSS class for `{learnr}` and `{gradethis}` message. +#' @param exercise.alert_class,exercise.info_class,exercise.success_class,exercise.warning_class,exercise.danger_class The CSS class for `{learnr}` and `{gradethis}` message. #' It can be one of `alert-success`, `alert-info`, `alert-warning`, `alert-danger`, #' `alert-red`, `alert-orange`, `alert-purple`, `alert-blue`, `alert-violet`, #' `alert-yellow`, `alert-pink`, `alert-green`, or `alert-grey`. @@ -44,10 +44,10 @@ tutorial_options <- function( exercise.feedback_show = TRUE, exercise.code_show = TRUE, exercise.execution_error_message = NULL, - exercise.gradethis_success_color = "alert-success", - exercise.gradethis_info_color = "alert-info", - exercise.gradethis_warning_color = "alert-warning", - exercise.gradethis_danger_color = "alert-danger", + exercise.success_class = "alert-success", + exercise.info_class = "alert-info", + exercise.warning_class = "alert-warning", + exercise.danger_class = "alert-danger", exercise.submitted_feedback = TRUE, exercise.submitted_output = TRUE ) @@ -59,19 +59,4 @@ tutorial_options <- function( for (i in names(formals())){ eval(parse(text = sprintf(set_option_code, i))) } - # browser() - # eval(parse(text = sprintf(set_option_code, "exercise.cap"))) - # eval(parse(text = sprintf(set_option_code, "exercise.eval"))) - # eval(parse(text = sprintf(set_option_code, "exercise.timelimit"))) - # eval(parse(text = sprintf(set_option_code, "exercise.lines"))) - # eval(parse(text = sprintf(set_option_code, "exercise.checker"))) - # eval(parse(text = sprintf(set_option_code, "exercise.error.check.code"))) - # eval(parse(text = sprintf(set_option_code, "exercise.completion"))) - # eval(parse(text = sprintf(set_option_code, "exercise.diagnostics"))) - # eval(parse(text = sprintf(set_option_code, "exercise.startover"))) - # eval(parse(text = sprintf(set_option_code, "exercise.alert_color"))) - # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_success_color"))) - # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_info_color"))) - # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_warning_color"))) - # eval(parse(text = sprintf(set_option_code, "exercise.gradethis_danger_color"))) } From 6e3747c33042b4f61c57ed27546f6818ae2895a1 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 11:07:53 +0200 Subject: [PATCH 20/31] Forgot a space in paste0 --- R/feedback.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/feedback.R b/R/feedback.R index e442e0b67..4419746bb 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -70,7 +70,7 @@ feedback_as_html <- function(feedback, exercise) { return(div( role = "alert", - class = paste0("alert", feedback$type), + class = paste0("alert ", feedback$type), feedback$message )) } From e19cae9f06e29a655b31d26f2238b85f9720ce31 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 1 Oct 2020 12:40:44 +0200 Subject: [PATCH 21/31] correct option names --- sandbox/colored-output-gradethis.Rmd | 50 ++++++++++++++-------------- sandbox/colored-output.Rmd | 34 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/sandbox/colored-output-gradethis.Rmd b/sandbox/colored-output-gradethis.Rmd index c1f42d83a..c76f73d2b 100644 --- a/sandbox/colored-output-gradethis.Rmd +++ b/sandbox/colored-output-gradethis.Rmd @@ -13,16 +13,16 @@ library(dplyr) #options(tutorial.event_recorder = learnr:::debug_event_recorder) gradethis::gradethis_setup( exercise.eval = FALSE, - exercise.alert_class = "orange", - exercise.gradethis_success_color = "pink", - exercise.gradethis_info_color = "orange", - exercise.gradethis_warning_color = "violet", - exercise.gradethis_danger_color = "blue" + exercise.alert_class = "alert-orange", + exercise.success_class = "alert-pink", + exercise.info_class = "alert-orange", + exercise.warning_class = "alert-violet", + exercise.danger_class = "alert-blue" ) tutorial_options( - exercise.gradethis_feedback_show = TRUE, - exercise.gradethis_code_show = TRUE + exercise.submitted_feedback = TRUE, + exercise.submitted_output = TRUE ) ``` @@ -31,20 +31,20 @@ tutorial_options( Done: -+ The gradethis colors can be set using options: `exercise.gradethis_success_color`, `exercise.gradethis_info_color`, `exercise.gradethis_warning_color` and `exercise.gradethis_danger_color` ++ The gradethis colors can be set using options: `exercise.success_class`, `exercise.info_class`, `exercise.warning_class` and `exercise.danger_class` __Example__ The current tutorial uses the following call in the setup chunk: ``` -tutorial_options( -exercise.eval = FALSE, -exercise.alert_class = "orange", -exercise.gradethis_success_color = "pink", -exercise.gradethis_info_color = "orange", -exercise.gradethis_warning_color = "violet", -exercise.gradethis_danger_color = "blue" +gradethis::gradethis_setup( + exercise.eval = FALSE, + exercise.alert_class = "alert-orange", + exercise.success_class = "alert-pink", + exercise.info_class = "alert-orange", + exercise.warning_class = "alert-violet", + exercise.danger_class = "alert-blue" ) ``` @@ -71,12 +71,12 @@ grade_result( With the following chunk setup: ``` -{r mtcars2 exercise.gradethis_success_color = "red", ,exercise.gradethis_info_color = "violet", exercise.gradethis_warning_color = "blue", exercise.gradethis_danger_color = "green"} +{r mtcars2 exercise.success_class = "alert-red", ,exercise.info_class = "alert-violet", exercise.warning_class = "alert-blue", exercise.danger_class = "alert-green"} ``` Enter `mtcars` -```{r mtcars2, exercise = TRUE, exercise.gradethis_success_color = "red", ,exercise.gradethis_info_color = "violet", exercise.gradethis_warning_color = "blue", exercise.gradethis_danger_color = "green"} +```{r mtcars2, exercise = TRUE, exercise.success_class = "alert-red", ,exercise.info_class = "alert-violet", exercise.warning_class = "alert-blue", exercise.danger_class = "alert-green"} ``` @@ -97,12 +97,12 @@ grade_result( With the following chunk: ``` -{r mtcars3, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = TRUE} +{r mtcars3, exercise.submitted_feedback = TRUE, exercise.submitted_output = TRUE} ``` Enter `mtcars` -```{r mtcars3, exercise = TRUE, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = TRUE} +```{r mtcars3, exercise = TRUE, exercise.submitted_feedback = TRUE, exercise.submitted_output = TRUE} airquality ``` @@ -121,12 +121,12 @@ grade_result( With the following chunk: ``` -{r mtcars4, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = FALSE} +{r mtcars4, exercise.submitted_feedback = TRUE, exercise.submitted_output = FALSE} ``` Enter `mtcars` -```{r mtcars4, exercise = TRUE, exercise.gradethis_feedback_show = TRUE, exercise.gradethis_code_show = FALSE} +```{r mtcars4, exercise = TRUE, exercise.submitted_feedback = TRUE, exercise.submitted_output = FALSE} airquality ``` @@ -145,12 +145,12 @@ grade_result( With the following chunk: ``` -{r mtcars5, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = TRUE} +{r mtcars5, exercise.submitted_feedback = FALSE, exercise.submitted_output = TRUE} ``` Enter `mtcars` -```{r mtcars5, exercise = TRUE, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = TRUE} +```{r mtcars5, exercise = TRUE, exercise.submitted_feedback = FALSE, exercise.submitted_output = TRUE} airquality ``` @@ -169,12 +169,12 @@ grade_result( With the following chunk: ``` -{r mtcars6, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = FALSE} +{r mtcars6, exercise.submitted_feedback = FALSE, exercise.submitted_output = FALSE} ``` Enter `mtcars` -```{r mtcars6, exercise = TRUE, exercise.gradethis_feedback_show = FALSE, exercise.gradethis_code_show = FALSE} +```{r mtcars6, exercise = TRUE, exercise.submitted_feedback = FALSE, exercise.submitted_output = FALSE} airquality ``` diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd index f56471a8f..941310505 100644 --- a/sandbox/colored-output.Rmd +++ b/sandbox/colored-output.Rmd @@ -13,7 +13,7 @@ library(dplyr) options(tutorial.event_recorder = learnr:::debug_event_recorder) tutorial_options( exercise.eval = FALSE, - exercise.alert_class = "orange" + exercise.alert_class = "alert-orange" ) ``` @@ -82,10 +82,10 @@ Colors can also be set at the chunk level. ### red ``` -{r car-red, exercise.alert_class = "red"} +{r car-red, exercise.alert_class = "alert-red"} ``` -```{r car-red, exercise.alert_class = "red", exercise=TRUE} +```{r car-red, exercise.alert_class = "alert-red", exercise=TRUE} list( ``` @@ -97,9 +97,9 @@ mtcars ### orange -`exercise.alert_class = "orange"` +`exercise.alert_class = "alert-orange"` -```{r car-orange, exercise.alert_class = "orange", exercise=TRUE, exercise.timelimit = 10} +```{r car-orange, exercise.alert_class = "alert-orange", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -111,9 +111,9 @@ mtcars ### purple -`exercise.alert_class = "purple"` +`exercise.alert_class = "alert-purple"` -```{r car-purple, exercise.alert_class = "purple", exercise=TRUE, exercise.timelimit = 10} +```{r car-purple, exercise.alert_class = "alert-purple", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -124,9 +124,9 @@ mtcars ### blue -`exercise.alert_class = "blue"` +`exercise.alert_class = "alert-blue"` -```{r car-blue, exercise.alert_class = "blue", exercise=TRUE, exercise.timelimit = 10} +```{r car-blue, exercise.alert_class = "alert-blue", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -138,9 +138,9 @@ mtcars ### violet -`exercise.alert_class = "violet"` +`exercise.alert_class = "alert-violet"` -```{r car-violet, exercise.alert_class = "violet", exercise=TRUE, exercise.timelimit = 10} +```{r car-violet, exercise.alert_class = "alert-violet", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -152,9 +152,9 @@ mtcars ### yellow -`exercise.alert_class = "yellow"` +`exercise.alert_class = "alert-yellow"` -```{r car-yellow, exercise.alert_class = "yellow", exercise=TRUE, exercise.timelimit = 10} +```{r car-yellow, exercise.alert_class = "alert-yellow", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -165,9 +165,9 @@ mtcars ### pink -`exercise.alert_class = "pink"` +`exercise.alert_class = "alert-pink"` -```{r car-pink, exercise.alert_class = "pink", exercise=TRUE, exercise.timelimit = 10} +```{r car-pink, exercise.alert_class = "alert-pink", exercise=TRUE, exercise.timelimit = 10} list( ``` @@ -178,9 +178,9 @@ mtcars ### green -`exercise.alert_class = "green"` +`exercise.alert_class = "alert-green"` -```{r car-green, exercise.alert_class = "green", exercise=TRUE, exercise.timelimit = 10} +```{r car-green, exercise.alert_class = "alert-green", exercise=TRUE, exercise.timelimit = 10} list( ``` From 8fb08315b96dd3b85764dec2dc1aae982dcf13ca Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 7 Oct 2020 15:04:48 +0200 Subject: [PATCH 22/31] Output is always printed when pressing Run Code, and colored box is added when error is returned --- R/feedback.R | 63 ++++++------------------------------ R/options.R | 7 +--- sandbox/colored-output.Rmd | 66 -------------------------------------- 3 files changed, 11 insertions(+), 125 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index 4419746bb..5cfc17fc0 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -79,66 +79,23 @@ feedback_as_html <- function(feedback, exercise) { # It is called by learnr when clicking "Run code" & the # code produced an error error_message_html <- function(message, exercise) { - error <- exercise$options$exercise.execution_error_message %||% "There was an error when running your code:" + # When the Run Code button is pressed, the output is __always__ shown. + # This html builder function adds colored border around the code output if there is an error. + class <- sprintf( "alert %s", exercise$options$exercise.alert_class %||% "alert-red" ) - if ( - is.null(exercise$check) && - is.null(exercise$code_check) - ){ - exercise.feedback_show <- TRUE - exercise.code_show <- TRUE - } else { - #Default to TRUE if the option is missing - exercise.feedback_show <- exercise$options$exercise.feedback_show %||% TRUE - exercise.code_show <- exercise$options$exercise.feedback_show %||% TRUE - } + div( + class = class, + role = "alert", + tags$pre( + message + ) + ) - # The trainer want feedbacks and code (the default) - if ( - exercise.feedback_show & - exercise.code_show - ){ - div( - class = class, - role = "alert", - error, - tags$pre( - message - ) - ) - } else if ( - # The trainer want feedbacks only - exercise.feedback_show & - ! exercise.code_show - ) { - div( - class = class, - role = "alert", - error - ) - } else if ( - # The trainer wants code only - ! exercise.feedback_show & - exercise.code_show - ) { - div( - tags$pre( - message - ) - ) - } else { - # Not sure what to do there, (i.e the trainer want neither feedback nor code) - div( - class = "alert alert-grey", - role = "alert", - "Code submitted" - ) - } } diff --git a/R/options.R b/R/options.R index 88f4f15f4..794c3f49a 100644 --- a/R/options.R +++ b/R/options.R @@ -23,9 +23,7 @@ #' `alert-red`, `alert-orange`, `alert-purple`, `alert-blue`, `alert-violet`, #' `alert-yellow`, `alert-pink`, `alert-green`, or `alert-grey`. #' You can also use your own CSS class. -#' @param exercise.feedback_show Should the `{learnr}` feedback be shown? -#' @param exercise.code_show Should `{learnr}` output code be shown? -#' @param exercise.execution_error_message What message should `{learnr}` print on error? +# #' @param exercise.execution_error_message What message should `{learnr}` print on error? #' @param exercise.submitted_feedback Should submitted exercise feedback be shown? #' @param exercise.submitted_output Should submitted exercise output be shown? #' @@ -41,9 +39,6 @@ tutorial_options <- function( exercise.diagnostics = TRUE, exercise.startover = TRUE, exercise.alert_class = "alert-red", - exercise.feedback_show = TRUE, - exercise.code_show = TRUE, - exercise.execution_error_message = NULL, exercise.success_class = "alert-success", exercise.info_class = "alert-info", exercise.warning_class = "alert-warning", diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd index 941310505..97c70b2cf 100644 --- a/sandbox/colored-output.Rmd +++ b/sandbox/colored-output.Rmd @@ -61,20 +61,6 @@ list( mtcars ``` -Example using a different `exercise.execution_error_message` - -``` -{r carbis, exercise=TRUE, exercise.execution_error_message = "Ouch!"} -``` - -```{r carbis, exercise=TRUE, exercise.execution_error_message = "Ouch!"} -list( -``` - -```{r carbis-solution} -mtcars -``` - ## Using locally set color Colors can also be set at the chunk level. @@ -187,56 +173,4 @@ list( ```{r car-green-solution} mtcars -``` - -## Toggle Feedback or code display - -Done: - -+ `exercise.feedback_show` and `exercise.feedback_show` set the content of the feedbacks from learnr - -To discuss: - -+ What should we print when trainer wants neither feedback nor code? - -__Example__ - -`{r exercise.feedback_show=TRUE, exercise.code_show = TRUE}` - -```{r cara, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=TRUE, exercise.code_show = TRUE} -list( -``` - -```{r cara-solution} -mtcars -``` - -`{r exercise.feedback_show=FALSE, exercise.code_show = TRUE}` - -```{r carb, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=FALSE, exercise.code_show = TRUE} -list( -``` - -```{r carb-solution} -mtcars -``` - -`{r exercise.feedback_show=TRUE, exercise.code_show = FALSE}` - -```{r carc, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=TRUE, exercise.code_show = FALSE} -list( -``` - -```{r carc-solution} -mtcars -``` - -`{r exercise.feedback_show=FALSE, exercise.code_show = FALSE}` - -```{r card, exercise=TRUE, exercise.timelimit = 10, exercise.feedback_show=FALSE, exercise.code_show = FALSE} -list( -``` - -```{r card-solution} -mtcars ``` \ No newline at end of file From bfde555383b44152e9d1a1c670b339d41cdbcc32 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 7 Oct 2020 15:18:32 +0200 Subject: [PATCH 23/31] typo --- sandbox/colored-output.Rmd | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sandbox/colored-output.Rmd b/sandbox/colored-output.Rmd index 97c70b2cf..702cd19df 100644 --- a/sandbox/colored-output.Rmd +++ b/sandbox/colored-output.Rmd @@ -22,12 +22,10 @@ tutorial_options( Done: -+ `exercise.alert_class` in the setup chunck can be used to change the alert color. ++ `exercise.alert_class` in the setup chunk can be used to change the alert color. + The output of the code is now inside the alert, formatted as code/table. -+ There is a default message in the error output, it can be changed by `exercise.execution_error_message` - To do: + Add a check that the colors set by the user is valid (we have a finite set of colors) From dc4cde2760dbdf9584c76be69d8dce707b654008 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 8 Oct 2020 16:00:25 +0200 Subject: [PATCH 24/31] padding table on outputs --- inst/lib/tutorial/tutorial.css | 258 ++++++++++++++++----------------- 1 file changed, 128 insertions(+), 130 deletions(-) diff --git a/inst/lib/tutorial/tutorial.css b/inst/lib/tutorial/tutorial.css index 03d9b4ac6..e49de969b 100644 --- a/inst/lib/tutorial/tutorial.css +++ b/inst/lib/tutorial/tutorial.css @@ -1,235 +1,233 @@ :root { - --red-back: #f2dede; - --red-color: #b94a48; - --red-border: #eed3d7; - --orange-back: #ffa0142e; - --orange-color: #b96e00; - --orange-border: #ffc10787; - --purple-back: #9c27b029; - --purple-color: #681876; - --purple-border: #9c27b01f; - --blue-back: #cce5ff; - --blue-color: #004085; - --blue-border: #b8daff; - --violet-back: #6610f214; - --violet-color: #3e246d; - --violet-border: #6610f23b; - --yellow-back: #ffc10747; - --yellow-color: #da6605; - --yellow-border: #ffc107; - --pink-back: #e83eb424; - --pink-color: #9b2158; - --pink-border: #e83e8c45; - --green-back: #dff0d8; - --green-color: #468847; - --green-border: #d6e9c6; - --grey-back: #f5f5f5; - --grey-color: #555555; - --grey-border: #dcdcdc; + --red-back: #f2dede; + --red-color: #b94a48; + --red-border: #eed3d7; + --orange-back: #ffa0142e; + --orange-color: #b96e00; + --orange-border: #ffc10787; + --purple-back: #9c27b029; + --purple-color: #681876; + --purple-border: #9c27b01f; + --blue-back: #cce5ff; + --blue-color: #004085; + --blue-border: #b8daff; + --violet-back: #6610f214; + --violet-color: #3e246d; + --violet-border: #6610f23b; + --yellow-back: #ffc10747; + --yellow-color: #da6605; + --yellow-border: #ffc107; + --pink-back: #e83eb424; + --pink-color: #9b2158; + --pink-border: #e83e8c45; + --green-back: #dff0d8; + --green-color: #468847; + --green-border: #d6e9c6; + --grey-back: #f5f5f5; + --grey-color: #555555; + --grey-border: #dcdcdc; } .tutorial-exercise-support { - display: none; + display: none; } .slide .tutorial-exercise { - line-height: 1.4; + line-height: 1.4; } .tutorial-exercise { - position: relative; + position: relative; } .tutorial-exercise-input { - margin-top: 15px; + margin-top: 15px; } .tutorial-panel-heading { - padding-top: 6px; - padding-bottom: 6px; - padding-left: 8px; - padding-right: 8px; - font-size: 13px; - font-weight: 500; - width: 100%; - display: flex; - justify-content: space-between; + padding-top: 6px; + padding-bottom: 6px; + padding-left: 8px; + padding-right: 8px; + font-size: 13px; + font-weight: 500; + width: 100%; + display: flex; + justify-content: space-between; } + .tutorial-panel-heading-left, .tutorial-panel-heading-right { - display: flex; + display: flex; } + .tutorial-quiz-title { - font-weight: 300; - font-size: 18px; - padding-top: 6px; - padding-bottom: 0px; - padding-left: 0px; - padding-right: 8px; - width: 100%; + font-weight: 300; + font-size: 18px; + padding-top: 6px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 8px; + width: 100%; } .tutorial-question { - padding-top: 10px; - padding-bottom: 15px; + padding-top: 10px; + padding-bottom: 15px; } .tutorial-exercise-input .btn-xs { - margin-right: 0; - margin-top: -1px; - font-size: 11px; - margin-left: 12px; - padding-right: 8px; - font-weight: normal; + margin-right: 0; + margin-top: -1px; + font-size: 11px; + margin-left: 12px; + padding-right: 8px; + font-weight: normal; } .btn-light { - color: #333; - background-color: #fff; - border-color: #ccc; + color: #333; + background-color: #fff; + border-color: #ccc; } .tutorial-exercise-input .btn-tutorial-solution { - margin-left: 15px; + margin-left: 15px; } .tutorial-exercise-input .btn-tutorial-next-hint { - margin-left: 15px; - padding-right: 4px; + margin-left: 15px; + padding-right: 4px; } .tutorial-exercise-input .btn-xs i { - width: 10px; - margin-right: 1px; + width: 10px; + margin-right: 1px; } - .tutorial-exercise-input .panel-body { - padding: 0; + padding: 0; } - .tutorial-exercise-code-editor { - width: 100%; + width: 100%; } - .tutorial-solution-popover { - max-width: none; - width: 100%; + max-width: none; + width: 100%; } .tutorial-solution-popover.top>.arrow { - margin-left: 0; + margin-left: 0; } -.tutorial-hint { - -} +.tutorial-hint {} .ace-tm { - font-family: monospace; - font-size: 90%; + font-family: monospace; + font-size: 90%; } - .tutorial-video-container { - position: relative; - margin-top: 15px; - margin-bottom: 15px; + position: relative; + margin-top: 15px; + margin-bottom: 15px; } .tutorial-exercise-output>pre { - max-height: 500px; - overflow-y: auto; + max-height: 500px; + overflow-y: auto; } .tutorial-video { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border: solid 1px #cccccc; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: solid 1px #cccccc; } .tutorial_engine_icon { - vertical-align: middle; - fill: currentColor; - height: 20px; - width: 20px; - margin-right: -9px; - /* net 6px */ + vertical-align: middle; + fill: currentColor; + height: 20px; + width: 20px; + margin-right: -9px; + /* net 6px */ } -.alert{ - width: 100%!important; +.alert { + width: 100%!important; } .alert-red { - background-color: var(--red-back); - color: var(--red-color); - border-color: var(--red-border); + background-color: var(--red-back); + color: var(--red-color); + border-color: var(--red-border); } .alert-orange { - background-color: var(--orange-back); - color: var(--orange-color); - border-color: var(--orange-border); + background-color: var(--orange-back); + color: var(--orange-color); + border-color: var(--orange-border); } .alert-purple { - background-color: var(--purple-back); - color: var(--purple-color); - border-color: var(--purple-border); + background-color: var(--purple-back); + color: var(--purple-color); + border-color: var(--purple-border); } .alert-blue { - background-color: var(--blue-back); - color: var(--blue-color); - border-color: var(--blue-border); + background-color: var(--blue-back); + color: var(--blue-color); + border-color: var(--blue-border); } .alert-violet { - background-color: var(--violet-back); - color: var(--violet-color); - border-color: var(--violet-border); + background-color: var(--violet-back); + color: var(--violet-color); + border-color: var(--violet-border); } .alert-yellow { - background-color: var(--yellow-back); - color: var(--yellow-color); - border-color: var(--yellow-border); + background-color: var(--yellow-back); + color: var(--yellow-color); + border-color: var(--yellow-border); } .alert-pink { - background-color: var(--pink-back); - color: var(--pink-color); - border-color: var(--pink-border); + background-color: var(--pink-back); + color: var(--pink-color); + border-color: var(--pink-border); } .alert-green { - background-color: var(--green-back); - color: var(--green-color); - border-color: var(--green-border); + background-color: var(--green-back); + color: var(--green-color); + border-color: var(--green-border); } .alert-grey { - background-color: var(--grey-back); - color: var(--grey-color); - border-color: var(--grey-border); + background-color: var(--grey-back); + color: var(--grey-color); + border-color: var(--grey-border); } + /* Class to display pagetable inside an alert without inheriting from it*/ -.alert > .pagedtable-wrapper { - background-color: white; - color: #555555; +.alert>.pagedtable-wrapper { + border: 0px!important; + margin-top: 1em; + background-color: white; + color: #555555; } -.alert > pre { +.alert>pre { border: none; border-radius: 4px; margin-top: 1em; -} - +} \ No newline at end of file From 1cbace03e1e869d27cc9ba9e286ff311f8c04c61 Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Thu, 8 Oct 2020 16:22:19 +0200 Subject: [PATCH 25/31] Apply suggestions from code review Co-authored-by: Barret Schloerke --- R/exercise.R | 4 +--- R/feedback.R | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index b7941ec04..b80c3ae06 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -501,9 +501,7 @@ exercise_result <- function( exercise = NULL ) { - # When `exercise` is empty, we return a list of NULL - # `exercise` is NULL when there was no code sent (i.e the - # student hasn't entered any code) + # When `exercise` is empty, we return a list of as.is values if (is.null(exercise)){ return( structure( diff --git a/R/feedback.R b/R/feedback.R index 5cfc17fc0..6e4c7d862 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -93,9 +93,5 @@ error_message_html <- function(message, exercise) { tags$pre( message ) - ) - - - } From 677664ea703ed9691cb42cbc15df325a0b3fd10c Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 13 Oct 2020 10:36:34 +0200 Subject: [PATCH 26/31] unsetting the color background when it's a learnr feedback --- R/feedback.R | 5 +++-- inst/lib/tutorial/tutorial.css | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/R/feedback.R b/R/feedback.R index 6e4c7d862..3f748f62c 100644 --- a/R/feedback.R +++ b/R/feedback.R @@ -43,6 +43,7 @@ feedback_validated <- function(feedback) { # This function is called to build the html of the feedback # provided by gradethis +# It's called both when pressing Run Code and Submit Answer feedback_as_html <- function(feedback, exercise) { if (!length(feedback)) { @@ -78,12 +79,12 @@ feedback_as_html <- function(feedback, exercise) { # helper function to create tags for error message # It is called by learnr when clicking "Run code" & the # code produced an error +# It's called only when pressing Run Code error_message_html <- function(message, exercise) { # When the Run Code button is pressed, the output is __always__ shown. # This html builder function adds colored border around the code output if there is an error. - class <- sprintf( - "alert %s", + "alert run-code %s", exercise$options$exercise.alert_class %||% "alert-red" ) diff --git a/inst/lib/tutorial/tutorial.css b/inst/lib/tutorial/tutorial.css index e49de969b..8a07b57f8 100644 --- a/inst/lib/tutorial/tutorial.css +++ b/inst/lib/tutorial/tutorial.css @@ -162,6 +162,11 @@ width: 100%!important; } +.run-code { + background-color: unset!important; + color: unset!important; +} + .alert-red { background-color: var(--red-back); color: var(--red-color); From ab0f6c20e9738648e6a281ab66567b64b80cc643 Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Tue, 13 Oct 2020 11:46:17 +0200 Subject: [PATCH 27/31] Update R/exercise.R Co-authored-by: Barret Schloerke --- R/exercise.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/exercise.R b/R/exercise.R index b80c3ae06..fb41d45f4 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -523,7 +523,7 @@ exercise_result <- function( is.null(exercise$check) && is.null(exercise$code_check) ){ - exercise.submitted_feedback <- TRUE + exercise.submitted_feedback <- FALSE exercise.submitted_output <- TRUE } else { exercise.submitted_feedback <- exercise$options$exercise.submitted_feedback %||% TRUE From 63aaf6904784b5899b102f2d8c21567d5ae1442e Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 13 Oct 2020 11:47:05 +0200 Subject: [PATCH 28/31] return(exercise_result(html_output = " ", exercise = NULL)) --- R/exercise.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/exercise.R b/R/exercise.R index fb41d45f4..860318dee 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -186,7 +186,7 @@ evaluate_exercise <- function(exercise, envir, evaluate_global_setup = FALSE) { # do not consider this an exercise submission if (!nzchar(str_trim(paste0(exercise$code, collapse = "\n")))) { # " " since html_output needs to pass a req() - return(exercise_result(html_output = " ")) + return(exercise_result(html_output = " ", exercise = NULL)) } if (evaluate_global_setup) { From 8d58d02f5deffb582a6821a67a7eec56ef334534 Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Wed, 14 Oct 2020 09:15:28 +0200 Subject: [PATCH 29/31] Update R/exercise.R Co-authored-by: Barret Schloerke --- R/exercise.R | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/exercise.R b/R/exercise.R index 860318dee..5d5fb6621 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -530,8 +530,6 @@ exercise_result <- function( exercise.submitted_output <- exercise$options$exercise.submitted_output %||% TRUE } - - # The trainer want feedbacks and code (the default) if ( exercise.submitted_feedback & From a606776045ef050e26405c730ce63a891c569b72 Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Wed, 14 Oct 2020 09:15:37 +0200 Subject: [PATCH 30/31] Update R/exercise.R Co-authored-by: Barret Schloerke --- R/exercise.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/exercise.R b/R/exercise.R index 5d5fb6621..c3626adcd 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -517,7 +517,7 @@ exercise_result <- function( } feedback <- feedback_validated(feedback) - feedback_html <- feedback_as_html(feedback, exercise) + feedback_html <- feedback_as_html(feedback, exercise = exercise) if ( is.null(exercise$check) && From f50731a76608d39881a0058289e9f429cef91f6d Mon Sep 17 00:00:00 2001 From: Colin Fay Date: Wed, 14 Oct 2020 09:15:46 +0200 Subject: [PATCH 31/31] Update R/exercise.R Co-authored-by: Barret Schloerke --- R/exercise.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/exercise.R b/R/exercise.R index c3626adcd..1f0467074 100644 --- a/R/exercise.R +++ b/R/exercise.R @@ -442,7 +442,7 @@ render_exercise <- function(exercise, envir, envir_prep) { ) html_output <- htmltools::tagList( - feedback_as_html(invisible_feedback, exercise), + feedback_as_html(invisible_feedback, exercise = exercise), html_output ) }