| Title: | Create Interactive Web Exercises |
|---|---|
| Description: | Functions for easily creating interactive web exercises in 'R Markdown', 'Quarto', and package vignettes that students can use in self-guided learning. |
| Authors: | Dale Barr [aut], Lisa DeBruine [aut], Caspar J. Van Lissa [aut, cre] (ORCID: <https://orcid.org/0000-0002-0808-5024>) |
| Maintainer: | Caspar J. Van Lissa <[email protected]> |
| License: | CC BY-SA 4.0 |
| Version: | 1.2.0 |
| Built: | 2026-10-09 11:00:09 UTC |
| Source: | https://github.com/psyteachr/webexercises |
Adds the necessary helper files to an existing bookdown project and edits the _output.yml and _bookdown.yml files accordingly. If the directory does not have a bookdown project in it, a template project will be set up.
add_to_bookdown( bookdown_dir = ".", include_dir = "include", script_dir = "R", output_format = c("bs4_book", "gitbook", "html_book", "tufte_html_book"), render = FALSE )add_to_bookdown( bookdown_dir = ".", include_dir = "include", script_dir = "R", output_format = c("bs4_book", "gitbook", "html_book", "tufte_html_book"), render = FALSE )
bookdown_dir |
The base directory for your bookdown project |
include_dir |
The directory where you want to put the css and js files (defaults to "include") |
script_dir |
The directory where you want to put the .R script (defaults to "R") |
output_format |
The bookdown format you want to add webexercises to (defaults to "bs4_book") This is typically your default HTML format in the _output.yml file. |
render |
Whether to render the book after updating (defaults to FALSE). |
No return value, called for side effects.
Adds the necessary helper files to an existing pkgdown project.
add_to_pkgdown(pkgdown_dir = ".")add_to_pkgdown(pkgdown_dir = ".")
pkgdown_dir |
The base directory for your pkgdown project |
No return value, called for side effects.
Adds the necessary helper files to an existing quarto project and edits the _quarto.yml file accordingly. A demo file for webexercises will be added and optionally rendered.
add_to_quarto( quarto_dir = ".", include_dir = "include", output_format = c("html") )add_to_quarto( quarto_dir = ".", include_dir = "include", output_format = c("html") )
quarto_dir |
The base directory for your quarto project |
include_dir |
The directory where you want to put the css and js files (defaults to "include") |
output_format |
The format you want to add webexercises to (only html for now) |
No return value, called for side effects.
Adds the necessary 'YAML' metadata to an existing 'Quarto' or 'Rmarkdown' file.
add_to_quarto_file(filename) add_to_rmarkdown_file(filename)add_to_quarto_file(filename) add_to_rmarkdown_file(filename)
filename |
The name of the file to edit. |
No return value, called for side effects.
Creates a new directory with the file name and copies in a demo qmd file and the necessary helper files.
create_quarto_doc(name = "Untitled", open = interactive())create_quarto_doc(name = "Untitled", open = interactive())
name |
Name of the new document |
open |
Whether to open the document in RStudio |
The file path to the document
Escape a string for regex
escape_regex(string)escape_regex(string)
string |
A string to escape. |
A string with escaped characters.
escape_regex("library(tidyverse)")escape_regex("library(tidyverse)")
Create a fill-in-the-blank question
fitb( answer, width = min(100, max(nchar(answer))), num = NULL, ignore_case = FALSE, tol = NULL, ignore_ws = TRUE, regex = FALSE )fitb( answer, width = min(100, max(nchar(answer))), num = NULL, ignore_case = FALSE, tol = NULL, ignore_ws = TRUE, regex = FALSE )
answer |
The correct answer (can be a vector if there is more than one correct answer). |
width |
Width of the input box in characters. Defaults to the length of the longest answer, with a minimum of 100 characters. |
num |
Whether the input is numeric, in which case allow for leading zeroes to be omitted. Determined from the answer data type if not specified. |
ignore_case |
Whether to ignore case (capitalization). |
tol |
The tolerance within which numeric answers will be
accepted; i.e. if |
ignore_ws |
Whether to ignore whitespace. |
regex |
Whether to use regex to match answers (concatenates all answers with '|' before matching). |
Writes html code that creates an input box widget. Call this function inline in an RMarkdown document. See the Web Exercises RMarkdown template for examples of its use in RMarkdown.
A character string with HTML code to generate an input box.
# What is 2 + 2? fitb(4, num = TRUE) # What was the name of the Beatles drummer? fitb(c("Ringo", "Ringo Starr"), ignore_case = TRUE) # What is pi to three decimal places? fitb(pi, num = TRUE, tol = .001)# What is 2 + 2? fitb(4, num = TRUE) # What was the name of the Beatles drummer? fitb(c("Ringo", "Ringo Starr"), ignore_case = TRUE) # What is pi to three decimal places? fitb(pi, num = TRUE, tol = .001)
Create button revealing hidden content
hide(button_text = "Solution")hide(button_text = "Solution")
button_text |
Text to appear on the button that reveals the hidden content. |
Writes HTML to create a content that is revealed by a
button press. Call this function inline in an RMarkdown
document. Any content appearing after this call up to an inline
call to unhide() will only be revealed when the user
clicks the button. See the Web Exercises RMarkdown Template for
examples.
A character string containing HTML code to create a button that reveals hidden content.
unhide
# default behavior is to generate a button that says "Solution" hide() # or the button can display custom text hide("Click here for a hint")# default behavior is to generate a button that says "Solution" hide() # or the button can display custom text hide("Click here for a hint")
Longer MCQs with Radio Buttons
longmcq(opts)longmcq(opts)
opts |
Vector of alternatives. The correct answer is the element(s) of this vector named 'answer'. |
Writes html code that creates a radio button widget, with a single correct answer. This is more suitable for longer answers. Call this function inline in an RMarkdown document. See the Web Exercises RMarkdown template for further examples.
A character string containing HTML code to create a set of radio buttons.
# What is a p-value? opts <- c( "the probability that the null hypothesis is true", answer = paste("the probability of the observed, or more extreme, data", "under the assumption that the null-hypothesis is true"), "the probability of making an error in your conclusion" ) longmcq(opts)# What is a p-value? opts <- c( "the probability that the null hypothesis is true", answer = paste("the probability of the observed, or more extreme, data", "under the assumption that the null-hypothesis is true"), "the probability of making an error in your conclusion" ) longmcq(opts)
Create a multiple-choice question
mcq(opts)mcq(opts)
opts |
Vector of alternatives. The correct answer is the element(s) of this vector named 'answer'. |
Writes html code that creates an option box widget, with one or more correct answers. Call this function inline in an RMarkdown document. See the Web Exercises RMarkdown template for further examples.
A character string with HTML code to generate a pull-down menu.
# How many planets orbit closer to the sun than the Earth? mcq(c(1, answer = 2, 3)) # Which actor played Luke Skywalker in the movie Star Wars? mcq(c("Alec Guinness", answer = "Mark Hamill", "Harrison Ford"))# How many planets orbit closer to the sun than the Earth? mcq(c(1, answer = 2, 3)) # Which actor played Luke Skywalker in the movie Star Wars? mcq(c("Alec Guinness", answer = "Mark Hamill", "Harrison Ford"))
Convenience function for creating a basic quiz in HTML format from the arguments captured by '...', where the type of each question is determined automatically from the class of the arguments.
quiz(..., title = "Quiz", show_box = TRUE, show_check = TRUE)quiz(..., title = "Quiz", show_box = TRUE, show_check = TRUE)
... |
Each argument should be a named vector, see Details. |
title |
Atomic character, default: 'Quiz' |
show_box |
Logical, whether or not to draw a box around the quiz. Default: 'TRUE' |
show_check |
Logical, whether or not to show a button to check answers. Default: 'TRUE' |
The function renders questions captured by the arguments in '...'. The name of each argument is the text of the question. The value of each argument determined the question type and its correct answer. The following types of questions are supported:
The argument should be a single value of type 'logical', e.g.: '"The answer to this question is true." = TRUE'
The argument should be a vector of type 'character'. The first element is taken as the correct answer; the order of answers is randomized. E.g.: '"This multiple choice question has three answers." = c("Correct", "Incorrect", "Not sure")'
The argument should be of type 'numeric'. If the vector is atomic, the first element is taken as the correct answer, e.g.: '"Provide an exact floating point answer of 0.81" = 0.81'. If the vector has two elements, the second element is taken as the tolerance 'tol', e.g.: '"Here, 0.8 will be correct." = c(0.81, 0.01)'. If the vector is of type 'integer', the tolerance is set to zero, e.g.: '"The answer is 4." = 4L'
Alternatively, '...' may contain a single atomic character referring to a text file that contains the questions, see examples.
'NULL', this function is called for its side effect of printing HTML code using 'cat()'.
# Quiz from arguments: invisible(capture.output( quiz( "The answer to this question is true." = TRUE, "This multiple choice question has three answers." = c("Correct", "Incorrect", "Not sure"), "Provide an exact floating point answer of 0.81" = 0.81 ) )) # From a file: quiz_file <- tempfile() writeLines( c("The answer is true. = TRUE", "The answer is correct = c(answer = \"Correct\", \"Incorrect\", \"Not sure\")", "The answer is exactly .81 = 0.81", "But here, .8 is also fine = c(0.81, .01)", "Here, answer exactly 4. = 4L") , quiz_file) invisible(capture.output(quiz(quiz_file)))# Quiz from arguments: invisible(capture.output( quiz( "The answer to this question is true." = TRUE, "This multiple choice question has three answers." = c("Correct", "Incorrect", "Not sure"), "Provide an exact floating point answer of 0.81" = 0.81 ) )) # From a file: quiz_file <- tempfile() writeLines( c("The answer is true. = TRUE", "The answer is correct = c(answer = \"Correct\", \"Incorrect\", \"Not sure\")", "The answer is exactly .81 = 0.81", "But here, .8 is also fine = c(0.81, .01)", "Here, answer exactly 4. = 4L") , quiz_file) invisible(capture.output(quiz(quiz_file)))
This convenience function can be called within an 'Rmarkdown' document to add the 'css' and 'JavaScript' code required for webexercises' html output.
rmd_webex_support()rmd_webex_support()
Character string of class 'HTML'.
invisible(rmd_webex_support())invisible(rmd_webex_support())
Round up from .5
round2(x, digits = 0)round2(x, digits = 0)
x |
A vector of numeric values. |
digits |
Integer indicating the number of decimal places ('round') or significant digits ('signif') to be used. |
Implements rounding using the "round up from .5" rule,
which is more conventional than the "round to even" rule
implemented by R's built-in round function.
A vector of rounded numeric values.
round2(c(2, 2.5)) # compare to: round(c(2, 2.5))round2(c(2, 2.5)) # compare to: round(c(2, 2.5))
Strip leading zero from numeric string
strip_lzero(x)strip_lzero(x)
x |
A numeric string (or number that can be converted to a string). |
A string with leading zero removed.
strip_lzero("0.05")strip_lzero("0.05")
Change webexercises widget style
style_widgets( incorrect = "#983E82", correct = "#59935B", highlight = "#467AAC" )style_widgets( incorrect = "#983E82", correct = "#59935B", highlight = "#467AAC" )
incorrect |
The colour of the widgets when the answer is incorrect (defaults to pink #983E82). |
correct |
The colour of the widgets when the correct answer not filled in (defaults to green #59935B). |
highlight |
The colour of the borders around hidden blocks and checked sections (defaults to blue #467AAC). |
Call this function in an RMarkdown document to change the feedback colours using R colour names (see 'colours()') or any valid CSS colour specification (e.g., red, rgb(255,0,0), hsl(0, 100
If you want more control over the widget styles, please edit the webex.css file directly.
A character string containing HTML code to change the CSS style values for widgets.
style_widgets("goldenrod", "purple")style_widgets("goldenrod", "purple")
Create a true-or-false question
torf(answer)torf(answer)
answer |
Logical value TRUE or FALSE, corresponding to the correct answer. |
Writes html code that creates an option box widget with TRUE or FALSE as alternatives. Call this function inline in an RMarkdown document. See the Web Exercises RMarkdown template for further examples.
A character string with HTML code to generate a pull-down menu with elements TRUE and FALSE.
# True or False? 2 + 2 = 4 torf(TRUE) # True or False? The month of April has 31 days. torf(FALSE)# True or False? 2 + 2 = 4 torf(TRUE) # True or False? The month of April has 31 days. torf(FALSE)
End hidden HTML content
unhide()unhide()
Call this function inline in an RMarkdown document to mark the end of hidden content (see the Web Exercises RMarkdown Template for examples).
A character string containing HTML code marking the end of hiddent content.
hide
# just produce the closing </div> unhide()# just produce the closing </div> unhide()
Wraps use_vignette to add a vignette or article to 'vignettes/' with support for 'webexercises'.
use_webex_vignette(name, title = NULL, type = c("vignette", "article"))use_webex_vignette(name, title = NULL, type = c("vignette", "article"))
name |
Atomic character, vignette name. See use_vignette. |
title |
Atomic character, vignette title. See use_vignette. |
type |
Atomic character, one of 'c("vignette", "article")', defaults to '"vignette"'. |
Returns 'NULL' invisibly, called for its side effects.
## Not run: use_webex_vignette("vignette_with_quiz.Rmd", "Quiz people with webexercises") ## End(Not run)## Not run: use_webex_vignette("vignette_with_quiz.Rmd", "Quiz people with webexercises") ## End(Not run)
This function wraps rmarkdown::html_document to configure
compilation to embed the default webexercises CSS and JavaScript files in
the resulting HTML.
webex_vignette(...)webex_vignette(...)
... |
Additional function arguments to pass to
|
Call this function as the output_format argument
for the render function when compiling
HTML documents from RMarkdown source.
R Markdown output format to pass to 'render'.
# copy the webexercises 'R Markdown' template to a temporary file ## Not run: my_rmd <- tempfile(fileext = ".Rmd") rmarkdown::draft(my_rmd, "webexercises", "webexercises") # compile it rmarkdown::render(my_rmd, webexercises::webex_vignette()) # view the result browseURL(sub("\\.Rmd$", ".html", my_rmd)) ## End(Not run)# copy the webexercises 'R Markdown' template to a temporary file ## Not run: my_rmd <- tempfile(fileext = ".Rmd") rmarkdown::draft(my_rmd, "webexercises", "webexercises") # compile it rmarkdown::render(my_rmd, webexercises::webex_vignette()) # view the result browseURL(sub("\\.Rmd$", ".html", my_rmd)) ## End(Not run)
This function wraps rmarkdown::html_document to configure
compilation to embed the default webexercises CSS and JavaScript files in
the resulting HTML.
webexercises_default(...)webexercises_default(...)
... |
Additional function arguments to pass to
|
Call this function as the output_format argument
for the render function when compiling
HTML documents from RMarkdown source.
R Markdown output format to pass to 'render'.
# copy the webexercises 'R Markdown' template to a temporary file ## Not run: my_rmd <- tempfile(fileext = ".Rmd") rmarkdown::draft(my_rmd, "webexercises", "webexercises") # compile it rmarkdown::render(my_rmd, webexercises::webexercises_default()) # view the result browseURL(sub("\\.Rmd$", ".html", my_rmd)) ## End(Not run)# copy the webexercises 'R Markdown' template to a temporary file ## Not run: my_rmd <- tempfile(fileext = ".Rmd") rmarkdown::draft(my_rmd, "webexercises", "webexercises") # compile it rmarkdown::render(my_rmd, webexercises::webexercises_default()) # view the result browseURL(sub("\\.Rmd$", ".html", my_rmd)) ## End(Not run)