- Renamed the
exercise_submissionevent toexercise_resultand added the following fields:id- a randomly generated identifier that can be used to align with the associatedexercise_resultevent.time_elapsed- the time required to run the exercise (in seconds)timeout_exceeded- indicates whether the exercise was interrupted due to an exceeded timeout. May beNAfor some platforms/evaluators if that information is not known or reported. (#337)
- If a
-code-checkchunk returns feedback for an exercise submission, the result of the exercise is no longer displayed for a correct answer (only the feedback is displayed). If both the result and feedback should be displayed, all checking should be performed in a-checkchunk (i.e., don't provide a-code-checkchunk). (#403) random_praise()no longer includes the phrase Correct!. Instead, it returns a random praising statement. (#463, #453)
- Introduced "setup chunk chaining", which allows a setup chunk to depend on another setup chunk and so on, forming a chain of setup code that can be used for exercises via
exercise.setup. Runrun_tutorial("setup-chunks", "learnr")for a demo. (#390) - Introduced an experimental function
external_evaluator()which can be used to define an exercise evaluator that runs on a remote server and is invoked via HTTP. This allows all exercise execution to be performed outside of the Shiny process hosting the learnr document. (#345, #354) - For the "forked" evaluator (the default used on Linux), add a limit to the number of forked exercises that learnr will execute in parallel. Previously, this was uncapped, which could cause a learnr process to run out of memory when an influx of traffic arrived. The default limit is 3, but it can be configured using the
tutorial.max.forked.procsoption or theTUTORIAL_MAX_FORKED_PROCSenvironment variable. (#353) - Added a new
tutorial_options(), namelyexercise.error.checker, for customizing feedback when exercise submission code produces an evaluation error. This option accepts a function with the same arguments asexercise.checker. Usegradethis::grade_learnr_error()for a sensible default for this option. (#403) - Added an event handler system, with the functions
event_register_handler()andone_time(). There is also a new event"section_viewed", which is triggered when a new section becomes visible. (#398) - Previously, when a question submission was reset, it would be recorded as a
"question_submission"event with the valuereset=TRUE. Now it a separate event,"reset_question_submission". (#398) - Added a new
polyglottutorial to learnr. This tutorial displays mixing R, python, and sql exercises. Seerun_tutorial("polyglot", "learnr")for a an example. (#397) - Text throughout the learnr interface can be customized or localized using the new
languageargument oftutorial(). Translations for English and French are provided and contributes will be welcomed. Read more about these features invignette("multilang", package = "learnr"). (#456, #479) - When a "data/" directory is found in the same directory as the tutorial R Markdown document, it is now automatically made available within exercises. An alternative directory can be specified using the
tutorial.data_dirglobal option. (#539) - Messages generated by R during exercises are now translated to match the tutorial language, if translations are available. (#558)
- Tutorial authors can now access the current state of the user's progress in a tutorial with
get_tutorial_state()or get information about the current tutorial withget_tutorial_info(). (#562) - Tutorial state is now returned by
get_tutorial_state()in order of appearance in the tutorial. The full list of exercises and questions is included asitemsin the list returned byget_tutorial_info(). (#570, #571) - Users are now warned if their submission contains blanks they are expected to fill in. The default blank pattern is three or more underscores, e.g.
____. The pattern for blanks can be set with theexercise.blankschunk or tutorial option. (#547)
- Added an
exercise_submittedevent which is fired before evaluating an exercise. This event can be associated with anexercise_resultevent using the randomly generatedidincluded in the data of both events. (#337) - Added a
restoreflag onexercise_submittedevents which isTRUEif the exercise is being restored from a previous execution, orFALSEif the exercise is being run interactively. - Add
labelfield to theexercise_hintevent to identify for which exercise the user requested a hint. (#377) - Added
include=FALSEto setup chunks to prevent exercises from printing out messages or potential code output for those setup chunks. (#390) - Added error handling when user specifies a non-existent label for
exercise.setupoption with an error message. (#390) - We no longer forward the checker code to browser (in html), but instead cache it. (#390)
- We no longer display an invisible exercise result warning automatically. Instead, authors must set the exercise chunk option
exercise.warn_invisible = TRUEto display an invisible result warning message. (#373) exercise.capnow accepts HTML input. If noexercise.capis provided, an icon of the exercise engine will be displayed. If no icon is known, theexercise.capwill default to the combination of the exercise engine and" code". (#397, #429)engineis now passed to theexercise.checkerto help distinguish what language is being checked in the exercise. (#397)- Hitting the
TABkey in an exercise has always opened the auto-completion drop down. Now, hitting theTABkey will also complete the currently selected code completion. (#428) question_text()gainsrowsandcolsparameters. If either is provided, a multi-linetextAreaInput()is used for the text input. (#460, #455)- Feedback messages can now be an htmltools tag or tagList, or a character message (#458)
- Added an option to reveal [default] (or hide) the solution to an exercise. Set
exercise.reveal_solutionin the chunk options of a*-solutionchunk to choose whether or not the solution is revealed to the user. The option can also be set globally withtutorial_options(). In a future version of learnr, the default will be changed to hide solutions. (#402) - Added shortcuts for pipe (
Command/Control+Shift+M) and assignment (Alt+-) operators in exercise code boxes. (#472) - Added Spanish language support (@yabellini #483, #546)
- Added Portuguese language support (@beatrizmilz #488, #551)
- Added Basque language support (@mikelmadina #489)
- Added Turkish language support (@hyigit2, @coatless #493, #554)
- Added option for quickly restoring a tutorial without re-evaluating the last stored exercise submission. This feature is enabled by setting the global option
tutorial.quick_restore = TRUEor the environment variableTUTORIAL_QUICK_RESTORE=1(thanks @mstackhouse, #509). - Clicking "Run Code" or using the keyboard shortcut (Cmd/Ctrl + Enter) now runs the selected code only, if any code is selected (#512).
exercise_result()no longer combines the code output and feedback; this now happens just before presenting the exercise result to the user (#522).- Correct/incorrect question markers are now configurable via CSS. You can change or style these markers using the
.tutorial-question .question-final .correct::beforeand.tutorial-qusetion .question-final .incorrect::beforeselectors. A new helper function,finalize_question(), can be used to apply the.question-finalclass to custom learnr questions. (#531) options()and environment variables are now reset after rendering exercises so changes made by user input or checking code cannot affect other exercises. (#542)- Exercise checking is now conducted in the same temporary directory where exercises are evaluated. (#544)
- User submissions for R code exercises are now checked for parsing errors prior to any other checks. If the submitted code is unparsable, a friendly error feedback message is returned and no further evaluation or checking is performed. (#547)
- Support the updated Bootstrap 4+ popover
disposemethod name, previouslydestroy. (#560) - Properly enforce time limits and measure exercise execution times that exceed 60 seconds (#366, #368)
- Fixed unexpected behavior for
question_is_correct.learnr_text()wheretrim = FALSE. Comparisons will now happen with the original input value, not theHTML()formatted answer value. (#376) - Fixed exercise progress spinner being prematurely cleared. (#384)
- Updated
run_tutorial()to render tutorials in a temp directory if the R user does not have write permissions. (#347) - An informative error is now thrown when an exercise chunk's body contains nothing, which lets the tutorial author know that something (e.g., empty line(s)) must be present in the chunk body for it to be rendered as an exercise. (#410) (#172)
- When
exercise.completion=TRUE, completion is no longer performed inside of quotes. This (intentionally) prevents the student from being able to list files on the R server (#401). - Fail gracefully when unable to open an indexedDB store (e.g. in cross-origin iframes in Safari). (#417).
- When a quiz's question or answer text are not characters, e.g. HTML,
htmltoolstags, numeric, etc., they are now cast to characters for the displayed answer text and the quiz's default loading text (#450). - The
envir_prepenvironment used in exercise checking now captures the result of both global and exercise-specific setup code, representing the environment in which the user code will be evaluated as described in the documentation. We also ensure thatenvir_result(the environment containing the result of evaluating global, setup and user code) is a sibling ofenvir_prep. (#480) - HTML dependencies of exercises run by users now excludes dependencies created with
htmltools::tags$head(). (thanks @andysouth, #484) - Avoid selecting the answer labeled
"FALSE"by default inquestion_radio()(#515). - Custom CSS files are now loaded last, after all of learnr's other web dependencies. (#574)
-
learnrgained the functionlearnr::tutorial_package_dependencies(), used to enumerate a tutorial's R package dependencies. Front-ends can use this to ensure a tutorial's dependencies are satisfied before attempting to run that tutorial.learnr::available_tutorials()gained the columnpackage_dependenciescontaining the required packages to run the document. (#329) -
Include vignette about publishing learnr tutorials on shinyapps.io. (#322)
-
learnr's built-in tutorials now come with a description as part of the YAML header, with the intention of this being used in front-end software that catalogues availablelearnrtutorials on the system. (#312) -
Add
session_startandsession_stopevents. (#311)
-
Fixed a bug where broken exercise code created non-"length-one character vector". (#311)
-
Fixed extra parameter documentation bug for CRAN. (#323)
-
Fixed video initialization error caused by a jQuery version increase in Shiny. (#326)
-
Fixed progressive reveal bug where the next section would not be displayed unless refreshed. (#330)
-
Fixed a bug where topics would not be loaded if they contained non-ascii characters. (#330)
-
Quiz questions are implemented using shiny modules (instead of htmlwidgets). (#194)
-
Aggressively rerender prerendered tutorials in favor of a cohesive exercise environment (#169, #179, and rstudio/rmarkdown#1420)
-
Added a new function,
safe, which evaluates code in a new, safe R environment. (#174)
-
Added the last evaluated exercise submission value,
last_value, as an exercise checker function argument. (#228) -
Question width will expand to the container width. (#222)
-
Available tutorial names will be displayed when no
nameparameter or an incorrectnameis provided torun_tutorial(). (#234) -
The
optionsparameter was added toquestionto allow custom questions to pass along custom information. Seesortable::sortable_questionfor an example. (#243) -
Missing package dependencies will ask to be installed at tutorial run time. (@isteves, #253)
-
When questions are tried again, the existing answer will remain, not forcing the user to restart from scratch. (#270)
-
A version number has been added to
question_submissionevents. This will help when using custom storage methods. (#291) -
Tutorial storage on the browser is now executed directly on
indexedDBusingidb-keyval(droppinglocalforage). This change prevents browser tabs from blocking each other when trying to accessindexedDBdata. (#305)
-
Fixed a spurious console warning when running exercises using Pandoc 2.0. (#154)
-
Added a fail-safe to try-catch bad student code that would crash the tutorial. (@adamblake, #229)
-
Replaced references to
checkthatandgraderin docs with gradethis (#269) -
Removed a warning created by pandoc when evaluating exercises where pandoc was wanting a title or pagetitle. #303
-
Fixed #136 by displaying full HTML messages (rather than just the text) if provided by the
incorrector thecorrectargs toquestion(). (#146) -
Improved documentation for deploying
learnrtutorials in Shiny Server. (#142) -
Fixed a highlight.js issue from rmarkdown 1.8. (#133)
-
Fixed an false positive in the diagnostics system. (#141)
- Fixed a compatibility issue, so that existing tutorials don't break when using Pandoc 2.0. (#130)
@ commit #14413cc
@ commit #eeae534
@ commit #b71c637
@ commit #55c33cf
@ commit #a853163
@ commit #3339f8a
@ commit #9cd0082
@ commit #a81a694
init commit! #e2dbb20