Changes in version 2.4-4 - All LaTeX templates gained a new counter {none} and corresponding \LTcaptype{none} which is employed by pandoc starting from version 3.8.2 for {longtable} without caption (see https://github.com/jgm/pandoc/issues/11201). - In answerlist() the markup argument was erroneously ignored and overwritten by match_exams_markup() in version 2.4-3 (reported by Jon Olav Vik). - In exams2canvas(..., solutionswitch = TRUE) (default) the solution section is now also shown in case of partially correct answers and not just fully correct or fully incorrect answers (as reported in https://stackoverflow.com/questions/79911350/). - MIME type handling for Base 64 coding of commonly-used audio and video file formats has been added (e.g., mp3, mp4, etc.) Changes in version 2.4-3 (2025-12-23) - New convenience functions for keeping track of all elements within an exercise (especially in cloze exercises): add_cloze() and format_metainfo(). These are particularly helpful for creating relatively simple exercises or tutorials where the elements are fixed or computed from a given data set etc. See help("add_cloze", package = "exams") for documentation and the new penguins.Rmd (or penguins.Rnw) exercise for a worked example. - Added first release version of new interface exams2ans() for the Dutch testing platform Ans. It is essentially a wrapper to exams2qti21() along with a few Ans-specific modifications of the QTI XML specification. The function has only received limited testing so far and is likely to improve in future versions. All five item types are supported but cloze questions can only consist of num and string combinations or mchoice and schoice combinations. The work on the function was financially supported by the Dutch National Growth Fund Programme Npuls (Regulation 'IO: 112026'). - Added first release version of new interface exams2wooclap() for Wooclap, a digital voting system for creating interaction during teaching moments. It is essentially a wrapper to exams2moodle() along with a few Wooclap-specific tweaks. The function has only received limited testing so far and is likely to improve in future versions. The supported exercise types are num, schoice, mchoice, and string (but only limited support for cloze questions). The work on the function was financially supported by the Dutch National Growth Fund Programme Npuls (Regulation 'IO: 112026'). - In nops_fix(..., display = "interactive") there is now also a checkbox for rotating the PNG of a scanned sheet. - In exams2pdf() the handling of duplicated graphics file names now also works for pandoc versions 3.2.1 or greater. Previously, the addition of \pandocbounded{} interfered with the correct handling (reported by Delia Gramm). - Added support for \pandocbounded{} (as well as some other LaTeX packages) in the default template for exams2pandoc(), mirroring changes that had been done in earlier versions for the exams2pdf() and exams2nops() templates (reported in https://stackoverflow.com/questions/79829958/). - In the manual page ?exams2ilias it is now explained rather explicitly that many features of the resulting QTI exports cannot be imported correctly into recent versions of ILIAS. Any ILIAS users who have some experience in QTI XML who would be willing to help with the R/exams interface are encouraged to get in touch. - In exams2moodle(), exams2qti12() (and hence also in exams2canvas()), and exams2qti21() (and hence also in exams2openolat()) the argument seed has been added and is simply passed on to xexams(). This allows to fix the random seeds for generating the exercise pools in these functions. - New arguments exams2nops(..., shortquiz = FALSE, filbreak = FALSE). With shortquiz = TRUE it is possible to create a short quiz that contains the questions directly at the bottom of a single exam sheet. Setting filbreak = TRUE a potential page break can be added at the beginning of each question, so that it is more likely that all parts of a question appear on the same page. - Additional NOPS language support: Basque (eu, contributed by Jone Guenetxea Gorostiza & Iker Apraiz Sánchez). - In exams2nops() the \usepackage[utf8]{inputenc} is not included anymore in order to facilitate setting texengine = "xelatex" or "lualatex". The setting is also not needed anymore in pdfLaTeX because it is the default since 2018. - In exams2nops(..., language = "de") the latest new German hyphenation patterns are loaded by \babelprovide[hyphenrules=ngerman-x-latest]{ngerman} (raised by Florian Hauser). - Examples from the manual page of exams2nops() are now excluded from the CRAN checks because they can sometimes take more than 5 seconds depending on the LaTeX setup. Instead a dedicated tests/exams2nops.R test file is included now. - MIME type handling for Base 64 coding of supplementary files has been improved. Some more MIME types have been added to the lookup table and text vs binary guessing has been added for unknown file types. - The handling of | symbols in the exsolution meta-information has been improved somewhat. The code still aims to support exsolution values containing regular expressions but is somewhat more robust compared to the previous version. However, there are still limitations and future improvements are planned. Users who run into problems with | in the exsolution are encouraged to get in touch. - Numeric values in the meta-information of R/Markdown exercises are now recovered more reliably, even when knitr switches to scientific notation by default (reported by Delia Gramm). - The pointvec() function set up by exams_eval(partial = TRUE, ...) now warns when it is applied to mchoice answers without correct answer alternatives (because it is impossible to attain any credits in that case). - In exams2qti21() (and hence also exams2openolat()) it is now assured that essay and file interactions in cloze exercises are always outside of a paragraph. - New function match_exams_markup() can be used within an exercise to use the same text markup ("markdown" vs. "latex") that xweave() is using. - New argument answerlist(..., write = TRUE) which can be set to FALSE in order to return the answerlist text, rather than writing it to the output. - HTML and Markdown converters now try harder to preserve file names in download links when encoding supplementary files in Base64. - In nops_scan() the shaving of long text above the exam ID box is improved (reported in https://stackoverflow.com/questions/79835752 by Florian Oswald). Furthermore, an informative error is thrown now if the scanner markings cannot be found when reading a PNG file (reported by Filipe Alberto). - Bug fix in nops_eval() for exams with string scans and duplicated exam IDs. Now the duplicates are dropped prior to evaluation along with a warning. Previously, the string scans were erroneously omitted (reported in https://stackoverflow.com/questions/79838688 by Samuel Merk). - In answerlist() the default markup is now determined via match_exams_markup() (rather than using "latex"). Changes in version 2.4-2 (2025-04-29) - Bug fix in exams2moodle() for cloze exercises: The rule was erroneously applied not only to to mchoice but also to schoice elements within cloze exercises. Hence incorrect answers in schoice elements were erroneously penalized with negative points by default (reported in https://stackoverflow.com/questions/79235737/ by Beatriz Lacruz Casaucau and in https://R-Forge.R-project.org/forum/message.php?msg_id=50046 by Błażej Kochański and in https://R-Forge.R-project.org/forum/message.php?msg_id=50063 by Martin Spott). - Support of string scans in nops_fix(). Moreover, a new option nops_fix(display = "interactive") was added where all data from a scanned sheet can be edited interactively in the browser (contributed by Sebastian Bachler). The latter is particularly useful if scanned sheets are too rotated to be read at all in nops_scan(). Finally, the rotation of PDF pages is always done relatively (rather than absolutely) in order to enable merging PDF files with different original orientations. - Improvements in nops_scan() to read the registration id somewhat more reliably in the presence of scanning artefacts (e.g., single white lines through a check box). Also scanner markings are found more reliably when the bottom margin is smaller than in the PDF from exams2nops(). And the top left scanner marking is approximated in case it is missing in the sheet for some reason. Finally, the rotate = TRUE option also works for PNG and not just PDF input. - Improvement in nops_eval(..., interactive = TRUE): If changes are made in the scans or string_scans files, then the original files are overwritten in the original directory rather than the working directory (reported by Chat Wacharamanotham). - In exsolution the | can now not only be used as the separator symbol for multiple solutions in a cloze exercise but additionally within the solutions. This is useful for example when the answer string is a regular expression. In this case the | has to be within round brackets (and possibly ^ and/or $), e.g., exsolution: ^(OLS|ML)$|01001. This gets interpreted as two elements with values ^(OLS|ML)$ and 01001. - In exams2pdf() the convenience argument usepackage = NULL was added. If specified with a character string, e.g., usepackage = "pdfpages", then "\\usepackage{pdfpages}" is added to the header argument. - The default header argument in exams2pdf() is now empty (NULL) so that all LaTeX templates shipped with the package (in particular plain.tex) could be augmented with a %% \exinput{header} placeholder. - The {Sweave} LaTeX package is no longer loaded in the LaTeX templates (like plain.tex, exams.tex, solution.tex, etc.). Instead the LaTeX environments for displaying R code and the accompanying LaTeX dependencies are loaded directly. Moreover, {xcolor} is used instead of {color}. - New demo exercise flags.Rmd/flags.Rnw added to the package, containing a single-choice knowledge quiz question about flags of countries around the world. The flags are displayed using Unicode characters unless PDF output is produced via LaTeX (using exams2pdf() or exams2nops()). In the latter case the {worldflags} LaTeX package is needed for compilation which can be added now via usepackage = "worldflags" in exams2pdf() (see above) as well as exams2nops(). - New demo exercise sumdiff.Rmd/sumdiff.Rnw added to the package, providing a minimal arithmetic task where the sum of two random numbers minus their difference has to be calculated. This exercise can demonstrate drawing random numbers where the correct solution is not completely obvious but can still be easily obtained with mental arithmetic. Also, no LaTeX markup is used. Hence the exercise is much simpler than deriv.Rmd/deriv.Rnw. - New argument exams2nops(..., helvet = TRUE). By default, exams2nops() uses a Helvetica font via the LaTeX packages {helvet} and {sfmath} (with helvet option). This can optionally be suppressed now (suggested by Bruce James in https://stackoverflow.com/questions/79545467/). - Improved num_to_schoice() by adding several new arguments but making their defaults backward compatible (based on suggestions from Stefan Jansen and Reto Stauffer). - format = TRUE: Should the question list be formatted to a character vector with LaTeX math markup (default)? Alternatively, the question list can be numeric (format = FALSE or "numeric") or a formatted character vector without LaTeX math markup (format = "character"). - order = getOption("num_to_schoice_order", FALSE): Should the question list be ordered numerically? If FALSE (default) the question list is shuffled randomly. - maxit = getOption("num_to_schoice_maxit", Inf): Maximum number of iterations to try to find a feasible set of wrong solutions for the question list. Moreover, the option for setting the verbose default was changed to getOption("num_to_schoice_verbose", TRUE) instead of the previous name "num_to_choice_warnings" for consistency. - When running exercises via knitr::knit() warnings are now reported to the console rather than being suppressed. This is achieved by setting knitr::opts_chunk$set(warning = NA) which was actually intended in the corresponding change in R/exams 2.4-0 where the default error = FALSE was implemented. If any exercise wants to change the behavior it can set another chunk option (either for individual chunks or for the entire exercise). - New argument stop_on_error in stresstest_exercise(). This is particularly useful when stresstesting a collection of exercises without stopping on each error but instead recordings all warnings and errors for inspecting them later. Additionally, a timeout argument can be set that sets a time limit for running each exercises, e.g., to avoid running into infinite loops etc. Finally, maxit is set by default to -10000 so that num_to_schoice() (if used at all) can use at most 10000 iterations to find a feasible question list (and stops with an error otherwise). - Added a warning in exams2arsnova() and make_exams_write_arsnova() that these functions will be removed in future versions of the package. The reason is that ARSnova has been superseded by Particify and hence it is recommended to transition to exams2particify(). - Changed default HTML/mathematics converter in exams2canvas() to converter = "pandoc-mathjax" (rather than enforcing MathML output as before). Recent versions of Canvas have improved MathJax support (see Canvas Release Notes 2021-02-20) and employing MathJax in the Canvas quiz might facilitate importing the quiz into a Canvas question bank (reported and tested by Jeff Pisklak). - Additional NOPS language support: Catalan (ca, contributed by Paco Rivière). - In exams2pdf() an empty getOption("pdfviewer") is now caught with an informative error (raised in https://stackoverflow.com/questions/79100895/). - Function match_exams_iteration(), introduced in the previous versions, was erroneously not exported from the NAMESPACE, added now. - Fixed long-standing bug in boxplots exercise. In rare cases (about once in 2,000 random versions) the exercises claimed that there were outliers in the plot when in fact there were none (reported by Gabriele Cantaluppi). Also, the explanation for outliers is now aligned with that of non-outliers being more/less than 1.5 times the IQR from the box, rather than the median (reported by Stefan Jansen). - All Rmd exercise templates with embedded graphics have been slightly simplified. The lines with just \ before the figure code chunks have been replaced with empty lines. Initially, the \ lines had been necessary to suppress figure captions but this has not been necessary anymore for a long time. - Improve handling of duplicated textattachmentfile names in exams2pdf() (reported by Francisco Goerlich). - In exams2moodle(..., cloze = list(enumerate = FALSE)) (the default since version 2.4-1) elements of questionlist did not get any formatting, they are paragraphs now (reported by Błażej Kochański). - In exams2canvas() for cloze exercises with multiple schoice interactions (rendered as multiple dropdown selections), the question list items are now converted to plain text (rather than HTML) because no HTML rendering is available in the Canvas dropdown selections (reported by Chad Worley). Note that this might work correctly but formatting (especially for mathematical notation) will be lost. - The default QTI 1.2 template in exams2canvas() (namely canvas_qti12.xml) now declares the xmlns etc. for the tag which may sometimes help in the import in Canvas (suggested by Andrew Leach). - When read_exercise() is applied to cloze exercises including schoice/mchoice elements and using a numeric exshuffle value, then no warning is issued if exshuffle is greater than some choice lists - as long as there is at least one choice list with length at least as long as exshuffle (suggested by Delia Gramm). Changes in version 2.4-1 (2024-07-10) - New function nops_fix() that can be applied to the ZIP file resulting from nops_scan(). By default it goes through all rows of the scanned data and interactively prompts for updates to fields from the scanned exam sheets that need updating. Optionally, the user can specify the rows of the scanned data and/or the fields that should be updated. - By default, nops_scan() now relies on the R packages qpdf and magick for merging/rotating/splitting PDF files and converting them to PNG, respectively. Thus, the system requirements of PDFTk (pdftk) and ImageMagick (convert), respectively, are not necessary anymore for scanning NOPS exams. However, for a transition period the old system calls for PDFTk/ImageMagick are still used when the R packages qpdf and/or magick are not available. - The default evaluation rule in exams2moodle() and all QTI-based exams2xyz() interfaces (e.g., exams2blackboard(), exams2canvas(), exams2openolat(), etc.) is now consistently partial = TRUE and negative = FALSE (as in previous versions) and rule = "false2". This was already the default rule in most scenarios in previous versions. But for mchoice elements within cloze exercises it often was "none" (i.e., no negative points even when partial credits were used) which has been changed to the more commonly-used rule = "false2" now. (Reported by Hans-Peter Schröcker.) - In exams2qti21() (and thus also in exams2openolat()) fractional points are now rounded up (if necessary) at eight decimal places. Otherwise the cutvalue might not be attained, especially for partial = FALSE. (Reported by Thomas Fetz.) - Convenience extension for cloze exercises with elements embedded by ##ANSWERi## tags: The "Answerlist" only has to be specified if there are schoice/mchoice elements, otherwise it can be omitted. For exercises with mixed elements, the "Answerlist" only has to specify the entries of the schoice/mchoice elements while the empty entries for all other num or string/essay/file elements can optionally be omitted. - New standard meta-information types exauthor and extags. The latter is for tagging an exercise so that it can eventually be filtered, grouped, etc. A typical example for an extags is extags: poisson which could signal that an exercise is related to the Poisson distribution. Note that this might complement the hierarchical exsection meta-information which can be used for hierarchical grouping, e.g., exsection: regression/glm/poisson. Finally, extags can define tag classes/group by adding a = as in extags: grade=2 or extags: stage=advanced etc. Multiple tags can be separated by |. - In schoice and mchoice questions an error (rather than just a warning) is thrown when the lengths of the question list and the exsolution do not match. Also, the reading of question lists is more robust now for Markdown exercises. - New convenience function match_exams_iteration() that can be used within an exercise to query the current iteration (within n replications), e.g., to always cycle through the same finite set of parameters. - Improvement in nops_scan() when finding the bottom markings of the scan. A smaller minimal bottom margin is assumed (3% instead of 7%) in order to better deal with different paper formats, specifically letter paper (reported by Perry de Valpine). - Improvement in nops_eval() so that for schoice questions no partial credits are used even if they are enabled for mchoice questions in the eval specification. - Additional NOPS language support: Bulgarian (bg, contributed by Nikolay Rachev) and Polish (pl, contributed by Paweł Kleka). Corrections in French (fr, contributed by Jean-Philippe Georget), Russian (ru, contributed by Nikolay Rachev), and Spanish (es, contributed by Flavio Lozano Isla). - Various exams2xyz() interfaces gained arguments envir = NULL and/or engine = NULL. Both are passed on to xweave(). The envir argument can be used to control in which environment all exercises are processed in case knitr is used. The engine argument specifies whether "Sweave" (default) or "knitr" is used for rendering Rnw exercises. These arguments have been added in: exams2arsnova(), exams2blackboard(), exams2grasple(), exams2html(), exams2lops(), exams2moodle(), exams2pandoc(), exams2qti12() (and hence interfaces based on it like exams2canvas()), exams2qti21() (and hence interfaces based on it like exams2openolat()), exams2testvision(). - In Rmd exercises only the meta-information tags (extype, exsolution, etc.) from the Meta-information are read. If the same tags occur elsewhere in the file they are ignored now. (Reported by Joan Sanz.) - Include better table formatting by default in exams2moodle(). Styles table = "table_shade", "table_rule", and "table_grid" had already been available since version 2.4-0, but table = "table_shade" is now the new default. Alternatively, users can also set a custom table class and then use the css argument for controlling the rendering of that class. - In exams2moodle(), exams2testvision(), exams2qti12(), and exams2qti21() (and all interfaces built on top of these like exams2openolat()) the default is now enumerate = FALSE (rather than TRUE) so that single-choice and multiple-choice answers are not listed with letters a., b., c., ... The default was changed because it produces questions with less "clutter" but may make it a little bit harder to match solution lists in the feedback to the item lists in the question. - In exams2moodle() the string elements in cloze exercises now also correctly support the usecase = TRUE option (reported by Joan Sanz). - In exams2moodle() the eval for schoice exercises is now correctly processed in case of negative points (reported in 78581471 on StackOverflow). - In both matrix_to_schoice() and matrix_to_mchoice() the handling of vector (rather than matrix) inputs is improved. In this case the question list shows only a single index for the chosen element(s) rather than row and column indexes (suggested by Thomas Fetz). - Further improved name handling in exams2qti21() (and thus also in exams2openolat()): Periods in file names are avoided (like spaces and leading integers) as OpenOlat otherwise cannot read the file (reported by Andrea Erhart). - The default in exams2particify() was changed to fix_choice = FALSE because most Particify systems in use will probably support the math rendering in answer options now. So the fixup does not need to be enabled by default. Also, the function now tries to assure Unix-style linebreaks on Windows systems because the default Windows linebreaks could lead to problems with reading the correct answers. - New argument exams2nops(..., newpage = FALSE). If set to TRUE a page break (\newpage in LaTeX) is added after every exercise. - The logo in exams2nops(..., logo = ...) can now also be a relative path (relative to the working directory). Also logo = "uibk" is supported as a convenience option for including the logo of Universität Innsbruck. - The exam type in exams2nops() now codes the number of exercises directly (rather than rounding the number to multiples of 5). This facilitates fixing the correct number of questions in nops_fix(). - The answer lists in exams2nops() are now labeled \alph{enumii}. rather than (\alph{enumii}). Also the main exam sheet also uses \alph{} with a custom counter to label the check boxes for the answers. - When converting exercises with a converter based on make_exercise_transform_pandoc() to Markdown with Base64 output, graphics in tags are now correctly encoded as well. - In all QTI-based interfaces (and also exams2moodle()) with exams2xyz(..., mchoice = list(enumerate = FALSE)) the solutionlist (if any) is formatted as an unordered list (rather than without any formatting). - It is now also possible to extract the meta-information from the output of xexams() and all exams2xyz() interfaces as a data.frame (rather than a list of lists) via exams_metainfo(..., class = "data.frame"). - Scientific notation produced by knitr is now correctly converted to numeric when reading the meta-information. (Reported in questions 61254298 and 75766543 on StackOverflow.) - The (total) number of points in exams2blackboard() is now formatted as %.3f rather than %d.0 so that it can also be fractional (with up to three decimal places) rather than integer. - Various improvements in exams2testvision(), especially for cloze exercises combining various types of questions. In particular, a bug was fixed for cloze exercises with ##ANSWERi## tags which lead to unbalanced
tags in previous versions. - Added support for \pandocbounded{} (as produced by pandoc starting from version 3.2.1) in all current LaTeX templates as well as exams2nops(). Currently, \pandocbounded{} does not anything in the exams templates so that the size of the graphics in PDF output still has to be controlled in one of the previously available ways (e.g., within the exercises, via the exams2xyz() interface, or via the Gin key in the LaTeX template). - In read_metainfo() a warning is now issued if exclozetype is specified in the metainformation but extype is not cloze (suggested by Matthias Gondan). Changes in version 2.4-0 (2022-10-17) - Switched the entire package to support UTF-8 encodings by default for all exercises types. Previously, this was only the case for .Rmd exercises due to the UTF-8 requirement of pandoc (which is now a system requirement for exams). All templates etc. have been modified to support UTF-8 out-of-the-box. Support for all other encodings like ISO-8859-* (latin1, latin9, etc.), which had previously been available for .Rnw exercises in certain interfaces, has been disabled. While this reduces the functionality of the package slightly, it greatly facilitates working with UTF-8 which appears to be predominantly used in practice. Documentation also becomes easier/clearer. - To facilitate working with .Rmd exercises and embedded graphics or data files base64enc, knitr, and rmarkdown are now imported in the package (and not just suggested). - Several extensions in exams2qti21() (and thus inherited by exams2openolat()) that provide more control and options in the assessments. - Improved processing of the cutvalue (for passing a test/exam/quiz). By default, this is cutvalue = NULL (or equivalently cutvalue = NA) which means that no pass/fail status is computed at all, i.e., only the sum of the points is reported. Moreover, cutvalue may be a float now and is not coerced to an integer anymore (also applied in exams2qti12()). - New argument navigation = "nonlinear". This can be switched to "linear" enforcing that questions in the test must be answered sequentially while the default "nonlinear" means that participants can switch back and forth between questions. - New argument selection = "pool" that controls how exercises and sections are sampled. By default, the function creates one section for each exercise from which one replication will be selected in the exam. If selection = "exam" each section contains all questions and one section will be selected for the exam. The "exam" variant has the advantage that nsamp can be fully used now and that questions that build on each other can be used in the exam. - New argument shufflesections = FALSE can be set to TRUE in order to randomly shuffle the order of sections/exercises for each participant. For selection = "pool" this corresponds to shuffling the sections that contain the pools of exercises. For selection = "exam" it corresponds to shuffling the exercises within each exam section. - New argument cloze_schoice_display = "auto" that controls the display of schoice elementsin cloze exercises. By default, radio "buttons" are used if the answer list appears in its own paragraph and a "dropdown" menu is used if the answer list appears inline (and has no mathematical markup). Both options can also be enforced explicitly, independently from the answer list appearing in a separate paragraph or inline. - New argument allowskipping = TRUE controlling whether exercises can be skipped without answering (default) or must be answered. - New argument allowreview = FALSE controlling whether exercises can be viewed again at the end of a test/exam. - New argument allowcomment = FALSE can be set to TRUE to allow comments. - New argument casesensitive = TRUE that controls whether the evaluation of string exercises is case sensitive or not. - The default stitle (section title) and ititle (item title) are now NULL so that items are simply numbered consecutively (1, ..., n) and section titles are omitted. - Similarly, the default sdescription is now empty omitting the section description as it is typically not necessary. - If solutionswitch = TRUE and maxattempts != 1 a warning is issued now. This is because with more than one attempt participants could otherwise copy the solution shown after an incorrect first attempt. - Also maxattempts can now be a vector so that different numbers of attempts per question are allowed for different sections/questions. - An extended list of configuration options for OpenOlat assessments is now provided through the argument config = TRUE in exams2openolat(). The logical specification config = TRUE/FALSE uses the default configuration or switches off the extra configuration entirely, respectively. Moreover, a list of options like config = list(cancel = TRUE, scoreprogress = TRUE) can be provided for customizing how OpenOlat renders the QTI 2.1 content. - Several extensions for cloze questions in exams2moodle(): - mchoice elements in cloze questions are now properly supported. By default they are shown as MULTIRESPONSE checkboxes and employ Moodle's default evaluation strategy where each incorrect box eliminates one correct box. A different evaluation strategy can, in principle, be chosen but Moodle might not process all negative points correctly. - schoice elements in cloze questions are still rendered as MULTICHOICE drop-down menus by default unless they contain math markup. As this is not rendered by Moodle in drop-down menus, a MULTICHOICE_V column of radio buttons is used in this case. - To allow for customization of both mchoice and schoice elements in cloze questions, the are now both cloze_mchoice_display and cloze_schoice_display arguments. This is not fully backward compatible because in previous versions cloze_mchoice_display was also used to customize schoice elements. Now a warning is issued in this case. - If choice items contained closing curly brackets, these would typically corrupt Moodle's embedded answers for cloze questions which relies on curly brackets. Hence, these are properly escaped now. - Similarly closing curly brackets in the solutions to string items (SHORTANSWER) needed to be properly escaped. - To fix the maximum width of fill-in-the-blank cells in num and/or string sub-items (e.g., when presented in a table), arguments numwidth and stringwidth have been added to make_question_moodle(). Alternatively, they can also be specified through exextra tags in each exercise. See the fourfold2 exercise for an example and ?make_question_moodle for more details. - For illustrating the new improved cloze capabilities in exams2moodle() and exams2qti21()/exams2openolat(), there is a new exercise "lm2" which combines all basic exercise types: num, schoice, mchoice, and string. Another extended version of this exercises, called "lm3", has also been added which adds essay (text editor) and file upload interactions (see also below). - Extended processing of string exercises for learning management systems like Moodle, OpenOlat, or other QTI-based systems. By default, string exercises are intended for closed-format short-text answers that have to be matched exactly by the participants. Additionally, open-ended text answers can now be enabled by setting the exstringtype meta-information to essay and/or file. The former requests a text editor for entering an answer while the latter requests a file upload dialogue. The "essayreg" exercise has been modified to leverage this new meta-information. - Similarly, the exclozetype meta-information now also accepts essay or file instead of string for elements of a cloze exercise. Currently, the combination of these types with num or schoice elements etc. is only possible for QTI-based systems (i.e., OpenOlat in particular) but not for Moodle (whose cloze format does not support open-ended text answers). For illustration, see the new "essayreg2" and "lm3" exercises. - Added new interface exams2ilias() for the open-source ILIAS learning management system (https://www.ilias.de/). This is essentially a convenience wrapper to exams2qti12(), tweaking a few defaults and employing a somewhat modified XML template. Not all question types are supported, though, mostly string questions with open-ended answers and multiple-choice and single-choice questions. Numeric and cloze questions are not supported, yet. - Added first release version of new interface exams2testvision() for the Dutch testing platform TestVision. It is essentially a fork of exams2qti21() that incorporates TestVision's own strict implementation of QTI 2.1. See the online tutorial on how to upload the zip output from exams2testvision() into the system by selecting it in the import menu and then moving the imported material to the appropriate directories. The work on the function was financially supported by the Dutch Ministry of Education, Culture and Science (Project code OL20-06), and the University of Amsterdam. - Added first release version of new interface exams2grasple() for Grasple, a Dutch practice platform for mathematics and statistics education. It supports num and schoice questions which are exported to a zip file containing Grasple's JSON format. Note that currently importing cannot be done by users themselves; it requires a request for manual import by a Grasple team member. The work on the function was financially supported by the Dutch Ministry of Education, Culture and Science (Project code OL20-06), and the University of Amsterdam. - Added new interface exams2particify() that can export exercises to a comma-separated values (CSV) format for import in the audience response system Particify (https://particify.de/), the successor to ARSnova. In particular, single-choice and multiple-choice exercises are fully supported while num and string question are converted to open-ended text questions. - Added new interface exams2kahoot() that can export sufficiently simple single-choice and multiple-choice exercises to an Excel sheet via openxlsx::write.xlsx() that can be imported by the game-based learning platform Kahoot! at https://kahoot.com/ (suggested by Rushad Faridi). Exercises are converted to plain text and questions must not exceed 120 characters, answers must not exceed 75 characters. - New experimental function moodle2exams() that can take a Moodle XML quiz file with numeric, multichoice, shortanswer, and essay exercises and convert them to R/exams exercise files, either in R/Markdown (Rmd, default) or R/LaTeX (Rnw) format. If the text formatting is more advanced (e.g., containing mathematical notation or tables etc.) the function might not lead to fully satisfactory results but still provide a useful starting point for subsequent manual editing. - New function testvision2exams() to convert TestVision's QTI 2.1 questions to R/exams exercise files, either in R/Markdown (Rmd, default) or R/LaTeX (Rnw) format. The supported TestVision question types are 'invul (numeriek)', 'een-uit-meer', 'meer-uit-meer', and 'open' which are converted to num, schoice, mchoice, and string, respectively. - When running exercises via knitr::knit() errors in the R code will stop the evaluation now by default. This was always the default behavior for Rnw exercises (i.e., when processed with engine = "sweave") but now is also the default for Rmd exercises and for Rnw exercises via engine = "knitr". In exercises processed via knitr::knit() it is possible to carry on with code evaluation after errors (the default in knitr) by setting the chunk option error = TRUE. Similarly, the default handling of warnings has been set to warning = FALSE so that warnings are reported on the console rather than in the weaved/knitted exercises. - Added new argument texengine = "pdflatex" to exams2pdf() which is passed on to tinytex::latexmk(..., engine = texengine). Provided that tinytex support is installed, this option can also be set to texengine = "xelatex" or "lualatex" for example. - Added exams2blackboard(..., mathjax = NULL) that optionally embeds the MathJax