Exclude OpenOlat's separate package configuration from QTI item/test schema validation, as already done for the content-package manifest.
Numeric and text gaps accept an incorrect score in points, including
penalties. Omissions remain zero, and entry minimum scores include penalties.
The Rmd helpers gap_numeric() and gap_text() accept the same setting.
The opt-in extended schema accepts the HTML5 download attribute on links,
including the file-name hint generated by provide_file(). Standard QTI 2.1
validation continues to reject it. The helper documentation distinguishes
schema validation from LMS/browser support for embedded data URIs.
Fall back to the first grading-table label for C.UTF-8 and unrecognized locales, so academic grading can be exported in noninteractive sessions.
Serialize section session controls, time limits, selection and ordering in the order required by the QTI schema.
Contributor dates default to the current date when a contributor is assigned. Dates can be set explicitly in YAML or the contributor helper. Preserve supplied dates when collecting item contributors into test metadata.
single_choice_scoring() and multiple_choice_scoring() configure the
corresponding item types through scoring_scheme, with separate help pages.
Single-choice items support custom correct,
incorrect and omitted credits and all 21 Kanzow et al. (2023) coefficients,
with their documented format restrictions. Multiple-choice items support
five literature methods, explicit weights, and all exams_eval() choice
policies, including exact matching, zero distractor weights and negative
floors. Existing defaults are unchanged. New rules use standard QTI 2.1
response processing; platform support should be checked separately.
Documentation has been regenerated with roxygen2 8.0.0; its version is
recorded in Config/roxygen2/version rather than the legacy RoxygenNote.
The bundled test_results.zip example now uses neutral task identifiers.
Scores, responses, dates, and participant filename pseudonyms are unchanged.
QTI 2.2 schemas are compressed in the installed package and unpacked on demand into the R session's temporary directory. All schema dependencies remain bundled, so validation works offline. Generated template previews are excluded from the source package.
OPAL credential services are derived automatically from the normalized
endpoint, allowing the same username to use different passwords on different
installations without a manual ID. Existing rqtiopal entries remain a
transparent fallback. credential_id is retained as an optional override.
set_opal_credentials() securely stores a password under the service derived
from an OPAL endpoint.
OPAL authentication tokens are now stored per connection instead of in the
process-wide X-OLAT-TOKEN environment variable. Implicit connections can
select a credential set with RQTI_API_CREDENTIAL_ID.
OPAL endpoints are normalized to one trailing slash, successful login bodies
are no longer parsed as unused XML, and a successful response without an
X-OLAT-TOKEN header now produces a clear error.
render_opal() forwards named endpoint, api_user, and credential_id
arguments to opal().
Live OPAL integration tests now require the explicit opt-in environment
variable RQTI_RUN_LIVE_TESTS=true. This prevents ordinary package checks
from authenticating against whichever endpoint happens to be configured in
the developer's environment.
extract_results(level = "item") now supports integer responses and labels
them as NumericGap. Missing or unsupported response base types now produce
an error identifying the affected item.
Fixed Pandoc compatibility by using the appropriate option to disable syntax highlighting based on the capabilities of the installed Pandoc version.
Rmd questions now support stylesheet_path (one or more local CSS files)
and css: | (CSS text) in YAML. Item stylesheets are written with XML
exports and included in item and assessment ZIPs and manifests. Relative
paths are resolved against the Rmd source directory.
Added read_qti() as an alias for extract_results().
Added OPAL API functions createCourseGroup() for creating course groups,
addGroupUser() for adding users to groups, and removeGroupUser() for
removing users from groups.
extract_results(level = "item") now includes task-level
candidate_comment and scorer_comment columns for each item row.
Added provide_audio() helper to embed local audio files directly into
QTI/HTML content using Base64 encoding. The function supports both
<object> and <audio> rendering methods and
self-contained audio embedding for portable assessment items.
preview_feedback.
The option should now be specified as a top-level YAML field instead of inside
params. The previous syntax within params is deprecated and will be removed
in a future release.Dropdown items (dropdown()) can now include commas and other punctuation without breaking YAML parsing.
Updated OPAL authentication to use the current REST login endpoint and header-based credentials.
Fixed grade feedback score ranges so that rounding to two decimal places no longer leaves gaps between adjacent grade intervals.
Replaced platform-specific external SHA1 commands in tests with an R-native hash implementation to improve portability across operating systems.
Fixed MathJax rendering for dynamically loaded referent content in QTI.JS.
Added support for OpenOlat via a new class AssessmentTestOpenOlat.
It introduced OpenOlat-specific configuration options (e.g., navigation behavior,
visibility settings, number of attempts) as slots and corresponding arguments in
assessmentTestOpenOlat().
Added fallback_titles argument to test() and test4opal() to control how
section and item titles are assigned when not explicitly provided. Supported
values are "filename" and "generic". The AssessmentTest class now includes a
fallback_titles slot.
Added a new slot scoring_scheme to the SingleChoice class to control how
response options are scored. Supported values are "standard" (default) and
"penalty". Introduced penalty-based scoring for single-choice tasks. When
scoring_scheme = "penalty", incorrect answers receive a negative score of
-points/(k-1), where k is the number of response options. This ensures
that random guessing yields an expected score of zero.
Added a new stylesheet_path slot to AssessmentTest objects, allowing users to
include custom CSS stylesheets at the assessment test level. When
academic_grading is enabled, the default styles/rqti.css stylesheet is included
automatically, and custom styles can be added to override the default appearance.
Added german_grading(), a helper function that returns a predefined German
grading scale for the academic_grading argument in test() and test4opal(),
avoiding the need to manually define grading vectors. This grading scheme can
also be stored directly in the academic_grading slot of AssessmentTest objects.
Added helper provide_file() to embed local files directly into .Rmd tasks as #
Base64-encoded hyperlinks for downloadable attachments.
section() now supports Rmd files created with the exams package.
Such files are automatically detected and converted to QTI 2.1 XML via
exams::exams2qti21(), so they can be used directly without additional wrapping.
Added exams_task() helper for explicit control over exams-based tasks.
While section() can handle exams .Rmd files automatically, exams_task()
can be used when additional control is needed, e.g., to assign a custom title.
The function converts the Rmd file and returns the path to the generated XML
file in a temporary directory, allowing combination with native rqti items.
Enhanced LMS Opal API with new functions getCourseGroups() and
getGroupUsers() for retrieving course groups and group users as data frames.
Improved extract_results() performance for archives with many result files
by extracting only relevant XML/result zip files, avoiding repeated row
binding, and reducing XPath work for item-level responses.
Enhanced verify_qti() to support different input types, provide more
informative validation messages, and use both xmllint and xml2 backends
for XML validation.
extract_results(level = "task") now includes an additional column
containing scorerComment for manually scored item results.
Images referenced in external XML files are now automatically embedded as Base64. This ensures that tasks are fully self-contained and do not depend on external image files.
Changed the default time_limit for AssessmentTest and AssessmentTestOpal
objects (and for all related helper functions) to NULL, so time limits are no
longer set at the test level by default.
Changed the default value of allow_paste in Essay items to TRUE.
Fixed handling of consecutive gaps in .Rmd tasks.
Fixed identifier validation regex to correctly allow hyphens in valid identifiers.
Fixed test() and test4opal() to correctly handle input provided as a list
containing a single section.
RQTI_API_USER environment variable. If api_user is not provided explicitly, its value is now read from the environment.Fixed an issue in upload2opal() where arguments open_in_browser and as_survey were not forwarded to upload2LMS().
Fixed problems in auto-generated scripts via RStudio template.
Fixed parameter serialization in dropdown() to preserve long values, normalize numeric and logical formatting, and ensure stable, test-consistent gap interaction output.
Rendering functions (render_qtijs(), render_xml(), and render_zip()) now accept a qtijs_path argument (defaulting to qtijs_pkg_path()), allowing explicit control over the qtijs installation path.
Added a daemon argument to start_server() for improved server control.
Exported the qtijs_pkg_path() helper function for accessing the qtijs installation path.
Improved error and warning messages for duplicate identifiers.
Major API Refactor: The API functionality has been refactored to require creating an Opal object for establishing a connection. Methods are now called on this object for interacting with the LMS API, replacing the previous function-based approach.
Added a verify_qti() function to validate XML documents against the QTI v2.1 schema. Two schema versions are supported: the original IMS Global schema and an extended version that permits additional HTML tags.
Added new constructor functions assessmentTest(), assessmentTestOpal(), assessmentSection().
The default values of the "academic_grading" parameter/slot have been updated in the functions assessmentTest(), assessmentTestOpal(), test(), and in the classes AssessmentTest and AssessmentTestOpal. This parameter/slot is a named numeric vector that defines the grade table shown to candidates as feedback at the end of the test. The updated default follows the German grading system: gt <- c("1.0" = 0.95, "1.3" = 0.9, "1.7" = 0.85, "2.0" = 0.8, "2.3" = 0.75, "2.7" = 0.7, "3.0" = 0.65, "3.3" = 0.6, "3.7" = 0.55, "4.0" = 0.5, "5.0" = 0), where each grade corresponds to the minimum percentage score required to achieve it. To disable the grading table at the end of the test, set this parameter to NA_real_.
Generic functions are now exported to allow advanced users to extend the functionality of S4 classes (createItemBody(), createResponseDeclaration(), createOutcomeDeclaration(), createResponseProcessing(), createText()).
Added support for the preview_feedback option within 'params' in the YAML section of R Markdown files.
Renamed the service name in the keyring system credential storage to "rqtiopal".
Renamed the "contributor" slot in QtiContributor to 'name'.
QTIJS rendering (DirectedPair type, round Score and Maxscore values).
Added a '<div>' tag as a root child within the 'itemBody' element for Entry type tasks to ensure compatibility with the LMS OpenOlat.
The functions qti_metadata() and qti_contributor() have been deprecated. Use qtiMetadata() and qtiContributor() instead.
The 'question_type' column has been removed from the data frame returned by extract_result(level = "item").
Fix parsing R Markdown files with tables according the latest pandoc version.
Fix extract_results(level="items") for Ordering type, when candidate response
is not given.
Fix error at createQtitask(obj, zip=TRUE).
New API OPAL function get_course_elements() returns a data frame with elements of
the course by course id.
New API OPAL function get_course_results() returns an xml with data about
results by course id and node id.
New API OPAL function publish_courses() for publishing a course by Resource ID.
method createQtiTask() can create XML or zip files, to control this use
parameter zip=TRUE.
QTIJS rendering shows feedback and score for tasks.
Handle problem with xsd scheme for xml validation.
Handle some problems with html and mathml entities.
Improved the appearance of the tasks in QTIJS viewer.
Added constructor functions for task classes: singleChoice(), multipleChoice(),
essay(), ordering(), entry(), directedPair(), oneInColTable(), oneInRowTable(), myltipleChoiceTable().
Added constructor functions for content of Entry class: numericGap(), textGap(),
textGapOpal(), inlineChoice().
Added constructor functions for the feedback objects: modalFeedback(),
correctFeedback(), wrongFeedback().
Added the ability to upload SURVEY resource type to Opal using the API. The upload2opal() function now includes a new parameter, "as_survey", which allows you to specify the resource type. Set "as_survey = TRUE" to upload as a SURVEY
resource type.
Added the ability to put metadata in the manifest file for tests. To store metadata information AssessmentItem and AssessmentTest use slot "@metadata" that takes QtiMetadata (and QtiContributor inside) classes as type. Two construction functions have been added to create objects: qti_metadata() and qti_contributor().
Added the missing qti.js for rendering Rmd-files with tasks.
Added processing of the pandoc --embed-resources parameter for pandoc versions < 2.19.
AssessmentItem, AssessmentSection and AssessmentTest objects are checked for compliance with QTI requirements.