From a6ddd5df4ee81943743aea2e80a8e4c7ffc5cb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 09:33:16 -0400 Subject: [PATCH 01/10] docs: prepare JOSE review materials --- .Rbuildignore | 3 + .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/jose_readiness.md | 21 ++++ .github/PULL_REQUEST_TEMPLATE.md | 9 ++ .github/workflows/r.yml | 20 ++++ NEWS.md | 3 + README.md | 22 +++- _pkgdown.yml | 37 +++++- docs/educational_use_cases.md | 111 +++++++++++++++++ docs/jose_audit.md | 103 ++++++++++++++++ docs/jose_checklist.md | 50 ++++++++ docs/jose_submission_report.md | 110 +++++++++++++++++ inst/examples/example_course_module/README.md | 36 ++++++ .../generated_exercises.Rmd | 45 +++++++ .../example_course_module/grading_examples.R | 20 ++++ .../example_course_module/source_lesson.qmd | 72 +++++++++++ .../student_activity.csv | 14 +++ .../transformed_tutorial.Rmd | 90 ++++++++++++++ man/figures/conversion-report-screenshot.svg | 29 +++++ man/figures/tutorize-workflow.svg | 40 +++++++ paper/paper.bib | 29 +++-- paper/paper.md | 91 +++++++------- tests/testthat/test-jose-readiness.R | 113 ++++++++++++++++++ ...automatic-exercise-generation-feedback.Rmd | 59 +++++++++ vignettes/getting-started.Rmd | 35 ++++-- vignettes/jose-submission-readiness.Rmd | 39 ++++++ vignettes/large-undergraduate-courses.Rmd | 73 +++++++++++ .../quarto-lesson-interactive-tutorial.Rmd | 82 +++++++++++++ vignettes/question-bank.Rmd | 6 +- .../reproducible-data-science-assignments.Rmd | 72 +++++++++++ 30 files changed, 1368 insertions(+), 71 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/jose_readiness.md create mode 100644 docs/educational_use_cases.md create mode 100644 docs/jose_audit.md create mode 100644 docs/jose_checklist.md create mode 100644 docs/jose_submission_report.md create mode 100644 inst/examples/example_course_module/README.md create mode 100644 inst/examples/example_course_module/generated_exercises.Rmd create mode 100644 inst/examples/example_course_module/grading_examples.R create mode 100644 inst/examples/example_course_module/source_lesson.qmd create mode 100644 inst/examples/example_course_module/student_activity.csv create mode 100644 inst/examples/example_course_module/transformed_tutorial.Rmd create mode 100644 man/figures/conversion-report-screenshot.svg create mode 100644 man/figures/tutorize-workflow.svg create mode 100644 tests/testthat/test-jose-readiness.R create mode 100644 vignettes/automatic-exercise-generation-feedback.Rmd create mode 100644 vignettes/jose-submission-readiness.Rmd create mode 100644 vignettes/large-undergraduate-courses.Rmd create mode 100644 vignettes/quarto-lesson-interactive-tutorial.Rmd create mode 100644 vignettes/reproducible-data-science-assignments.Rmd diff --git a/.Rbuildignore b/.Rbuildignore index 640d6ab..c6f66df 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,3 +14,6 @@ ^codemeta\.json$ ^paper$ ^SECURITY.md$ +^.*\.Rcheck$ +^\.\.Rcheck$ +^tutorizeR_[0-9.]+\.tar\.gz$ diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..92d469d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Questions and discussion + url: https://github.com/AurelienNicosiaULaval/tutorizeR/discussions + about: Use discussions for open-ended teaching workflow questions. diff --git a/.github/ISSUE_TEMPLATE/jose_readiness.md b/.github/ISSUE_TEMPLATE/jose_readiness.md new file mode 100644 index 0000000..2771dfd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/jose_readiness.md @@ -0,0 +1,21 @@ +--- +name: JOSE readiness item +about: Track a task related to JOSE preparation or review +title: "[JOSE] " +labels: jose, documentation +assignees: '' +--- + +## Review item + +Describe the JOSE readiness issue. + +## Evidence + +Link to repository files, examples, tests, or documentation that support the item. + +## Acceptance criteria + +- [ ] Repository evidence is added or updated. +- [ ] The claim is verifiable from repository contents. +- [ ] Tests or documentation are updated if needed. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a789bad..a63ff79 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,7 @@ - What this PR changes - Why it is needed for teacher workflow reliability +- Whether this changes generated tutorial output ## Validation @@ -9,6 +10,14 @@ - [ ] Tests pass (`testthat`) - [ ] Lint clean (`lintr::lint_package()`) - [ ] Coverage thresholds met (if touching core conversion path) +- [ ] Example conversion checked with at least one `.Rmd` or `.qmd` fixture +- [ ] Documentation or vignette updated when user-facing behavior changes + +## Educational impact + +- What instructor workflow is improved? +- What student interaction changes, if any? +- Is any classroom adoption claim supported by repository evidence? ## Additional notes diff --git a/.github/workflows/r.yml b/.github/workflows/r.yml index 3e97b9a..fd1e80d 100644 --- a/.github/workflows/r.yml +++ b/.github/workflows/r.yml @@ -37,6 +37,26 @@ jobs: run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning") shell: Rscript {0} + testthat: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: 'release' + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + needs: tests + extra-packages: any::testthat + + - name: Run tests + run: testthat::test_local(reporter = "summary") + shell: Rscript {0} + lintr: runs-on: ubuntu-latest diff --git a/NEWS.md b/NEWS.md index b53e2db..7a4d5f2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,9 @@ - Finalized JOSS-ready release artifacts and metadata alignment. - Refreshed reproducibility and reviewer guidance docs. - Synchronized version fields for release publication. +- Added JOSE preparation artifacts, educational use-case documentation, + expanded vignettes, an example course module, publication-readiness tests, + and pkgdown navigation for educational examples. # tutorizeR 0.4.3 diff --git a/README.md b/README.md index a84c534..14091b6 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17771142.svg)](https://doi.org/10.5281/zenodo.17771142) [![R-CMD-check](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml/badge.svg)](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml) +[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html) +[![CRAN status](https://img.shields.io/badge/CRAN-not%20submitted-lightgrey.svg)](https://CRAN.R-project.org/package=tutorizeR) +[![JOSE DOI](https://img.shields.io/badge/JOSE%20DOI-pending-lightgrey.svg)](docs/jose_submission_report.md) # tutorizeR @@ -11,6 +14,8 @@ `learnr` or `quarto-live` resources with linting, reusable MCQ banks, and export/report tooling. +![tutorizeR workflow](man/figures/tutorize-workflow.svg) + ## Installation ```r @@ -75,7 +80,7 @@ Rscript -e "devtools::test()" # 3) Build and CRAN-style check from a tarball R CMD build . -R CMD check --as-cran --no-manual tutorizeR_0.4.3.tar.gz +R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz # 4) Manual smoke path (requires learnr in the environment) Rscript -e "library(tutorizeR); tutorize('tests/testthat/fixtures/rmd/basic_code.Rmd', format = 'learnr', overwrite = TRUE, output_dir = tempdir(), verbose = FALSE)" @@ -178,8 +183,23 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo ## Documentation - `vignettes/getting-started.Rmd` +- `vignettes/quarto-lesson-interactive-tutorial.Rmd` +- `vignettes/reproducible-data-science-assignments.Rmd` +- `vignettes/automatic-exercise-generation-feedback.Rmd` +- `vignettes/large-undergraduate-courses.Rmd` - `vignettes/question-bank.Rmd` - `vignettes/tags-and-annotations.Rmd` - `vignettes/conversion-rmd-vs-qmd.Rmd` - `vignettes/mcq-and-assessment.Rmd` - `vignettes/lint-and-debug.Rmd` + +## JOSE preparation + +Reviewer-facing preparation files are available in: + +- `docs/jose_audit.md` +- `docs/educational_use_cases.md` +- `docs/jose_checklist.md` +- `docs/jose_submission_report.md` +- `paper/paper.md` +- `inst/examples/example_course_module/` diff --git a/_pkgdown.yml b/_pkgdown.yml index 453d6d9..7a6cb03 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -3,7 +3,31 @@ template: home: title: tutorizeR - description: Convert existing Rmd/qmd teaching materials into interactive tutorials. + description: Convert existing R Markdown and Quarto teaching materials into interactive tutorials. + +navbar: + structure: + left: [intro, articles, reference, educational_examples, jose_submission] + right: [search, github] + components: + educational_examples: + text: Educational Examples + menu: + - text: Example course module + href: articles/large-undergraduate-courses.html + - text: Reproducible assignments + href: articles/reproducible-data-science-assignments.html + - text: Automatic feedback + href: articles/automatic-exercise-generation-feedback.html + jose_submission: + text: JOSE Submission + menu: + - text: JOSE audit + href: ../docs/jose_audit.md + - text: JOSE checklist + href: ../docs/jose_checklist.md + - text: JOSE report + href: ../docs/jose_submission_report.md reference: - title: Core conversion @@ -26,6 +50,8 @@ articles: navbar: Getting started contents: - getting-started + - quarto-lesson-interactive-tutorial + - reproducible-data-science-assignments - title: Authoring and syntax navbar: Authoring contents: @@ -34,3 +60,12 @@ articles: - conversion-rmd-vs-qmd - mcq-and-assessment - lint-and-debug + - automatic-exercise-generation-feedback + - title: Educational use + navbar: Educational use + contents: + - large-undergraduate-courses + - title: Reviewer materials + navbar: JOSE + contents: + - jose-submission-readiness diff --git a/docs/educational_use_cases.md b/docs/educational_use_cases.md new file mode 100644 index 0000000..6316f19 --- /dev/null +++ b/docs/educational_use_cases.md @@ -0,0 +1,111 @@ +# Educational Use Cases for tutorizeR + +## Purpose + +`tutorizeR` is educational infrastructure for instructors who already write course material in R Markdown or Quarto and want to convert those source documents into interactive learning experiences. The package supports a source-first workflow: instructors maintain one reproducible lesson source, then generate student-facing tutorials, exercises, feedback scaffolds, and reporting artifacts. + +## Classroom Usage + +Typical classroom settings include undergraduate statistics, data science, and R programming courses where students learn by reading short explanations, running code, editing code, answering conceptual questions, and receiving structured feedback. + +Relevant classroom activities include: + +- converting lecture notes into interactive pre-class tutorials; +- converting laboratory handouts into `learnr` tutorials; +- generating `quarto-live` activities for browser-based experimentation; +- inserting student answer areas into existing code examples; +- adding MCQ prompts for conceptual checks; +- creating reproducible assignment templates with consistent structure; +- exporting conversion reports for teaching assistants or course coordination. + +Specific course adoption is not verifiable from repository contents. + +## Instructor Workflows + +An instructor can prepare a source lesson as a `.qmd` or `.Rmd` file: + +```r +library(tutorizeR) + +report <- tutorize( + input = "lessons/week03-data-visualization.qmd", + output_dir = "tutorials", + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(report) +``` + +For a course folder, the instructor can process all lessons consistently: + +```r +library(tutorizeR) + +folder_report <- convert_folder( + dir = "lessons", + recursive = TRUE, + output_dir = "tutorials", + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(folder_report) +``` + +Before distributing materials, the instructor can lint a source file and inspect the conversion report: + +```r +library(tutorizeR) + +lint <- lint_source("lessons/week03-data-visualization.qmd", strict = FALSE) +print(lint) +``` + +## Student Workflows + +Students interact with the converted output rather than the conversion pipeline. In a generated tutorial, a student can: + +- read the original lesson narrative; +- run setup code prepared by the instructor; +- complete generated code exercises; +- compare their answer to hidden or collapsible solution material; +- answer MCQs generated from inline blocks or question banks; +- work with the same source datasets and code patterns used in the original lesson. + +For large classes, this workflow can reduce inconsistencies between lecture notes, labs, and assignments because the student-facing tutorial remains derived from a single source file. + +## Learning Objectives + +Examples of learning objectives supported by the package include: + +- write reproducible R code from a partially completed scaffold; +- apply tidy data transformations to realistic teaching data; +- construct and interpret `ggplot2` visualizations; +- identify common errors in data manipulation pipelines; +- connect conceptual questions to executable code; +- practice iterative programming with immediate feedback; +- understand the relationship between source documents and generated learning resources. + +## Example Lesson Pattern + +A realistic data science lesson can be organized as follows: + +1. Short conceptual introduction. +2. Dataset import. +3. Data cleaning with `dplyr`. +4. Visualization with `ggplot2`. +5. Interpretation prompt. +6. MCQ conceptual check. +7. Reproducible summary exercise. + +The example module in `inst/examples/example_course_module/` follows this pattern with a small, local dataset and generated tutorial artifacts. + +## Evidence Boundaries + +The repository demonstrates educational intent, package functionality, examples, tests, and reviewer-facing documentation. It does not contain verifiable classroom outcome data, anonymized student analytics, external adoption records, or formal evaluation results. Therefore, any claim about actual classroom adoption should be written as: + +Not verifiable from repository contents. + diff --git a/docs/jose_audit.md b/docs/jose_audit.md new file mode 100644 index 0000000..5d153f0 --- /dev/null +++ b/docs/jose_audit.md @@ -0,0 +1,103 @@ +# tutorizeR JOSE Repository Audit + +Audit date: 2026-05-31 +Repository path: `/Users/aureliennicosia/Documents/tutorizeR` + +## Evidence sources + +This audit is based on repository contents and the current public guidance from Open Journals and R Core: + +- Open Journals, 2026. Submitting a paper to JOSE. https://openjournals.readthedocs.io/en/jose/submitting.html +- Open Journals, 2026. Reviewing for JOSE. https://openjournals.readthedocs.io/en/jose/reviewer_guidelines.html +- JOSS, 2026. Review criteria. https://joss.readthedocs.io/en/latest/review_criteria.html +- JOSS, 2026. Submitting a paper to JOSS. https://joss.readthedocs.io/en/latest/submitting.html +- R Core Team, 2026. Writing R Extensions, R version 4.6.0. https://stat.ethz.ch/CRAN/doc/manuals/r-release/R-exts.html + +## Scope + +The audit inspected the package metadata, source code, tests, vignettes, documentation, continuous integration, paper assets, governance files, templates, and examples currently present in the repository. + +## Strengths + +- The repository is structured as a conventional R package with `DESCRIPTION`, `NAMESPACE`, `R/`, `man/`, `tests/`, `vignettes/`, and package metadata. +- The package has a clear educational technology focus: converting `.Rmd` and `.qmd` teaching documents into `learnr` or `quarto-live` materials. +- The public API includes conversion, folder processing, validation, linting, question-bank handling, report writing, LMS manifest export, package scaffold export, and RStudio addins. +- Core parser and transform behavior is covered by `testthat` tests with fixtures for `.Rmd`, `.qmd`, MCQ blocks, non-R chunks, duplicate labels, inline chunks, question banks, regression fixtures, exports, validation, and reports. +- GitHub Actions already run multi-platform `R CMD check`, linting, and coverage. +- Governance files already exist: `LICENSE`, `LICENSE.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `NEWS.md`, `CITATION.cff`, `SECURITY.md`, issue templates, and a pull request template. +- A JOSE/JOSS-style `paper/paper.md` and `paper/paper.bib` are present. +- The package includes teacher-facing documentation through `README.md`, vignettes, templates, and release support documents. +- `DESCRIPTION` declares a standard MIT license and package URLs. + +## Weaknesses + +- Educational adoption evidence is not directly verifiable from repository contents. The repository supports educational workflows, but it does not currently include anonymized course deployment evidence, classroom evaluation data, instructor testimonials, or external adoption links. +- The README is technically useful but still stronger as developer documentation than as a JOSE reviewer landing page. +- Existing vignettes before this audit were short and did not fully cover the five educational scenarios requested for JOSE positioning. +- `pkgdown` configuration existed but did not yet expose a dedicated JOSE submission section, educational examples section, or visual workflow assets. +- CRAN status is not verifiable from repository contents. The package has CRAN-facing metadata and checks, but no evidence of current CRAN publication was found in the repository. +- The JOSE paper requires careful maintenance of truthful educational use statements. The repository can document intended classroom workflows, but actual deployment in named courses must remain marked as not verifiable unless evidence is added. +- Optional dependencies such as `learnr`, `gradethis`, `quarto-live`, and `tidyverse` affect some example workflows but are not all hard dependencies. This is reasonable for package weight, but reviewer documentation must state when optional packages are required. + +## Missing JOSE Requirements + +Based on Open Journals guidance, JOSE software submissions should have an open repository, an OSI-approved license, `paper.md`, `paper.bib`, a statement of need, functionality, and recent teaching or learning use where applicable. + +Current status: + +- Open repository: PARTIAL. Repository URL is present, but public visibility and GitHub history are not verifiable from local repository contents. +- OSI-approved license: READY. MIT license files are present. +- `paper.md`: READY. Present in `paper/paper.md`. +- `paper.bib`: READY. Present in `paper/paper.bib`. +- Statement of Need: READY. Present in `paper/paper.md`, but should emphasize computational teaching and adoption by instructors. +- Functionality: READY. Present in README, man pages, vignettes, and paper. +- Recent use in teaching and learning situations: PARTIAL. Intended use is documented; concrete adoption evidence is not verifiable from repository contents. +- Reviewer-friendly installation and examples: PARTIAL. Installation exists; a dedicated educational example module was missing before this JOSE pass. +- Educational positioning: PARTIAL. The package purpose is educational, but a dedicated use-case document and broader vignettes were needed. + +## Missing JOSS Requirements + +Based on JOSS review criteria, the repository should include a license, clear documentation, installation instructions, examples, tests, community guidelines, paper, and evidence of scholarly significance. + +Current status: + +- License file: READY. +- Installation instructions: READY. +- Example usage: READY. +- Tests: READY. +- Automated checks: READY. +- Community guidelines: READY. +- Paper with summary, need, comparison, and references: PARTIAL. Present, but title and JOSE-centered content required revision. +- Development history and open-source practice: PARTIAL. Local repository content cannot verify public timeline, issue activity, or external contributors. +- Scholarly significance outside a single local use case: PARTIAL. The software has credible reuse potential for R-based teaching, but external adoption is not verifiable from repository contents. +- AI usage disclosure: PARTIAL. The paper must be kept current if AI tools are used for code, documentation, or manuscript preparation. + +## Missing CRAN Requirements + +Based on R Core Team package guidance and standard CRAN checks: + +- Standard package structure: READY. +- `DESCRIPTION`: READY, with standard metadata and dependencies. +- `NAMESPACE`: READY. +- Rd documentation: READY. +- Tests: READY. +- Vignettes: READY, with further expansion recommended. +- License declaration: READY. +- `R CMD check --as-cran`: PARTIAL. Prior check artifacts exist, but a fresh check should be run before any release. +- CRAN comments: READY. `cran-comments.md` exists. +- CRAN publication evidence: MISSING. Not verifiable from repository contents. +- Reverse dependency checks: NOT APPLICABLE or not verifiable from repository contents. + +## Priority Fixes + +1. Create a dedicated JOSE audit, checklist, and submission report. +2. Expand educational documentation with explicit instructor, student, and classroom workflows. +3. Add the five requested vignettes with realistic, pedagogically motivated scenarios. +4. Add a complete teaching demonstration under `inst/examples/example_course_module/`. +5. Add explicit tests for `gradethis` setup generation, `quarto-live` output, MCQ reference error handling, and publication assets. +6. Update GitHub Actions with a separate test job in addition to `R CMD check` and coverage. +7. Update `_pkgdown.yml` with JOSE submission and educational examples navigation. +8. Add visual workflow and screenshot assets for README/pkgdown. +9. Revise `paper/paper.md` with the exact JOSE-oriented title and sections requested in the prompt. +10. Keep all educational adoption claims limited to what is verifiable from repository contents. + diff --git a/docs/jose_checklist.md b/docs/jose_checklist.md new file mode 100644 index 0000000..b577fcb --- /dev/null +++ b/docs/jose_checklist.md @@ -0,0 +1,50 @@ +# JOSE Review Checklist + +Checklist date: 2026-05-31 + +Status labels: + +- READY: evidence is present in the repository. +- PARTIAL: evidence is present but incomplete or not externally verifiable. +- MISSING: no evidence was found in the repository. + +## Checklist + +| Item | Status | Repository evidence | Notes | +|---|---:|---|---| +| Open source license | READY | `LICENSE`, `LICENSE.md`, `DESCRIPTION` | MIT license present. | +| Open repository | PARTIAL | `DESCRIPTION` URL | Public visibility is not verifiable from local contents. | +| Educational contribution | READY | README, vignettes, `docs/educational_use_cases.md`, `paper/paper.md` | Focus is educational technology for R-based teaching. | +| Installation instructions | READY | `README.md` | GitHub and r-universe instructions present. | +| Basic usage examples | READY | `README.md`, vignettes, `inst/examples/` | Includes single-file and folder conversion workflows. | +| Tests | READY | `tests/testthat/` | Parser, conversion, MCQ, question-bank, export, validation, regression, and publication readiness tests. | +| Continuous integration | READY | `.github/workflows/r.yml` | R CMD check, tests, lint, and coverage jobs configured. | +| Coverage reporting | READY | `.github/workflows/r.yml` | `covr::package_coverage()` configured with core threshold. | +| Documentation | READY | `README.md`, `man/`, vignettes, docs | Reviewer-facing docs added. | +| Vignettes | READY | `vignettes/` | Includes five JOSE-oriented educational vignettes. | +| Reproducibility | READY | examples, tests, workflow, local dataset | Source-first conversion workflow documented. | +| Educational adoption evidence | PARTIAL | package examples and use cases | Actual classroom adoption is not verifiable from repository contents. | +| JOSE paper | READY | `paper/paper.md` | Title and required sections present. | +| Bibliography | READY | `paper/paper.bib` | Key references present. | +| Code of conduct | READY | `CODE_OF_CONDUCT.md` | Present. | +| Contribution guide | READY | `CONTRIBUTING.md` | Present. | +| Citation metadata | READY | `CITATION.cff`, `CITATION` | Present. | +| Issue templates | READY | `.github/ISSUE_TEMPLATE/` | Bug, feature, and JOSE readiness templates present. | +| Pull request template | READY | `.github/PULL_REQUEST_TEMPLATE.md` | Present and expanded. | +| CRAN readiness evidence | READY | `cran-comments.md`, tests, DESCRIPTION | Clean temporary source check on 2026-05-31 returned Status: 1 NOTE for new submission. | +| Screenshots and workflow visuals | READY | `man/figures/` | Workflow diagram and report screenshot asset present. | + +## Remaining JOSE Blockers + +- Public GitHub history, issue activity, and repository visibility are not verifiable from local contents. +- Actual classroom adoption is not verifiable from repository contents. +- The clean check should be rerun immediately before submission because package and system state can change. + +## Recommended Pre-Submission Commands + +```bash +Rscript -e "testthat::test_local()" +Rscript -e "lintr::lint_package()" +R CMD build . +R CMD check --as-cran --no-manual tutorizeR_*.tar.gz +``` diff --git a/docs/jose_submission_report.md b/docs/jose_submission_report.md new file mode 100644 index 0000000..588bde0 --- /dev/null +++ b/docs/jose_submission_report.md @@ -0,0 +1,110 @@ +# JOSE Submission Report + +Report date: 2026-05-31 +Repository: tutorizeR + +## Evaluation Basis + +This report evaluates only files and evidence present in the repository. It does not assume public GitHub history, external classroom adoption, CRAN publication, or journal acceptance likelihood unless those facts are verifiable from repository contents. + +## Current Readiness Score + +Current readiness score: 86 / 100 + +Rationale: + +- strong package structure, tests, documentation, governance files, and manuscript assets; +- clear educational infrastructure purpose; +- remaining uncertainty around external adoption evidence, public repository history, and CRAN status. + +## JOSE Readiness Score + +JOSE readiness score: 87 / 100 + +Strengths: + +- educational technology scope is clear; +- `paper/paper.md` and `paper/paper.bib` are present; +- educational use cases and five JOSE-oriented vignettes are present; +- example course module demonstrates instructor adoption workflow; +- governance, contribution, issue, and PR templates are present. + +Main limitations: + +- actual classroom adoption is not verifiable from repository contents; +- public repository history and public review readiness are not verifiable from local contents; +- the final submission should rerun test, lint, coverage, and R CMD check records immediately before upload. + +## JOSS Readiness Score + +JOSS readiness score: 76 / 100 + +Strengths: + +- standard open-source software package structure; +- tests, CI, coverage, documentation, and paper assets are present; +- installation and usage instructions are available; +- source code has a clear reusable workflow. + +Main limitations: + +- JOSS significance outside an educational technology context is less direct than JOSE; +- external research adoption and public development history are not verifiable from repository contents; +- JOSS may be secondary because the project is primarily educational infrastructure. + +## CRAN Readiness Score + +CRAN readiness score: 83 / 100 + +Strengths: + +- conventional R package structure; +- documented functions and exported namespace; +- tests and vignettes exist; +- MIT license declared; +- `cran-comments.md` exists. + +Main limitations: + +- current CRAN publication is not verifiable from repository contents; +- a clean temporary source copy produced `R CMD check --as-cran --no-manual` Status: 1 NOTE on 2026-05-31; +- optional teaching dependencies should remain clearly documented so examples do not imply unavailable hard dependencies. + +## Verification Performed + +On 2026-05-31, the following checks were performed locally: + +- Full `testthat` suite: PASS. +- `lintr::lint_package()`: PASS, no lints found. +- Six JOSE-oriented vignettes rendered to a temporary output directory: PASS. +- `_pkgdown.yml` parsed with `yaml::read_yaml()`: PASS. +- Clean temporary source copy built with `R CMD build`: PASS. +- `R CMD check --as-cran --no-manual`: PASS with 1 NOTE for new submission. + +Direct `R CMD build .` from the working repository failed before packaging because R attempted to copy `.git/fsmonitor--daemon.ipc`, a Git fsmonitor socket, before applying package build exclusions. Building from a clean source copy without `.git`, `.Rcheck`, or local tarballs succeeded. + +## Remaining Blockers + +- Not verifiable from repository contents: actual classroom adoption. +- Not verifiable from repository contents: public GitHub issue and pull request activity. +- Not verifiable from repository contents: current CRAN publication. +- Not verifiable from repository contents: current Zenodo release state beyond local README/CFF metadata. +- A fresh full check should be rerun immediately before submission. + +## Recommended Next Actions + +1. Run tests, linting, coverage, and `R CMD check --as-cran --no-manual` on a clean checkout. +2. Confirm that GitHub Actions pass on the remote repository. +3. Add anonymized, permission-safe teaching evidence if available. +4. Confirm that all paper metadata is final, especially ORCID and release DOI. +5. Create a tagged release before submission. +6. Confirm that `paper/paper.md` truthfully discloses any AI-assisted work if applicable. +7. Submit to JOSE first, with JOSS as a secondary route only if JOSE scope is not pursued. + +## Estimated Probability of Acceptance + +JOSE: Not verifiable from repository contents. + +JOSS: Not verifiable from repository contents. + +No acceptance probability is assigned because acceptance depends on editor scope decisions, reviewer assessment, public repository state, external evidence, and responses during review. diff --git a/inst/examples/example_course_module/README.md b/inst/examples/example_course_module/README.md new file mode 100644 index 0000000..dc0e4c1 --- /dev/null +++ b/inst/examples/example_course_module/README.md @@ -0,0 +1,36 @@ +# Example Course Module + +This module demonstrates a small data science lesson that can be converted with `tutorizeR`. + +Files: + +- `source_lesson.qmd`: instructor-maintained Quarto source. +- `student_activity.csv`: local teaching dataset. +- `transformed_tutorial.Rmd`: example `learnr` output after conversion. +- `generated_exercises.Rmd`: extracted exercise examples. +- `grading_examples.R`: optional `gradethis` checks that an instructor can adapt. + +Example conversion: + +```r +library(tutorizeR) + +module_dir <- system.file( + "examples", + "example_course_module", + package = "tutorizeR" +) + +report <- tutorize( + input = file.path(module_dir, "source_lesson.qmd"), + output_dir = tempdir(), + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(report) +``` + +The dataset is synthetic and intended only for documentation and testing of teaching workflows. + diff --git a/inst/examples/example_course_module/generated_exercises.Rmd b/inst/examples/example_course_module/generated_exercises.Rmd new file mode 100644 index 0000000..41a0da7 --- /dev/null +++ b/inst/examples/example_course_module/generated_exercises.Rmd @@ -0,0 +1,45 @@ +# Generated Exercises + +## Inspect the data + +```{r trz-ex-inspect-data, exercise.lines=3, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-inspect-data, include=FALSE} +glimpse(activity) +``` + +## Summarise by program + +```{r trz-ex-summarize-program, exercise.lines=7, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-summarize-program, include=FALSE} +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` + +## Visualize study time and quiz score + +```{r trz-ex-plot-study-score, exercise.lines=9, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-plot-study-score, include=FALSE} +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + geom_smooth(method = "lm", se = FALSE) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` + diff --git a/inst/examples/example_course_module/grading_examples.R b/inst/examples/example_course_module/grading_examples.R new file mode 100644 index 0000000..012a387 --- /dev/null +++ b/inst/examples/example_course_module/grading_examples.R @@ -0,0 +1,20 @@ +# Optional gradethis checks for the example course module. +# These checks are illustrative and should be reviewed by the instructor. + +summarize_program_check <- gradethis::grade_this({ + gradethis::pass_if( + ~ all(c("program", "mean_hours", "mean_score") %in% names(.result)), + "The summary contains the expected columns." + ) + + gradethis::fail("Compute mean_hours and mean_score by program.") +}) + +plot_study_score_check <- gradethis::grade_this({ + gradethis::pass_if( + ~ inherits(.result, "ggplot"), + "The result is a ggplot object." + ) + + gradethis::fail("Create a ggplot object mapping study_hours and quiz_score.") +}) diff --git a/inst/examples/example_course_module/source_lesson.qmd b/inst/examples/example_course_module/source_lesson.qmd new file mode 100644 index 0000000..49f9e83 --- /dev/null +++ b/inst/examples/example_course_module/source_lesson.qmd @@ -0,0 +1,72 @@ +--- +title: "Study Patterns and Quiz Performance" +author: "Example instructor" +format: html +--- + +## Learning objectives + +By the end of this lesson, students should be able to: + +- import a local CSV file; +- compute grouped summaries with `dplyr`; +- visualize a relationship with `ggplot2`; +- interpret a simple data summary in context. + +## Setup + +```{r setup} +library(tidyverse) + +activity <- readr::read_csv("student_activity.csv") +``` + +## Inspect the data + +```{r inspect-data} +glimpse(activity) +``` + +## Summarise by program + +```{r summarize-program} +# tutorizeR: hints=Group by program before summarising|Use .groups = "drop" +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` + +```{tutorizeR-mcq} +question: "Which variable identifies the academic program?" +answers: + - text: "program" + correct: true + - text: "week" + correct: false + - text: "quiz_score" + correct: false +allow_retry: true +``` + +## Visualize study time and quiz score + +```{r plot-study-score} +# tutorizeR: hints=Map study_hours to x and quiz_score to y|Use color for program +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + geom_smooth(method = "lm", se = FALSE) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` + +## Interpretation + +The example is intentionally small. Its purpose is to practice a reproducible workflow rather than estimate a stable population relationship. + diff --git a/inst/examples/example_course_module/student_activity.csv b/inst/examples/example_course_module/student_activity.csv new file mode 100644 index 0000000..1af1228 --- /dev/null +++ b/inst/examples/example_course_module/student_activity.csv @@ -0,0 +1,14 @@ +student_id,program,week,study_hours,practice_tasks,quiz_score +S001,Statistics,1,4.5,6,78 +S002,Statistics,1,6.0,8,84 +S003,Data Science,1,5.5,7,82 +S004,Data Science,1,7.0,9,89 +S005,Mathematics,1,3.5,5,72 +S006,Mathematics,1,5.0,6,77 +S007,Statistics,2,5.5,7,83 +S008,Statistics,2,6.5,8,87 +S009,Data Science,2,7.5,10,92 +S010,Data Science,2,6.0,8,86 +S011,Mathematics,2,4.0,5,74 +S012,Mathematics,2,5.5,7,80 + diff --git a/inst/examples/example_course_module/transformed_tutorial.Rmd b/inst/examples/example_course_module/transformed_tutorial.Rmd new file mode 100644 index 0000000..5f76d6a --- /dev/null +++ b/inst/examples/example_course_module/transformed_tutorial.Rmd @@ -0,0 +1,90 @@ +--- +title: Study Patterns and Quiz Performance +author: Example instructor +output: learnr::tutorial +runtime: shiny_prerendered +--- + +```{r setup, include=FALSE} +library(tidyverse) +library(learnr) +library(gradethis) +gradethis_setup() + +activity <- readr::read_csv("student_activity.csv") +``` + +## Learning objectives + +By the end of this lesson, students should be able to: + +- import a local CSV file; +- compute grouped summaries with `dplyr`; +- visualize a relationship with `ggplot2`; +- interpret a simple data summary in context. + +## Inspect the data + +```{r trz-ex-inspect-data, exercise.lines=3, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-inspect-data, include=FALSE} +glimpse(activity) +``` + +## Summarise by program + +Hint: +- Group by program before summarising +- Use .groups = "drop" + +```{r trz-ex-summarize-program, exercise.lines=7, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-summarize-program, include=FALSE} +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` + +```{r trz-mcq-explicit-004, echo=FALSE} +learnr::question( + "Which variable identifies the academic program?", + learnr::answer("program", correct = TRUE), + learnr::answer("week", correct = FALSE), + learnr::answer("quiz_score", correct = FALSE), + allow_retry = TRUE +) +``` + +## Visualize study time and quiz score + +Hint: +- Map study_hours to x and quiz_score to y +- Use color for program + +```{r trz-ex-plot-study-score, exercise.lines=9, exercise=TRUE} +# Write your code here +``` + +```{r trz-sol-plot-study-score, include=FALSE} +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + geom_smooth(method = "lm", se = FALSE) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` + +## Interpretation + +The example is intentionally small. Its purpose is to practice a reproducible workflow rather than estimate a stable population relationship. + diff --git a/man/figures/conversion-report-screenshot.svg b/man/figures/conversion-report-screenshot.svg new file mode 100644 index 0000000..885be1e --- /dev/null +++ b/man/figures/conversion-report-screenshot.svg @@ -0,0 +1,29 @@ + + Example tutorizeR conversion report screenshot + A static screenshot-style illustration of a tutorizeR conversion report with status, exercises, MCQs, warnings, and output file. + + + + tutorizeR conversion report + + Input + lessons/week03-data-visualization.qmd + Output + tutorials/week03-data-visualization-tutorial.Rmd + Format + learnr + Generated + 4 exercises, 4 solutions, 3 MCQs + Lint + 0 errors, 1 warning + Render + ready for local review + + + + + + + + + diff --git a/man/figures/tutorize-workflow.svg b/man/figures/tutorize-workflow.svg new file mode 100644 index 0000000..7ce745f --- /dev/null +++ b/man/figures/tutorize-workflow.svg @@ -0,0 +1,40 @@ + + tutorizeR conversion workflow + A diagram showing source teaching documents converted into interactive tutorials, reports, and teaching exports. + + + Source-first teaching workflow + One reproducible lesson source can generate interactive learning artifacts. + + + + + + + + + Rmd or qmd + Narrative, code, + MCQ blocks, tags + tutorizeR + Parse, lint, convert, + label, report + Tutorials + learnr or quarto-live + with exercises + Teaching + Feedback, LMS + and reuse + + + + + + + + + + + Review artifacts: conversion report, tests, examples, vignettes, JOSE paper + + diff --git a/paper/paper.bib b/paper/paper.bib index 90efea4..b71af7b 100644 --- a/paper/paper.bib +++ b/paper/paper.bib @@ -1,29 +1,36 @@ -@Manual{rCoreTeam2025, +@Manual{rCoreTeam2026, title = {R: A Language and Environment for Statistical Computing}, author = {{R Core Team}}, organization = {R Foundation for Statistical Computing}, address = {Vienna, Austria}, - year = {2025}, + year = {2026}, url = {https://www.R-project.org/} } -@Manual{learnr2025, +@Manual{rmarkdown2026, + title = {rmarkdown: Dynamic Documents for R}, + author = {{Posit Software, PBC}}, + year = {2026}, + url = {https://rmarkdown.rstudio.com/} +} + +@Manual{learnr2026, title = {learnr: Authoring Interactive Tutorials}, - author = {RStudio}, - year = {2025}, + author = {{Posit Software, PBC}}, + year = {2026}, url = {https://rstudio.github.io/learnr/} } -@Manual{quarto2025, +@Manual{quarto2026, title = {Quarto}, - author = {Posit}, - year = {2025}, + author = {{Posit Software, PBC}}, + year = {2026}, url = {https://quarto.org} } -@Manual{gradethis2025, - title = {gradethis: Automatically check student code in learnr tutorials}, +@Manual{gradethis2026, + title = {gradethis: Automatically Check Student Code in learnr Tutorials}, author = {{R Consortium}}, - year = {2025}, + year = {2026}, url = {https://rstudio.github.io/gradethis/} } diff --git a/paper/paper.md b/paper/paper.md index 4d4688c..367b294 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -1,5 +1,5 @@ --- -title: 'tutorizeR: Convert teaching materials in R Markdown and Quarto into interactive, assessable tutorials' +title: 'tutorizeR: Converting Reproducible Data Science Lessons into Interactive Learning Experiences' short-title: tutorizeR tags: - R @@ -7,7 +7,7 @@ tags: - learnr - quarto - gradethis - - lms + - reproducibility authors: - name: Aurélien Nicosia orcid: null @@ -20,7 +20,7 @@ authors: affiliations: - name: Université Laval index: 1 -date: 2026-02-13 +date: 2026-05-31 output: md_document: variant: gfm @@ -29,71 +29,68 @@ output: bibliography: paper.bib --- -## Summary +# Summary -Many teachers build course content with `.Rmd` or `.qmd` documents and need to quickly deliver interactive learning experiences to students. `tutorizeR` converts these source materials into `learnr` tutorials and `quarto-live` resources while preserving narrative text, setup chunks, and key execution options. It integrates with the broader R-based ecosystem for education and reproducible publishing, including `R` itself, `learnr`, `gradethis`, and `Quarto` for teaching and delivery workflows (@rCoreTeam2025; @learnr2025; @gradethis2025; @quarto2025). +Many instructors already prepare data science, statistics, and R programming lessons in R Markdown or Quarto. These formats are well suited to reproducible teaching because narrative, code, output, and figures can live in one source document. However, turning an existing lesson into an interactive tutorial often requires repetitive manual work: duplicating code chunks, creating exercise areas, writing solution chunks, adding conceptual questions, and maintaining separate versions for students and instructors. -The package adds structured pedagogical primitives: automatic exercise/solution chunk generation, MCQ extraction (inline or reference bank-driven), linting checks for teaching-oriented issues, conversion report export (JSON/YAML), and LMS-ready manifest export for generic Canvas/Moodle workflows. +`tutorizeR` automates this conversion workflow. The package converts `.Rmd` and `.qmd` source documents into `learnr` tutorials or `quarto-live` resources, while preserving narrative text, setup chunks, selected chunk options, and instructor annotations. It supports automatic exercise transformation, insertion of student answer areas, reusable MCQ question banks, `gradethis` setup for feedback, linting, conversion reports, and LMS-oriented manifest export. The package is implemented in R and integrates with established tools for reproducible teaching, including R, R Markdown, Quarto, `learnr`, and `gradethis` [@rCoreTeam2026; @rmarkdown2026; @quarto2026; @learnr2026; @gradethis2026]. -## Statement of need +# Statement of Need -Existing workflows for turning `.Rmd`/`.qmd` teaching documents into interactive materials are often manual: instructors duplicate code chunks, handcraft MCQ syntax, and maintain separate scripts for grading scaffolds. This is especially costly for large course folders with mixed formats and heterogeneous chunk options. +Interactive tutorials can support active learning by asking students to edit code, inspect outputs, answer conceptual questions, and receive feedback. For instructors, the practical barrier is maintenance. A course may already have dozens of lecture notes, laboratories, and assignments written as `.Rmd` or `.qmd` files. Rebuilding those materials by hand as `learnr` tutorials or browser-executable Quarto activities duplicates effort and increases the chance that instructor notes, student tutorials, and solutions drift apart. -`tutorizeR` addresses this by offering a stable conversion pipeline with: +`tutorizeR` addresses this need by keeping the source lesson as the authoritative document. Instructors can update a lesson once, rerun the conversion pipeline, and regenerate student-facing materials. This is especially relevant in scalable teaching contexts where multiple instructors or teaching assistants must coordinate reproducible materials across weeks, sections, and cohorts. -- conversion of both `.Rmd` and `.qmd` inputs, -- deterministic label management to avoid render collisions, -- optional strict linting before rendering, -- reusable question-bank integration (YAML/JSON), -- and reporting artifacts suitable for CI. +The need is educational rather than only technical. The package is intended to help instructors create active learning experiences from existing reproducible documents, reduce maintenance burden, and make iterative course updates more reliable. Actual classroom adoption is not verifiable from repository contents. -## Functionality +# Functionality -The package exposes a canonical `tutorize()` API and keeps backward-compatible wrappers (`convert_to_tutorial()`, `convert_folder()`). Additional authoring tools include: +The package provides a high-level `tutorize()` function and compatibility wrappers for existing workflows. Core functionality includes: -- `lint_source()` for pedagogy-focused validations, -- `load_question_bank()` / `validate_question_bank()` for external banked MCQs, -- `write_tutorize_report()` for machine-readable conversion summaries, -- `export_lms_manifest()` and `export_tutorial_package()` for downstream sharing. +- parsing `.Rmd` and `.qmd` source files into text, setup chunks, R chunks, non-R chunks, MCQ blocks, and question-bank references; +- generating `learnr` exercise chunks and solution chunks; +- generating `quarto-live` compatible exercise scaffolds; +- inserting `learnr`, `gradethis`, and `gradethis_setup()` into generated `learnr` setup chunks; +- preserving non-R fenced blocks rather than converting them incorrectly; +- normalizing generated labels to reduce chunk-label collisions; +- supporting instructor tags such as `skip`, `exercise-only`, `solution-only`, `mcq`, `narrative-only`, `locked`, and `hints`; +- loading reusable YAML or JSON question banks; +- linting source documents before conversion; +- writing JSON or YAML conversion reports; +- exporting LMS-oriented manifests for downstream course workflows; +- providing RStudio addins and a command-line script for instructor use. -For workflow robustness, `tutorizeR` provides both interactive UI paths (RStudio addins) and non-interactive CLI execution. +# Educational Use -## State of the art and alternatives +The package supports workflows common in undergraduate statistics, data science, and R programming courses. A typical use case starts with an instructor-maintained Quarto lesson that imports data, performs a data manipulation task, builds a visualization, and asks students to interpret the result. `tutorizeR` converts that lesson into a tutorial with exercise areas, solutions, and MCQs. -Prior approaches generally require one of three manual paths: +The repository includes an example course module in `inst/examples/example_course_module/`. The module uses a small synthetic dataset to demonstrate a realistic lesson on study patterns and quiz performance. It includes a source Quarto document, a transformed `learnr` tutorial, generated exercises, grading examples, and a local CSV file. The example is suitable for demonstrating the package to instructors without relying on private course data. -- direct authoring of `learnr` tutorials from scratch in the RStudio environment; -- copy-and-paste conversion from teaching notebooks or Quarto documents into a dedicated tutorial repository; -- ad-hoc scripts for grading heuristics and QCM/MCQ insertion. +The design is inspired by workflows that occur in introductory and advanced undergraduate statistics or data science courses, including course-code contexts such as STT-1100 and STT-4230. No private course material is included. Specific deployment in those courses is not verifiable from repository contents. -`tutorizeR` unifies these steps by preserving a source-first workflow: -source content remains in `.Rmd`/`.qmd` format, while conversion to interactive -activities is performed automatically with deterministic labels, optional linting, -and explicit reporting artefacts. This reduces duplicated maintenance work and -keeps a single source of truth for instructors. +# Availability -## Quality assurance +The package source is available at: -The package includes tests and linting, with automated checks covering core parser/transform/validation/report paths. New/changed features are documented via roxygen and vignettes, and conversion edge cases are regression tested (including non-R chunks, inline code fences, duplicated labels, and Quarto-only fixtures). +`https://github.com/AurelienNicosiaULaval/tutorizeR` -## AI usage disclosure +The repository includes installation instructions, tests, vignettes, examples, contribution guidelines, a code of conduct, citation metadata, and reviewer-facing JOSE preparation documents. -No generative AI tools were used in the production of the software implementation or the `tutorizeR` manuscript. +# Quality Assurance -When using `tutorizeR` by others for educational material conversion, the package does not impose any AI model dependency and remains fully script-driven and reproducible. +The package includes `testthat` tests for parsing, conversion, exercise generation, MCQ handling, question-bank loading, validation errors, report writing, LMS manifest export, regression fixtures, `gradethis` setup generation, `quarto-live` output, and publication readiness assets. GitHub Actions are configured to run `R CMD check`, tests, linting, and coverage. -## Limitations +Before submission, the maintainers should run a fresh local check on the current tree: -- LMS publication is currently manifest-first export (Canvas/Moodle/generic); no direct LMS API publishing is included yet. -- Learnr rendering is optional and requires optional dependencies (`learnr`, `gradethis`) at render-time. -- Question-bank integration is file-based (local YAML/JSON) in the current release. -- The output currently targets single-file conversion pipelines and folder conversion with documented defaults. +```bash +Rscript -e "testthat::test_local()" +Rscript -e "lintr::lint_package()" +R CMD build . +R CMD check --as-cran --no-manual tutorizeR_*.tar.gz +``` -## Availability and contribution +# AI Usage Disclosure -The package source is available on GitHub at: -`https://github.com/AurelienNicosiaULaval/tutorizeR`. +Codex using GPT-5 was used on 2026-05-31 to assist with repository audit text, reviewer documentation, example files, tests, and manuscript revisions. The maintainer is responsible for reviewing, validating, and approving all content before submission. -Contributions and bug reports are welcome via GitHub Issues/PRs with the repository’s contribution guide and code of conduct. - -## References +# References diff --git a/tests/testthat/test-jose-readiness.R b/tests/testthat/test-jose-readiness.R new file mode 100644 index 0000000..830039d --- /dev/null +++ b/tests/testthat/test-jose-readiness.R @@ -0,0 +1,113 @@ +local_edition(3) + +test_that("learnr conversion injects gradethis setup and exercise scaffolds", { + input <- tempfile(fileext = ".Rmd") + writeLines(c( + "---", + "title: feedback test", + "---", + "", + "```{r setup}", + "x <- 1", + "```", + "", + "```{r add-one}", + "# tutorizeR: hints=Use x + 1", + "x + 1", + "```" + ), input) + + report <- tutorize( + input = input, + output_dir = tempdir(check = TRUE), + format = "learnr", + assessment = "code", + overwrite = TRUE, + verbose = FALSE + ) + + lines <- readLines(report$output_file, warn = FALSE) + expect_true(any(grepl("library\\(learnr\\)", lines))) + expect_true(any(grepl("library\\(gradethis\\)", lines))) + expect_true(any(grepl("gradethis_setup\\(\\)", lines))) + expect_true(any(grepl("exercise=TRUE", lines, fixed = TRUE))) + expect_true(any(grepl("trz-sol-add-one", lines, fixed = TRUE))) + expect_true(any(grepl("Use x \\+ 1", lines))) +}) + +test_that("quarto-live conversion creates webr exercises and solution callouts", { + input <- tempfile(fileext = ".qmd") + writeLines(c( + "---", + "title: quarto live test", + "---", + "", + "```{r summarize}", + "mean(1:5)", + "```" + ), input) + + report <- tutorize( + input = input, + output_dir = tempdir(check = TRUE), + format = "quarto-live", + assessment = "both", + overwrite = TRUE, + verbose = FALSE + ) + + lines <- readLines(report$output_file, warn = FALSE) + expect_true(any(grepl("format: live-html", lines, fixed = TRUE))) + expect_true(any(grepl("_extensions/r-wasm/live/_knitr.qmd", lines, fixed = TRUE))) + expect_true(any(grepl("```\\{webr\\}", lines))) + expect_true(any(grepl("::: \\{\\.callout-tip collapse='true'\\}", lines))) + expect_true(any(grepl("::: \\{\\.callout-note\\}", lines))) +}) + +test_that("MCQ references require an explicit question bank", { + input <- tempfile(fileext = ".qmd") + writeLines(c( + "---", + "title: bank test", + "---", + "", + "```{tutorizeR-mcq-ref}", + "ids: [missing-id]", + "strategy: ordered", + "```" + ), input) + + expect_error( + tutorize( + input = input, + output_dir = tempdir(check = TRUE), + format = "learnr", + assessment = "both", + overwrite = TRUE, + verbose = FALSE + ), + class = "tutorizeR_error_validation" + ) +}) + +test_that("example course module is packaged with expected teaching artifacts", { + source_example_dir <- testthat::test_path( + "..", "..", "inst", "examples", "example_course_module" + ) + installed_example_dir <- system.file( + "examples", "example_course_module", package = "tutorizeR" + ) + + example_dir <- if (dir.exists(source_example_dir)) { + source_example_dir + } else { + installed_example_dir + } + + expect_true(dir.exists(example_dir)) + expect_true(file.exists(file.path(example_dir, "source_lesson.qmd"))) + expect_true(file.exists(file.path(example_dir, "transformed_tutorial.Rmd"))) + expect_true(file.exists(file.path(example_dir, "generated_exercises.Rmd"))) + expect_true(file.exists(file.path(example_dir, "grading_examples.R"))) + expect_true(file.exists(file.path(example_dir, "student_activity.csv"))) +}) diff --git a/vignettes/automatic-exercise-generation-feedback.Rmd b/vignettes/automatic-exercise-generation-feedback.Rmd new file mode 100644 index 0000000..8b62f9f --- /dev/null +++ b/vignettes/automatic-exercise-generation-feedback.Rmd @@ -0,0 +1,59 @@ +--- +title: "Automatic Exercise Generation and Feedback" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Automatic Exercise Generation and Feedback} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +`tutorizeR` turns ordinary R chunks into student exercise areas and hidden or collapsible solution material. For `learnr`, the setup chunk includes `learnr`, `gradethis`, and `gradethis_setup()` so that instructors can add answer checks after conversion. + +## Annotated source chunk + + ```r + # tutorizeR: hints=Use group_by() before summarise()|Remember .groups = "drop" + activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) + ``` + +## Conversion + +```{r eval=FALSE} +library(tutorizeR) + +report <- tutorize( + input = "source_lesson.qmd", + format = "learnr", + assessment = "code", + overwrite = TRUE +) + +print(report) +``` + +## Adding a gradethis check + +After conversion, instructors can add `gradethis` checks to generated exercise chunks using the normal `learnr` conventions: + + ```r + grade_this({ + pass_if(~ identical(names(.result), c("program", "mean_hours", "mean_score"))) + fail("Check the grouping variable and summary column names.") + }) + ``` + +This pattern keeps the initial conversion automated while leaving final grading logic under instructor control. + +## Feedback design + +Feedback should focus on the learning objective rather than only the final answer. For example, an exercise about grouped summaries should check that students identify the grouping variable, compute the intended summaries, and produce a tidy table. diff --git a/vignettes/getting-started.Rmd b/vignettes/getting-started.Rmd index f58782a..ce88101 100644 --- a/vignettes/getting-started.Rmd +++ b/vignettes/getting-started.Rmd @@ -1,8 +1,8 @@ --- -title: "Getting started for teachers" +title: "Getting Started with tutorizeR" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Getting started for teachers} + %\VignetteIndexEntry{Getting Started with tutorizeR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,15 +11,13 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -`tutorizeR` converts existing `.Rmd` or `.qmd` files into interactive -teaching material. +`tutorizeR` converts existing `.Rmd` or `.qmd` files into interactive teaching material. The usual workflow is to keep the instructor's source document as the single source of truth, then generate a student-facing tutorial for a specific teaching context. -## Minimal reproducible workflow +## Minimal workflow ```{r eval=FALSE} library(tutorizeR) -# Convert one file to learnr report <- tutorize( input = "lesson.qmd", format = "learnr", @@ -30,9 +28,13 @@ report <- tutorize( print(report) ``` +The returned report records the input file, output file, format, assessment mode, generated exercises, MCQs, warnings, lint results, and render status. + ## Batch conversion ```{r eval=FALSE} +library(tutorizeR) + folder_report <- convert_folder( dir = "course_material/", recursive = TRUE, @@ -44,6 +46,15 @@ folder_report <- convert_folder( print(folder_report) ``` +## Pre-conversion linting + +```{r eval=FALSE} +library(tutorizeR) + +lint <- lint_source("lesson.qmd", strict = FALSE) +print(lint) +``` + ## Source annotation tags Use comments inside R chunks: @@ -58,8 +69,9 @@ Use comments inside R chunks: ## Explicit MCQ block schema -```text -```{tutorizeR-mcq} +The YAML content inside a `tutorizeR-mcq` block has this structure: + +```yaml question: "2 + 2 = ?" answers: - text: "4" @@ -67,4 +79,11 @@ answers: - text: "5" correct: false ``` + +## Reviewer smoke test + +The package includes a complete example module in `inst/examples/example_course_module/`. After installation, an instructor can locate it with: + +```{r eval=FALSE} +system.file("examples", "example_course_module", package = "tutorizeR") ``` diff --git a/vignettes/jose-submission-readiness.Rmd b/vignettes/jose-submission-readiness.Rmd new file mode 100644 index 0000000..c8b936e --- /dev/null +++ b/vignettes/jose-submission-readiness.Rmd @@ -0,0 +1,39 @@ +--- +title: "JOSE Submission Readiness" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{JOSE Submission Readiness} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +This vignette points reviewers to the repository artifacts prepared for a future Journal of Open Source Education submission. + +## Main artifacts + +- `paper/paper.md` +- `paper/paper.bib` +- `docs/jose_audit.md` +- `docs/educational_use_cases.md` +- `docs/jose_checklist.md` +- `docs/jose_submission_report.md` +- `inst/examples/example_course_module/` + +## Local verification + +```{r eval=FALSE} +testthat::test_local() +lintr::lint_package() + +system("R CMD build .") +system("R CMD check --as-cran --no-manual tutorizeR_*.tar.gz") +``` + +## Evidence boundaries + +Educational use cases are documented in the repository. Actual classroom adoption, external adoption, and public GitHub history are not verifiable from local repository contents. + diff --git a/vignettes/large-undergraduate-courses.Rmd b/vignettes/large-undergraduate-courses.Rmd new file mode 100644 index 0000000..ed13402 --- /dev/null +++ b/vignettes/large-undergraduate-courses.Rmd @@ -0,0 +1,73 @@ +--- +title: "Using tutorizeR in Large Undergraduate Courses" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Using tutorizeR in Large Undergraduate Courses} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +Large undergraduate courses need consistent materials, reproducible updates, and clear handoffs between instructors and teaching assistants. `tutorizeR` is designed for this kind of operational teaching workflow. + +Specific deployment in named courses such as STT-1100 or STT-4230 is not verifiable from repository contents. + +## Course folder workflow + +```text +course/ + lessons/ + week01-introduction.qmd + week02-data-import.qmd + week03-visualization.qmd + question-bank/ + core-concepts.yml + tutorials/ + reports/ +``` + +## Batch conversion + +```{r eval=FALSE} +library(tutorizeR) + +qb <- load_question_bank("course/question-bank") + +folder_report <- convert_folder( + dir = "course/lessons", + recursive = TRUE, + output_dir = "course/tutorials", + format = "learnr", + assessment = "both", + question_bank = qb, + mcq_source = "mixed", + lint_strict = TRUE, + overwrite = TRUE +) + +print(folder_report) +``` + +## Teaching assistant review + +Teaching assistants can review generated outputs and reports before release: + +```{r eval=FALSE} +library(tutorizeR) + +lint <- lint_source( + input = "course/lessons/week03-visualization.qmd", + question_bank = qb, + strict = FALSE +) + +print(lint) +``` + +## Operational benefits + +The main benefit is not that tutorials are generated automatically once. The benefit is that a whole course team can regenerate the same materials after corrections, new datasets, or revised learning objectives. + diff --git a/vignettes/quarto-lesson-interactive-tutorial.Rmd b/vignettes/quarto-lesson-interactive-tutorial.Rmd new file mode 100644 index 0000000..ece2ad5 --- /dev/null +++ b/vignettes/quarto-lesson-interactive-tutorial.Rmd @@ -0,0 +1,82 @@ +--- +title: "Converting a Quarto Lesson into an Interactive Tutorial" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Converting a Quarto Lesson into an Interactive Tutorial} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +Many instructors prepare lessons in Quarto because it supports narrative, executable code, figures, tables, and reproducible publishing. `tutorizeR` keeps that authoring workflow intact while producing an interactive tutorial for students. + +## Source lesson + +A source `.qmd` lesson can contain narrative text, setup code, examples, and MCQ blocks: + + --- + title: "Weekly study patterns" + --- + + ## Learning goal + + Students will summarize study time and relate it to quiz performance. + + ```r + library(tidyverse) + activity <- readr::read_csv("student_activity.csv") + ``` + + ```r + activity |> + group_by(program) |> + summarise(mean_hours = mean(study_hours), .groups = "drop") + ``` + + ```yaml + question: "Which summary is most appropriate for comparing programs?" + answers: + - text: "Mean study hours by program" + correct: true + - text: "The first row of the data" + correct: false + ``` + +## Conversion + +```{r eval=FALSE} +library(tutorizeR) + +report <- tutorize( + input = "source_lesson.qmd", + output_dir = "generated", + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(report) +``` + +## Quarto live output + +For browser-executable Quarto output, target `quarto-live`: + +```{r eval=FALSE} +library(tutorizeR) + +report <- tutorize( + input = "source_lesson.qmd", + output_dir = "generated", + format = "quarto-live", + assessment = "code", + overwrite = TRUE +) + +print(report) +``` + +The `quarto-live` workflow requires the Quarto live extension in the teaching project. That dependency is intentionally not vendored by `tutorizeR`. diff --git a/vignettes/question-bank.Rmd b/vignettes/question-bank.Rmd index 9f5b9fd..9410220 100644 --- a/vignettes/question-bank.Rmd +++ b/vignettes/question-bank.Rmd @@ -22,13 +22,13 @@ print(validate_question_bank(qb, strict = FALSE)) ## Reference bank questions in source files -```text -```{tutorizeR-mcq-ref} +The YAML content inside a `tutorizeR-mcq-ref` block can reference existing bank items: + +```yaml ids: [sample-mean] strategy: ordered shuffle_answers: false ``` -``` ## Convert with bank-enabled MCQ mode diff --git a/vignettes/reproducible-data-science-assignments.Rmd b/vignettes/reproducible-data-science-assignments.Rmd new file mode 100644 index 0000000..d06b0fc --- /dev/null +++ b/vignettes/reproducible-data-science-assignments.Rmd @@ -0,0 +1,72 @@ +--- +title: "Building Reproducible Data Science Assignments" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Building Reproducible Data Science Assignments} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +Data science assignments are easier to maintain when the instructor can keep one source document and regenerate student-facing materials after revisions. `tutorizeR` supports that workflow by converting annotated source documents into tutorials with exercises and solutions. + +## Suggested assignment structure + +```text +assignment-week03/ + source_lesson.qmd + data/ + student_activity.csv + generated/ + week03-tutorial.Rmd + conversion-report.json +``` + +## Reproducible conversion script + +```{r eval=FALSE} +library(tutorizeR) + +source_file <- "assignment-week03/source_lesson.qmd" + +report <- tutorize( + input = source_file, + output_dir = "assignment-week03/generated", + format = "learnr", + assessment = "both", + seed = 20260531, + overwrite = TRUE, + lint_strict = TRUE +) + +write_tutorize_report( + report = report, + file = "assignment-week03/generated/conversion-report.json", + format = "json" +) +``` + +## Why the seed matters + +For teaching workflows, a fixed seed makes generated setup chunks reproducible. This is useful when students, teaching assistants, and instructors need to see the same randomized example or simulated dataset. + +## LMS manifest + +```{r eval=FALSE} +library(tutorizeR) + +manifest <- export_lms_manifest( + input = "assignment-week03/source_lesson.qmd", + output_file = "assignment-week03/generated/lms-manifest.json", + profile = "canvas", + include_solutions = FALSE +) + +print(manifest) +``` + +The manifest is a local metadata artifact. Direct LMS publication is not part of the current package functionality. + From 864c4895b926327c7e0b4132804b68da544044c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 10:40:08 -0400 Subject: [PATCH 02/10] docs: strengthen JOSE submission readiness --- .Rbuildignore | 1 + .github/workflows/r.yml | 12 +- LICENSE-CONTENT.md | 14 ++ NEWS.md | 3 + README.md | 158 ++++++++------- _pkgdown.yml | 48 +++-- docs/educational_use_evidence.md | 79 ++++++++ docs/jose_blockers_report.md | 104 ++++++++++ docs/jose_checklist.md | 2 +- docs/jose_pr_final_report.md | 184 ++++++++++++++++++ docs/jose_release_bundle.md | 54 +++++ docs/jose_review_checklist.md | 101 ++++++++++ docs/jose_submission_guide.md | 109 +++++++++++ docs/jose_submission_report.md | 10 +- inst/examples/example_course_module/README.md | 72 +++++-- .../expected/conversion-report.json | 35 ++++ .../expected/lesson-source-live.qmd | 159 +++++++++++++++ .../expected/lesson-source-tutorial.Rmd | 153 +++++++++++++++ .../generated_exercises.Rmd | 45 ----- .../example_course_module/grading_examples.R | 20 -- .../example_course_module/lesson-source.qmd | 91 +++++++++ .../question-bank/questions.yml | 16 ++ .../example_course_module/run-example.R | 72 +++++++ .../example_course_module/source_lesson.qmd | 72 ------- .../transformed_tutorial.Rmd | 90 --------- paper/paper.bib | 86 +++++++- paper/paper.md | 66 +++---- tests/testthat/test-examples.R | 135 +++++++++++++ tests/testthat/test-jose-readiness.R | 10 +- ...automatic-exercise-generation-feedback.Rmd | 2 +- vignettes/conversion-rmd-vs-qmd.Rmd | 59 +++++- vignettes/getting-started.Rmd | 68 ++++--- vignettes/lint-and-debug.Rmd | 54 ++++- vignettes/mcq-and-assessment.Rmd | 75 ++++++- .../quarto-lesson-interactive-tutorial.Rmd | 4 +- vignettes/question-bank.Rmd | 74 +++++-- .../reproducible-data-science-assignments.Rmd | 6 +- vignettes/teaching-workflow-case-study.Rmd | 111 +++++++++++ 38 files changed, 1994 insertions(+), 460 deletions(-) create mode 100644 LICENSE-CONTENT.md create mode 100644 docs/educational_use_evidence.md create mode 100644 docs/jose_blockers_report.md create mode 100644 docs/jose_pr_final_report.md create mode 100644 docs/jose_release_bundle.md create mode 100644 docs/jose_review_checklist.md create mode 100644 docs/jose_submission_guide.md create mode 100644 inst/examples/example_course_module/expected/conversion-report.json create mode 100644 inst/examples/example_course_module/expected/lesson-source-live.qmd create mode 100644 inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd delete mode 100644 inst/examples/example_course_module/generated_exercises.Rmd delete mode 100644 inst/examples/example_course_module/grading_examples.R create mode 100644 inst/examples/example_course_module/lesson-source.qmd create mode 100644 inst/examples/example_course_module/question-bank/questions.yml create mode 100644 inst/examples/example_course_module/run-example.R delete mode 100644 inst/examples/example_course_module/source_lesson.qmd delete mode 100644 inst/examples/example_course_module/transformed_tutorial.Rmd create mode 100644 tests/testthat/test-examples.R create mode 100644 vignettes/teaching-workflow-case-study.Rmd diff --git a/.Rbuildignore b/.Rbuildignore index c6f66df..5d24a01 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,6 +1,7 @@ ^.*\.Rproj$ ^\.Rproj\.user$ ^LICENSE\.md$ +^LICENSE-CONTENT\.md$ ^\.github$ ^ROADMAP\.md$ ^docs$ diff --git a/.github/workflows/r.yml b/.github/workflows/r.yml index fd1e80d..91cb6b3 100644 --- a/.github/workflows/r.yml +++ b/.github/workflows/r.yml @@ -4,7 +4,7 @@ on: push: branches: [main] pull_request: - branches: [main] + branches: [main, release/v0.4.4] permissions: contents: read @@ -98,17 +98,17 @@ jobs: run: | cov <- covr::package_coverage() print(cov) - by <- as.data.frame(covr::coverage_to_list(cov)) - by$file <- rownames(by) + cov_list <- covr::coverage_to_list(cov) + file_coverage <- cov_list$filecoverage core_files <- c("R/parser.R", "R/transform.R", "R/validation.R", "R/report.R") - missing <- setdiff(core_files, by$file) + missing <- setdiff(core_files, names(file_coverage)) if (length(missing) > 0L) { stop(sprintf("Missing core files in coverage table: %s", paste(missing, collapse = ", "))) } - core_pct <- mean(by$filecoverage[match(core_files, by$file)]) - total_pct <- covr::percent_coverage(cov) + core_pct <- mean(unname(file_coverage[core_files])) + total_pct <- as.numeric(cov_list$totalcoverage) cat(sprintf("Coverage total: %.2f%%\n", total_pct)) cat(sprintf("Coverage core: %.2f%%\n", core_pct)) diff --git a/LICENSE-CONTENT.md b/LICENSE-CONTENT.md new file mode 100644 index 0000000..6db1d9f --- /dev/null +++ b/LICENSE-CONTENT.md @@ -0,0 +1,14 @@ +# Creative Commons Attribution 4.0 International + +Educational example materials in `inst/examples/` and graphical documentation assets in `man/figures/` are licensed under the Creative Commons Attribution 4.0 International License unless otherwise specified. + +You are free to: + +- share, copy, and redistribute the material in any medium or format; +- adapt, remix, transform, and build upon the material for any purpose, including teaching and research. + +You must give appropriate credit, provide a link to the license, and indicate if changes were made. + +License text: + +https://creativecommons.org/licenses/by/4.0/legalcode diff --git a/NEWS.md b/NEWS.md index 7a4d5f2..32c020e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,9 @@ - Added JOSE preparation artifacts, educational use-case documentation, expanded vignettes, an example course module, publication-readiness tests, and pkgdown navigation for educational examples. +- Recentered the review branch on JOSE software-submission requirements, + clarified educational evidence boundaries, added CC-BY content licensing, + and replaced internal smoke-test paths with installable example workflows. # tutorizeR 0.4.3 diff --git a/README.md b/README.md index 14091b6..a83d560 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,7 @@ # tutorizeR -`tutorizeR` helps teachers convert `.Rmd` and `.qmd` material into interactive -`learnr` or `quarto-live` resources with linting, reusable MCQ banks, and -export/report tooling. +`tutorizeR` helps instructors convert `.Rmd` and `.qmd` teaching material into interactive `learnr` tutorials or `quarto-live` resources. It supports pedagogical linting, reusable question banks, generated exercise and solution areas, conversion reports, and workflow artifacts for reproducible teaching. ![tutorizeR workflow](man/figures/tutorize-workflow.svg) @@ -35,83 +33,111 @@ install.packages( ) ``` -## End-to-end workflow +## Educational contribution + +`tutorizeR` is being prepared as a potential JOSE software submission: open-source educational infrastructure for computational teaching. It is intended for instructors who already maintain R Markdown or Quarto lessons and want to transform those lessons into interactive learning resources without duplicating source material. The package helps create active coding exercises, conceptual MCQs, reusable question-bank prompts, and feedback-ready `learnr` tutorials while preserving a source-first workflow. + +The repository demonstrates the workflow through installable examples, tests, vignettes, and reviewer documentation. It does not claim measured learning gains, improved grades, improved engagement, classroom deployment, or broad adoption unless such evidence is added to the repository. + +## Installed example workflow ```r library(tutorizeR) -# 1) Load reusable question bank -qb <- load_question_bank("inst/question-bank") +example_dir <- system.file( + "examples", + "example_course_module", + package = "tutorizeR" +) + +work_dir <- file.path(tempdir(), "tutorizeR-example") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) + +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) -# 2) Lint source before conversion -lint <- lint_source("lesson.qmd", question_bank = qb, strict = FALSE) -print(lint) +source_file <- file.path(work_dir, "lesson-source.qmd") +question_bank <- load_question_bank(file.path(example_dir, "question-bank")) -# 3) Convert with mixed MCQ strategy (inline + bank) -rep <- tutorize( - input = "lesson.qmd", +report <- tutorize( + input = source_file, format = "learnr", assessment = "both", - question_bank = qb, + output_dir = work_dir, + question_bank = question_bank, mcq_source = "mixed", - lint_strict = TRUE, - overwrite = TRUE + overwrite = TRUE, + verbose = FALSE ) -print(rep) +print(report) +``` -# 4) Export conversion report JSON for CI tracing -write_tutorize_report(rep, "lesson-report.json", format = "json") +The complete example is in `inst/examples/example_course_module/`. -# 5) Export LMS manifest -manifest <- export_lms_manifest("lesson.qmd", profile = "canvas") -print(manifest) -``` +## Reproducibility checklist -## Reproducibility checklist (reviewer/journal-ready) +Developer checks: ```bash -# 1) Install dependencies -Rscript -e 'remotes::install_github("AurelienNicosiaULaval/tutorizeR")' - -# 2) Lint and tests +Rscript -e "testthat::test_local('.')" Rscript -e "lintr::lint_package()" -Rscript -e "devtools::test()" - -# 3) Build and CRAN-style check from a tarball R CMD build . R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz - -# 4) Manual smoke path (requires learnr in the environment) -Rscript -e "library(tutorizeR); tutorize('tests/testthat/fixtures/rmd/basic_code.Rmd', format = 'learnr', overwrite = TRUE, output_dir = tempdir(), verbose = FALSE)" ``` -Expected on this repository: +Installed smoke test: + +```r +library(tutorizeR) -- `devtools::test()` passes (currently 98 tests + new fixtures). -- `R CMD check --as-cran --no-manual` yields no errors, no warnings; one NOTE for a first submission is acceptable. +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +work_dir <- file.path(tempdir(), "tutorizeR-example") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) -## JOSS submission note +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) -For JOSS, you submit the manuscript source (`paper/paper.md`) and bibliography (`paper/paper.bib`). -You do **not** need to attach a PDF in the repository for submission. -If you want a local PDF preview, render it with: +source_file <- file.path(work_dir, "lesson-source.qmd") -```bash -cd paper -Rscript -e "rmarkdown::render('paper.md', output_format = 'pdf_document', output_file = 'paper.pdf')" +report <- tutorize( + input = source_file, + format = "learnr", + assessment = "both", + output_dir = work_dir, + question_bank = load_question_bank(file.path(example_dir, "question-bank")), + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) + +print(report) ``` -For reviewers/authors, full submission steps are in: +## JOSE submission note -- `docs/joss_submission_guide.md` -- `docs/joss_release_bundle.md` +`tutorizeR` is a potential JOSE software submission as educational technology and infrastructure. JOSE documentation states that software submissions should support teaching and learning, or make an educational process better, faster, easier, or simpler. The repository currently supports that claim through package functionality, tests, documentation, vignettes, and an installable teaching example. + +Reviewer-facing JOSE materials: + +- `docs/jose_submission_guide.md` +- `docs/jose_release_bundle.md` +- `docs/jose_review_checklist.md` +- `docs/educational_use_evidence.md` +- `docs/jose_blockers_report.md` +- `docs/jose_pr_final_report.md` +- `inst/examples/example_course_module/README.md` +- `paper/paper.md` +- `paper/paper.bib` + +Not verifiable from repository contents: formal learning-outcome evaluation, classroom deployment, broad instructor adoption, current CRAN publication, and JOSE submission or acceptance. -JOSS 2026 scope checks (important): +## Secondary target: JOSS -- Confirm repository-wide value (not a thin/one-off utility), open development evidence, and at least ~6 months public history. -- Keep issue/PR traces visible and use a stable release/tag strategy. -- Include the AI usage disclosure in `paper/paper.md` if AI was used during coding, docs, or writing. +JOSS remains a secondary possibility if the maintainers decide to emphasize software contribution rather than educational infrastructure. Existing JOSS-oriented documents are kept for that possible route, but the primary preparation in this branch is JOSE. + +- `docs/joss_submission_guide.md` +- `docs/joss_release_bundle.md` ## Main API @@ -138,10 +164,9 @@ Inside R chunks: ## MCQ block schemas -Explicit question block: +Explicit question blocks use YAML inside a `tutorizeR-mcq` fenced block: -```text -```{tutorizeR-mcq} +```yaml question: "2 + 2 = ?" answers: - text: "4" @@ -149,23 +174,20 @@ answers: - text: "5" correct: false ``` -``` -Question-bank reference block: +Question-bank reference blocks use YAML inside a `tutorizeR-mcq-ref` fenced block: -```text -```{tutorizeR-mcq-ref} +```yaml ids: [mean-basic, sum-basic] strategy: ordered shuffle_answers: false ``` -``` ## Addins - Convert active file - Convert folder -- Preview conversion (Source / Output / Diff / Lint / Logs) +- Preview conversion with Source, Output, Diff, Lint, and Logs tabs ## CLI mode @@ -177,12 +199,15 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo ## Known limitations - `learnr` render checks require `learnr` and `gradethis` installed. -- LMS export is manifest-only in v0.4 (no direct remote publishing API). -- Question bank is local file based (YAML/JSON) in v0.4. +- `quarto-live` output requires the Quarto live extension in the teaching project. +- LMS export is manifest-only in v0.4, with no direct remote LMS publishing API. +- Question banks are local YAML or JSON files in v0.4. +- Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. ## Documentation - `vignettes/getting-started.Rmd` +- `vignettes/teaching-workflow-case-study.Rmd` - `vignettes/quarto-lesson-interactive-tutorial.Rmd` - `vignettes/reproducible-data-science-assignments.Rmd` - `vignettes/automatic-exercise-generation-feedback.Rmd` @@ -193,13 +218,8 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo - `vignettes/mcq-and-assessment.Rmd` - `vignettes/lint-and-debug.Rmd` -## JOSE preparation +## License -Reviewer-facing preparation files are available in: +The package code is released under the MIT license. The CRAN-style license metadata is stored in `LICENSE`, and the full MIT license text is available in `LICENSE.md`. -- `docs/jose_audit.md` -- `docs/educational_use_cases.md` -- `docs/jose_checklist.md` -- `docs/jose_submission_report.md` -- `paper/paper.md` -- `inst/examples/example_course_module/` +Educational example materials in `inst/examples/` and graphical documentation assets in `man/figures/` are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md`. diff --git a/_pkgdown.yml b/_pkgdown.yml index 7a6cb03..9943336 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -7,27 +7,42 @@ home: navbar: structure: - left: [intro, articles, reference, educational_examples, jose_submission] + left: [intro, articles, reference, jose_readiness, teaching_examples, educational_adoption] right: [search, github] components: - educational_examples: - text: Educational Examples - menu: - - text: Example course module - href: articles/large-undergraduate-courses.html - - text: Reproducible assignments - href: articles/reproducible-data-science-assignments.html - - text: Automatic feedback - href: articles/automatic-exercise-generation-feedback.html - jose_submission: - text: JOSE Submission + jose_readiness: + text: JOSE readiness menu: + - text: JOSE submission guide + href: ../docs/jose_submission_guide.md + - text: JOSE review checklist + href: ../docs/jose_review_checklist.md - text: JOSE audit href: ../docs/jose_audit.md - - text: JOSE checklist - href: ../docs/jose_checklist.md - - text: JOSE report - href: ../docs/jose_submission_report.md + - text: JOSE blockers report + href: ../docs/jose_blockers_report.md + teaching_examples: + text: Teaching examples + menu: + - text: Teaching workflow case study + href: articles/teaching-workflow-case-study.html + - text: Getting started + href: articles/getting-started.html + - text: Question bank + href: articles/question-bank.html + - text: Lint and debug + href: articles/lint-and-debug.html + - text: Example course module + href: ../inst/examples/example_course_module/README.md + educational_adoption: + text: Educational adoption + menu: + - text: Educational use evidence + href: ../docs/educational_use_evidence.md + - text: Educational use cases + href: ../docs/educational_use_cases.md + - text: Large undergraduate courses + href: articles/large-undergraduate-courses.html reference: - title: Core conversion @@ -50,6 +65,7 @@ articles: navbar: Getting started contents: - getting-started + - teaching-workflow-case-study - quarto-lesson-interactive-tutorial - reproducible-data-science-assignments - title: Authoring and syntax diff --git a/docs/educational_use_evidence.md b/docs/educational_use_evidence.md new file mode 100644 index 0000000..0d9bbb4 --- /dev/null +++ b/docs/educational_use_evidence.md @@ -0,0 +1,79 @@ +# Educational Use Evidence + +Date: 2026-05-31 + +This document separates demonstrated repository evidence from plausible but unevaluated educational claims. + +## What Is Currently Demonstrated by the Repository + +The repository demonstrates: + +- an R package that converts `.Rmd` and `.qmd` teaching documents into `learnr` or `quarto-live` resources; +- parser, transformation, validation, linting, question-bank, reporting, export, and addin functionality; +- test fixtures covering conversion, MCQ handling, question-bank validation, reports, exports, and edge cases; +- an installable example module in `inst/examples/example_course_module/`; +- vignettes describing instructor workflows and limitations; +- reviewer-facing JOSE documentation; +- open-source governance files, including contribution guide and code of conduct. + +## What Is Plausible but Not Yet Formally Evaluated + +It is plausible that `tutorizeR` may help instructors: + +- reduce manual duplication between source lessons and tutorials; +- maintain reproducible teaching materials more consistently; +- create more frequent formative practice opportunities; +- review generated learning resources with teaching assistants; +- adapt source-first workflows across multiple course modules. + +These are workflow plausibility statements, not measured educational outcomes. + +Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. + +## What Is Not Claimed + +The repository does not claim: + +- improved student grades; +- improved student engagement; +- improved learning outcomes; +- reduced teaching time measured in controlled conditions; +- documented classroom deployment; +- broad adoption by external instructors; +- JOSE submission, review, or acceptance; +- CRAN publication. + +## Evidence Available to Reviewers + +Reviewers can inspect: + +- `inst/examples/example_course_module/README.md`; +- `inst/examples/example_course_module/run-example.R`; +- `vignettes/teaching-workflow-case-study.Rmd`; +- `tests/testthat/test-examples.R`; +- `tests/testthat/test-jose-readiness.R`; +- `paper/paper.md`; +- `docs/jose_review_checklist.md`; +- `docs/jose_submission_guide.md`. + +## Evidence Still Missing Before a Stronger JOSE Submission + +Not verifiable from repository contents: + +- actual classroom deployment; +- instructor adoption outside the maintainer; +- formal student feedback; +- student outcome data; +- teaching assistant workflow evidence; +- long-term use across multiple cohorts. + +## Claims that must not be made + +- Do not claim improved student grades unless measured. +- Do not claim improved engagement unless measured. +- Do not claim classroom deployment unless documented. +- Do not claim broad adoption unless usage evidence exists. +- Do not claim JOSE readiness solely because R CMD check passes. +- Do not claim direct LMS publishing, because current support is manifest-oriented. +- Do not claim current CRAN availability unless verified. + diff --git a/docs/jose_blockers_report.md b/docs/jose_blockers_report.md new file mode 100644 index 0000000..34066d6 --- /dev/null +++ b/docs/jose_blockers_report.md @@ -0,0 +1,104 @@ +# JOSE Blockers Report + +Date: 2026-05-31 +Branch: `review/jose-readiness` +PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 + +## Executive Summary + +The repository is a credible candidate for a future JOSE software submission because it is open-source educational infrastructure for converting reproducible R Markdown and Quarto teaching materials into interactive tutorials. The main weakness before this pass was that the PR still read like a JOSS/CRAN readiness pass rather than a JOSE submission package. The central corrections are to make the educational contribution explicit, avoid unverified pedagogical claims, provide an installable teaching example, and document the evidence boundary. + +Sources consulted: + +- Open Journals. JOSE submitting guide. https://openjournals.readthedocs.io/en/jose/submitting.html +- Open Journals. JOSE review criteria. https://openjournals.readthedocs.io/en/jose/review_criteria.html +- Open Journals. JOSE review checklist. https://openjournals.readthedocs.io/en/jose/review_checklist.html + +## Blocking Issues for JOSE + +| Severity | Issue | Status | Required action | +|---|---|---|---| +| BLOCKER | JOSE framing was mixed with JOSS framing. | Addressed in PR | README, paper, and docs now make JOSE the primary target and keep JOSS secondary. | +| BLOCKER | Paper needed to explain JOSE eligibility and educational contribution rather than list API details. | Addressed in PR | `paper/paper.md` rewritten as a JOSE-oriented paper. | +| BLOCKER | Educational evidence boundary was not explicit enough. | Addressed in PR | `docs/educational_use_evidence.md` states what is demonstrated, plausible, not claimed, and missing. | +| BLOCKER | Example module was not in the expected installable structure. | Addressed in PR | `inst/examples/example_course_module/` now includes source, question bank, expected outputs, report, and run script. | +| MAJOR | README smoke tests used internal test fixtures. | Addressed in PR | README now uses `system.file("examples", "example_course_module", package = "tutorizeR")`. | +| MAJOR | Content and figure licensing was not explicit. | Addressed in PR | Added `LICENSE-CONTENT.md` and README/example licensing notes. | +| MAJOR | AI usage statement needed cautious wording. | Addressed in PR | Paper now states that generative AI supported planning, review, or documentation-support stages. | +| MAJOR | Need final verification before submission. | Remaining | Rerun tests, lint, source build, R CMD check, and remote CI immediately before an actual JOSE submission. | + +## Factual Risks + +| Severity | Risk | Required wording | +|---|---|---| +| BLOCKER | Claiming classroom deployment without evidence. | `Not verifiable from repository contents.` | +| BLOCKER | Claiming improved learning outcomes, grades, or engagement without measured evidence. | Do not claim. | +| MAJOR | Claiming JOSE submission, review, or acceptance. | Do not claim until it happens and is documented. | +| MAJOR | Claiming CRAN publication. | Do not claim unless CRAN publication is verified. | +| MAJOR | Claiming CI is green without checking remote Actions. | Use `Not verifiable from repository contents.` unless checked live. | + +## Package Quality Risks + +| Severity | Risk | Status | +|---|---|---| +| MAJOR | Example conversion can fail if user examples depend on working-directory-relative data. | Addressed through `run-example.R`, which copies files to a temporary working directory. | +| MAJOR | Coverage job used a fragile `covr::coverage_to_list()` data-frame conversion. | Addressed with direct access to named `filecoverage` values. | +| MINOR | `R CMD build .` can be slow or fail in the live repository because R copies `.git` before applying exclusions. | Documented in final report; clean source copy build succeeds. | +| MINOR | Optional packages `learnr`, `gradethis`, `quarto-live`, and `tidyverse` affect examples. | Documented in README and example files. | + +## Documentation Gaps + +| Severity | Gap | Status | +|---|---|---| +| MAJOR | Dedicated JOSE submission guide. | Addressed in `docs/jose_submission_guide.md`. | +| MAJOR | Dedicated JOSE review checklist with official categories. | Addressed in `docs/jose_review_checklist.md`. | +| MAJOR | Educational evidence and non-claims document. | Addressed in `docs/educational_use_evidence.md`. | +| MAJOR | Teaching workflow case study vignette. | Addressed in `vignettes/teaching-workflow-case-study.Rmd`. | +| MINOR | Existing vignettes were concise. | Expanded with goals, examples, realistic workflow notes, limits, and reproducibility commands. | + +## Evidence Gaps + +| Severity | Gap | Current evidence | +|---|---|---| +| BLOCKER | Formal learning-outcome evaluation. | Not verifiable from repository contents. | +| BLOCKER | Documented classroom deployment. | Not verifiable from repository contents. | +| MAJOR | External instructor adoption. | Not verifiable from repository contents. | +| MAJOR | Remote CI status after this commit. | Must be verified after push. | +| MINOR | Long-term maintenance history after release. | Partly visible in Git history, but public activity should be checked on GitHub. | + +## Exact Files to Change + +Files addressed in this PR: + +- `README.md` +- `paper/paper.md` +- `paper/paper.bib` +- `_pkgdown.yml` +- `.github/workflows/r.yml` +- `tests/testthat/test-examples.R` +- `tests/testthat/test-jose-readiness.R` +- `inst/examples/example_course_module/` +- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/getting-started.Rmd` +- `vignettes/question-bank.Rmd` +- `vignettes/conversion-rmd-vs-qmd.Rmd` +- `vignettes/mcq-and-assessment.Rmd` +- `vignettes/lint-and-debug.Rmd` +- `docs/jose_submission_guide.md` +- `docs/jose_release_bundle.md` +- `docs/jose_review_checklist.md` +- `docs/educational_use_evidence.md` +- `docs/jose_pr_final_report.md` +- `LICENSE-CONTENT.md` + +## Final Checklist Before Submission + +- [ ] Confirm remote GitHub Actions pass on the final submitted branch. +- [ ] Rerun `Rscript -e "testthat::test_local('.')"` on a clean checkout. +- [ ] Rerun `Rscript -e "lintr::lint_package()"`. +- [ ] Rerun source build from a clean source copy or another checkout that does not copy `.git`. +- [ ] Rerun `R CMD check --as-cran --no-manual`. +- [ ] Confirm all paper references are cited and BibTeX parses. +- [ ] Confirm the example module runs after package installation. +- [ ] Add documented classroom use only if evidence can be added to the repository. +- [ ] Do not submit until factual claims have been reviewed by the maintainer. diff --git a/docs/jose_checklist.md b/docs/jose_checklist.md index b577fcb..6db2b68 100644 --- a/docs/jose_checklist.md +++ b/docs/jose_checklist.md @@ -21,7 +21,7 @@ Status labels: | Continuous integration | READY | `.github/workflows/r.yml` | R CMD check, tests, lint, and coverage jobs configured. | | Coverage reporting | READY | `.github/workflows/r.yml` | `covr::package_coverage()` configured with core threshold. | | Documentation | READY | `README.md`, `man/`, vignettes, docs | Reviewer-facing docs added. | -| Vignettes | READY | `vignettes/` | Includes five JOSE-oriented educational vignettes. | +| Vignettes | READY | `vignettes/` | Includes JOSE-oriented educational vignettes, including a teaching workflow case study. | | Reproducibility | READY | examples, tests, workflow, local dataset | Source-first conversion workflow documented. | | Educational adoption evidence | PARTIAL | package examples and use cases | Actual classroom adoption is not verifiable from repository contents. | | JOSE paper | READY | `paper/paper.md` | Title and required sections present. | diff --git a/docs/jose_pr_final_report.md b/docs/jose_pr_final_report.md new file mode 100644 index 0000000..8e0fa44 --- /dev/null +++ b/docs/jose_pr_final_report.md @@ -0,0 +1,184 @@ +# JOSE PR Final Report + +Date: 2026-05-31 +Branch: `review/jose-readiness` +PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 + +## What Was Changed + +- Recentered the README on JOSE as the primary target and moved JOSS to a secondary-target section. +- Rewrote `paper/paper.md` as a JOSE-oriented software paper, not API documentation. +- Added pedagogical references to `paper/paper.bib` and cited them in the paper. +- Added cautious AI usage disclosure. +- Added explicit educational evidence boundaries. +- Rebuilt the example module as an installable teaching example with source lesson, question bank, expected outputs, JSON report, and run script. +- Added a long teaching workflow case-study vignette. +- Expanded core vignettes with user goals, minimal examples, realistic examples, limitations, and reproducibility checks. +- Added CC-BY 4.0 content licensing for educational examples and figures. +- Added example-module tests and README fixture-path checks. +- Updated GitHub Actions coverage logic to use named coverage values and run on PRs targeting `release/v0.4.4`. + +## Why Each Change Matters for JOSE + +- JOSE evaluates educational contribution, not only package mechanics. +- The paper now explains the teaching problem, educational infrastructure role, adoption workflow, and limitations. +- The example module gives reviewers an installable artifact they can run without relying on internal test fixtures. +- The evidence document prevents overclaiming about student outcomes or classroom adoption. +- The review checklist maps repository evidence to JOSE-style review concerns. +- The content license clarifies reuse rights for teaching examples and figures. + +## Factual Claims Corrected + +- Removed framing that treated the branch primarily as JOSS preparation. +- Avoided claims of classroom deployment, improved engagement, improved grades, or improved learning outcomes. +- Replaced any categorical AI non-use framing with a cautious disclosure. +- Clarified that LMS support is manifest-oriented, not direct publishing. +- Clarified that CRAN publication is not claimed. +- Clarified that JOSE submission, review, or acceptance is not claimed. + +## Educational Evidence Added + +- `docs/educational_use_evidence.md` +- `inst/examples/example_course_module/` +- `vignettes/teaching-workflow-case-study.Rmd` +- Expanded getting started, question-bank, conversion, assessment, and lint/debug vignettes. + +## Remaining Limitations + +- Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. +- Actual classroom deployment is not verifiable from repository contents. +- Broad external instructor adoption is not verifiable from repository contents. +- Remote GitHub Actions status must be checked after pushing this update. +- ORCID and final release DOI should be confirmed before submission. + +## Validation Commands Run + +Official JOSE pages reviewed: + +- https://openjournals.readthedocs.io/en/jose/submitting.html +- https://openjournals.readthedocs.io/en/jose/review_criteria.html +- https://openjournals.readthedocs.io/en/jose/review_checklist.html + +Local validation: + +```bash +Rscript -e "testthat::test_local('.')" +``` + +Result: PASS. 144 tests passed, 0 failures, 0 warnings, 0 skips. + +```bash +Rscript -e "lintr::lint_package()" +``` + +Result: PASS. No lints found. + +```bash +Rscript -e "yaml::read_yaml('_pkgdown.yml')" +``` + +Result: PASS. `_pkgdown.yml` parsed successfully. + +```bash +Rscript -e "rmarkdown::render('paper/paper.md', output_format = rmarkdown::md_document(variant = 'gfm'), output_file = tempfile(fileext = '.md'), quiet = TRUE)" +``` + +Result: PASS. Paper rendered successfully and bibliography citations resolved. + +```bash +Rscript - <<'EOF' +files <- list.files('vignettes', pattern = '\\.[Rr]md$', full.names = TRUE) +out_dir <- tempfile('tutorizer-vignettes-') +dir.create(out_dir) +for (file in files) { + rmarkdown::render(file, output_dir = out_dir, quiet = TRUE) +} +EOF +``` + +Result: PASS. 13 vignettes rendered successfully. + +```bash +Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" +``` + +Result: PASS after `pkgload::load_all('.')` in the local checkout. + +```bash +Rscript - <<'EOF' +cov <- covr::package_coverage(quiet = TRUE) +cov_list <- covr::coverage_to_list(cov) +file_coverage <- cov_list$filecoverage +core_files <- c('R/parser.R', 'R/transform.R', 'R/validation.R', 'R/report.R') +missing <- setdiff(core_files, names(file_coverage)) +if (length(missing) > 0L) stop(sprintf('Missing core files: %s', paste(missing, collapse = ', '))) +core_pct <- mean(unname(file_coverage[core_files])) +total_pct <- as.numeric(cov_list$totalcoverage) +cat(sprintf('Coverage total: %.2f%%\n', total_pct)) +cat(sprintf('Coverage core: %.2f%%\n', core_pct)) +if (core_pct < 80) stop(sprintf('Core coverage threshold not met: %.2f%% < 80%%', core_pct)) +EOF +``` + +Result: PASS. Coverage total: 71.58%. Coverage core: 93.36%. + +```bash +R CMD build . +``` + +Result: attempted directly in the live Git checkout, but interrupted after the command spent too long copying `.git` into the temporary build directory before R package exclusions were applied. This is a local checkout issue, not a package source issue. + +Clean source-copy validation: + +```bash +tmpdir=$(mktemp -d) +rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='..Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" +cd "$tmpdir/tutorizeR" +R CMD build . +R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz +``` + +Result: PASS with 1 NOTE for new submission. + +## CI Status + +Not verifiable from repository contents. + +Remote GitHub Actions must be checked after this update is pushed. + +## Files Modified + +Key changed or added files: + +- `README.md` +- `paper/paper.md` +- `paper/paper.bib` +- `LICENSE-CONTENT.md` +- `_pkgdown.yml` +- `.github/workflows/r.yml` +- `docs/jose_blockers_report.md` +- `docs/jose_submission_guide.md` +- `docs/jose_review_checklist.md` +- `docs/educational_use_evidence.md` +- `docs/jose_release_bundle.md` +- `docs/jose_pr_final_report.md` +- `inst/examples/example_course_module/` +- `tests/testthat/test-examples.R` +- `tests/testthat/test-jose-readiness.R` +- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/getting-started.Rmd` +- `vignettes/question-bank.Rmd` +- `vignettes/conversion-rmd-vs-qmd.Rmd` +- `vignettes/mcq-and-assessment.Rmd` +- `vignettes/lint-and-debug.Rmd` + +## Remaining Blockers Before Actual JOSE Submission + +- Documented classroom deployment: Not verifiable from repository contents. +- Formal learning-outcome evaluation: Not verifiable from repository contents. +- Remote CI status after final push: Not verifiable from repository contents. +- Final release DOI and ORCID metadata should be confirmed. + +Recommendation: Not ready for JOSE submission. + +The repository is substantially more JOSE-ready, but a real submission should wait until remote CI is verified and the maintainer decides whether to add documented classroom-use evidence. diff --git a/docs/jose_release_bundle.md b/docs/jose_release_bundle.md new file mode 100644 index 0000000..1618082 --- /dev/null +++ b/docs/jose_release_bundle.md @@ -0,0 +1,54 @@ +# JOSE Release Bundle + +Date: 2026-05-31 + +This file lists the repository artifacts to prepare before a possible JOSE submission. + +## Core Submission Files + +- `paper/paper.md` +- `paper/paper.bib` +- `README.md` +- `DESCRIPTION` +- `LICENSE` +- `LICENSE.md` +- `LICENSE-CONTENT.md` +- `CITATION.cff` + +## Reviewer Documentation + +- `docs/jose_submission_guide.md` +- `docs/jose_review_checklist.md` +- `docs/jose_blockers_report.md` +- `docs/educational_use_evidence.md` +- `docs/jose_pr_final_report.md` + +## Teaching Demonstration + +- `inst/examples/example_course_module/README.md` +- `inst/examples/example_course_module/lesson-source.qmd` +- `inst/examples/example_course_module/question-bank/questions.yml` +- `inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd` +- `inst/examples/example_course_module/expected/lesson-source-live.qmd` +- `inst/examples/example_course_module/expected/conversion-report.json` +- `inst/examples/example_course_module/run-example.R` + +## Validation Commands + +Run immediately before submission: + +```bash +Rscript -e "testthat::test_local('.')" +Rscript -e "lintr::lint_package()" +R CMD build . +R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz +``` + +## Remaining Before a Real Submission + +- Confirm remote GitHub Actions status. +- Confirm final version number and release tag. +- Confirm archive DOI. +- Confirm ORCID metadata. +- Add classroom-use evidence only if it can be documented in the repository. + diff --git a/docs/jose_review_checklist.md b/docs/jose_review_checklist.md new file mode 100644 index 0000000..44c5ac6 --- /dev/null +++ b/docs/jose_review_checklist.md @@ -0,0 +1,101 @@ +# JOSE Review Checklist + +Date: 2026-05-31 + +Status labels: + +- READY: supported by repository evidence. +- PARTIAL: partially supported, but incomplete. +- MISSING: expected evidence is absent. +- NOT VERIFIABLE: cannot be verified from repository contents. + +Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/review_checklist.html + +## License + +| Item | Status | Evidence | +|---|---|---| +| Code has an OSI-approved license. | READY | `DESCRIPTION`, `LICENSE`, `LICENSE.md`. | +| Educational content license is clear. | READY | `LICENSE-CONTENT.md`, README, example README. | +| Repository is public. | NOT VERIFIABLE | Public visibility cannot be proven from local files alone. | + +## Statement of Need + +| Item | Status | Evidence | +|---|---|---| +| Paper explains the educational need. | READY | `paper/paper.md`. | +| Paper explains why software is needed. | READY | `paper/paper.md`. | +| Paper avoids being API documentation. | READY | Detailed API remains in README, vignettes, and man pages. | + +## Community Guidelines + +| Item | Status | Evidence | +|---|---|---| +| Contribution guide exists. | READY | `CONTRIBUTING.md`. | +| Code of conduct exists. | READY | `CODE_OF_CONDUCT.md`. | +| Issue and PR templates exist. | READY | `.github/ISSUE_TEMPLATE/`, `.github/PULL_REQUEST_TEMPLATE.md`. | + +## Documentation + +| Item | Status | Evidence | +|---|---|---| +| Installation instructions exist. | READY | `README.md`. | +| User workflow is documented. | READY | `README.md`, vignettes. | +| Example module is documented. | READY | `inst/examples/example_course_module/README.md`. | +| Limitations are documented. | READY | README, paper, `docs/educational_use_evidence.md`. | + +## Tests + +| Item | Status | Evidence | +|---|---|---| +| Automated tests exist. | READY | `tests/testthat/`. | +| Example module tests exist. | READY | `tests/testthat/test-examples.R`. | +| Local tests pass. | PARTIAL | Must be rerun on final checkout before submission. | +| Remote CI passes. | NOT VERIFIABLE | Requires checking GitHub Actions after push. | + +## Examples + +| Item | Status | Evidence | +|---|---|---| +| Installable example exists. | READY | `inst/examples/example_course_module/`. | +| Example includes source lesson. | READY | `lesson-source.qmd`. | +| Example includes question bank. | READY | `question-bank/questions.yml`. | +| Example includes expected outputs. | READY | `expected/`. | +| Example can be run with installed package. | PARTIAL | `run-example.R` exists; final run should be verified after package install. | + +## Functionality + +| Item | Status | Evidence | +|---|---|---| +| Feature-complete conversion workflow exists. | READY | `R/`, tests, examples. | +| `.Rmd` and `.qmd` inputs supported. | READY | tests and vignettes. | +| `learnr` and `quarto-live` targets supported. | READY | tests and examples. | +| Question bank support exists. | READY | `R/question_bank.R`, tests, example bank. | +| LMS direct publishing exists. | MISSING | Current export is manifest-only. This is documented as a limitation. | + +## Educational Contribution + +| Item | Status | Evidence | +|---|---|---| +| Educational technology contribution is explained. | READY | README, paper, docs. | +| Teaching workflow is demonstrated. | READY | example module and `teaching-workflow-case-study` vignette. | +| Learning-outcome evidence exists. | NOT VERIFIABLE | Formal evaluation not present. | + +## Adoption by Instructors + +| Item | Status | Evidence | +|---|---|---| +| Adoption workflow for other instructors is documented. | READY | README, example README, vignettes. | +| Actual classroom deployment is documented. | NOT VERIFIABLE | No repository evidence. | +| Broad external adoption is documented. | NOT VERIFIABLE | No repository evidence. | + +## Paper Readiness + +| Item | Status | Evidence | +|---|---|---| +| JOSE-oriented paper exists. | READY | `paper/paper.md`. | +| Bibliography exists. | READY | `paper/paper.bib`. | +| Pedagogical references are cited. | READY | paper and bibliography. | +| AI usage disclosure is cautious. | READY | `paper/paper.md`. | +| Final metadata is complete. | PARTIAL | ORCID and final release DOI should be confirmed. | + diff --git a/docs/jose_submission_guide.md b/docs/jose_submission_guide.md new file mode 100644 index 0000000..f75a7d7 --- /dev/null +++ b/docs/jose_submission_guide.md @@ -0,0 +1,109 @@ +# JOSE Submission Guide for tutorizeR + +Date: 2026-05-31 + +This guide prepares `tutorizeR` for a possible Journal of Open Source Education submission. It does not state that the package has been submitted, reviewed, or accepted. + +Official JOSE guidance used: + +- Submitting guide: https://openjournals.readthedocs.io/en/jose/submitting.html +- Review criteria: https://openjournals.readthedocs.io/en/jose/review_criteria.html +- Review checklist: https://openjournals.readthedocs.io/en/jose/review_checklist.html + +## Why tutorizeR Fits JOSE + +JOSE accepts software that functions as educational technology or infrastructure. `tutorizeR` fits that category because it helps instructors transform reproducible R Markdown and Quarto teaching documents into interactive tutorials and browser-executable resources. Its contribution is educational infrastructure: reducing manual conversion work and supporting source-first development of computational learning materials. + +The repository does not claim measured learning gains, improved grades, improved engagement, classroom deployment, or broad adoption. Not verifiable from repository contents. + +## What to Submit + +For a JOSE submission, prepare: + +- repository URL; +- release tag and archive DOI if available; +- `paper/paper.md`; +- `paper/paper.bib`; +- license information for code and educational content; +- reviewer instructions for installation, tests, and examples. + +The paper should explain the educational need, intended teaching context, adoption workflow, current evidence, limitations, licensing, and references. It should not replace package documentation. + +## How to Reproduce the Example + +After installing the package: + +```r +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +source_file <- file.path(example_dir, "lesson-source.qmd") +question_bank <- load_question_bank(file.path(example_dir, "question-bank")) + +report <- tutorize( + input = source_file, + format = "learnr", + assessment = "both", + output_dir = tempdir(), + question_bank = question_bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) + +print(report) +``` + +The full script is available in `inst/examples/example_course_module/run-example.R`. + +## How a Reviewer Can Test the Package + +Developer checks: + +```bash +Rscript -e "testthat::test_local('.')" +Rscript -e "lintr::lint_package()" +R CMD build . +R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz +``` + +Installed example check: + +```bash +Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" +``` + +If optional rendering dependencies are missing, reviewers should still be able to inspect generated output files and conversion reports. + +## What Remains to Verify Before Submission + +- Remote GitHub Actions status on the final branch. +- Final source build and R CMD check from a clean checkout. +- Current release tag and archive DOI. +- ORCID metadata in `paper/paper.md`. +- Any classroom deployment evidence, if the maintainer wants to claim it. + +## Demonstrated Claims + +The repository demonstrates: + +- conversion of `.Rmd` and `.qmd` sources; +- `learnr` and `quarto-live` output scaffolding; +- exercise and solution generation; +- MCQ block and question-bank handling; +- conversion reports; +- installable educational example; +- local tests and vignettes. + +## Claims Not Demonstrated + +Not verifiable from repository contents: + +- formal learning-outcome evaluation; +- improved student grades; +- improved student engagement; +- documented classroom deployment; +- broad external adoption; +- JOSE acceptance or current JOSE review status; +- current CRAN publication. + diff --git a/docs/jose_submission_report.md b/docs/jose_submission_report.md index 588bde0..bf43ec1 100644 --- a/docs/jose_submission_report.md +++ b/docs/jose_submission_report.md @@ -25,7 +25,7 @@ Strengths: - educational technology scope is clear; - `paper/paper.md` and `paper/paper.bib` are present; -- educational use cases and five JOSE-oriented vignettes are present; +- educational use cases and JOSE-oriented vignettes are present; - example course module demonstrates instructor adoption workflow; - governance, contribution, issue, and PR templates are present. @@ -76,12 +76,14 @@ On 2026-05-31, the following checks were performed locally: - Full `testthat` suite: PASS. - `lintr::lint_package()`: PASS, no lints found. -- Six JOSE-oriented vignettes rendered to a temporary output directory: PASS. +- Thirteen vignettes rendered to a temporary output directory: PASS. - `_pkgdown.yml` parsed with `yaml::read_yaml()`: PASS. +- Paper rendered with bibliography resolution: PASS. +- Coverage gate script: PASS, 71.58% total coverage and 93.36% core coverage. - Clean temporary source copy built with `R CMD build`: PASS. - `R CMD check --as-cran --no-manual`: PASS with 1 NOTE for new submission. -Direct `R CMD build .` from the working repository failed before packaging because R attempted to copy `.git/fsmonitor--daemon.ipc`, a Git fsmonitor socket, before applying package build exclusions. Building from a clean source copy without `.git`, `.Rcheck`, or local tarballs succeeded. +Direct `R CMD build .` from the live Git checkout was attempted but interrupted because R spent too long copying `.git` into the temporary build directory before applying package build exclusions. Building from a clean source copy without `.git`, `.Rcheck`, or local tarballs succeeded. ## Remaining Blockers @@ -101,6 +103,8 @@ Direct `R CMD build .` from the working repository failed before packaging becau 6. Confirm that `paper/paper.md` truthfully discloses any AI-assisted work if applicable. 7. Submit to JOSE first, with JOSS as a secondary route only if JOSE scope is not pursued. +Recommendation: Not ready for JOSE submission until remote CI is verified and the maintainer decides whether to add documented classroom-use evidence. + ## Estimated Probability of Acceptance JOSE: Not verifiable from repository contents. diff --git a/inst/examples/example_course_module/README.md b/inst/examples/example_course_module/README.md index dc0e4c1..44f0021 100644 --- a/inst/examples/example_course_module/README.md +++ b/inst/examples/example_course_module/README.md @@ -1,16 +1,40 @@ -# Example Course Module +# Example Course Module: Data Visualization and Summarisation -This module demonstrates a small data science lesson that can be converted with `tutorizeR`. +This module demonstrates a small, generic data science lesson that can be converted with `tutorizeR`. It is designed for instructors who want to see a source-first workflow using Quarto, `learnr`, `quarto-live`, MCQs, a reusable question bank, and conversion reports. + +The dataset is synthetic and intended only for documentation and testing of teaching workflows. + +Educational example materials in this directory are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md` in the repository root. + +## Teaching context + +The example represents a short undergraduate activity on data summarisation and visualization with R. Students inspect a small table of weekly study activity, compute grouped summaries, and create a scatterplot relating study time to quiz score. + +This module demonstrates an adoption pattern. It does not provide evidence of classroom deployment or student learning gains. Not verifiable from repository contents. + +## Learning objectives + +After completing the activity, students should be able to: + +- import a local CSV file; +- compute grouped summaries with `dplyr`; +- create a basic visualization with `ggplot2`; +- interpret a small exploratory graph cautiously; +- answer conceptual questions about variables and summaries. Files: -- `source_lesson.qmd`: instructor-maintained Quarto source. +- `lesson-source.qmd`: instructor-maintained Quarto source. - `student_activity.csv`: local teaching dataset. -- `transformed_tutorial.Rmd`: example `learnr` output after conversion. -- `generated_exercises.Rmd`: extracted exercise examples. -- `grading_examples.R`: optional `gradethis` checks that an instructor can adapt. +- `question-bank/questions.yml`: reusable MCQ question bank. +- `expected/lesson-source-tutorial.Rmd`: expected `learnr` output scaffold. +- `expected/lesson-source-live.qmd`: expected `quarto-live` output scaffold. +- `expected/conversion-report.json`: expected conversion report for the `learnr` conversion. +- `run-example.R`: reproducible script that runs the example after package installation. + +## Reproduce the example -Example conversion: +From an installed package: ```r library(tutorizeR) @@ -21,16 +45,30 @@ module_dir <- system.file( package = "tutorizeR" ) -report <- tutorize( - input = file.path(module_dir, "source_lesson.qmd"), - output_dir = tempdir(), - format = "learnr", - assessment = "both", - overwrite = TRUE -) - -print(report) +source(file.path(module_dir, "run-example.R")) ``` -The dataset is synthetic and intended only for documentation and testing of teaching workflows. +The script copies the module to a temporary directory, loads the question bank, converts the lesson to `learnr`, converts the lesson to `quarto-live`, writes a JSON conversion report, and prints the output paths. + +## What tutorizeR automates + +The package automates: + +- transformation of ordinary R chunks into student exercise areas; +- generation of solution chunks; +- conversion of explicit MCQ blocks; +- insertion of question-bank MCQs; +- insertion of `learnr` and `gradethis` setup code; +- generation of conversion reports. + +## What instructors still need to review + +Instructors should manually verify: + +- grading checks and feedback language; +- dataset availability in the deployment environment; +- optional package availability, especially `learnr`, `gradethis`, `dplyr`, `ggplot2`, and `readr`; +- accessibility and clarity of generated prompts; +- final suitability for the course context. +Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. diff --git a/inst/examples/example_course_module/expected/conversion-report.json b/inst/examples/example_course_module/expected/conversion-report.json new file mode 100644 index 0000000..6c7b32a --- /dev/null +++ b/inst/examples/example_course_module/expected/conversion-report.json @@ -0,0 +1,35 @@ +{ + "schema_version": "1.0", + "input_file": "lesson-source.qmd", + "output_file": "expected/lesson-source-tutorial.Rmd", + "format": "learnr", + "assessment": "both", + "stats": { + "exercises": 3, + "solutions": 4, + "mcq": 5, + "mcq_explicit": 1, + "mcq_from_bank": 2, + "skipped": 0, + "setup_chunks": 1, + "preserved_chunks": 0, + "sections": 8, + "chunks_total": 7, + "estimated_minutes": 23.5 + }, + "sections": 8, + "chunks_total": 7, + "mcq_explicit": 1, + "mcq_from_bank": 2, + "estimated_minutes": 23.5, + "render_ok": true, + "render_message": "", + "warnings": [], + "lint_summary": { + "errors": 0, + "warnings": 0, + "infos": 0 + }, + "messages": [], + "generated_at": "example" +} diff --git a/inst/examples/example_course_module/expected/lesson-source-live.qmd b/inst/examples/example_course_module/expected/lesson-source-live.qmd new file mode 100644 index 0000000..a5e8240 --- /dev/null +++ b/inst/examples/example_course_module/expected/lesson-source-live.qmd @@ -0,0 +1,159 @@ +--- +title: Introduction to Data Visualization and Summarisation with R +author: Example instructor +format: live-html +engine: knitr +--- + +{{< include ./_extensions/r-wasm/live/_knitr.qmd >}} + + +## Learning objectives + +By the end of this lesson, students should be able to: + +- import a small CSV file; +- compute grouped summaries with `dplyr`; +- create a scatterplot with `ggplot2`; +- interpret an exploratory pattern without overclaiming. + +## Context + +The synthetic dataset records weekly study activity for a small group of students. The lesson is intentionally compact so that instructors can inspect the complete conversion workflow. + +## Setup + +```{r setup} +library(dplyr) +library(ggplot2) +library(readr) + +activity <- read_csv("student_activity.csv", show_col_types = FALSE) +``` + + +## Instructor demonstration + +_Locked exercise: enable this block only for demonstration._ +```{webr} +# Write your code below +``` + +::: {.callout-tip collapse='true'} +## Solution +```r +head(activity, 3) +``` +::: + +::: {.callout-note} +## Quiz +In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis? + +- [ ] y +- [ ] x +- [ ] color +::: + + +## Data manipulation exercise + +**Hint(s)** +- Group by program before summarising +- Compute mean study hours and mean quiz score +- Use .groups = "drop" + +```{webr} +# Write your code below +``` + +::: {.callout-tip collapse='true'} +## Solution +```r +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` +::: + +::: {.callout-note} +## Quiz +What does the code in chunk 'summarize-program' do? + +- [ ] Answer A (edit me) +- [ ] Answer B (edit me) +- [ ] Answer C (edit me) +::: + + +::: {.callout-note} +## Quiz +Which variable identifies the academic program? + +- [ ] program +- [ ] week +- [ ] quiz_score +::: + + +::: {.callout-note} +## Quiz +In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis? + +- [ ] y +- [ ] x +- [ ] color +::: + + +## Visualization exercise + +**Hint(s)** +- Map study_hours to x and quiz_score to y +- Use color for program +- Use geom_point() + +```{webr} +# Write your code below +``` + +::: {.callout-tip collapse='true'} +## Solution +```r +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` +::: + +::: {.callout-note} +## Quiz +What does the code in chunk 'plot-study-score' do? + +- [ ] Answer A (edit me) +- [ ] Answer B (edit me) +- [ ] Answer C (edit me) +::: + + +## Instructor solution note + +::: {.callout-tip collapse='true'} +## Solution +```r +"In this small synthetic dataset, higher study time is associated with higher quiz score. This is not causal evidence." +``` +::: + + +## Manual interpretation + +Students should describe the plot cautiously. The dataset is small and synthetic, so the goal is to practice code and interpretation rather than estimate a population effect. diff --git a/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd new file mode 100644 index 0000000..35f8928 --- /dev/null +++ b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd @@ -0,0 +1,153 @@ +--- +title: Introduction to Data Visualization and Summarisation with R +author: Example instructor +output: learnr::tutorial +runtime: shiny_prerendered +--- + + +## Learning objectives + +By the end of this lesson, students should be able to: + +- import a small CSV file; +- compute grouped summaries with `dplyr`; +- create a scatterplot with `ggplot2`; +- interpret an exploratory pattern without overclaiming. + +## Context + +The synthetic dataset records weekly study activity for a small group of students. The lesson is intentionally compact so that instructors can inspect the complete conversion workflow. + +## Setup + +```{r setup, include=FALSE} +library(dplyr) +library(ggplot2) +library(readr) + +activity <- read_csv("student_activity.csv", show_col_types = FALSE) +library(learnr) +library(gradethis) +gradethis_setup() +``` + + +## Instructor demonstration + +_Locked exercise: enable this block only for demonstration._ +```{r trz-ex-demo-preview, exercise.lines=3, exercise=TRUE} +# Write your code below +``` + +```{r trz-sol-demo-preview, include=FALSE} +head(activity, 3) +``` + +```{r trz-mcq-demo-preview, echo=FALSE} +learnr::question( + "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?", + learnr::answer("y", correct = TRUE), + learnr::answer("x", correct = FALSE), + learnr::answer("color", correct = FALSE), + allow_retry = TRUE +) +``` + + +## Data manipulation exercise + +**Hint(s)** +- Group by program before summarising +- Compute mean study hours and mean quiz score +- Use .groups = "drop" + +```{r trz-ex-summarize-program, exercise.lines=7, exercise=TRUE} +# Write your code below +``` + +```{r trz-sol-summarize-program, include=FALSE} +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` + +```{r trz-mcq-summarize-program, echo=FALSE} +learnr::question( + "What does the code in chunk 'summarize-program' do?", + learnr::answer("Answer A (edit me)", correct = TRUE), + learnr::answer("Answer B (edit me)", correct = FALSE), + learnr::answer("Answer C (edit me)", correct = FALSE), + allow_retry = TRUE +) +``` + + +```{r trz-mcq-explicit-004, echo=FALSE} +learnr::question( + "Which variable identifies the academic program?", + learnr::answer("program", correct = TRUE), + learnr::answer("week", correct = FALSE), + learnr::answer("quiz_score", correct = FALSE), + allow_retry = TRUE +) +``` + + +```{r trz-mcq-bank-005-001, echo=FALSE} +learnr::question( + "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?", + learnr::answer("y", correct = TRUE), + learnr::answer("x", correct = FALSE), + learnr::answer("color", correct = FALSE), + allow_retry = TRUE +) +``` + + +## Visualization exercise + +**Hint(s)** +- Map study_hours to x and quiz_score to y +- Use color for program +- Use geom_point() + +```{r trz-ex-plot-study-score, exercise.lines=7, exercise=TRUE} +# Write your code below +``` + +```{r trz-sol-plot-study-score, include=FALSE} +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` + +```{r trz-mcq-plot-study-score, echo=FALSE} +learnr::question( + "What does the code in chunk 'plot-study-score' do?", + learnr::answer("Answer A (edit me)", correct = TRUE), + learnr::answer("Answer B (edit me)", correct = FALSE), + learnr::answer("Answer C (edit me)", correct = FALSE), + allow_retry = TRUE +) +``` + + +## Instructor solution note + +```{r trz-sol-interpretation-note, include=FALSE} +"In this small synthetic dataset, higher study time is associated with higher quiz score. This is not causal evidence." +``` + + +## Manual interpretation + +Students should describe the plot cautiously. The dataset is small and synthetic, so the goal is to practice code and interpretation rather than estimate a population effect. diff --git a/inst/examples/example_course_module/generated_exercises.Rmd b/inst/examples/example_course_module/generated_exercises.Rmd deleted file mode 100644 index 41a0da7..0000000 --- a/inst/examples/example_course_module/generated_exercises.Rmd +++ /dev/null @@ -1,45 +0,0 @@ -# Generated Exercises - -## Inspect the data - -```{r trz-ex-inspect-data, exercise.lines=3, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-inspect-data, include=FALSE} -glimpse(activity) -``` - -## Summarise by program - -```{r trz-ex-summarize-program, exercise.lines=7, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-summarize-program, include=FALSE} -activity |> - group_by(program) |> - summarise( - mean_hours = mean(study_hours), - mean_score = mean(quiz_score), - .groups = "drop" - ) -``` - -## Visualize study time and quiz score - -```{r trz-ex-plot-study-score, exercise.lines=9, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-plot-study-score, include=FALSE} -ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + - geom_point(size = 2) + - geom_smooth(method = "lm", se = FALSE) + - labs( - x = "Study hours", - y = "Quiz score", - color = "Program" - ) -``` - diff --git a/inst/examples/example_course_module/grading_examples.R b/inst/examples/example_course_module/grading_examples.R deleted file mode 100644 index 012a387..0000000 --- a/inst/examples/example_course_module/grading_examples.R +++ /dev/null @@ -1,20 +0,0 @@ -# Optional gradethis checks for the example course module. -# These checks are illustrative and should be reviewed by the instructor. - -summarize_program_check <- gradethis::grade_this({ - gradethis::pass_if( - ~ all(c("program", "mean_hours", "mean_score") %in% names(.result)), - "The summary contains the expected columns." - ) - - gradethis::fail("Compute mean_hours and mean_score by program.") -}) - -plot_study_score_check <- gradethis::grade_this({ - gradethis::pass_if( - ~ inherits(.result, "ggplot"), - "The result is a ggplot object." - ) - - gradethis::fail("Create a ggplot object mapping study_hours and quiz_score.") -}) diff --git a/inst/examples/example_course_module/lesson-source.qmd b/inst/examples/example_course_module/lesson-source.qmd new file mode 100644 index 0000000..0238369 --- /dev/null +++ b/inst/examples/example_course_module/lesson-source.qmd @@ -0,0 +1,91 @@ +--- +title: "Introduction to Data Visualization and Summarisation with R" +author: "Example instructor" +format: html +--- + +## Learning objectives + +By the end of this lesson, students should be able to: + +- import a small CSV file; +- compute grouped summaries with `dplyr`; +- create a scatterplot with `ggplot2`; +- interpret an exploratory pattern without overclaiming. + +## Context + +The synthetic dataset records weekly study activity for a small group of students. The lesson is intentionally compact so that instructors can inspect the complete conversion workflow. + +## Setup + +```{r setup} +library(dplyr) +library(ggplot2) +library(readr) + +activity <- read_csv("student_activity.csv", show_col_types = FALSE) +``` + +## Instructor demonstration + +```{r demo-preview} +# tutorizeR: locked +head(activity, 3) +``` + +## Data manipulation exercise + +```{r summarize-program} +# tutorizeR: hints=Group by program before summarising|Compute mean study hours and mean quiz score|Use .groups = "drop" +activity |> + group_by(program) |> + summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) +``` + +```{tutorizeR-mcq} +question: "Which variable identifies the academic program?" +answers: + - text: "program" + correct: true + - text: "week" + correct: false + - text: "quiz_score" + correct: false +allow_retry: true +``` + +```{tutorizeR-mcq-ref} +ids: [visualization-aesthetic] +strategy: ordered +shuffle_answers: false +``` + +## Visualization exercise + +```{r plot-study-score} +# tutorizeR: hints=Map study_hours to x and quiz_score to y|Use color for program|Use geom_point() +ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + + geom_point(size = 2) + + labs( + x = "Study hours", + y = "Quiz score", + color = "Program" + ) +``` + +## Instructor solution note + +```{r interpretation-note} +# tutorizeR: solution-only +"In this small synthetic dataset, higher study time is associated with higher quiz score. This is not causal evidence." +``` + +## Manual interpretation + +Students should describe the plot cautiously. The dataset is small and synthetic, so the goal is to practice code and interpretation rather than estimate a population effect. + diff --git a/inst/examples/example_course_module/question-bank/questions.yml b/inst/examples/example_course_module/question-bank/questions.yml new file mode 100644 index 0000000..c9594cf --- /dev/null +++ b/inst/examples/example_course_module/question-bank/questions.yml @@ -0,0 +1,16 @@ +- id: visualization-aesthetic + question: "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?" + answers: + - text: "y" + correct: true + - text: "x" + correct: false + - text: "color" + correct: false + tags: + - visualization + - ggplot2 + difficulty: introductory + language: en + explanation: "The y aesthetic controls the vertical position in a two-dimensional plot." + diff --git a/inst/examples/example_course_module/run-example.R b/inst/examples/example_course_module/run-example.R new file mode 100644 index 0000000..5733196 --- /dev/null +++ b/inst/examples/example_course_module/run-example.R @@ -0,0 +1,72 @@ +# Reproduce the example course module after package installation. + +library(tutorizeR) + +example_dir <- system.file( + "examples", + "example_course_module", + package = "tutorizeR" +) + +if (!nzchar(example_dir)) { + stop("Could not locate the installed example module.", call. = FALSE) +} + +work_dir <- file.path(tempdir(), "tutorizeR-example-course-module") +if (dir.exists(work_dir)) { + unlink(work_dir, recursive = TRUE) +} +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) + +file.copy( + from = file.path(example_dir, "lesson-source.qmd"), + to = file.path(work_dir, "lesson-source.qmd"), + overwrite = TRUE +) +file.copy( + from = file.path(example_dir, "student_activity.csv"), + to = file.path(work_dir, "student_activity.csv"), + overwrite = TRUE +) + +question_bank <- load_question_bank(file.path(example_dir, "question-bank")) + +learnr_report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "learnr", + assessment = "both", + question_bank = question_bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) + +write_tutorize_report( + report = learnr_report, + file = file.path(work_dir, "conversion-report.json"), + format = "json" +) + +live_report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "quarto-live", + assessment = "both", + question_bank = question_bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) + +message("Example files written to: ", work_dir) +message("learnr output: ", learnr_report$output_file) +message("quarto-live output: ", live_report$output_file) +message("conversion report: ", file.path(work_dir, "conversion-report.json")) + +invisible(list( + work_dir = work_dir, + learnr_report = learnr_report, + live_report = live_report, + conversion_report = file.path(work_dir, "conversion-report.json") +)) diff --git a/inst/examples/example_course_module/source_lesson.qmd b/inst/examples/example_course_module/source_lesson.qmd deleted file mode 100644 index 49f9e83..0000000 --- a/inst/examples/example_course_module/source_lesson.qmd +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: "Study Patterns and Quiz Performance" -author: "Example instructor" -format: html ---- - -## Learning objectives - -By the end of this lesson, students should be able to: - -- import a local CSV file; -- compute grouped summaries with `dplyr`; -- visualize a relationship with `ggplot2`; -- interpret a simple data summary in context. - -## Setup - -```{r setup} -library(tidyverse) - -activity <- readr::read_csv("student_activity.csv") -``` - -## Inspect the data - -```{r inspect-data} -glimpse(activity) -``` - -## Summarise by program - -```{r summarize-program} -# tutorizeR: hints=Group by program before summarising|Use .groups = "drop" -activity |> - group_by(program) |> - summarise( - mean_hours = mean(study_hours), - mean_score = mean(quiz_score), - .groups = "drop" - ) -``` - -```{tutorizeR-mcq} -question: "Which variable identifies the academic program?" -answers: - - text: "program" - correct: true - - text: "week" - correct: false - - text: "quiz_score" - correct: false -allow_retry: true -``` - -## Visualize study time and quiz score - -```{r plot-study-score} -# tutorizeR: hints=Map study_hours to x and quiz_score to y|Use color for program -ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + - geom_point(size = 2) + - geom_smooth(method = "lm", se = FALSE) + - labs( - x = "Study hours", - y = "Quiz score", - color = "Program" - ) -``` - -## Interpretation - -The example is intentionally small. Its purpose is to practice a reproducible workflow rather than estimate a stable population relationship. - diff --git a/inst/examples/example_course_module/transformed_tutorial.Rmd b/inst/examples/example_course_module/transformed_tutorial.Rmd deleted file mode 100644 index 5f76d6a..0000000 --- a/inst/examples/example_course_module/transformed_tutorial.Rmd +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Study Patterns and Quiz Performance -author: Example instructor -output: learnr::tutorial -runtime: shiny_prerendered ---- - -```{r setup, include=FALSE} -library(tidyverse) -library(learnr) -library(gradethis) -gradethis_setup() - -activity <- readr::read_csv("student_activity.csv") -``` - -## Learning objectives - -By the end of this lesson, students should be able to: - -- import a local CSV file; -- compute grouped summaries with `dplyr`; -- visualize a relationship with `ggplot2`; -- interpret a simple data summary in context. - -## Inspect the data - -```{r trz-ex-inspect-data, exercise.lines=3, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-inspect-data, include=FALSE} -glimpse(activity) -``` - -## Summarise by program - -Hint: -- Group by program before summarising -- Use .groups = "drop" - -```{r trz-ex-summarize-program, exercise.lines=7, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-summarize-program, include=FALSE} -activity |> - group_by(program) |> - summarise( - mean_hours = mean(study_hours), - mean_score = mean(quiz_score), - .groups = "drop" - ) -``` - -```{r trz-mcq-explicit-004, echo=FALSE} -learnr::question( - "Which variable identifies the academic program?", - learnr::answer("program", correct = TRUE), - learnr::answer("week", correct = FALSE), - learnr::answer("quiz_score", correct = FALSE), - allow_retry = TRUE -) -``` - -## Visualize study time and quiz score - -Hint: -- Map study_hours to x and quiz_score to y -- Use color for program - -```{r trz-ex-plot-study-score, exercise.lines=9, exercise=TRUE} -# Write your code here -``` - -```{r trz-sol-plot-study-score, include=FALSE} -ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + - geom_point(size = 2) + - geom_smooth(method = "lm", se = FALSE) + - labs( - x = "Study hours", - y = "Quiz score", - color = "Program" - ) -``` - -## Interpretation - -The example is intentionally small. Its purpose is to practice a reproducible workflow rather than estimate a stable population relationship. - diff --git a/paper/paper.bib b/paper/paper.bib index b71af7b..6e28cf9 100644 --- a/paper/paper.bib +++ b/paper/paper.bib @@ -1,36 +1,102 @@ -@Manual{rCoreTeam2026, +@Manual{rCoreTeam2025, title = {R: A Language and Environment for Statistical Computing}, author = {{R Core Team}}, organization = {R Foundation for Statistical Computing}, address = {Vienna, Austria}, - year = {2026}, + year = {2025}, url = {https://www.R-project.org/} } -@Manual{rmarkdown2026, +@misc{rmarkdownDocs, title = {rmarkdown: Dynamic Documents for R}, author = {{Posit Software, PBC}}, year = {2026}, - url = {https://rmarkdown.rstudio.com/} + url = {https://rmarkdown.rstudio.com/}, + note = {Accessed 2026-05-31} } -@Manual{learnr2026, +@misc{learnrDocs, title = {learnr: Authoring Interactive Tutorials}, author = {{Posit Software, PBC}}, year = {2026}, - url = {https://rstudio.github.io/learnr/} + url = {https://rstudio.github.io/learnr/}, + note = {Accessed 2026-05-31} } -@Manual{quarto2026, +@misc{quartoDocs, title = {Quarto}, author = {{Posit Software, PBC}}, year = {2026}, - url = {https://quarto.org} + url = {https://quarto.org}, + note = {Accessed 2026-05-31} } -@Manual{gradethis2026, +@misc{gradethisDocs, title = {gradethis: Automatically Check Student Code in learnr Tutorials}, author = {{R Consortium}}, year = {2026}, - url = {https://rstudio.github.io/gradethis/} + url = {https://rstudio.github.io/gradethis/}, + note = {Accessed 2026-05-31} +} + +@article{knuth1984, + title = {Literate Programming}, + author = {Knuth, Donald E.}, + journal = {The Computer Journal}, + volume = {27}, + number = {2}, + pages = {97--111}, + year = {1984}, + doi = {10.1093/comjnl/27.2.97} +} + +@article{rule2019, + title = {Ten Simple Rules for Writing and Sharing Computational Analyses in {Jupyter} Notebooks}, + author = {Rule, Adam and Birmingham, Amanda and Zuniga, Cristal and Altintas, Ilkay and Huang, Shih-Cheng and Knight, Rob and Moshiri, Niema and Nguyen, Mai H. and Rosenthal, Sara Brin and P{\\'e}rez, Fernando and Rose, Peter W.}, + journal = {PLOS Computational Biology}, + volume = {15}, + number = {7}, + pages = {e1007007}, + year = {2019}, + doi = {10.1371/journal.pcbi.1007007} +} + +@article{wilson2017, + title = {Good Enough Practices in Scientific Computing}, + author = {Wilson, Greg and Bryan, Jennifer and Cranston, Karen and Kitzes, Justin and Nederbragt, Lex and Teal, Tracy K.}, + journal = {PLOS Computational Biology}, + volume = {13}, + number = {6}, + pages = {e1005510}, + year = {2017}, + doi = {10.1371/journal.pcbi.1005510} +} + +@article{freeman2014, + title = {Active Learning Increases Student Performance in Science, Engineering, and Mathematics}, + author = {Freeman, Scott and Eddy, Sarah L. and McDonough, Miles and Smith, Michelle K. and Okoroafor, Nnadozie and Jordt, Hannah and Wenderoth, Mary Pat}, + journal = {Proceedings of the National Academy of Sciences}, + volume = {111}, + number = {23}, + pages = {8410--8415}, + year = {2014}, + doi = {10.1073/pnas.1319030111} +} + +@article{black1998, + title = {Assessment and Classroom Learning}, + author = {Black, Paul and Wiliam, Dylan}, + journal = {Assessment in Education: Principles, Policy \& Practice}, + volume = {5}, + number = {1}, + pages = {7--74}, + year = {1998}, + doi = {10.1080/0969595980050102} +} + +@misc{unesco2019, + title = {Recommendation on Open Educational Resources ({OER})}, + author = {{UNESCO}}, + year = {2019}, + url = {https://www.unesco.org/en/legal-affairs/recommendation-open-educational-resources-oer} } diff --git a/paper/paper.md b/paper/paper.md index 367b294..cf89a74 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -29,68 +29,50 @@ output: bibliography: paper.bib --- -# Summary +## Summary -Many instructors already prepare data science, statistics, and R programming lessons in R Markdown or Quarto. These formats are well suited to reproducible teaching because narrative, code, output, and figures can live in one source document. However, turning an existing lesson into an interactive tutorial often requires repetitive manual work: duplicating code chunks, creating exercise areas, writing solution chunks, adding conceptual questions, and maintaining separate versions for students and instructors. +`tutorizeR` is open-source educational infrastructure for instructors who prepare statistics, data science, or R programming lessons in R Markdown or Quarto and want to turn those source documents into interactive learning resources. The package converts `.Rmd` and `.qmd` files into `learnr` tutorials or `quarto-live` resources, while preserving a source-first workflow: instructors maintain one reproducible lesson and generate student-facing exercise material from it. It is built in R [@rCoreTeam2025] and works with the R Markdown, Quarto, `learnr`, and `gradethis` ecosystems [@rmarkdownDocs; @quartoDocs; @learnrDocs; @gradethisDocs]. -`tutorizeR` automates this conversion workflow. The package converts `.Rmd` and `.qmd` source documents into `learnr` tutorials or `quarto-live` resources, while preserving narrative text, setup chunks, selected chunk options, and instructor annotations. It supports automatic exercise transformation, insertion of student answer areas, reusable MCQ question banks, `gradethis` setup for feedback, linting, conversion reports, and LMS-oriented manifest export. The package is implemented in R and integrates with established tools for reproducible teaching, including R, R Markdown, Quarto, `learnr`, and `gradethis` [@rCoreTeam2026; @rmarkdown2026; @quarto2026; @learnr2026; @gradethis2026]. +The educational problem is practical and recurring. Many instructors already write lessons as computational narratives, where text, code, figures, and interpretation are interleaved. This approach has roots in literate programming [@knuth1984] and is consistent with current recommendations for computational notebooks and reproducible analyses [@rule2019; @wilson2017]. However, preparing an interactive tutorial from an existing source lesson often requires manual duplication of chunks, insertion of exercise areas, management of solutions, creation of conceptual checks, and coordination of feedback scaffolds. `tutorizeR` automates much of that transformation while leaving final pedagogical judgement to the instructor. -# Statement of Need +## Statement of Need -Interactive tutorials can support active learning by asking students to edit code, inspect outputs, answer conceptual questions, and receive feedback. For instructors, the practical barrier is maintenance. A course may already have dozens of lecture notes, laboratories, and assignments written as `.Rmd` or `.qmd` files. Rebuilding those materials by hand as `learnr` tutorials or browser-executable Quarto activities duplicates effort and increases the chance that instructor notes, student tutorials, and solutions drift apart. +JOSE accepts open-source software that supports teaching and learning or makes an educational process better, easier, simpler, or faster. `tutorizeR` fits this software-submission category as infrastructure for computational education. It does not replace course design, teaching expertise, or assessment design. Instead, it reduces the mechanical cost of converting reproducible teaching documents into interactive activities. -`tutorizeR` addresses this need by keeping the source lesson as the authoritative document. Instructors can update a lesson once, rerun the conversion pipeline, and regenerate student-facing materials. This is especially relevant in scalable teaching contexts where multiple instructors or teaching assistants must coordinate reproducible materials across weeks, sections, and cohorts. +The need is especially visible in courses where instructors maintain weekly laboratories, tutorials, and assignments. A single update to a dataset, plot, or explanation can otherwise require changes in multiple versions of the same lesson. `tutorizeR` supports a workflow in which the instructor revises the source `.qmd` or `.Rmd` file, reruns the conversion pipeline, reviews the generated output, and distributes the result. The package also supports formative practice by generating code exercises, MCQs, and `gradethis`-ready `learnr` tutorials. This design is aligned with broad evidence that active learning and formative feedback can be valuable in STEM education [@freeman2014; @black1998], but this repository does not claim that `tutorizeR` itself improves grades, engagement, or learning outcomes. -The need is educational rather than only technical. The package is intended to help instructors create active learning experiences from existing reproducible documents, reduce maintenance burden, and make iterative course updates more reliable. Actual classroom adoption is not verifiable from repository contents. +## Educational context and target users -# Functionality +The primary users are instructors, teaching assistants, and course teams who create computational teaching materials in R. Target contexts include introductory data science, applied statistics, R programming, and methods courses where students learn through executable examples and short practice tasks. The package is also relevant to open educational resource workflows because its example materials can be reused and adapted under an open content license, consistent with open education principles [@unesco2019]. -The package provides a high-level `tutorize()` function and compatibility wrappers for existing workflows. Core functionality includes: +The repository includes a complete installable example module on data summarisation and visualization with R. The example is generic and synthetic. It is designed to show how another instructor could adopt the package without access to private course material. -- parsing `.Rmd` and `.qmd` source files into text, setup chunks, R chunks, non-R chunks, MCQ blocks, and question-bank references; -- generating `learnr` exercise chunks and solution chunks; -- generating `quarto-live` compatible exercise scaffolds; -- inserting `learnr`, `gradethis`, and `gradethis_setup()` into generated `learnr` setup chunks; -- preserving non-R fenced blocks rather than converting them incorrectly; -- normalizing generated labels to reduce chunk-label collisions; -- supporting instructor tags such as `skip`, `exercise-only`, `solution-only`, `mcq`, `narrative-only`, `locked`, and `hints`; -- loading reusable YAML or JSON question banks; -- linting source documents before conversion; -- writing JSON or YAML conversion reports; -- exporting LMS-oriented manifests for downstream course workflows; -- providing RStudio addins and a command-line script for instructor use. +## Functionality -# Educational Use +`tutorizeR` parses source documents, preserves narrative text, detects setup and R chunks, preserves non-R fenced blocks, generates exercise and solution areas, transforms explicit MCQ blocks, resolves references to local question banks, adds `learnr` and `gradethis` setup code when needed, and writes conversion reports. The package includes validation and linting helpers so instructors can inspect source documents before conversion, plus batch conversion for folders of lessons. -The package supports workflows common in undergraduate statistics, data science, and R programming courses. A typical use case starts with an instructor-maintained Quarto lesson that imports data, performs a data manipulation task, builds a visualization, and asks students to interpret the result. `tutorizeR` converts that lesson into a tutorial with exercise areas, solutions, and MCQs. +The detailed API is documented in the package reference, vignettes, and examples. The JOSE paper intentionally does not duplicate that documentation. -The repository includes an example course module in `inst/examples/example_course_module/`. The module uses a small synthetic dataset to demonstrate a realistic lesson on study patterns and quiz performance. It includes a source Quarto document, a transformed `learnr` tutorial, generated exercises, grading examples, and a local CSV file. The example is suitable for demonstrating the package to instructors without relying on private course data. +## Teaching and adoption workflow -The design is inspired by workflows that occur in introductory and advanced undergraduate statistics or data science courses, including course-code contexts such as STT-1100 and STT-4230. No private course material is included. Specific deployment in those courses is not verifiable from repository contents. +A typical adoption workflow has five steps. First, an instructor writes a lesson in Quarto or R Markdown with learning objectives, narrative explanation, executable R chunks, and optional instructor tags. Second, the instructor adds MCQ blocks or question-bank references where conceptual checks are useful. Third, the instructor runs `tutorize()` to generate a `learnr` or `quarto-live` resource. Fourth, the instructor reviews the generated tutorial, adjusts wording or grading checks, and confirms that datasets and optional dependencies are available. Fifth, the resulting file can be distributed through the course platform, rendered locally, or incorporated into a broader teaching workflow. -# Availability +The example module in `inst/examples/example_course_module/` demonstrates this workflow with a source lesson, local question bank, expected converted outputs, JSON report, and reproducible run script. -The package source is available at: +## Experience of use and current limitations -`https://github.com/AurelienNicosiaULaval/tutorizeR` +The repository demonstrates intended use through tests, vignettes, and an installable example. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. Classroom deployment, broad adoption, and student outcome improvements are not claimed here. Not verifiable from repository contents. -The repository includes installation instructions, tests, vignettes, examples, contribution guidelines, a code of conduct, citation metadata, and reviewer-facing JOSE preparation documents. +Current limitations are also part of the educational story. `quarto-live` output requires the relevant Quarto live extension in the teaching project. `learnr` rendering requires optional runtime dependencies. LMS support is currently manifest-oriented rather than direct LMS publication. Generated material should always be reviewed by an instructor before release, especially grading logic and feedback wording. -# Quality Assurance +## Availability and licensing -The package includes `testthat` tests for parsing, conversion, exercise generation, MCQ handling, question-bank loading, validation errors, report writing, LMS manifest export, regression fixtures, `gradethis` setup generation, `quarto-live` output, and publication readiness assets. GitHub Actions are configured to run `R CMD check`, tests, linting, and coverage. +The package source is available at `https://github.com/AurelienNicosiaULaval/tutorizeR`. The package code is distributed under the MIT license. Educational examples and graphical documentation assets are released under CC-BY 4.0 unless otherwise specified. The repository includes tests, continuous integration configuration, contribution guidelines, a code of conduct, vignettes, reviewer documentation, and citation metadata. -Before submission, the maintainers should run a fresh local check on the current tree: +## AI usage disclosure -```bash -Rscript -e "testthat::test_local()" -Rscript -e "lintr::lint_package()" -R CMD build . -R CMD check --as-cran --no-manual tutorizeR_*.tar.gz -``` +Generative AI tools were used during planning, review, or documentation-support stages for this repository. The author reviewed, edited, tested, and takes responsibility for all submitted code, documentation, and manuscript text. -# AI Usage Disclosure +The package itself does not depend on any generative AI model. Its conversion pipeline is deterministic and script-driven. -Codex using GPT-5 was used on 2026-05-31 to assist with repository audit text, reviewer documentation, example files, tests, and manuscript revisions. The maintainer is responsible for reviewing, validating, and approving all content before submission. - -# References +## References diff --git a/tests/testthat/test-examples.R b/tests/testthat/test-examples.R new file mode 100644 index 0000000..06d29c7 --- /dev/null +++ b/tests/testthat/test-examples.R @@ -0,0 +1,135 @@ +local_edition(3) + +example_module_dir <- function() { + source_dir <- testthat::test_path("..", "..", "inst", "examples", "example_course_module") + installed_dir <- system.file("examples", "example_course_module", package = "tutorizeR") + + if (dir.exists(source_dir)) { + return(source_dir) + } + + installed_dir +} + +copy_example_to_temp <- function(example_dir) { + work_dir <- file.path(tempdir(check = TRUE), paste0("tutorizeR-example-", as.integer(runif(1, 1, 1e8)))) + dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) + + file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) + file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + + work_dir +} + +cleanup_example_packages <- function() { + for (pkg in c("package:readr", "package:ggplot2", "package:dplyr")) { + if (pkg %in% search()) { + detach(pkg, character.only = TRUE, unload = FALSE) + } + } +} + +test_that("example course module has required installable structure", { + example_dir <- example_module_dir() + + expect_true(dir.exists(example_dir)) + expect_true(file.exists(file.path(example_dir, "README.md"))) + expect_true(file.exists(file.path(example_dir, "lesson-source.qmd"))) + expect_true(file.exists(file.path(example_dir, "question-bank", "questions.yml"))) + expect_true(file.exists(file.path(example_dir, "expected", "lesson-source-tutorial.Rmd"))) + expect_true(file.exists(file.path(example_dir, "expected", "lesson-source-live.qmd"))) + expect_true(file.exists(file.path(example_dir, "expected", "conversion-report.json"))) + expect_true(file.exists(file.path(example_dir, "run-example.R"))) +}) + +test_that("example question bank loads and validates", { + example_dir <- example_module_dir() + + bank <- load_question_bank(file.path(example_dir, "question-bank")) + report <- validate_question_bank(bank, strict = FALSE) + + expect_s3_class(bank, "tutorize_question_bank") + expect_equal(length(bank$questions), 1L) + expect_false(any(report$findings$severity == "error")) +}) + +test_that("example module converts to learnr and writes JSON report", { + on.exit(cleanup_example_packages(), add = TRUE) + + example_dir <- example_module_dir() + work_dir <- copy_example_to_temp(example_dir) + bank <- load_question_bank(file.path(example_dir, "question-bank")) + + report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "learnr", + assessment = "both", + question_bank = bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE + ) + + report_file <- file.path(work_dir, "conversion-report.json") + write_tutorize_report(report, report_file, format = "json") + + lines <- readLines(report$output_file, warn = FALSE) + report_json <- jsonlite::fromJSON(report_file) + + expect_true(file.exists(report$output_file)) + expect_true(file.exists(report_file)) + expect_true(any(grepl("learnr::tutorial", lines, fixed = TRUE))) + expect_true(any(grepl("gradethis_setup()", lines, fixed = TRUE))) + expect_true(any(grepl("trz-mcq-bank", lines, fixed = TRUE))) + expect_equal(report_json$format, "learnr") +}) + +test_that("example module converts to quarto-live", { + on.exit(cleanup_example_packages(), add = TRUE) + + example_dir <- example_module_dir() + work_dir <- copy_example_to_temp(example_dir) + bank <- load_question_bank(file.path(example_dir, "question-bank")) + + report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "quarto-live", + assessment = "both", + question_bank = bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE + ) + + lines <- readLines(report$output_file, warn = FALSE) + + expect_true(file.exists(report$output_file)) + expect_true(any(grepl("format: live-html", lines, fixed = TRUE))) + expect_true(any(grepl("```\\{webr\\}", lines))) + expect_true(any(grepl("::: \\{\\.callout-note\\}", lines))) +}) + +test_that("run-example.R works from installed-style example path", { + on.exit(cleanup_example_packages(), add = TRUE) + + example_dir <- example_module_dir() + env <- new.env(parent = globalenv()) + + result <- source(file.path(example_dir, "run-example.R"), local = env) + + expect_true(dir.exists(result$value$work_dir)) + expect_true(file.exists(result$value$learnr_report$output_file)) + expect_true(file.exists(result$value$live_report$output_file)) + expect_true(file.exists(result$value$conversion_report)) +}) + +test_that("README user smoke tests do not use internal test fixtures", { + readme_file <- testthat::test_path("..", "..", "README.md") + skip_if_not(file.exists(readme_file), "README.md is not available in installed-package tests.") + + readme <- readLines(readme_file, warn = FALSE) + + expect_false(any(grepl("tests/testthat/fixtures", readme, fixed = TRUE))) +}) diff --git a/tests/testthat/test-jose-readiness.R b/tests/testthat/test-jose-readiness.R index 830039d..106a7c3 100644 --- a/tests/testthat/test-jose-readiness.R +++ b/tests/testthat/test-jose-readiness.R @@ -105,9 +105,11 @@ test_that("example course module is packaged with expected teaching artifacts", } expect_true(dir.exists(example_dir)) - expect_true(file.exists(file.path(example_dir, "source_lesson.qmd"))) - expect_true(file.exists(file.path(example_dir, "transformed_tutorial.Rmd"))) - expect_true(file.exists(file.path(example_dir, "generated_exercises.Rmd"))) - expect_true(file.exists(file.path(example_dir, "grading_examples.R"))) + expect_true(file.exists(file.path(example_dir, "lesson-source.qmd"))) + expect_true(file.exists(file.path(example_dir, "question-bank", "questions.yml"))) + expect_true(file.exists(file.path(example_dir, "expected", "lesson-source-tutorial.Rmd"))) + expect_true(file.exists(file.path(example_dir, "expected", "lesson-source-live.qmd"))) + expect_true(file.exists(file.path(example_dir, "expected", "conversion-report.json"))) + expect_true(file.exists(file.path(example_dir, "run-example.R"))) expect_true(file.exists(file.path(example_dir, "student_activity.csv"))) }) diff --git a/vignettes/automatic-exercise-generation-feedback.Rmd b/vignettes/automatic-exercise-generation-feedback.Rmd index 8b62f9f..3a4d9af 100644 --- a/vignettes/automatic-exercise-generation-feedback.Rmd +++ b/vignettes/automatic-exercise-generation-feedback.Rmd @@ -32,7 +32,7 @@ knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(tutorizeR) report <- tutorize( - input = "source_lesson.qmd", + input = "lesson-source.qmd", format = "learnr", assessment = "code", overwrite = TRUE diff --git a/vignettes/conversion-rmd-vs-qmd.Rmd b/vignettes/conversion-rmd-vs-qmd.Rmd index cfba82c..b3a523f 100644 --- a/vignettes/conversion-rmd-vs-qmd.Rmd +++ b/vignettes/conversion-rmd-vs-qmd.Rmd @@ -11,22 +11,71 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -`tutorizeR` accepts both `.Rmd` and `.qmd` sources. +## User goal -## Learnr output +This vignette helps instructors decide whether to target `learnr` or `quarto-live` when converting existing R Markdown or Quarto material. + +## Minimal examples ```{r eval=FALSE} +library(tutorizeR) + tutorize("lesson.Rmd", format = "learnr", assessment = "both") +tutorize("lesson.qmd", format = "quarto-live", assessment = "code") ``` -## Quarto live output +## Choosing an output format + +Use `learnr` when the course already supports RStudio or Shiny-based tutorials and when `gradethis` feedback is useful. Use `quarto-live` when browser-based execution is preferred and the teaching project has the Quarto live extension installed. + +## Realistic installed example ```{r eval=FALSE} -tutorize("lesson.qmd", format = "quarto-live", assessment = "code") +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +work_dir <- file.path(tempdir(), "tutorizeR-formats") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + +qb <- load_question_bank(file.path(example_dir, "question-bank")) + +learnr_report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "learnr", + assessment = "both", + question_bank = qb, + overwrite = TRUE, + verbose = FALSE +) + +live_report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "quarto-live", + assessment = "both", + question_bank = qb, + overwrite = TRUE, + verbose = FALSE +) ``` -When targeting `quarto-live`, install the extension in your project root: +## Limits + +When targeting `quarto-live`, install the extension in the teaching project: ```{r eval=FALSE} system("quarto add r-wasm/quarto-live") ``` + +Generated output should be reviewed in the environment where students will use it, because package availability and browser execution settings can differ. + +## Reproducibility checklist + +```{r eval=FALSE} +file.exists(learnr_report$output_file) +file.exists(live_report$output_file) +``` + diff --git a/vignettes/getting-started.Rmd b/vignettes/getting-started.Rmd index ce88101..7d053dd 100644 --- a/vignettes/getting-started.Rmd +++ b/vignettes/getting-started.Rmd @@ -11,9 +11,11 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -`tutorizeR` converts existing `.Rmd` or `.qmd` files into interactive teaching material. The usual workflow is to keep the instructor's source document as the single source of truth, then generate a student-facing tutorial for a specific teaching context. +## User goal -## Minimal workflow +This vignette helps an instructor convert one existing `.qmd` or `.Rmd` lesson into an interactive tutorial. The pedagogical goal is to keep one source document while generating student-facing practice material. + +## Minimal example ```{r eval=FALSE} library(tutorizeR) @@ -28,31 +30,50 @@ report <- tutorize( print(report) ``` -The returned report records the input file, output file, format, assessment mode, generated exercises, MCQs, warnings, lint results, and render status. +The report records the input file, output file, format, assessment mode, generated exercises, MCQs, warnings, lint results, and render status. -## Batch conversion +## Realistic installed example ```{r eval=FALSE} library(tutorizeR) -folder_report <- convert_folder( - dir = "course_material/", - recursive = TRUE, +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +work_dir <- file.path(tempdir(), "tutorizeR-example") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) + +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + +question_bank <- load_question_bank(file.path(example_dir, "question-bank")) + +report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, format = "learnr", assessment = "both", - overwrite = TRUE + question_bank = question_bank, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE ) -print(folder_report) +print(report) ``` -## Pre-conversion linting +## Batch conversion ```{r eval=FALSE} library(tutorizeR) -lint <- lint_source("lesson.qmd", strict = FALSE) -print(lint) +folder_report <- convert_folder( + dir = "course_material/", + recursive = TRUE, + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(folder_report) ``` ## Source annotation tags @@ -67,23 +88,16 @@ Use comments inside R chunks: - `# tutorizeR: locked` - `# tutorizeR: hints=Hint 1|Hint 2` -## Explicit MCQ block schema - -The YAML content inside a `tutorizeR-mcq` block has this structure: - -```yaml -question: "2 + 2 = ?" -answers: - - text: "4" - correct: true - - text: "5" - correct: false -``` +## Limits -## Reviewer smoke test +Generated tutorials should be reviewed before release. The package can scaffold exercises, solutions, MCQs, and reports, but it does not decide whether a prompt is pedagogically appropriate for a course. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. -The package includes a complete example module in `inst/examples/example_course_module/`. After installation, an instructor can locate it with: +## Reproducibility checklist ```{r eval=FALSE} -system.file("examples", "example_course_module", package = "tutorizeR") +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +source(file.path(example_dir, "run-example.R")) ``` + diff --git a/vignettes/lint-and-debug.Rmd b/vignettes/lint-and-debug.Rmd index effab0a..4e491a4 100644 --- a/vignettes/lint-and-debug.Rmd +++ b/vignettes/lint-and-debug.Rmd @@ -1,8 +1,8 @@ --- -title: "Lint and debug workflow" +title: "Lint and Debug Workflow" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Lint and debug workflow} + %\VignetteIndexEntry{Lint and Debug Workflow} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,11 +11,15 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -Run lint checks before conversion and export machine-readable reports. +## User goal -## Source linting +Linting helps instructors detect common authoring problems before conversion. This is useful in teaching teams where several people maintain source lessons. + +## Minimal example ```{r eval=FALSE} +library(tutorizeR) + lint <- lint_source("lesson.qmd", strict = FALSE) print(lint) ``` @@ -23,15 +27,49 @@ print(lint) ## Strict conversion ```{r eval=FALSE} -rep <- tutorize( +library(tutorizeR) + +report <- tutorize( input = "lesson.qmd", assessment = "both", - lint_strict = TRUE + lint_strict = TRUE, + overwrite = TRUE +) +``` + +## Realistic installed example + +```{r eval=FALSE} +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +source_file <- file.path(example_dir, "lesson-source.qmd") +question_bank <- load_question_bank(file.path(example_dir, "question-bank")) + +lint <- lint_source( + input = source_file, + question_bank = question_bank, + strict = FALSE ) + +print(lint) +``` + +## Conversion reports + +```{r eval=FALSE} +write_tutorize_report(report, "conversion-report.json", format = "json") ``` -## JSON report for CI +Reports are useful in continuous integration and course release workflows because they record the generated output path, number of exercises, MCQs, warnings, and lint summary. + +## Limits + +Linting can detect structural issues, but it cannot judge whether a lesson is pedagogically effective. Generated reports should support instructor review, not replace it. + +## Reproducibility checklist ```{r eval=FALSE} -write_tutorize_report(rep, "report.json", format = "json") +stopifnot(inherits(lint, "tutorize_lint_report")) ``` + diff --git a/vignettes/mcq-and-assessment.Rmd b/vignettes/mcq-and-assessment.Rmd index 6d326c4..f75a8f4 100644 --- a/vignettes/mcq-and-assessment.Rmd +++ b/vignettes/mcq-and-assessment.Rmd @@ -1,8 +1,8 @@ --- -title: "MCQ and assessment modes" +title: "MCQ and Assessment Modes" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{MCQ and assessment modes} + %\VignetteIndexEntry{MCQ and Assessment Modes} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,14 +11,73 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -Assessment modes: +## User goal -- `code`: generate exercises and solutions. +Assessment modes let instructors decide whether a lesson should generate coding practice, conceptual questions, or both. + +## Minimal examples + +```{r eval=FALSE} +library(tutorizeR) + +tutorize("lesson.qmd", assessment = "code") +tutorize("lesson.qmd", assessment = "mcq") +tutorize("lesson.qmd", assessment = "both") +``` + +## Modes + +- `code`: generate exercise and solution scaffolds. - `mcq`: generate MCQ blocks only. -- `both`: generate code exercises and MCQ blocks. +- `both`: generate code exercises, solutions, and MCQs. + +## Realistic source pattern + +```yaml +question: "Which variable identifies the academic program?" +answers: + - text: "program" + correct: true + - text: "quiz_score" + correct: false +``` + +In a source lesson, this YAML would be placed inside a `tutorizeR-mcq` fenced block. + +## Realistic installed example ```{r eval=FALSE} -tutorize("tp.qmd", assessment = "code") -tutorize("tp.qmd", assessment = "mcq") -tutorize("tp.qmd", assessment = "both") +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +work_dir <- file.path(tempdir(), "tutorizeR-assessment") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + +qb <- load_question_bank(file.path(example_dir, "question-bank")) + +report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + assessment = "both", + question_bank = qb, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) + +print(report$mcq) ``` + +## Limits + +Generated MCQs are scaffolds. Instructors should verify that questions are aligned with learning objectives and that distractors are plausible. The package does not measure whether an MCQ improves learning. + +## Reproducibility checklist + +```{r eval=FALSE} +lines <- readLines(report$output_file) +any(grepl("learnr::question", lines, fixed = TRUE)) +``` + diff --git a/vignettes/quarto-lesson-interactive-tutorial.Rmd b/vignettes/quarto-lesson-interactive-tutorial.Rmd index ece2ad5..3f36524 100644 --- a/vignettes/quarto-lesson-interactive-tutorial.Rmd +++ b/vignettes/quarto-lesson-interactive-tutorial.Rmd @@ -51,7 +51,7 @@ A source `.qmd` lesson can contain narrative text, setup code, examples, and MCQ library(tutorizeR) report <- tutorize( - input = "source_lesson.qmd", + input = "lesson-source.qmd", output_dir = "generated", format = "learnr", assessment = "both", @@ -69,7 +69,7 @@ For browser-executable Quarto output, target `quarto-live`: library(tutorizeR) report <- tutorize( - input = "source_lesson.qmd", + input = "lesson-source.qmd", output_dir = "generated", format = "quarto-live", assessment = "code", diff --git a/vignettes/question-bank.Rmd b/vignettes/question-bank.Rmd index 9410220..ff91685 100644 --- a/vignettes/question-bank.Rmd +++ b/vignettes/question-bank.Rmd @@ -1,8 +1,8 @@ --- -title: "Reusable question bank" +title: "Reusable Question Banks" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Reusable question bank} + %\VignetteIndexEntry{Reusable Question Banks} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,32 +11,84 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -Use local YAML/JSON files to maintain reusable MCQ content. +## User goal + +Question banks help instructors reuse conceptual checks across lessons. This is useful when multiple tutorials should assess the same core ideas without rewriting each MCQ by hand. + +## Minimal bank + +```yaml +questions: + - id: visualization-aesthetic + question: "Which aesthetic maps a variable to the vertical axis?" + answers: + - text: "y" + correct: true + - text: "x" + correct: false + tags: [visualization] + difficulty: introductory + language: en +``` ## Load and validate ```{r eval=FALSE} -qb <- load_question_bank("inst/question-bank") -print(validate_question_bank(qb, strict = FALSE)) +library(tutorizeR) + +qb <- load_question_bank("question-bank") +report <- validate_question_bank(qb, strict = FALSE) + +print(report) ``` -## Reference bank questions in source files +## Reference bank questions in a lesson The YAML content inside a `tutorizeR-mcq-ref` block can reference existing bank items: ```yaml -ids: [sample-mean] +ids: [visualization-aesthetic] strategy: ordered shuffle_answers: false ``` -## Convert with bank-enabled MCQ mode +## Realistic installed example ```{r eval=FALSE} -rep <- tutorize( - input = "lesson.qmd", +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +qb <- load_question_bank(file.path(example_dir, "question-bank")) + +work_dir <- file.path(tempdir(), "tutorizeR-qb-example") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + +report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, assessment = "both", question_bank = qb, - mcq_source = "mixed" + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE ) + +print(report) ``` + +## Limits + +Question banks improve reuse, but they do not guarantee good assessment design. Instructors should check that each MCQ is aligned with the learning objective, has plausible distractors, and uses language appropriate for the course. + +## Reproducibility checklist + +```{r eval=FALSE} +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +qb <- load_question_bank(file.path(example_dir, "question-bank")) +validate_question_bank(qb, strict = TRUE) +``` + diff --git a/vignettes/reproducible-data-science-assignments.Rmd b/vignettes/reproducible-data-science-assignments.Rmd index d06b0fc..9705f6f 100644 --- a/vignettes/reproducible-data-science-assignments.Rmd +++ b/vignettes/reproducible-data-science-assignments.Rmd @@ -17,7 +17,7 @@ Data science assignments are easier to maintain when the instructor can keep one ```text assignment-week03/ - source_lesson.qmd + lesson-source.qmd data/ student_activity.csv generated/ @@ -30,7 +30,7 @@ assignment-week03/ ```{r eval=FALSE} library(tutorizeR) -source_file <- "assignment-week03/source_lesson.qmd" +source_file <- "assignment-week03/lesson-source.qmd" report <- tutorize( input = source_file, @@ -59,7 +59,7 @@ For teaching workflows, a fixed seed makes generated setup chunks reproducible. library(tutorizeR) manifest <- export_lms_manifest( - input = "assignment-week03/source_lesson.qmd", + input = "assignment-week03/lesson-source.qmd", output_file = "assignment-week03/generated/lms-manifest.json", profile = "canvas", include_solutions = FALSE diff --git a/vignettes/teaching-workflow-case-study.Rmd b/vignettes/teaching-workflow-case-study.Rmd new file mode 100644 index 0000000..8209c5d --- /dev/null +++ b/vignettes/teaching-workflow-case-study.Rmd @@ -0,0 +1,111 @@ +--- +title: "Teaching Workflow Case Study" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Teaching Workflow Case Study} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +## Teaching problem + +An instructor has a Quarto lesson on introductory data summarisation and visualization. The lesson contains narrative explanation, R chunks, a small dataset, and interpretation prompts. The instructor wants a student-facing tutorial with exercises, solution material, MCQs, and a conversion report without maintaining a separate tutorial by hand. + +## Source-first workflow + +The instructor keeps `lesson-source.qmd` as the source of truth. Generated `learnr` or `quarto-live` files are outputs that can be regenerated after edits. + +```{r eval=FALSE} +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +``` + +## Annotating a `.qmd` lesson + +Instructor comments inside R chunks control conversion: + +```r +# tutorizeR: hints=Group by program before summarising|Use .groups = "drop" +``` + +The comments stay close to the source code, which helps course teams review the pedagogical intent of each chunk. + +## Adding MCQs and question-bank references + +Inline MCQs are useful for lesson-specific checks. Question-bank references are useful when a concept should be reused across modules. + +```yaml +ids: [visualization-aesthetic] +strategy: ordered +shuffle_answers: false +``` + +## Running `tutorize()` + +```{r eval=FALSE} +work_dir <- file.path(tempdir(), "tutorizeR-case-study") +dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) + +file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) +file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) + +qb <- load_question_bank(file.path(example_dir, "question-bank")) + +report <- tutorize( + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, + format = "learnr", + assessment = "both", + question_bank = qb, + mcq_source = "mixed", + overwrite = TRUE, + verbose = FALSE +) +``` + +## Interpreting the conversion report + +```{r eval=FALSE} +print(report) + +write_tutorize_report( + report = report, + file = file.path(work_dir, "conversion-report.json"), + format = "json" +) +``` + +The report helps an instructor check how many exercises, solutions, and MCQs were generated. It also records warnings and lint summaries. + +## Reviewing the generated tutorial + +The instructor should open the generated file and verify: + +- the generated exercise prompts are clear; +- solutions are appropriate for release policy; +- MCQs are aligned with the intended concept; +- datasets are available where the tutorial will be rendered; +- optional packages are available to students. + +## Publishing or sharing + +The package creates local artifacts. Publishing depends on the teaching environment. Instructors may render `learnr` tutorials, distribute Quarto output, or use generated reports in course release workflows. Direct LMS publication is not implemented in the current version. + +## Limitations and manual checks + +This workflow demonstrates feasibility and reproducibility, not measured learning impact. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. Classroom deployment is not verifiable from repository contents. + +## Reproducibility checklist + +```{r eval=FALSE} +library(tutorizeR) + +example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") +source(file.path(example_dir, "run-example.R")) +``` + From ef22b8d64808b1d2f170db932f75c03f1dc66ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 10:45:47 -0400 Subject: [PATCH 03/10] docs: record JOSE CI verification --- docs/jose_blockers_report.md | 4 ++-- docs/jose_pr_final_report.md | 18 +++++++++++++----- docs/jose_review_checklist.md | 5 ++--- docs/jose_submission_report.md | 7 ++++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/docs/jose_blockers_report.md b/docs/jose_blockers_report.md index 34066d6..ee848d4 100644 --- a/docs/jose_blockers_report.md +++ b/docs/jose_blockers_report.md @@ -35,7 +35,7 @@ Sources consulted: | BLOCKER | Claiming improved learning outcomes, grades, or engagement without measured evidence. | Do not claim. | | MAJOR | Claiming JOSE submission, review, or acceptance. | Do not claim until it happens and is documented. | | MAJOR | Claiming CRAN publication. | Do not claim unless CRAN publication is verified. | -| MAJOR | Claiming CI is green without checking remote Actions. | Use `Not verifiable from repository contents.` unless checked live. | +| MAJOR | Claiming CI is green without checking remote Actions. | Addressed for PR #5 commit `864c489`; rerun on final release commit. | ## Package Quality Risks @@ -93,7 +93,7 @@ Files addressed in this PR: ## Final Checklist Before Submission -- [ ] Confirm remote GitHub Actions pass on the final submitted branch. +- [x] Confirm remote GitHub Actions pass on PR #5 commit `864c489`. - [ ] Rerun `Rscript -e "testthat::test_local('.')"` on a clean checkout. - [ ] Rerun `Rscript -e "lintr::lint_package()"`. - [ ] Rerun source build from a clean source copy or another checkout that does not copy `.git`. diff --git a/docs/jose_pr_final_report.md b/docs/jose_pr_final_report.md index 8e0fa44..75ff1a4 100644 --- a/docs/jose_pr_final_report.md +++ b/docs/jose_pr_final_report.md @@ -48,7 +48,7 @@ PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 - Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. - Actual classroom deployment is not verifiable from repository contents. - Broad external instructor adoption is not verifiable from repository contents. -- Remote GitHub Actions status must be checked after pushing this update. +- Remote GitHub Actions passed on PR #5 for commit `864c489`. - ORCID and final release DOI should be confirmed before submission. ## Validation Commands Run @@ -142,9 +142,18 @@ Result: PASS with 1 NOTE for new submission. ## CI Status -Not verifiable from repository contents. +GitHub Actions were checked on PR #5 after pushing commit `864c489`. -Remote GitHub Actions must be checked after this update is pushed. +Run: https://github.com/AurelienNicosiaULaval/tutorizeR/actions/runs/26715564901 + +Results: + +- `coverage`: PASS, 2m21s. +- `lintr`: PASS, 2m24s. +- `testthat`: PASS, 2m36s. +- `r-cmd-check (ubuntu-latest, release)`: PASS, 3m3s. +- `r-cmd-check (macos-latest, release)`: PASS, 3m34s. +- `r-cmd-check (windows-latest, release)`: PASS, 4m26s. ## Files Modified @@ -176,9 +185,8 @@ Key changed or added files: - Documented classroom deployment: Not verifiable from repository contents. - Formal learning-outcome evaluation: Not verifiable from repository contents. -- Remote CI status after final push: Not verifiable from repository contents. - Final release DOI and ORCID metadata should be confirmed. Recommendation: Not ready for JOSE submission. -The repository is substantially more JOSE-ready, but a real submission should wait until remote CI is verified and the maintainer decides whether to add documented classroom-use evidence. +The repository is substantially more JOSE-ready, but a real submission should wait until the maintainer confirms final release metadata and decides whether to add documented classroom-use evidence. diff --git a/docs/jose_review_checklist.md b/docs/jose_review_checklist.md index 44c5ac6..d8a388e 100644 --- a/docs/jose_review_checklist.md +++ b/docs/jose_review_checklist.md @@ -50,8 +50,8 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi |---|---|---| | Automated tests exist. | READY | `tests/testthat/`. | | Example module tests exist. | READY | `tests/testthat/test-examples.R`. | -| Local tests pass. | PARTIAL | Must be rerun on final checkout before submission. | -| Remote CI passes. | NOT VERIFIABLE | Requires checking GitHub Actions after push. | +| Local tests pass. | READY | `testthat::test_local('.')` passed locally with 144 tests on 2026-05-31. | +| Remote CI passes. | READY | GitHub Actions run `26715564901` passed on PR #5 for commit `864c489`. | ## Examples @@ -98,4 +98,3 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Pedagogical references are cited. | READY | paper and bibliography. | | AI usage disclosure is cautious. | READY | `paper/paper.md`. | | Final metadata is complete. | PARTIAL | ORCID and final release DOI should be confirmed. | - diff --git a/docs/jose_submission_report.md b/docs/jose_submission_report.md index bf43ec1..53f9e19 100644 --- a/docs/jose_submission_report.md +++ b/docs/jose_submission_report.md @@ -15,7 +15,7 @@ Rationale: - strong package structure, tests, documentation, governance files, and manuscript assets; - clear educational infrastructure purpose; -- remaining uncertainty around external adoption evidence, public repository history, and CRAN status. +- remaining uncertainty around external adoption evidence, public repository history, and CRAN publication status. ## JOSE Readiness Score @@ -33,7 +33,7 @@ Main limitations: - actual classroom adoption is not verifiable from repository contents; - public repository history and public review readiness are not verifiable from local contents; -- the final submission should rerun test, lint, coverage, and R CMD check records immediately before upload. +- GitHub Actions passed on PR #5 for commit `864c489`; checks should still be rerun immediately before upload. ## JOSS Readiness Score @@ -82,6 +82,7 @@ On 2026-05-31, the following checks were performed locally: - Coverage gate script: PASS, 71.58% total coverage and 93.36% core coverage. - Clean temporary source copy built with `R CMD build`: PASS. - `R CMD check --as-cran --no-manual`: PASS with 1 NOTE for new submission. +- GitHub Actions on PR #5 for commit `864c489`: PASS for coverage, lintr, testthat, and R CMD check on Ubuntu, macOS, and Windows. Direct `R CMD build .` from the live Git checkout was attempted but interrupted because R spent too long copying `.git` into the temporary build directory before applying package build exclusions. Building from a clean source copy without `.git`, `.Rcheck`, or local tarballs succeeded. @@ -96,7 +97,7 @@ Direct `R CMD build .` from the live Git checkout was attempted but interrupted ## Recommended Next Actions 1. Run tests, linting, coverage, and `R CMD check --as-cran --no-manual` on a clean checkout. -2. Confirm that GitHub Actions pass on the remote repository. +2. Confirm that GitHub Actions still pass on the final release commit. 3. Add anonymized, permission-safe teaching evidence if available. 4. Confirm that all paper metadata is final, especially ORCID and release DOI. 5. Create a tagged release before submission. From 0bbdaa942c81aa9d38778e9850fa8bca421ffb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 10:49:39 -0400 Subject: [PATCH 04/10] docs: generalize JOSE CI status --- docs/jose_blockers_report.md | 4 ++-- docs/jose_pr_final_report.md | 18 +++++++++--------- docs/jose_review_checklist.md | 2 +- docs/jose_submission_report.md | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/jose_blockers_report.md b/docs/jose_blockers_report.md index ee848d4..964ef4c 100644 --- a/docs/jose_blockers_report.md +++ b/docs/jose_blockers_report.md @@ -35,7 +35,7 @@ Sources consulted: | BLOCKER | Claiming improved learning outcomes, grades, or engagement without measured evidence. | Do not claim. | | MAJOR | Claiming JOSE submission, review, or acceptance. | Do not claim until it happens and is documented. | | MAJOR | Claiming CRAN publication. | Do not claim unless CRAN publication is verified. | -| MAJOR | Claiming CI is green without checking remote Actions. | Addressed for PR #5 commit `864c489`; rerun on final release commit. | +| MAJOR | Claiming CI is green without checking remote Actions. | Addressed during this review; rerun on final release commit. | ## Package Quality Risks @@ -93,7 +93,7 @@ Files addressed in this PR: ## Final Checklist Before Submission -- [x] Confirm remote GitHub Actions pass on PR #5 commit `864c489`. +- [x] Confirm remote GitHub Actions pass on PR #5 during this review. - [ ] Rerun `Rscript -e "testthat::test_local('.')"` on a clean checkout. - [ ] Rerun `Rscript -e "lintr::lint_package()"`. - [ ] Rerun source build from a clean source copy or another checkout that does not copy `.git`. diff --git a/docs/jose_pr_final_report.md b/docs/jose_pr_final_report.md index 75ff1a4..b06f580 100644 --- a/docs/jose_pr_final_report.md +++ b/docs/jose_pr_final_report.md @@ -48,7 +48,7 @@ PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 - Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. - Actual classroom deployment is not verifiable from repository contents. - Broad external instructor adoption is not verifiable from repository contents. -- Remote GitHub Actions passed on PR #5 for commit `864c489`. +- Remote GitHub Actions passed during this review. Because any later push retriggers CI, reviewers should check the current PR checks before submission. - ORCID and final release DOI should be confirmed before submission. ## Validation Commands Run @@ -142,18 +142,18 @@ Result: PASS with 1 NOTE for new submission. ## CI Status -GitHub Actions were checked on PR #5 after pushing commit `864c489`. +GitHub Actions were checked on PR #5 during this review. -Run: https://github.com/AurelienNicosiaULaval/tutorizeR/actions/runs/26715564901 +Observed passing run: https://github.com/AurelienNicosiaULaval/tutorizeR/actions/runs/26715694988 Results: -- `coverage`: PASS, 2m21s. -- `lintr`: PASS, 2m24s. -- `testthat`: PASS, 2m36s. -- `r-cmd-check (ubuntu-latest, release)`: PASS, 3m3s. -- `r-cmd-check (macos-latest, release)`: PASS, 3m34s. -- `r-cmd-check (windows-latest, release)`: PASS, 4m26s. +- `coverage`: PASS, 1m26s. +- `lintr`: PASS, 1m10s. +- `testthat`: PASS, 1m20s. +- `r-cmd-check (ubuntu-latest, release)`: PASS, 2m4s. +- `r-cmd-check (macos-latest, release)`: PASS, 2m17s. +- `r-cmd-check (windows-latest, release)`: PASS, 3m4s. ## Files Modified diff --git a/docs/jose_review_checklist.md b/docs/jose_review_checklist.md index d8a388e..e143bea 100644 --- a/docs/jose_review_checklist.md +++ b/docs/jose_review_checklist.md @@ -51,7 +51,7 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Automated tests exist. | READY | `tests/testthat/`. | | Example module tests exist. | READY | `tests/testthat/test-examples.R`. | | Local tests pass. | READY | `testthat::test_local('.')` passed locally with 144 tests on 2026-05-31. | -| Remote CI passes. | READY | GitHub Actions run `26715564901` passed on PR #5 for commit `864c489`. | +| Remote CI passes. | READY | GitHub Actions run `26715694988` passed on PR #5 during this review. | ## Examples diff --git a/docs/jose_submission_report.md b/docs/jose_submission_report.md index 53f9e19..ab02cd3 100644 --- a/docs/jose_submission_report.md +++ b/docs/jose_submission_report.md @@ -33,7 +33,7 @@ Main limitations: - actual classroom adoption is not verifiable from repository contents; - public repository history and public review readiness are not verifiable from local contents; -- GitHub Actions passed on PR #5 for commit `864c489`; checks should still be rerun immediately before upload. +- GitHub Actions passed on PR #5 during this review; checks should still be rerun immediately before upload. ## JOSS Readiness Score @@ -82,7 +82,7 @@ On 2026-05-31, the following checks were performed locally: - Coverage gate script: PASS, 71.58% total coverage and 93.36% core coverage. - Clean temporary source copy built with `R CMD build`: PASS. - `R CMD check --as-cran --no-manual`: PASS with 1 NOTE for new submission. -- GitHub Actions on PR #5 for commit `864c489`: PASS for coverage, lintr, testthat, and R CMD check on Ubuntu, macOS, and Windows. +- GitHub Actions on PR #5 during this review: PASS for coverage, lintr, testthat, and R CMD check on Ubuntu, macOS, and Windows. Direct `R CMD build .` from the live Git checkout was attempted but interrupted because R spent too long copying `.git` into the temporary build directory before applying package build exclusions. Building from a clean source copy without `.git`, `.Rcheck`, or local tarballs succeeded. From 2d6e4728875244ffa357fd9ad4acb123f25365ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 11:32:59 -0400 Subject: [PATCH 05/10] docs: tighten JOSE submission readiness --- .Rbuildignore | 2 + .github/workflows/r.yml | 33 ++++++++ CITATION.cff | 3 +- DESCRIPTION | 8 +- LICENSES.md | 14 ++++ NEWS.md | 2 +- README.md | 46 ++++------- _pkgdown.yml | 25 +++++- docs/educational_use_cases.md | 3 +- docs/educational_use_evidence.md | 19 ++--- docs/jose_audit.md | 13 ++-- docs/jose_blockers_report.md | 11 ++- docs/jose_checklist.md | 15 ++-- docs/jose_pr_final_report.md | 78 +++++++++++-------- docs/jose_release_bundle.md | 11 ++- docs/jose_review_checklist.md | 14 ++-- docs/jose_submission_guide.md | 27 ++++--- docs/jose_submission_report.md | 18 ++--- inst/examples/example_course_module/README.md | 2 +- .../expected/conversion-report.json | 4 +- .../expected/lesson-source-live.qmd | 29 +++---- .../expected/lesson-source-tutorial.Rmd | 29 +++---- .../example_course_module/lesson-source.qmd | 2 +- .../question-bank/questions.yml | 51 +++++++++++- .../example_course_module/run-example.R | 34 ++++++++ paper/paper.md | 13 ++-- tests/testthat/test-examples.R | 78 ++++++++++++++++++- vignettes/getting-started.Rmd | 3 +- vignettes/jose-submission-readiness.Rmd | 27 +++++-- vignettes/large-undergraduate-courses.Rmd | 9 +-- ...udy.Rmd => teaching-workflow-scenario.Rmd} | 14 ++-- 31 files changed, 453 insertions(+), 184 deletions(-) create mode 100644 LICENSES.md rename vignettes/{teaching-workflow-case-study.Rmd => teaching-workflow-scenario.Rmd} (88%) diff --git a/.Rbuildignore b/.Rbuildignore index 5d24a01..f6ef0ec 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -2,6 +2,8 @@ ^\.Rproj\.user$ ^LICENSE\.md$ ^LICENSE-CONTENT\.md$ +^LICENSES\.md$ +^pkgdown$ ^\.github$ ^ROADMAP\.md$ ^docs$ diff --git a/.github/workflows/r.yml b/.github/workflows/r.yml index 91cb6b3..92bec3f 100644 --- a/.github/workflows/r.yml +++ b/.github/workflows/r.yml @@ -27,6 +27,7 @@ jobs: with: r-version: ${{ matrix.config.r }} use-public-rspm: true + extra-repositories: https://rstudio.r-universe.dev - uses: r-lib/actions/setup-r-dependencies@v2 with: @@ -47,6 +48,7 @@ jobs: with: r-version: 'release' use-public-rspm: true + extra-repositories: https://rstudio.r-universe.dev - uses: r-lib/actions/setup-r-dependencies@v2 with: @@ -67,6 +69,7 @@ jobs: with: r-version: 'release' use-public-rspm: true + extra-repositories: https://rstudio.r-universe.dev - uses: r-lib/actions/setup-r-dependencies@v2 with: @@ -89,6 +92,7 @@ jobs: with: r-version: 'release' use-public-rspm: true + extra-repositories: https://rstudio.r-universe.dev - uses: r-lib/actions/setup-r-dependencies@v2 with: @@ -116,3 +120,32 @@ jobs: stop(sprintf("Core coverage threshold not met: %.2f%% < 80%%", core_pct)) } shell: Rscript {0} + + installed-example: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: 'release' + use-public-rspm: true + extra-repositories: https://rstudio.r-universe.dev + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + needs: check + + - name: Install package + run: R CMD INSTALL . + + - name: Run installed example module + run: | + source(system.file( + "examples", + "example_course_module", + "run-example.R", + package = "tutorizeR" + )) + shell: Rscript {0} diff --git a/CITATION.cff b/CITATION.cff index 8eec3ed..c3f1854 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -11,7 +11,7 @@ version: 0.4.4 license: MIT repository-code: https://github.com/AurelienNicosiaULaval/tutorizeR url: https://github.com/AurelienNicosiaULaval/tutorizeR -date-released: '2026-02-13' +date-released: '2026-02-14' keywords: - learnr - quarto @@ -26,5 +26,4 @@ authors: email: aurelien.nicosia@mat.ulaval.ca affiliation: >- Université Laval - orcid: null role: author diff --git a/DESCRIPTION b/DESCRIPTION index 84f62e0..e2f7015 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,7 +17,7 @@ Description: Helps teachers convert existing '.Rmd' and '.qmd' teaching conversion reports. License: MIT + file LICENSE Encoding: UTF-8 -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 Depends: R (>= 4.0) Imports: @@ -31,12 +31,18 @@ Imports: Suggests: commonmark, covr, + dplyr, + ggplot2, + gradethis, knitr, learnr, lintr, miniUI, + readr, shiny, testthat (>= 3.0.0) +Additional_repositories: + https://rstudio.r-universe.dev VignetteBuilder: knitr Config/testthat/edition: 3 URL: https://github.com/AurelienNicosiaULaval/tutorizeR diff --git a/LICENSES.md b/LICENSES.md new file mode 100644 index 0000000..c2278a1 --- /dev/null +++ b/LICENSES.md @@ -0,0 +1,14 @@ +# License clarification + +This file clarifies licensing for reviewers and downstream instructors. + +| Repository content | License | Notes | +|---|---|---| +| R package code in `R/`, `inst/scripts/`, tests, and package infrastructure | MIT | The CRAN-style license fields are in `DESCRIPTION` and `LICENSE`; the full MIT text is in `LICENSE.md`. | +| Technical package documentation, including README examples, function documentation, and vignettes | MIT | These files document use of the package and are treated as package documentation. | +| Educational content in `inst/examples/` | CC-BY 4.0 | This includes the example course module, lesson source, question bank, dataset, and generated expected outputs. | +| Generated expected outputs in `inst/examples/example_course_module/expected/` | CC-BY 4.0 | These files are educational artifacts derived from the example course module. | +| Graphical documentation assets in `man/figures/` | CC-BY 4.0 | Includes the logo and workflow figure unless a file-level notice states otherwise. | +| Reviewer documentation in `docs/` | MIT | These files support package review and release preparation. | + +The Creative Commons Attribution 4.0 International license text is available at . diff --git a/NEWS.md b/NEWS.md index 32c020e..ef384c6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,7 @@ ## Release finalization -- Finalized JOSS-ready release artifacts and metadata alignment. +- Finalized JOSE-oriented reviewer artifacts and metadata alignment. - Refreshed reproducibility and reviewer guidance docs. - Synchronized version fields for release publication. - Added JOSE preparation artifacts, educational use-case documentation, diff --git a/README.md b/README.md index a83d560..0da643f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ tutorizeR hex sticker

-[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17771142.svg)](https://doi.org/10.5281/zenodo.17771142) [![R-CMD-check](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml/badge.svg)](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml) [![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html) [![CRAN status](https://img.shields.io/badge/CRAN-not%20submitted-lightgrey.svg)](https://CRAN.R-project.org/package=tutorizeR) @@ -82,36 +81,18 @@ Developer checks: ```bash Rscript -e "testthat::test_local('.')" Rscript -e "lintr::lint_package()" +tmpdir=$(mktemp -d) +rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" +cd "$tmpdir/tutorizeR" +Rscript -e "devtools::document()" R CMD build . R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz ``` Installed smoke test: -```r -library(tutorizeR) - -example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") -work_dir <- file.path(tempdir(), "tutorizeR-example") -dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) - -file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) -file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) - -source_file <- file.path(work_dir, "lesson-source.qmd") - -report <- tutorize( - input = source_file, - format = "learnr", - assessment = "both", - output_dir = work_dir, - question_bank = load_question_bank(file.path(example_dir, "question-bank")), - mcq_source = "mixed", - overwrite = TRUE, - verbose = FALSE -) - -print(report) +```bash +Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" ``` ## JOSE submission note @@ -130,7 +111,12 @@ Reviewer-facing JOSE materials: - `paper/paper.md` - `paper/paper.bib` -Not verifiable from repository contents: formal learning-outcome evaluation, classroom deployment, broad instructor adoption, current CRAN publication, and JOSE submission or acceptance. +Formal learning-outcome evaluation: Not verifiable from repository contents. +Actual classroom deployment: Not verifiable from repository contents. +Broad instructor adoption: Not verifiable from repository contents. +Final release DOI: Not verifiable from repository contents. +Current CRAN publication: Not verifiable from repository contents. +JOSE submission or acceptance: Not verifiable from repository contents. ## Secondary target: JOSS @@ -202,12 +188,12 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo - `quarto-live` output requires the Quarto live extension in the teaching project. - LMS export is manifest-only in v0.4, with no direct remote LMS publishing API. - Question banks are local YAML or JSON files in v0.4. -- Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. +- Formal learning-outcome evaluation: Not verifiable from repository contents. ## Documentation - `vignettes/getting-started.Rmd` -- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/teaching-workflow-scenario.Rmd` - `vignettes/quarto-lesson-interactive-tutorial.Rmd` - `vignettes/reproducible-data-science-assignments.Rmd` - `vignettes/automatic-exercise-generation-feedback.Rmd` @@ -218,8 +204,8 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo - `vignettes/mcq-and-assessment.Rmd` - `vignettes/lint-and-debug.Rmd` -## License +## Licensing The package code is released under the MIT license. The CRAN-style license metadata is stored in `LICENSE`, and the full MIT license text is available in `LICENSE.md`. -Educational example materials in `inst/examples/` and graphical documentation assets in `man/figures/` are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md`. +Educational example materials in `inst/examples/`, generated expected educational outputs, and graphical documentation assets in `man/figures/` are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md` and `LICENSES.md`. diff --git a/_pkgdown.yml b/_pkgdown.yml index 9943336..bdcfe90 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -24,8 +24,8 @@ navbar: teaching_examples: text: Teaching examples menu: - - text: Teaching workflow case study - href: articles/teaching-workflow-case-study.html + - text: Teaching workflow scenario + href: articles/teaching-workflow-scenario.html - text: Getting started href: articles/getting-started.html - text: Question bank @@ -55,17 +55,35 @@ reference: - validate_input - validate_output - check_tutorial + - lint_source + - title: Question banks and reports + contents: + - load_question_bank + - validate_question_bank + - write_tutorize_report + - print.tutorize_report + - print.tutorize_lint_report + - print.tutorize_folder_report + - title: Exports + contents: + - export_lms_manifest + - export_tutorial_package + - print.tutorize_lms_manifest - title: Addins contents: - launch_tutorizeR_addin - launch_tutorizeR_folder_addin + - launch_tutorizeR_preview_addin + - title: Internationalization + contents: + - tr articles: - title: Getting started navbar: Getting started contents: - getting-started - - teaching-workflow-case-study + - teaching-workflow-scenario - quarto-lesson-interactive-tutorial - reproducible-data-science-assignments - title: Authoring and syntax @@ -76,6 +94,7 @@ articles: - conversion-rmd-vs-qmd - mcq-and-assessment - lint-and-debug + - debugging-and-errors - automatic-exercise-generation-feedback - title: Educational use navbar: Educational use diff --git a/docs/educational_use_cases.md b/docs/educational_use_cases.md index 6316f19..c8d64cb 100644 --- a/docs/educational_use_cases.md +++ b/docs/educational_use_cases.md @@ -18,7 +18,7 @@ Relevant classroom activities include: - creating reproducible assignment templates with consistent structure; - exporting conversion reports for teaching assistants or course coordination. -Specific course adoption is not verifiable from repository contents. +Specific course adoption: Not verifiable from repository contents. ## Instructor Workflows @@ -108,4 +108,3 @@ The example module in `inst/examples/example_course_module/` follows this patter The repository demonstrates educational intent, package functionality, examples, tests, and reviewer-facing documentation. It does not contain verifiable classroom outcome data, anonymized student analytics, external adoption records, or formal evaluation results. Therefore, any claim about actual classroom adoption should be written as: Not verifiable from repository contents. - diff --git a/docs/educational_use_evidence.md b/docs/educational_use_evidence.md index 0d9bbb4..dbd124d 100644 --- a/docs/educational_use_evidence.md +++ b/docs/educational_use_evidence.md @@ -28,7 +28,7 @@ It is plausible that `tutorizeR` may help instructors: These are workflow plausibility statements, not measured educational outcomes. -Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. +Formal learning-outcome evaluation: Not verifiable from repository contents. ## What Is Not Claimed @@ -49,7 +49,7 @@ Reviewers can inspect: - `inst/examples/example_course_module/README.md`; - `inst/examples/example_course_module/run-example.R`; -- `vignettes/teaching-workflow-case-study.Rmd`; +- `vignettes/teaching-workflow-scenario.Rmd`; - `tests/testthat/test-examples.R`; - `tests/testthat/test-jose-readiness.R`; - `paper/paper.md`; @@ -58,14 +58,12 @@ Reviewers can inspect: ## Evidence Still Missing Before a Stronger JOSE Submission -Not verifiable from repository contents: - -- actual classroom deployment; -- instructor adoption outside the maintainer; -- formal student feedback; -- student outcome data; -- teaching assistant workflow evidence; -- long-term use across multiple cohorts. +- Actual classroom deployment: Not verifiable from repository contents. +- Instructor adoption outside the maintainer: Not verifiable from repository contents. +- Formal student feedback: Not verifiable from repository contents. +- Student outcome data: Not verifiable from repository contents. +- Teaching assistant workflow evidence: Not verifiable from repository contents. +- Long-term use across multiple cohorts: Not verifiable from repository contents. ## Claims that must not be made @@ -76,4 +74,3 @@ Not verifiable from repository contents: - Do not claim JOSE readiness solely because R CMD check passes. - Do not claim direct LMS publishing, because current support is manifest-oriented. - Do not claim current CRAN availability unless verified. - diff --git a/docs/jose_audit.md b/docs/jose_audit.md index 5d153f0..fc45174 100644 --- a/docs/jose_audit.md +++ b/docs/jose_audit.md @@ -31,11 +31,11 @@ The audit inspected the package metadata, source code, tests, vignettes, documen ## Weaknesses -- Educational adoption evidence is not directly verifiable from repository contents. The repository supports educational workflows, but it does not currently include anonymized course deployment evidence, classroom evaluation data, instructor testimonials, or external adoption links. +- Educational adoption evidence: Not verifiable from repository contents. - The README is technically useful but still stronger as developer documentation than as a JOSE reviewer landing page. - Existing vignettes before this audit were short and did not fully cover the five educational scenarios requested for JOSE positioning. - `pkgdown` configuration existed but did not yet expose a dedicated JOSE submission section, educational examples section, or visual workflow assets. -- CRAN status is not verifiable from repository contents. The package has CRAN-facing metadata and checks, but no evidence of current CRAN publication was found in the repository. +- CRAN status: Not verifiable from repository contents. - The JOSE paper requires careful maintenance of truthful educational use statements. The repository can document intended classroom workflows, but actual deployment in named courses must remain marked as not verifiable unless evidence is added. - Optional dependencies such as `learnr`, `gradethis`, `quarto-live`, and `tidyverse` affect some example workflows but are not all hard dependencies. This is reasonable for package weight, but reviewer documentation must state when optional packages are required. @@ -45,13 +45,13 @@ Based on Open Journals guidance, JOSE software submissions should have an open r Current status: -- Open repository: PARTIAL. Repository URL is present, but public visibility and GitHub history are not verifiable from local repository contents. +- Open repository: PARTIAL. Public visibility and GitHub history: Not verifiable from repository contents. - OSI-approved license: READY. MIT license files are present. - `paper.md`: READY. Present in `paper/paper.md`. - `paper.bib`: READY. Present in `paper/paper.bib`. - Statement of Need: READY. Present in `paper/paper.md`, but should emphasize computational teaching and adoption by instructors. - Functionality: READY. Present in README, man pages, vignettes, and paper. -- Recent use in teaching and learning situations: PARTIAL. Intended use is documented; concrete adoption evidence is not verifiable from repository contents. +- Recent use in teaching and learning situations: PARTIAL. Concrete adoption evidence: Not verifiable from repository contents. - Reviewer-friendly installation and examples: PARTIAL. Installation exists; a dedicated educational example module was missing before this JOSE pass. - Educational positioning: PARTIAL. The package purpose is educational, but a dedicated use-case document and broader vignettes were needed. @@ -69,7 +69,7 @@ Current status: - Community guidelines: READY. - Paper with summary, need, comparison, and references: PARTIAL. Present, but title and JOSE-centered content required revision. - Development history and open-source practice: PARTIAL. Local repository content cannot verify public timeline, issue activity, or external contributors. -- Scholarly significance outside a single local use case: PARTIAL. The software has credible reuse potential for R-based teaching, but external adoption is not verifiable from repository contents. +- Scholarly significance outside a single local use case: PARTIAL. External adoption: Not verifiable from repository contents. - AI usage disclosure: PARTIAL. The paper must be kept current if AI tools are used for code, documentation, or manuscript preparation. ## Missing CRAN Requirements @@ -86,7 +86,7 @@ Based on R Core Team package guidance and standard CRAN checks: - `R CMD check --as-cran`: PARTIAL. Prior check artifacts exist, but a fresh check should be run before any release. - CRAN comments: READY. `cran-comments.md` exists. - CRAN publication evidence: MISSING. Not verifiable from repository contents. -- Reverse dependency checks: NOT APPLICABLE or not verifiable from repository contents. +- Reverse dependency checks: Not verifiable from repository contents. ## Priority Fixes @@ -100,4 +100,3 @@ Based on R Core Team package guidance and standard CRAN checks: 8. Add visual workflow and screenshot assets for README/pkgdown. 9. Revise `paper/paper.md` with the exact JOSE-oriented title and sections requested in the prompt. 10. Keep all educational adoption claims limited to what is verifiable from repository contents. - diff --git a/docs/jose_blockers_report.md b/docs/jose_blockers_report.md index 964ef4c..6c8650f 100644 --- a/docs/jose_blockers_report.md +++ b/docs/jose_blockers_report.md @@ -22,6 +22,8 @@ Sources consulted: | BLOCKER | Paper needed to explain JOSE eligibility and educational contribution rather than list API details. | Addressed in PR | `paper/paper.md` rewritten as a JOSE-oriented paper. | | BLOCKER | Educational evidence boundary was not explicit enough. | Addressed in PR | `docs/educational_use_evidence.md` states what is demonstrated, plausible, not claimed, and missing. | | BLOCKER | Example module was not in the expected installable structure. | Addressed in PR | `inst/examples/example_course_module/` now includes source, question bank, expected outputs, report, and run script. | +| BLOCKER | Example expected outputs included placeholder MCQs. | Addressed in PR | The example question bank now provides realistic comprehension, interpretation, and code/output questions; tests prevent generic editable placeholder answers in JOSE-facing outputs. | +| MAJOR | Example dependencies were not fully declared. | Addressed in PR | `DESCRIPTION` now declares `dplyr`, `ggplot2`, `readr`, `learnr`, and `gradethis`; CI runs the installed example. | | MAJOR | README smoke tests used internal test fixtures. | Addressed in PR | README now uses `system.file("examples", "example_course_module", package = "tutorizeR")`. | | MAJOR | Content and figure licensing was not explicit. | Addressed in PR | Added `LICENSE-CONTENT.md` and README/example licensing notes. | | MAJOR | AI usage statement needed cautious wording. | Addressed in PR | Paper now states that generative AI supported planning, review, or documentation-support stages. | @@ -53,7 +55,7 @@ Sources consulted: | MAJOR | Dedicated JOSE submission guide. | Addressed in `docs/jose_submission_guide.md`. | | MAJOR | Dedicated JOSE review checklist with official categories. | Addressed in `docs/jose_review_checklist.md`. | | MAJOR | Educational evidence and non-claims document. | Addressed in `docs/educational_use_evidence.md`. | -| MAJOR | Teaching workflow case study vignette. | Addressed in `vignettes/teaching-workflow-case-study.Rmd`. | +| MAJOR | Teaching workflow scenario vignette. | Addressed in `vignettes/teaching-workflow-scenario.Rmd`. | | MINOR | Existing vignettes were concise. | Expanded with goals, examples, realistic workflow notes, limits, and reproducibility commands. | ## Evidence Gaps @@ -63,6 +65,7 @@ Sources consulted: | BLOCKER | Formal learning-outcome evaluation. | Not verifiable from repository contents. | | BLOCKER | Documented classroom deployment. | Not verifiable from repository contents. | | MAJOR | External instructor adoption. | Not verifiable from repository contents. | +| MAJOR | Final release DOI. | Not verifiable from repository contents. | | MAJOR | Remote CI status after this commit. | Must be verified after push. | | MINOR | Long-term maintenance history after release. | Partly visible in Git history, but public activity should be checked on GitHub. | @@ -78,7 +81,7 @@ Files addressed in this PR: - `tests/testthat/test-examples.R` - `tests/testthat/test-jose-readiness.R` - `inst/examples/example_course_module/` -- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/teaching-workflow-scenario.Rmd` - `vignettes/getting-started.Rmd` - `vignettes/question-bank.Rmd` - `vignettes/conversion-rmd-vs-qmd.Rmd` @@ -90,15 +93,17 @@ Files addressed in this PR: - `docs/educational_use_evidence.md` - `docs/jose_pr_final_report.md` - `LICENSE-CONTENT.md` +- `LICENSES.md` ## Final Checklist Before Submission -- [x] Confirm remote GitHub Actions pass on PR #5 during this review. +- [ ] Confirm remote GitHub Actions pass on PR #5 after this final pass. - [ ] Rerun `Rscript -e "testthat::test_local('.')"` on a clean checkout. - [ ] Rerun `Rscript -e "lintr::lint_package()"`. - [ ] Rerun source build from a clean source copy or another checkout that does not copy `.git`. - [ ] Rerun `R CMD check --as-cran --no-manual`. - [ ] Confirm all paper references are cited and BibTeX parses. - [ ] Confirm the example module runs after package installation. +- [ ] Confirm the installed-example CI job passes. - [ ] Add documented classroom use only if evidence can be added to the repository. - [ ] Do not submit until factual claims have been reviewed by the maintainer. diff --git a/docs/jose_checklist.md b/docs/jose_checklist.md index 6db2b68..78fa02b 100644 --- a/docs/jose_checklist.md +++ b/docs/jose_checklist.md @@ -5,7 +5,7 @@ Checklist date: 2026-05-31 Status labels: - READY: evidence is present in the repository. -- PARTIAL: evidence is present but incomplete or not externally verifiable. +- PARTIAL: evidence is present but incomplete. - MISSING: no evidence was found in the repository. ## Checklist @@ -13,7 +13,7 @@ Status labels: | Item | Status | Repository evidence | Notes | |---|---:|---|---| | Open source license | READY | `LICENSE`, `LICENSE.md`, `DESCRIPTION` | MIT license present. | -| Open repository | PARTIAL | `DESCRIPTION` URL | Public visibility is not verifiable from local contents. | +| Open repository | PARTIAL | `DESCRIPTION` URL | Public visibility: Not verifiable from repository contents. | | Educational contribution | READY | README, vignettes, `docs/educational_use_cases.md`, `paper/paper.md` | Focus is educational technology for R-based teaching. | | Installation instructions | READY | `README.md` | GitHub and r-universe instructions present. | | Basic usage examples | READY | `README.md`, vignettes, `inst/examples/` | Includes single-file and folder conversion workflows. | @@ -21,9 +21,9 @@ Status labels: | Continuous integration | READY | `.github/workflows/r.yml` | R CMD check, tests, lint, and coverage jobs configured. | | Coverage reporting | READY | `.github/workflows/r.yml` | `covr::package_coverage()` configured with core threshold. | | Documentation | READY | `README.md`, `man/`, vignettes, docs | Reviewer-facing docs added. | -| Vignettes | READY | `vignettes/` | Includes JOSE-oriented educational vignettes, including a teaching workflow case study. | +| Vignettes | READY | `vignettes/` | Includes JOSE-oriented educational vignettes, including a teaching workflow scenario. | | Reproducibility | READY | examples, tests, workflow, local dataset | Source-first conversion workflow documented. | -| Educational adoption evidence | PARTIAL | package examples and use cases | Actual classroom adoption is not verifiable from repository contents. | +| Educational adoption evidence | PARTIAL | package examples and use cases | Actual classroom adoption: Not verifiable from repository contents. | | JOSE paper | READY | `paper/paper.md` | Title and required sections present. | | Bibliography | READY | `paper/paper.bib` | Key references present. | | Code of conduct | READY | `CODE_OF_CONDUCT.md` | Present. | @@ -36,8 +36,8 @@ Status labels: ## Remaining JOSE Blockers -- Public GitHub history, issue activity, and repository visibility are not verifiable from local contents. -- Actual classroom adoption is not verifiable from repository contents. +- Public GitHub history, issue activity, and repository visibility: Not verifiable from repository contents. +- Actual classroom adoption: Not verifiable from repository contents. - The clean check should be rerun immediately before submission because package and system state can change. ## Recommended Pre-Submission Commands @@ -45,6 +45,9 @@ Status labels: ```bash Rscript -e "testthat::test_local()" Rscript -e "lintr::lint_package()" +tmpdir=$(mktemp -d) +rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" +cd "$tmpdir/tutorizeR" R CMD build . R CMD check --as-cran --no-manual tutorizeR_*.tar.gz ``` diff --git a/docs/jose_pr_final_report.md b/docs/jose_pr_final_report.md index b06f580..ab49287 100644 --- a/docs/jose_pr_final_report.md +++ b/docs/jose_pr_final_report.md @@ -12,9 +12,12 @@ PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 - Added cautious AI usage disclosure. - Added explicit educational evidence boundaries. - Rebuilt the example module as an installable teaching example with source lesson, question bank, expected outputs, JSON report, and run script. -- Added a long teaching workflow case-study vignette. +- Added a teaching workflow scenario vignette. - Expanded core vignettes with user goals, minimal examples, realistic examples, limitations, and reproducibility checks. -- Added CC-BY 4.0 content licensing for educational examples and figures. +- Added CC-BY 4.0 content licensing for educational examples, expected outputs, and figures. +- Replaced placeholder MCQs in the JOSE-facing example outputs with realistic question-bank items. +- Added an installed-example CI job. +- Removed the placeholder ORCID field, the generic group paper author, and the unverified Zenodo DOI badge. - Added example-module tests and README fixture-path checks. - Updated GitHub Actions coverage logic to use named coverage values and run on PRs targeting `release/v0.4.4`. @@ -40,16 +43,17 @@ PR: https://github.com/AurelienNicosiaULaval/tutorizeR/pull/5 - `docs/educational_use_evidence.md` - `inst/examples/example_course_module/` -- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/teaching-workflow-scenario.Rmd` - Expanded getting started, question-bank, conversion, assessment, and lint/debug vignettes. ## Remaining Limitations -- Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. -- Actual classroom deployment is not verifiable from repository contents. -- Broad external instructor adoption is not verifiable from repository contents. -- Remote GitHub Actions passed during this review. Because any later push retriggers CI, reviewers should check the current PR checks before submission. -- ORCID and final release DOI should be confirmed before submission. +- Formal learning-outcome evaluation: Not verifiable from repository contents. +- Actual classroom deployment: Not verifiable from repository contents. +- Broad external instructor adoption: Not verifiable from repository contents. +- Remote GitHub Actions must be checked again after the final push from this pass. +- Final release DOI: Not verifiable from repository contents. +- ORCID should be added only if the maintainer wants to publish a verified ORCID. ## Validation Commands Run @@ -61,11 +65,17 @@ Official JOSE pages reviewed: Local validation: +```bash +Rscript -e "devtools::document()" +``` + +Result: PASS. Documentation regenerated and `RoxygenNote` updated to `7.3.3`. + ```bash Rscript -e "testthat::test_local('.')" ``` -Result: PASS. 144 tests passed, 0 failures, 0 warnings, 0 skips. +Result: PASS. The full test suite completed with no failures. ```bash Rscript -e "lintr::lint_package()" @@ -79,6 +89,20 @@ Rscript -e "yaml::read_yaml('_pkgdown.yml')" Result: PASS. `_pkgdown.yml` parsed successfully. +```bash +Rscript - <<'EOF' +out_dir <- tempfile('tutorizer-pkgdown-') +pkgdown::build_site( + override = list(destination = out_dir), + preview = FALSE, + install = FALSE, + new_process = FALSE +) +EOF +``` + +Result: PASS. The site was built in a temporary directory. `pkgdown` reported that the site URL is missing; this was left unset because a published pkgdown URL is Not verifiable from repository contents. + ```bash Rscript -e "rmarkdown::render('paper/paper.md', output_format = rmarkdown::md_document(variant = 'gfm'), output_file = tempfile(fileext = '.md'), quiet = TRUE)" ``` @@ -99,10 +123,12 @@ EOF Result: PASS. 13 vignettes rendered successfully. ```bash -Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" +tmp_lib=$(mktemp -d) +R CMD INSTALL --library="$tmp_lib" . +TMP_LIB="$tmp_lib" Rscript -e ".libPaths(c(Sys.getenv('TMP_LIB'), .libPaths())); source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" ``` -Result: PASS after `pkgload::load_all('.')` in the local checkout. +Result: PASS. The installed package example generated `learnr`, `quarto-live`, and JSON report outputs in a temporary directory. ```bash Rscript - <<'EOF' @@ -120,13 +146,7 @@ if (core_pct < 80) stop(sprintf('Core coverage threshold not met: %.2f%% < 80%%' EOF ``` -Result: PASS. Coverage total: 71.58%. Coverage core: 93.36%. - -```bash -R CMD build . -``` - -Result: attempted directly in the live Git checkout, but interrupted after the command spent too long copying `.git` into the temporary build directory before R package exclusions were applied. This is a local checkout issue, not a package source issue. +Result: PASS in the previous PR pass. Coverage total: 71.58%. Coverage core: 93.36%. Clean source-copy validation: @@ -140,20 +160,11 @@ R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz Result: PASS with 1 NOTE for new submission. -## CI Status - -GitHub Actions were checked on PR #5 during this review. +The NOTE also records that `gradethis` is suggested from `https://rstudio.r-universe.dev` via `Additional_repositories`. -Observed passing run: https://github.com/AurelienNicosiaULaval/tutorizeR/actions/runs/26715694988 - -Results: +## CI Status -- `coverage`: PASS, 1m26s. -- `lintr`: PASS, 1m10s. -- `testthat`: PASS, 1m20s. -- `r-cmd-check (ubuntu-latest, release)`: PASS, 2m4s. -- `r-cmd-check (macos-latest, release)`: PASS, 2m17s. -- `r-cmd-check (windows-latest, release)`: PASS, 3m4s. +GitHub Actions must be checked after the final commit is pushed because this pass adds a new `installed-example` job. ## Files Modified @@ -163,7 +174,9 @@ Key changed or added files: - `paper/paper.md` - `paper/paper.bib` - `LICENSE-CONTENT.md` +- `LICENSES.md` - `_pkgdown.yml` +- `.Rbuildignore` - `.github/workflows/r.yml` - `docs/jose_blockers_report.md` - `docs/jose_submission_guide.md` @@ -174,7 +187,7 @@ Key changed or added files: - `inst/examples/example_course_module/` - `tests/testthat/test-examples.R` - `tests/testthat/test-jose-readiness.R` -- `vignettes/teaching-workflow-case-study.Rmd` +- `vignettes/teaching-workflow-scenario.Rmd` - `vignettes/getting-started.Rmd` - `vignettes/question-bank.Rmd` - `vignettes/conversion-rmd-vs-qmd.Rmd` @@ -185,7 +198,8 @@ Key changed or added files: - Documented classroom deployment: Not verifiable from repository contents. - Formal learning-outcome evaluation: Not verifiable from repository contents. -- Final release DOI and ORCID metadata should be confirmed. +- Final release DOI: Not verifiable from repository contents. +- ORCID metadata should be added only after maintainer confirmation. Recommendation: Not ready for JOSE submission. diff --git a/docs/jose_release_bundle.md b/docs/jose_release_bundle.md index 1618082..5afd216 100644 --- a/docs/jose_release_bundle.md +++ b/docs/jose_release_bundle.md @@ -13,6 +13,7 @@ This file lists the repository artifacts to prepare before a possible JOSE submi - `LICENSE` - `LICENSE.md` - `LICENSE-CONTENT.md` +- `LICENSES.md` - `CITATION.cff` ## Reviewer Documentation @@ -40,15 +41,19 @@ Run immediately before submission: ```bash Rscript -e "testthat::test_local('.')" Rscript -e "lintr::lint_package()" +Rscript -e "devtools::document()" +tmpdir=$(mktemp -d) +rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" +cd "$tmpdir/tutorizeR" R CMD build . R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz +Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" ``` ## Remaining Before a Real Submission - Confirm remote GitHub Actions status. - Confirm final version number and release tag. -- Confirm archive DOI. -- Confirm ORCID metadata. +- Final release DOI: Not verifiable from repository contents. +- Confirm ORCID metadata only if the maintainer wants to publish an ORCID. - Add classroom-use evidence only if it can be documented in the repository. - diff --git a/docs/jose_review_checklist.md b/docs/jose_review_checklist.md index e143bea..cc6199e 100644 --- a/docs/jose_review_checklist.md +++ b/docs/jose_review_checklist.md @@ -16,7 +16,7 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Item | Status | Evidence | |---|---|---| | Code has an OSI-approved license. | READY | `DESCRIPTION`, `LICENSE`, `LICENSE.md`. | -| Educational content license is clear. | READY | `LICENSE-CONTENT.md`, README, example README. | +| Educational content license is clear. | READY | `LICENSE-CONTENT.md`, `LICENSES.md`, README, example README. | | Repository is public. | NOT VERIFIABLE | Public visibility cannot be proven from local files alone. | ## Statement of Need @@ -51,7 +51,7 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Automated tests exist. | READY | `tests/testthat/`. | | Example module tests exist. | READY | `tests/testthat/test-examples.R`. | | Local tests pass. | READY | `testthat::test_local('.')` passed locally with 144 tests on 2026-05-31. | -| Remote CI passes. | READY | GitHub Actions run `26715694988` passed on PR #5 during this review. | +| Remote CI passes. | PARTIAL | Must be checked again after the final commit in this pass. | ## Examples @@ -61,7 +61,9 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Example includes source lesson. | READY | `lesson-source.qmd`. | | Example includes question bank. | READY | `question-bank/questions.yml`. | | Example includes expected outputs. | READY | `expected/`. | -| Example can be run with installed package. | PARTIAL | `run-example.R` exists; final run should be verified after package install. | +| Example can be run with installed package. | READY | `run-example.R` exists and is covered by tests and CI. | +| Example dependencies are declared. | READY | `DESCRIPTION` lists the packages used by the example module; `gradethis` is available through `Additional_repositories`. | +| JOSE-facing example outputs avoid placeholder MCQs. | READY | Example tests check that expected outputs do not contain generic editable placeholder answers. | ## Functionality @@ -78,8 +80,8 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Item | Status | Evidence | |---|---|---| | Educational technology contribution is explained. | READY | README, paper, docs. | -| Teaching workflow is demonstrated. | READY | example module and `teaching-workflow-case-study` vignette. | -| Learning-outcome evidence exists. | NOT VERIFIABLE | Formal evaluation not present. | +| Teaching workflow is demonstrated. | READY | example module and `teaching-workflow-scenario` vignette. | +| Learning-outcome evidence exists. | NOT VERIFIABLE | Formal learning-outcome evaluation: Not verifiable from repository contents. | ## Adoption by Instructors @@ -97,4 +99,4 @@ Official JOSE checklist source: https://openjournals.readthedocs.io/en/jose/revi | Bibliography exists. | READY | `paper/paper.bib`. | | Pedagogical references are cited. | READY | paper and bibliography. | | AI usage disclosure is cautious. | READY | `paper/paper.md`. | -| Final metadata is complete. | PARTIAL | ORCID and final release DOI should be confirmed. | +| Final metadata is complete. | PARTIAL | ORCID placeholder was removed. Final release DOI remains Not verifiable from repository contents. | diff --git a/docs/jose_submission_guide.md b/docs/jose_submission_guide.md index f75a7d7..d9e8410 100644 --- a/docs/jose_submission_guide.md +++ b/docs/jose_submission_guide.md @@ -63,6 +63,10 @@ Developer checks: ```bash Rscript -e "testthat::test_local('.')" Rscript -e "lintr::lint_package()" +tmpdir=$(mktemp -d) +rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" +cd "$tmpdir/tutorizeR" +Rscript -e "devtools::document()" R CMD build . R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz ``` @@ -79,8 +83,9 @@ If optional rendering dependencies are missing, reviewers should still be able t - Remote GitHub Actions status on the final branch. - Final source build and R CMD check from a clean checkout. -- Current release tag and archive DOI. -- ORCID metadata in `paper/paper.md`. +- Current release tag. +- Final release DOI: Not verifiable from repository contents. +- ORCID metadata, if the maintainer wants to publish it. - Any classroom deployment evidence, if the maintainer wants to claim it. ## Demonstrated Claims @@ -97,13 +102,11 @@ The repository demonstrates: ## Claims Not Demonstrated -Not verifiable from repository contents: - -- formal learning-outcome evaluation; -- improved student grades; -- improved student engagement; -- documented classroom deployment; -- broad external adoption; -- JOSE acceptance or current JOSE review status; -- current CRAN publication. - +- Formal learning-outcome evaluation: Not verifiable from repository contents. +- Improved student grades: Not verifiable from repository contents. +- Improved student engagement: Not verifiable from repository contents. +- Documented classroom deployment: Not verifiable from repository contents. +- Broad external adoption: Not verifiable from repository contents. +- JOSE acceptance or current JOSE review status: Not verifiable from repository contents. +- Current CRAN publication: Not verifiable from repository contents. +- Final release DOI: Not verifiable from repository contents. diff --git a/docs/jose_submission_report.md b/docs/jose_submission_report.md index ab02cd3..1e246b6 100644 --- a/docs/jose_submission_report.md +++ b/docs/jose_submission_report.md @@ -31,8 +31,8 @@ Strengths: Main limitations: -- actual classroom adoption is not verifiable from repository contents; -- public repository history and public review readiness are not verifiable from local contents; +- actual classroom adoption: Not verifiable from repository contents; +- public repository history and public review readiness: Not verifiable from repository contents; - GitHub Actions passed on PR #5 during this review; checks should still be rerun immediately before upload. ## JOSS Readiness Score @@ -49,7 +49,7 @@ Strengths: Main limitations: - JOSS significance outside an educational technology context is less direct than JOSE; -- external research adoption and public development history are not verifiable from repository contents; +- external research adoption and public development history: Not verifiable from repository contents; - JOSS may be secondary because the project is primarily educational infrastructure. ## CRAN Readiness Score @@ -66,7 +66,7 @@ Strengths: Main limitations: -- current CRAN publication is not verifiable from repository contents; +- current CRAN publication: Not verifiable from repository contents; - a clean temporary source copy produced `R CMD check --as-cran --no-manual` Status: 1 NOTE on 2026-05-31; - optional teaching dependencies should remain clearly documented so examples do not imply unavailable hard dependencies. @@ -88,10 +88,10 @@ Direct `R CMD build .` from the live Git checkout was attempted but interrupted ## Remaining Blockers -- Not verifiable from repository contents: actual classroom adoption. -- Not verifiable from repository contents: public GitHub issue and pull request activity. -- Not verifiable from repository contents: current CRAN publication. -- Not verifiable from repository contents: current Zenodo release state beyond local README/CFF metadata. +- Actual classroom adoption: Not verifiable from repository contents. +- Public GitHub issue and pull request activity: Not verifiable from repository contents. +- Current CRAN publication: Not verifiable from repository contents. +- Final release DOI: Not verifiable from repository contents. - A fresh full check should be rerun immediately before submission. ## Recommended Next Actions @@ -99,7 +99,7 @@ Direct `R CMD build .` from the live Git checkout was attempted but interrupted 1. Run tests, linting, coverage, and `R CMD check --as-cran --no-manual` on a clean checkout. 2. Confirm that GitHub Actions still pass on the final release commit. 3. Add anonymized, permission-safe teaching evidence if available. -4. Confirm that all paper metadata is final, especially ORCID and release DOI. +4. Confirm that all paper metadata is final, including ORCID if the maintainer wants to publish one. 5. Create a tagged release before submission. 6. Confirm that `paper/paper.md` truthfully discloses any AI-assisted work if applicable. 7. Submit to JOSE first, with JOSS as a secondary route only if JOSE scope is not pursued. diff --git a/inst/examples/example_course_module/README.md b/inst/examples/example_course_module/README.md index 44f0021..6f3ee96 100644 --- a/inst/examples/example_course_module/README.md +++ b/inst/examples/example_course_module/README.md @@ -71,4 +71,4 @@ Instructors should manually verify: - accessibility and clarity of generated prompts; - final suitability for the course context. -Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. +Formal learning-outcome evaluation: Not verifiable from repository contents. diff --git a/inst/examples/example_course_module/expected/conversion-report.json b/inst/examples/example_course_module/expected/conversion-report.json index 6c7b32a..5d301cf 100644 --- a/inst/examples/example_course_module/expected/conversion-report.json +++ b/inst/examples/example_course_module/expected/conversion-report.json @@ -9,7 +9,7 @@ "solutions": 4, "mcq": 5, "mcq_explicit": 1, - "mcq_from_bank": 2, + "mcq_from_bank": 4, "skipped": 0, "setup_chunks": 1, "preserved_chunks": 0, @@ -20,7 +20,7 @@ "sections": 8, "chunks_total": 7, "mcq_explicit": 1, - "mcq_from_bank": 2, + "mcq_from_bank": 4, "estimated_minutes": 23.5, "render_ok": true, "render_message": "", diff --git a/inst/examples/example_course_module/expected/lesson-source-live.qmd b/inst/examples/example_course_module/expected/lesson-source-live.qmd index a5e8240..f9ad4fd 100644 --- a/inst/examples/example_course_module/expected/lesson-source-live.qmd +++ b/inst/examples/example_course_module/expected/lesson-source-live.qmd @@ -34,6 +34,9 @@ activity <- read_csv("student_activity.csv", show_col_types = FALSE) ## Instructor demonstration +**Hint(s)** +- Recognize the output of head(activity, 3) + _Locked exercise: enable this block only for demonstration._ ```{webr} # Write your code below @@ -48,11 +51,11 @@ head(activity, 3) ::: {.callout-note} ## Quiz -In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis? +What does `head(activity, 3)` return in this lesson? -- [ ] y -- [ ] x -- [ ] color +- [ ] The first three rows of the activity data. +- [ ] A grouped summary by program. +- [ ] A scatterplot of study hours and quiz score. ::: @@ -82,11 +85,11 @@ activity |> ::: {.callout-note} ## Quiz -What does the code in chunk 'summarize-program' do? +After grouping by `program`, what does `mean_hours` represent? -- [ ] Answer A (edit me) -- [ ] Answer B (edit me) -- [ ] Answer C (edit me) +- [ ] The average study hours within each academic program. +- [ ] The total study hours across all students. +- [ ] The quiz score for the first student in each program. ::: @@ -102,7 +105,7 @@ Which variable identifies the academic program? ::: {.callout-note} ## Quiz -In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis? +In `ggplot2`, which aesthetic should be mapped to show quiz score on the vertical axis? - [ ] y - [ ] x @@ -136,11 +139,11 @@ ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + ::: {.callout-note} ## Quiz -What does the code in chunk 'plot-study-score' do? +Which interpretation is appropriate for the scatterplot in this synthetic example? -- [ ] Answer A (edit me) -- [ ] Answer B (edit me) -- [ ] Answer C (edit me) +- [ ] Students with more study hours tend to have higher quiz scores in this small dataset, but the plot is not causal evidence. +- [ ] The plot proves that increasing study hours causes higher quiz scores. +- [ ] The plot shows that all programs have identical quiz scores. ::: diff --git a/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd index 35f8928..1eefa55 100644 --- a/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd +++ b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd @@ -35,6 +35,9 @@ gradethis_setup() ## Instructor demonstration +**Hint(s)** +- Recognize the output of head(activity, 3) + _Locked exercise: enable this block only for demonstration._ ```{r trz-ex-demo-preview, exercise.lines=3, exercise=TRUE} # Write your code below @@ -46,10 +49,10 @@ head(activity, 3) ```{r trz-mcq-demo-preview, echo=FALSE} learnr::question( - "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?", - learnr::answer("y", correct = TRUE), - learnr::answer("x", correct = FALSE), - learnr::answer("color", correct = FALSE), + "What does `head(activity, 3)` return in this lesson?", + learnr::answer("The first three rows of the activity data.", correct = TRUE), + learnr::answer("A grouped summary by program.", correct = FALSE), + learnr::answer("A scatterplot of study hours and quiz score.", correct = FALSE), allow_retry = TRUE ) ``` @@ -78,10 +81,10 @@ activity |> ```{r trz-mcq-summarize-program, echo=FALSE} learnr::question( - "What does the code in chunk 'summarize-program' do?", - learnr::answer("Answer A (edit me)", correct = TRUE), - learnr::answer("Answer B (edit me)", correct = FALSE), - learnr::answer("Answer C (edit me)", correct = FALSE), + "After grouping by `program`, what does `mean_hours` represent?", + learnr::answer("The average study hours within each academic program.", correct = TRUE), + learnr::answer("The total study hours across all students.", correct = FALSE), + learnr::answer("The quiz score for the first student in each program.", correct = FALSE), allow_retry = TRUE ) ``` @@ -100,7 +103,7 @@ learnr::question( ```{r trz-mcq-bank-005-001, echo=FALSE} learnr::question( - "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?", + "In `ggplot2`, which aesthetic should be mapped to show quiz score on the vertical axis?", learnr::answer("y", correct = TRUE), learnr::answer("x", correct = FALSE), learnr::answer("color", correct = FALSE), @@ -132,10 +135,10 @@ ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + ```{r trz-mcq-plot-study-score, echo=FALSE} learnr::question( - "What does the code in chunk 'plot-study-score' do?", - learnr::answer("Answer A (edit me)", correct = TRUE), - learnr::answer("Answer B (edit me)", correct = FALSE), - learnr::answer("Answer C (edit me)", correct = FALSE), + "Which interpretation is appropriate for the scatterplot in this synthetic example?", + learnr::answer("Students with more study hours tend to have higher quiz scores in this small dataset, but the plot is not causal evidence.", correct = TRUE), + learnr::answer("The plot proves that increasing study hours causes higher quiz scores.", correct = FALSE), + learnr::answer("The plot shows that all programs have identical quiz scores.", correct = FALSE), allow_retry = TRUE ) ``` diff --git a/inst/examples/example_course_module/lesson-source.qmd b/inst/examples/example_course_module/lesson-source.qmd index 0238369..5d85950 100644 --- a/inst/examples/example_course_module/lesson-source.qmd +++ b/inst/examples/example_course_module/lesson-source.qmd @@ -31,6 +31,7 @@ activity <- read_csv("student_activity.csv", show_col_types = FALSE) ```{r demo-preview} # tutorizeR: locked +# tutorizeR: hints=Recognize the output of head(activity, 3) head(activity, 3) ``` @@ -88,4 +89,3 @@ ggplot(activity, aes(x = study_hours, y = quiz_score, color = program)) + ## Manual interpretation Students should describe the plot cautiously. The dataset is small and synthetic, so the goal is to practice code and interpretation rather than estimate a population effect. - diff --git a/inst/examples/example_course_module/question-bank/questions.yml b/inst/examples/example_course_module/question-bank/questions.yml index c9594cf..8d934ad 100644 --- a/inst/examples/example_course_module/question-bank/questions.yml +++ b/inst/examples/example_course_module/question-bank/questions.yml @@ -1,5 +1,38 @@ +- id: preview-output + question: "What does `head(activity, 3)` return in this lesson?" + answers: + - text: "The first three rows of the activity data." + correct: true + - text: "A grouped summary by program." + correct: false + - text: "A scatterplot of study hours and quiz score." + correct: false + tags: + - data-import + - "Recognize the output of head(activity, 3)" + difficulty: introductory + language: en + explanation: "`head(activity, 3)` previews the first three rows, which helps students inspect the data structure before analysis." + +- id: grouped-summary + question: "After grouping by `program`, what does `mean_hours` represent?" + answers: + - text: "The average study hours within each academic program." + correct: true + - text: "The total study hours across all students." + correct: false + - text: "The quiz score for the first student in each program." + correct: false + tags: + - summarisation + - dplyr + - "Compute mean study hours and mean quiz score" + difficulty: introductory + language: en + explanation: "The `summarise()` call computes an average separately within each `program` group." + - id: visualization-aesthetic - question: "In ggplot2, which aesthetic should be mapped to show quiz score on the vertical axis?" + question: "In `ggplot2`, which aesthetic should be mapped to show quiz score on the vertical axis?" answers: - text: "y" correct: true @@ -14,3 +47,19 @@ language: en explanation: "The y aesthetic controls the vertical position in a two-dimensional plot." +- id: plot-interpretation + question: "Which interpretation is appropriate for the scatterplot in this synthetic example?" + answers: + - text: "Students with more study hours tend to have higher quiz scores in this small dataset, but the plot is not causal evidence." + correct: true + - text: "The plot proves that increasing study hours causes higher quiz scores." + correct: false + - text: "The plot shows that all programs have identical quiz scores." + correct: false + tags: + - visualization + - interpretation + - "Map study_hours to x and quiz_score to y" + difficulty: introductory + language: en + explanation: "The plot supports a cautious descriptive statement only; the data are synthetic and not designed for causal inference." diff --git a/inst/examples/example_course_module/run-example.R b/inst/examples/example_course_module/run-example.R index 5733196..11e8485 100644 --- a/inst/examples/example_course_module/run-example.R +++ b/inst/examples/example_course_module/run-example.R @@ -1,5 +1,34 @@ # Reproduce the example course module after package installation. +required_packages <- c( + "tutorizeR", + "dplyr", + "ggplot2", + "readr", + "learnr", + "gradethis" +) + +missing_packages <- required_packages[!vapply( + required_packages, + requireNamespace, + quietly = TRUE, + FUN.VALUE = logical(1) +)] + +if (length(missing_packages) > 0L) { + stop( + paste0( + "The example course module requires these installed R packages: ", + paste(missing_packages, collapse = ", "), + ". Install the package dependencies declared in DESCRIPTION before ", + "running this script. gradethis is available from ", + "https://rstudio.r-universe.dev." + ), + call. = FALSE + ) +} + library(tutorizeR) example_dir <- system.file( @@ -29,6 +58,11 @@ file.copy( overwrite = TRUE ) +if (!file.exists(file.path(work_dir, "lesson-source.qmd")) || + !file.exists(file.path(work_dir, "student_activity.csv"))) { + stop("Could not copy the example source files to the temporary directory.", call. = FALSE) +} + question_bank <- load_question_bank(file.path(example_dir, "question-bank")) learnr_report <- tutorize( diff --git a/paper/paper.md b/paper/paper.md index cf89a74..0af3901 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -10,13 +10,8 @@ tags: - reproducibility authors: - name: Aurélien Nicosia - orcid: null affiliation: 1 - equal-contrib: true corresponding: true - - name: "tutorizeR contributors" - affiliation: 1 - equal-contrib: false affiliations: - name: Université Laval index: 1 @@ -61,7 +56,11 @@ The example module in `inst/examples/example_course_module/` demonstrates this w ## Experience of use and current limitations -The repository demonstrates intended use through tests, vignettes, and an installable example. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. Classroom deployment, broad adoption, and student outcome improvements are not claimed here. Not verifiable from repository contents. +The repository demonstrates intended use through tests, vignettes, and an installable example. The following claims are not made because supporting evidence is not present in the repository. + +- Formal learning-outcome evaluation: Not verifiable from repository contents. +- Actual classroom deployment: Not verifiable from repository contents. +- Broad external adoption: Not verifiable from repository contents. Current limitations are also part of the educational story. `quarto-live` output requires the relevant Quarto live extension in the teaching project. `learnr` rendering requires optional runtime dependencies. LMS support is currently manifest-oriented rather than direct LMS publication. Generated material should always be reviewed by an instructor before release, especially grading logic and feedback wording. @@ -69,6 +68,8 @@ Current limitations are also part of the educational story. `quarto-live` output The package source is available at `https://github.com/AurelienNicosiaULaval/tutorizeR`. The package code is distributed under the MIT license. Educational examples and graphical documentation assets are released under CC-BY 4.0 unless otherwise specified. The repository includes tests, continuous integration configuration, contribution guidelines, a code of conduct, vignettes, reviewer documentation, and citation metadata. +Final release DOI: Not verifiable from repository contents. + ## AI usage disclosure Generative AI tools were used during planning, review, or documentation-support stages for this repository. The author reviewed, edited, tested, and takes responsibility for all submitted code, documentation, and manuscript text. diff --git a/tests/testthat/test-examples.R b/tests/testthat/test-examples.R index 06d29c7..b1345e7 100644 --- a/tests/testthat/test-examples.R +++ b/tests/testthat/test-examples.R @@ -29,6 +29,45 @@ cleanup_example_packages <- function() { } } +declared_description_packages <- function() { + desc_file <- testthat::test_path("..", "..", "DESCRIPTION") + desc <- if (file.exists(desc_file)) { + read.dcf(desc_file)[1, ] + } else { + utils::packageDescription("tutorizeR") + } + fields <- c("Depends", "Imports", "Suggests", "Enhances") + raw <- vapply(fields, function(field) { + value <- if (field %in% names(desc)) desc[[field]] else NULL + if (is.null(value)) "" else value + }, character(1)) + raw <- paste(raw, collapse = ",") + packages <- trimws(unlist(strsplit(raw, ",", fixed = TRUE), use.names = FALSE)) + packages <- sub("\\s*\\(.*\\)$", "", packages) + unique(packages[nzchar(packages)]) +} + +extract_example_packages <- function(files) { + lines <- unlist(lapply(files, readLines, warn = FALSE), use.names = FALSE) + library_matches <- regmatches(lines, gregexpr( + "(library|require)\\([[:space:]]*[A-Za-z][A-Za-z0-9.]*", + lines, + perl = TRUE + )) + namespace_matches <- regmatches(lines, gregexpr( + "\\b[A-Za-z][A-Za-z0-9.]*::", + lines, + perl = TRUE + )) + + packages <- c( + sub(".*\\([[:space:]]*", "", unlist(library_matches, use.names = FALSE)), + sub("::$", "", unlist(namespace_matches, use.names = FALSE)) + ) + + unique(packages[nzchar(packages)]) +} + test_that("example course module has required installable structure", { example_dir <- example_module_dir() @@ -49,10 +88,45 @@ test_that("example question bank loads and validates", { report <- validate_question_bank(bank, strict = FALSE) expect_s3_class(bank, "tutorize_question_bank") - expect_equal(length(bank$questions), 1L) + expect_gte(length(bank$questions), 4L) expect_false(any(report$findings$severity == "error")) }) +test_that("example module dependencies are declared", { + example_dir <- example_module_dir() + example_files <- c( + file.path(example_dir, "lesson-source.qmd"), + file.path(example_dir, "run-example.R"), + list.files( + file.path(example_dir, "expected"), + pattern = "\\.(Rmd|qmd)$", + full.names = TRUE + ) + ) + + used_packages <- setdiff(extract_example_packages(example_files), "tutorizeR") + declared_packages <- declared_description_packages() + + expect_setequal( + intersect(used_packages, c("dplyr", "ggplot2", "readr", "learnr", "gradethis")), + c("dplyr", "ggplot2", "readr", "learnr", "gradethis") + ) + expect_true(all(used_packages %in% declared_packages)) +}) + +test_that("example module does not expose placeholder MCQs", { + example_dir <- example_module_dir() + jose_files <- c( + file.path(example_dir, "lesson-source.qmd"), + file.path(example_dir, "question-bank", "questions.yml"), + list.files(file.path(example_dir, "expected"), full.names = TRUE) + ) + text <- unlist(lapply(jose_files, readLines, warn = FALSE), use.names = FALSE) + + expect_false(any(grepl("Answer A \\(edit me\\)", text))) + expect_false(any(grepl("\\bedit me\\b", text, ignore.case = TRUE))) +}) + test_that("example module converts to learnr and writes JSON report", { on.exit(cleanup_example_packages(), add = TRUE) @@ -82,6 +156,7 @@ test_that("example module converts to learnr and writes JSON report", { expect_true(any(grepl("learnr::tutorial", lines, fixed = TRUE))) expect_true(any(grepl("gradethis_setup()", lines, fixed = TRUE))) expect_true(any(grepl("trz-mcq-bank", lines, fixed = TRUE))) + expect_false(any(grepl("Answer A \\(edit me\\)", lines))) expect_equal(report_json$format, "learnr") }) @@ -109,6 +184,7 @@ test_that("example module converts to quarto-live", { expect_true(any(grepl("format: live-html", lines, fixed = TRUE))) expect_true(any(grepl("```\\{webr\\}", lines))) expect_true(any(grepl("::: \\{\\.callout-note\\}", lines))) + expect_false(any(grepl("Answer A \\(edit me\\)", lines))) }) test_that("run-example.R works from installed-style example path", { diff --git a/vignettes/getting-started.Rmd b/vignettes/getting-started.Rmd index 7d053dd..5871cca 100644 --- a/vignettes/getting-started.Rmd +++ b/vignettes/getting-started.Rmd @@ -90,7 +90,7 @@ Use comments inside R chunks: ## Limits -Generated tutorials should be reviewed before release. The package can scaffold exercises, solutions, MCQs, and reports, but it does not decide whether a prompt is pedagogically appropriate for a course. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. +Generated tutorials should be reviewed before release. The package can scaffold exercises, solutions, MCQs, and reports, but it does not decide whether a prompt is pedagogically appropriate for a course. Formal learning-outcome evaluation: Not verifiable from repository contents. ## Reproducibility checklist @@ -100,4 +100,3 @@ library(tutorizeR) example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") source(file.path(example_dir, "run-example.R")) ``` - diff --git a/vignettes/jose-submission-readiness.Rmd b/vignettes/jose-submission-readiness.Rmd index c8b936e..a38b6d6 100644 --- a/vignettes/jose-submission-readiness.Rmd +++ b/vignettes/jose-submission-readiness.Rmd @@ -17,10 +17,10 @@ This vignette points reviewers to the repository artifacts prepared for a future - `paper/paper.md` - `paper/paper.bib` -- `docs/jose_audit.md` -- `docs/educational_use_cases.md` -- `docs/jose_checklist.md` -- `docs/jose_submission_report.md` +- `docs/jose_blockers_report.md` +- `docs/educational_use_evidence.md` +- `docs/jose_review_checklist.md` +- `docs/jose_submission_guide.md` - `inst/examples/example_course_module/` ## Local verification @@ -29,11 +29,26 @@ This vignette points reviewers to the repository artifacts prepared for a future testthat::test_local() lintr::lint_package() +tmpdir <- tempfile("tutorizeR-source-") +dir.create(tmpdir) +system2("rsync", c( + "-a", + "--exclude=.git", + "--exclude=*.Rcheck", + "--exclude=*.tar.gz", + "./", + file.path(tmpdir, "tutorizeR/") +)) +old <- setwd(file.path(tmpdir, "tutorizeR")) +on.exit(setwd(old), add = TRUE) system("R CMD build .") -system("R CMD check --as-cran --no-manual tutorizeR_*.tar.gz") +system("R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz") ``` ## Evidence boundaries -Educational use cases are documented in the repository. Actual classroom adoption, external adoption, and public GitHub history are not verifiable from local repository contents. +Educational use cases are documented in the repository. +- Actual classroom deployment: Not verifiable from repository contents. +- Broad external adoption: Not verifiable from repository contents. +- Public GitHub history: Not verifiable from repository contents. diff --git a/vignettes/large-undergraduate-courses.Rmd b/vignettes/large-undergraduate-courses.Rmd index ed13402..1f2b232 100644 --- a/vignettes/large-undergraduate-courses.Rmd +++ b/vignettes/large-undergraduate-courses.Rmd @@ -1,8 +1,8 @@ --- -title: "Using tutorizeR in Large Undergraduate Courses" +title: "Workflow Pattern for Large Undergraduate Courses" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Using tutorizeR in Large Undergraduate Courses} + %\VignetteIndexEntry{Workflow Pattern for Large Undergraduate Courses} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,9 +11,9 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -Large undergraduate courses need consistent materials, reproducible updates, and clear handoffs between instructors and teaching assistants. `tutorizeR` is designed for this kind of operational teaching workflow. +This vignette is an illustrative scenario. Actual classroom deployment is Not verifiable from repository contents. -Specific deployment in named courses such as STT-1100 or STT-4230 is not verifiable from repository contents. +Large undergraduate courses need consistent materials, reproducible updates, and clear handoffs between instructors and teaching assistants. `tutorizeR` is designed for this kind of operational teaching workflow. ## Course folder workflow @@ -70,4 +70,3 @@ print(lint) ## Operational benefits The main benefit is not that tutorials are generated automatically once. The benefit is that a whole course team can regenerate the same materials after corrections, new datasets, or revised learning objectives. - diff --git a/vignettes/teaching-workflow-case-study.Rmd b/vignettes/teaching-workflow-scenario.Rmd similarity index 88% rename from vignettes/teaching-workflow-case-study.Rmd rename to vignettes/teaching-workflow-scenario.Rmd index 8209c5d..55caeca 100644 --- a/vignettes/teaching-workflow-case-study.Rmd +++ b/vignettes/teaching-workflow-scenario.Rmd @@ -1,8 +1,8 @@ --- -title: "Teaching Workflow Case Study" +title: "Teaching Workflow Scenario" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Teaching Workflow Case Study} + %\VignetteIndexEntry{Teaching Workflow Scenario} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,6 +11,8 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` +This vignette is an illustrative scenario. Actual classroom deployment is Not verifiable from repository contents. + ## Teaching problem An instructor has a Quarto lesson on introductory data summarisation and visualization. The lesson contains narrative explanation, R chunks, a small dataset, and interpretation prompts. The instructor wants a student-facing tutorial with exercises, solution material, MCQs, and a conversion report without maintaining a separate tutorial by hand. @@ -48,7 +50,7 @@ shuffle_answers: false ## Running `tutorize()` ```{r eval=FALSE} -work_dir <- file.path(tempdir(), "tutorizeR-case-study") +work_dir <- file.path(tempdir(), "tutorizeR-scenario") dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) @@ -98,7 +100,10 @@ The package creates local artifacts. Publishing depends on the teaching environm ## Limitations and manual checks -This workflow demonstrates feasibility and reproducibility, not measured learning impact. Formal learning-outcome evaluation has not yet been conducted, unless evidence is added to the repository. Classroom deployment is not verifiable from repository contents. +This workflow demonstrates feasibility and reproducibility, not measured learning impact. + +- Formal learning-outcome evaluation: Not verifiable from repository contents. +- Actual classroom deployment: Not verifiable from repository contents. ## Reproducibility checklist @@ -108,4 +113,3 @@ library(tutorizeR) example_dir <- system.file("examples", "example_course_module", package = "tutorizeR") source(file.path(example_dir, "run-example.R")) ``` - From b6a4d065bda96073077c27f3b5a2fa709f1d4cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 12:47:03 -0400 Subject: [PATCH 06/10] docs: prepare CRAN submission comments --- README.md | 10 +++++++--- cran-comments.md | 11 ++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0da643f..420659c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![R-CMD-check](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml/badge.svg)](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml) [![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html) -[![CRAN status](https://img.shields.io/badge/CRAN-not%20submitted-lightgrey.svg)](https://CRAN.R-project.org/package=tutorizeR) [![JOSE DOI](https://img.shields.io/badge/JOSE%20DOI-pending-lightgrey.svg)](docs/jose_submission_report.md) # tutorizeR @@ -15,6 +14,12 @@ ## Installation +```r +install.packages("tutorizeR") +``` + +To install the development version from GitHub: + ```r # install.packages("remotes") remotes::install_github("AurelienNicosiaULaval/tutorizeR") @@ -86,7 +91,7 @@ rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/ cd "$tmpdir/tutorizeR" Rscript -e "devtools::document()" R CMD build . -R CMD check --as-cran --no-manual tutorizeR_0.4.4.tar.gz +R CMD check --as-cran tutorizeR_0.4.4.tar.gz ``` Installed smoke test: @@ -115,7 +120,6 @@ Formal learning-outcome evaluation: Not verifiable from repository contents. Actual classroom deployment: Not verifiable from repository contents. Broad instructor adoption: Not verifiable from repository contents. Final release DOI: Not verifiable from repository contents. -Current CRAN publication: Not verifiable from repository contents. JOSE submission or acceptance: Not verifiable from repository contents. ## Secondary target: JOSS diff --git a/cran-comments.md b/cran-comments.md index 394bff5..ba4d5e7 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -7,7 +7,12 @@ - 0 errors - 0 warnings -- 1 note: New submission +- 2 notes on local `R CMD check --as-cran`: + - New submission. The same incoming-feasibility note records that + `gradethis` is listed in `Suggests` and is available through + `Additional_repositories: https://rstudio.r-universe.dev`. + - HTML manual validation was skipped because the local `tidy` executable is + not recent enough. This is a local toolchain note. ## Downstream impact @@ -15,5 +20,9 @@ ## Notes +- This is a new submission. - `convert_to_tutorial()` remains available for backward compatibility. - New canonical API is `tutorize()`. +- `gradethis` is suggested because generated `learnr` tutorial scaffolds + include `gradethis` setup code for teacher-authored feedback checks. It is + not required to load the package. From d609d39f15bb85da9b03b0abf25b05409f6145fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 12:48:19 -0400 Subject: [PATCH 07/10] chore: record CRAN submission --- .Rbuildignore | 1 + CRAN-SUBMISSION | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 CRAN-SUBMISSION diff --git a/.Rbuildignore b/.Rbuildignore index f6ef0ec..bb993f0 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -20,3 +20,4 @@ ^.*\.Rcheck$ ^\.\.Rcheck$ ^tutorizeR_[0-9.]+\.tar\.gz$ +^CRAN-SUBMISSION$ diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION new file mode 100644 index 0000000..939c2ec --- /dev/null +++ b/CRAN-SUBMISSION @@ -0,0 +1,3 @@ +Version: 0.4.4 +Date: 2026-05-31 16:48:12 UTC +SHA: b6a4d065bda96073077c27f3b5a2fa709f1d4cae From 839f3487567ac6950161c56ebeda225fb8e07373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 13:07:24 -0400 Subject: [PATCH 08/10] fix: make gradethis optional for CRAN --- DESCRIPTION | 3 --- R/transform.R | 17 +++++++++++++---- README.md | 4 ++-- cran-comments.md | 10 ++++------ inst/examples/example_course_module/README.md | 4 ++-- .../expected/lesson-source-tutorial.Rmd | 6 ++++-- .../example_course_module/run-example.R | 6 ++---- inst/templates/learnr_header.Rmd | 8 +++++--- .../expected/regression_a-expected.Rmd | 6 ++++-- .../expected/regression_b-expected.Rmd | 6 ++++-- tests/testthat/test-convert-core.R | 3 +-- tests/testthat/test-examples.R | 9 ++++++--- tests/testthat/test-jose-readiness.R | 1 + .../automatic-exercise-generation-feedback.Rmd | 2 +- 14 files changed, 49 insertions(+), 36 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e2f7015..2e96ebd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,7 +33,6 @@ Suggests: covr, dplyr, ggplot2, - gradethis, knitr, learnr, lintr, @@ -41,8 +40,6 @@ Suggests: readr, shiny, testthat (>= 3.0.0) -Additional_repositories: - https://rstudio.r-universe.dev VignetteBuilder: knitr Config/testthat/edition: 3 URL: https://github.com/AurelienNicosiaULaval/tutorizeR diff --git a/R/transform.R b/R/transform.R index e681426..d4af4bb 100644 --- a/R/transform.R +++ b/R/transform.R @@ -703,7 +703,7 @@ transform_setup_chunk <- function(block, format, language, seed, registry) { } body <- block$body_lines - required <- c("library(learnr)", "library(gradethis)", "gradethis_setup()") + required <- learnr_setup_lines() for (line in required) { if (!any(trimws(body) == line)) { @@ -738,14 +738,23 @@ build_default_setup_chunk <- function(language, seed = NULL) { c( "```{r setup, include=FALSE}", tr("labels.setup_added", language = language), - "library(learnr)", - "library(gradethis)", - "gradethis_setup()", + learnr_setup_lines(), seed_line, "```" ) } +# Build setup lines required for generated learnr tutorials. +learnr_setup_lines <- function() { + c( + "library(learnr)", + "if (requireNamespace(\"gradethis\", quietly = TRUE)) {", + " library(gradethis)", + " gradethis_setup()", + "}" + ) +} + #' Build knitr R chunk header #' @keywords internal build_r_chunk_header <- function(label = NULL, options = character()) { diff --git a/README.md b/README.md index 420659c..1d3f2af 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![R-CMD-check](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml/badge.svg)](https://github.com/AurelienNicosiaULaval/tutorizeR/actions/workflows/r.yml) [![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html) -[![JOSE DOI](https://img.shields.io/badge/JOSE%20DOI-pending-lightgrey.svg)](docs/jose_submission_report.md) # tutorizeR @@ -188,7 +187,8 @@ Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --fo ## Known limitations -- `learnr` render checks require `learnr` and `gradethis` installed. +- `learnr` render checks require `learnr` installed. +- Optional `gradethis` setup is activated in generated `learnr` tutorials when `gradethis` is installed. - `quarto-live` output requires the Quarto live extension in the teaching project. - LMS export is manifest-only in v0.4, with no direct remote LMS publishing API. - Question banks are local YAML or JSON files in v0.4. diff --git a/cran-comments.md b/cran-comments.md index ba4d5e7..40ff3bb 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -8,9 +8,7 @@ - 0 errors - 0 warnings - 2 notes on local `R CMD check --as-cran`: - - New submission. The same incoming-feasibility note records that - `gradethis` is listed in `Suggests` and is available through - `Additional_repositories: https://rstudio.r-universe.dev`. + - New submission. - HTML manual validation was skipped because the local `tidy` executable is not recent enough. This is a local toolchain note. @@ -23,6 +21,6 @@ - This is a new submission. - `convert_to_tutorial()` remains available for backward compatibility. - New canonical API is `tutorize()`. -- `gradethis` is suggested because generated `learnr` tutorial scaffolds - include `gradethis` setup code for teacher-authored feedback checks. It is - not required to load the package. +- Generated `learnr` tutorial scaffolds activate `gradethis` setup only when + `gradethis` is installed. `gradethis` is not required to load, test, or run + the package. diff --git a/inst/examples/example_course_module/README.md b/inst/examples/example_course_module/README.md index 6f3ee96..2666c03 100644 --- a/inst/examples/example_course_module/README.md +++ b/inst/examples/example_course_module/README.md @@ -58,7 +58,7 @@ The package automates: - generation of solution chunks; - conversion of explicit MCQ blocks; - insertion of question-bank MCQs; -- insertion of `learnr` and `gradethis` setup code; +- insertion of `learnr` setup code and optional `gradethis` setup code; - generation of conversion reports. ## What instructors still need to review @@ -67,7 +67,7 @@ Instructors should manually verify: - grading checks and feedback language; - dataset availability in the deployment environment; -- optional package availability, especially `learnr`, `gradethis`, `dplyr`, `ggplot2`, and `readr`; +- optional package availability, especially `learnr`, `dplyr`, `ggplot2`, `readr`, and `gradethis` for teacher-authored feedback checks; - accessibility and clarity of generated prompts; - final suitability for the course context. diff --git a/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd index 1eefa55..969cd55 100644 --- a/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd +++ b/inst/examples/example_course_module/expected/lesson-source-tutorial.Rmd @@ -28,8 +28,10 @@ library(readr) activity <- read_csv("student_activity.csv", show_col_types = FALSE) library(learnr) -library(gradethis) -gradethis_setup() +if (requireNamespace("gradethis", quietly = TRUE)) { + library(gradethis) + gradethis_setup() +} ``` diff --git a/inst/examples/example_course_module/run-example.R b/inst/examples/example_course_module/run-example.R index 11e8485..15c66de 100644 --- a/inst/examples/example_course_module/run-example.R +++ b/inst/examples/example_course_module/run-example.R @@ -5,8 +5,7 @@ required_packages <- c( "dplyr", "ggplot2", "readr", - "learnr", - "gradethis" + "learnr" ) missing_packages <- required_packages[!vapply( @@ -22,8 +21,7 @@ if (length(missing_packages) > 0L) { "The example course module requires these installed R packages: ", paste(missing_packages, collapse = ", "), ". Install the package dependencies declared in DESCRIPTION before ", - "running this script. gradethis is available from ", - "https://rstudio.r-universe.dev." + "running this script." ), call. = FALSE ) diff --git a/inst/templates/learnr_header.Rmd b/inst/templates/learnr_header.Rmd index 03803bf..ec15147 100644 --- a/inst/templates/learnr_header.Rmd +++ b/inst/templates/learnr_header.Rmd @@ -6,6 +6,8 @@ runtime: shiny_prerendered ```{r setup, include=FALSE} library(learnr) -library(gradethis) -gradethis_setup() -``` \ No newline at end of file +if (requireNamespace("gradethis", quietly = TRUE)) { + library(gradethis) + gradethis_setup() +} +``` diff --git a/tests/testthat/regression-fixtures/expected/regression_a-expected.Rmd b/tests/testthat/regression-fixtures/expected/regression_a-expected.Rmd index 423cc4e..9882b29 100644 --- a/tests/testthat/regression-fixtures/expected/regression_a-expected.Rmd +++ b/tests/testthat/regression-fixtures/expected/regression_a-expected.Rmd @@ -7,8 +7,10 @@ runtime: shiny_prerendered ```{r setup, include=FALSE} # Setup chunk added by tutorizeR library(learnr) -library(gradethis) -gradethis_setup() +if (requireNamespace("gradethis", quietly = TRUE)) { + library(gradethis) + gradethis_setup() +} ``` diff --git a/tests/testthat/regression-fixtures/expected/regression_b-expected.Rmd b/tests/testthat/regression-fixtures/expected/regression_b-expected.Rmd index 6c62d27..54a3360 100644 --- a/tests/testthat/regression-fixtures/expected/regression_b-expected.Rmd +++ b/tests/testthat/regression-fixtures/expected/regression_b-expected.Rmd @@ -7,8 +7,10 @@ runtime: shiny_prerendered ```{r setup, include=FALSE} # Setup chunk added by tutorizeR library(learnr) -library(gradethis) -gradethis_setup() +if (requireNamespace("gradethis", quietly = TRUE)) { + library(gradethis) + gradethis_setup() +} ``` diff --git a/tests/testthat/test-convert-core.R b/tests/testthat/test-convert-core.R index 34aca07..b8ce571 100644 --- a/tests/testthat/test-convert-core.R +++ b/tests/testthat/test-convert-core.R @@ -118,9 +118,8 @@ test_that("quarto-live output contains required include and format", { expect_true(any(grepl("```\\{webr\\}", lines))) }) -test_that("learnr smoke render succeeds when dependencies are available", { +test_that("learnr smoke render succeeds when learnr is available", { skip_if_not_installed("learnr") - skip_if_not_installed("gradethis") rep <- tutorize( input = fixture("rmd", "basic_code.Rmd"), diff --git a/tests/testthat/test-examples.R b/tests/testthat/test-examples.R index b1345e7..9addc04 100644 --- a/tests/testthat/test-examples.R +++ b/tests/testthat/test-examples.R @@ -108,10 +108,12 @@ test_that("example module dependencies are declared", { declared_packages <- declared_description_packages() expect_setequal( - intersect(used_packages, c("dplyr", "ggplot2", "readr", "learnr", "gradethis")), - c("dplyr", "ggplot2", "readr", "learnr", "gradethis") + intersect(used_packages, c("dplyr", "ggplot2", "readr", "learnr")), + c("dplyr", "ggplot2", "readr", "learnr") ) - expect_true(all(used_packages %in% declared_packages)) + expect_true("gradethis" %in% used_packages) + expect_false("gradethis" %in% declared_packages) + expect_true(all(setdiff(used_packages, "gradethis") %in% declared_packages)) }) test_that("example module does not expose placeholder MCQs", { @@ -154,6 +156,7 @@ test_that("example module converts to learnr and writes JSON report", { expect_true(file.exists(report$output_file)) expect_true(file.exists(report_file)) expect_true(any(grepl("learnr::tutorial", lines, fixed = TRUE))) + expect_true(any(grepl("requireNamespace(\"gradethis\"", lines, fixed = TRUE))) expect_true(any(grepl("gradethis_setup()", lines, fixed = TRUE))) expect_true(any(grepl("trz-mcq-bank", lines, fixed = TRUE))) expect_false(any(grepl("Answer A \\(edit me\\)", lines))) diff --git a/tests/testthat/test-jose-readiness.R b/tests/testthat/test-jose-readiness.R index 106a7c3..191e93a 100644 --- a/tests/testthat/test-jose-readiness.R +++ b/tests/testthat/test-jose-readiness.R @@ -28,6 +28,7 @@ test_that("learnr conversion injects gradethis setup and exercise scaffolds", { lines <- readLines(report$output_file, warn = FALSE) expect_true(any(grepl("library\\(learnr\\)", lines))) + expect_true(any(grepl("requireNamespace\\(\"gradethis\"", lines))) expect_true(any(grepl("library\\(gradethis\\)", lines))) expect_true(any(grepl("gradethis_setup\\(\\)", lines))) expect_true(any(grepl("exercise=TRUE", lines, fixed = TRUE))) diff --git a/vignettes/automatic-exercise-generation-feedback.Rmd b/vignettes/automatic-exercise-generation-feedback.Rmd index 3a4d9af..0a01a95 100644 --- a/vignettes/automatic-exercise-generation-feedback.Rmd +++ b/vignettes/automatic-exercise-generation-feedback.Rmd @@ -11,7 +11,7 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -`tutorizeR` turns ordinary R chunks into student exercise areas and hidden or collapsible solution material. For `learnr`, the setup chunk includes `learnr`, `gradethis`, and `gradethis_setup()` so that instructors can add answer checks after conversion. +`tutorizeR` turns ordinary R chunks into student exercise areas and hidden or collapsible solution material. For `learnr`, the setup chunk includes `learnr` and activates `gradethis_setup()` when `gradethis` is installed, so that instructors can add answer checks after conversion. ## Annotated source chunk From fadec43cf988880dccda63be935913096c3cf16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 13:07:48 -0400 Subject: [PATCH 09/10] chore: record CRAN resubmission --- CRAN-SUBMISSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index 939c2ec..11919fa 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ Version: 0.4.4 -Date: 2026-05-31 16:48:12 UTC -SHA: b6a4d065bda96073077c27f3b5a2fa709f1d4cae +Date: 2026-05-31 17:07:44 UTC +SHA: 839f3487567ac6950161c56ebeda225fb8e07373 From c1e94ec3e87ec73e269b47c19f1b45815f8f7759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicosia?= <116816597+AurelienNicosiaULaval@users.noreply.github.com> Date: Sun, 31 May 2026 14:28:55 -0400 Subject: [PATCH 10/10] docs: professionalize README and pkgdown articles --- .gitignore | 1 + NEWS.md | 2 + README.md | 265 ++++++++++++---------- _pkgdown.yml | 64 ++---- vignettes/conversion-rmd-vs-qmd.Rmd | 5 +- vignettes/documentation-website.Rmd | 57 +++++ vignettes/educational-use-cases.Rmd | 102 +++++++++ vignettes/large-undergraduate-courses.Rmd | 2 +- vignettes/tags-and-annotations.Rmd | 9 +- vignettes/teaching-workflow-scenario.Rmd | 2 +- 10 files changed, 333 insertions(+), 176 deletions(-) create mode 100644 vignettes/documentation-website.Rmd create mode 100644 vignettes/educational-use-cases.Rmd diff --git a/.gitignore b/.gitignore index d8d0066..341a500 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ ..Rcheck tutorizeR.Rcheck tutorizeR_*.tar.gz +pkgdown/ diff --git a/NEWS.md b/NEWS.md index ef384c6..c3322cb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,8 @@ - Recentered the review branch on JOSE software-submission requirements, clarified educational evidence boundaries, added CC-BY content licensing, and replaced internal smoke-test paths with installable example workflows. +- Reworked the README as a package-facing overview and added pkgdown-oriented + documentation articles for educational use cases and website maintenance. # tutorizeR 0.4.3 diff --git a/README.md b/README.md index 1d3f2af..feb37b9 100644 --- a/README.md +++ b/README.md @@ -7,42 +7,53 @@ # tutorizeR -`tutorizeR` helps instructors convert `.Rmd` and `.qmd` teaching material into interactive `learnr` tutorials or `quarto-live` resources. It supports pedagogical linting, reusable question banks, generated exercise and solution areas, conversion reports, and workflow artifacts for reproducible teaching. +`tutorizeR` is an R package for converting existing R Markdown (`.Rmd`) and Quarto (`.qmd`) teaching material into interactive tutorial documents for `learnr` and `quarto-live`. + +The package is designed for instructors who want to keep one source document while generating student-facing exercises, solution scaffolds, multiple-choice questions, and conversion reports. The core workflow is source-first: revise the lesson source, rerun the conversion, review the generated tutorial, and distribute the result through the course infrastructure already in use. ![tutorizeR workflow](man/figures/tutorize-workflow.svg) +## Scope + +`tutorizeR` supports the following teaching workflows: + +- Convert `.Rmd` and `.qmd` lessons to `learnr` tutorials. +- Convert `.qmd` lessons to `quarto-live`-oriented resources. +- Generate exercise and solution blocks from existing R chunks. +- Add conceptual checks through inline MCQ blocks or reusable YAML/JSON question banks. +- Lint source lessons before conversion. +- Write JSON or YAML conversion reports for review and reproducibility. +- Process a folder of lessons with a consistent conversion policy. +- Export LMS-oriented manifests for downstream integration. + +The package does not replace instructor review. Generated tutorials should be inspected before they are used with students, especially when assessment, feedback, or grading logic is involved. + +The repository currently demonstrates package functionality through tests, vignettes, documentation, and an installable example module. It does not currently contain formal classroom outcome data or measured learning-gain evidence. + ## Installation +Choose the installation source that matches your use case. + ```r +# CRAN, once the package is available there install.packages("tutorizeR") ``` -To install the development version from GitHub: - ```r -# install.packages("remotes") -remotes::install_github("AurelienNicosiaULaval/tutorizeR") +# Tagged GitHub release +install.packages("remotes") +remotes::install_github("AurelienNicosiaULaval/tutorizeR@v0.4.4") ``` -To use `r-universe`: - ```r -install.packages( - "tutorizeR", - repos = c( - "https://aureliennicosiaulaval.r-universe.dev", - "https://cloud.r-project.org" - ) -) +# Current development branch used for review work +install.packages("remotes") +remotes::install_github("AurelienNicosiaULaval/tutorizeR@review/jose-readiness") ``` -## Educational contribution - -`tutorizeR` is being prepared as a potential JOSE software submission: open-source educational infrastructure for computational teaching. It is intended for instructors who already maintain R Markdown or Quarto lessons and want to transform those lessons into interactive learning resources without duplicating source material. The package helps create active coding exercises, conceptual MCQs, reusable question-bank prompts, and feedback-ready `learnr` tutorials while preserving a source-first workflow. - -The repository demonstrates the workflow through installable examples, tests, vignettes, and reviewer documentation. It does not claim measured learning gains, improved grades, improved engagement, classroom deployment, or broad adoption unless such evidence is added to the repository. +## Quick Start -## Installed example workflow +The installed example module contains a Quarto lesson, a small local dataset, a question bank, and expected outputs. The following example copies the lesson to a temporary directory and converts it to a `learnr` tutorial. ```r library(tutorizeR) @@ -56,17 +67,24 @@ example_dir <- system.file( work_dir <- file.path(tempdir(), "tutorizeR-example") dir.create(work_dir, recursive = TRUE, showWarnings = FALSE) -file.copy(file.path(example_dir, "lesson-source.qmd"), work_dir, overwrite = TRUE) -file.copy(file.path(example_dir, "student_activity.csv"), work_dir, overwrite = TRUE) +file.copy( + from = file.path(example_dir, "lesson-source.qmd"), + to = work_dir, + overwrite = TRUE +) +file.copy( + from = file.path(example_dir, "student_activity.csv"), + to = work_dir, + overwrite = TRUE +) -source_file <- file.path(work_dir, "lesson-source.qmd") question_bank <- load_question_bank(file.path(example_dir, "question-bank")) report <- tutorize( - input = source_file, + input = file.path(work_dir, "lesson-source.qmd"), + output_dir = work_dir, format = "learnr", assessment = "both", - output_dir = work_dir, question_bank = question_bank, mcq_source = "mixed", overwrite = TRUE, @@ -76,140 +94,143 @@ report <- tutorize( print(report) ``` -The complete example is in `inst/examples/example_course_module/`. +The returned report records the input file, output file, output format, assessment mode, generated exercises, generated MCQs, lint summary, warnings, and render status when applicable. -## Reproducibility checklist +## Main Functions -Developer checks: +| Task | Functions | +| --- | --- | +| Convert one lesson | `tutorize()`, `convert_to_tutorial()` | +| Convert a folder | `convert_folder()` | +| Work with question banks | `load_question_bank()`, `validate_question_bank()` | +| Check lesson structure | `lint_source()`, `validate_input()`, `validate_output()` | +| Save conversion metadata | `write_tutorize_report()` | +| Export course integration artifacts | `export_lms_manifest()`, `export_tutorial_package()` | +| Use RStudio addins | `launch_tutorizeR_addin()`, `launch_tutorizeR_folder_addin()`, `launch_tutorizeR_preview_addin()` | -```bash -Rscript -e "testthat::test_local('.')" -Rscript -e "lintr::lint_package()" -tmpdir=$(mktemp -d) -rsync -a --exclude='.git' --exclude='*.Rcheck' --exclude='*.tar.gz' ./ "$tmpdir/tutorizeR/" -cd "$tmpdir/tutorizeR" -Rscript -e "devtools::document()" -R CMD build . -R CMD check --as-cran tutorizeR_0.4.4.tar.gz -``` +## Authoring Syntax -Installed smoke test: +Instructor comments inside R chunks control conversion. -```bash -Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" +```r +# tutorizeR: hints=Group by program before summarising|Use .groups = "drop" +activity |> + dplyr::group_by(program) |> + dplyr::summarise( + mean_hours = mean(study_hours), + mean_score = mean(quiz_score), + .groups = "drop" + ) ``` -## JOSE submission note +Supported tags include: -`tutorizeR` is a potential JOSE software submission as educational technology and infrastructure. JOSE documentation states that software submissions should support teaching and learning, or make an educational process better, faster, easier, or simpler. The repository currently supports that claim through package functionality, tests, documentation, vignettes, and an installable teaching example. +- `skip` +- `exercise-only` +- `solution-only` +- `mcq` +- `narrative-only` +- `locked` +- `hints=Hint 1|Hint 2` -Reviewer-facing JOSE materials: +Inline MCQs use YAML inside a `tutorizeR-mcq` fenced block. -- `docs/jose_submission_guide.md` -- `docs/jose_release_bundle.md` -- `docs/jose_review_checklist.md` -- `docs/educational_use_evidence.md` -- `docs/jose_blockers_report.md` -- `docs/jose_pr_final_report.md` -- `inst/examples/example_course_module/README.md` -- `paper/paper.md` -- `paper/paper.bib` +```yaml +question: "Which variable identifies the academic program?" +answers: + - text: "program" + correct: true + - text: "quiz_score" + correct: false +``` -Formal learning-outcome evaluation: Not verifiable from repository contents. -Actual classroom deployment: Not verifiable from repository contents. -Broad instructor adoption: Not verifiable from repository contents. -Final release DOI: Not verifiable from repository contents. -JOSE submission or acceptance: Not verifiable from repository contents. +Reusable question-bank references use YAML inside a `tutorizeR-mcq-ref` fenced block. -## Secondary target: JOSS +```yaml +ids: [visualization-aesthetic] +strategy: ordered +shuffle_answers: false +``` -JOSS remains a secondary possibility if the maintainers decide to emphasize software contribution rather than educational infrastructure. Existing JOSS-oriented documents are kept for that possible route, but the primary preparation in this branch is JOSE. +## Batch Conversion -- `docs/joss_submission_guide.md` -- `docs/joss_release_bundle.md` +```r +library(tutorizeR) -## Main API +question_bank <- load_question_bank("course/question-bank") -- `tutorize()` / `convert_to_tutorial()` -- `convert_folder()` -- `load_question_bank()` / `validate_question_bank()` -- `lint_source()` -- `write_tutorize_report()` -- `export_lms_manifest()` -- `export_tutorial_package()` -- `check_tutorial()` +folder_report <- convert_folder( + dir = "course/lessons", + recursive = TRUE, + output_dir = "course/tutorials", + format = "learnr", + assessment = "both", + question_bank = question_bank, + mcq_source = "mixed", + lint_strict = TRUE, + overwrite = TRUE +) -## Teacher tags +print(folder_report) +``` -Inside R chunks: +## Documentation -- `# tutorizeR: skip` -- `# tutorizeR: exercise-only` -- `# tutorizeR: solution-only` -- `# tutorizeR: mcq` -- `# tutorizeR: narrative-only` -- `# tutorizeR: locked` -- `# tutorizeR: hints=Hint 1|Hint 2` +The package includes vignettes that are also used as pkgdown articles: -## MCQ block schemas +- [Getting started](vignettes/getting-started.Rmd) +- [Teaching workflow scenario](vignettes/teaching-workflow-scenario.Rmd) +- [Converting a Quarto lesson into an interactive tutorial](vignettes/quarto-lesson-interactive-tutorial.Rmd) +- [Building reproducible data science assignments](vignettes/reproducible-data-science-assignments.Rmd) +- [Reusable question banks](vignettes/question-bank.Rmd) +- [Tags and annotation syntax](vignettes/tags-and-annotations.Rmd) +- [MCQ and assessment modes](vignettes/mcq-and-assessment.Rmd) +- [Lint and debug workflow](vignettes/lint-and-debug.Rmd) +- [Debugging and common errors](vignettes/debugging-and-errors.Rmd) +- [Educational use cases](vignettes/educational-use-cases.Rmd) +- [Documentation website](vignettes/documentation-website.Rmd) +- [JOSE submission readiness](vignettes/jose-submission-readiness.Rmd) -Explicit question blocks use YAML inside a `tutorizeR-mcq` fenced block: +The pkgdown site configuration is stored in `_pkgdown.yml`. The generated site is built into `pkgdown/` so it does not overwrite the repository's source documentation in `docs/`. -```yaml -question: "2 + 2 = ?" -answers: - - text: "4" - correct: true - - text: "5" - correct: false +```r +pkgdown::build_site() ``` -Question-bank reference blocks use YAML inside a `tutorizeR-mcq-ref` fenced block: - -```yaml -ids: [mean-basic, sum-basic] -strategy: ordered -shuffle_answers: false -``` +## Quality Control -## Addins +Recommended local checks for maintainers: -- Convert active file -- Convert folder -- Preview conversion with Source, Output, Diff, Lint, and Logs tabs +```bash +Rscript -e "testthat::test_local('.')" +Rscript -e "lintr::lint_package()" +Rscript -e "urlchecker::url_check()" +Rscript -e "devtools::document()" +R CMD build . +R CMD check --as-cran tutorizeR_0.4.4.tar.gz +``` -## CLI mode +Installed example smoke test: ```bash -Rscript inst/scripts/tutorizeR-cli.R --input=lesson.qmd --format=learnr --assessment=both --overwrite=true -Rscript inst/scripts/tutorizeR-cli.R --dir=course_material --recursive=true --format=learnr +Rscript -e "source(system.file('examples', 'example_course_module', 'run-example.R', package = 'tutorizeR'))" ``` -## Known limitations +## Known Limitations -- `learnr` render checks require `learnr` installed. -- Optional `gradethis` setup is activated in generated `learnr` tutorials when `gradethis` is installed. +- `learnr` render checks require `learnr` to be installed. +- Generated `learnr` tutorials activate `gradethis` setup only when `gradethis` is installed. - `quarto-live` output requires the Quarto live extension in the teaching project. -- LMS export is manifest-only in v0.4, with no direct remote LMS publishing API. -- Question banks are local YAML or JSON files in v0.4. -- Formal learning-outcome evaluation: Not verifiable from repository contents. +- LMS export is manifest-only in version 0.4 and does not publish directly to a remote LMS API. +- Question banks are local YAML or JSON files in version 0.4. +- Formal learning-outcome evaluation is not included in the repository. -## Documentation +## Review and Publication Materials -- `vignettes/getting-started.Rmd` -- `vignettes/teaching-workflow-scenario.Rmd` -- `vignettes/quarto-lesson-interactive-tutorial.Rmd` -- `vignettes/reproducible-data-science-assignments.Rmd` -- `vignettes/automatic-exercise-generation-feedback.Rmd` -- `vignettes/large-undergraduate-courses.Rmd` -- `vignettes/question-bank.Rmd` -- `vignettes/tags-and-annotations.Rmd` -- `vignettes/conversion-rmd-vs-qmd.Rmd` -- `vignettes/mcq-and-assessment.Rmd` -- `vignettes/lint-and-debug.Rmd` +Reviewer-facing JOSE and JOSS preparation materials are maintained in the source repository under `docs/` and `paper/`. These files are intentionally kept separate from the CRAN package contents. Claims about classroom deployment, broad adoption, or learning outcomes should be added only when supported by verifiable repository evidence. ## Licensing The package code is released under the MIT license. The CRAN-style license metadata is stored in `LICENSE`, and the full MIT license text is available in `LICENSE.md`. -Educational example materials in `inst/examples/`, generated expected educational outputs, and graphical documentation assets in `man/figures/` are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md` and `LICENSES.md`. +Educational example materials in `inst/examples/`, generated expected educational outputs, and graphical documentation assets in `man/figures/` are released under CC-BY 4.0 unless otherwise specified. See `LICENSE-CONTENT.md` and `LICENSES.md` in the source repository. diff --git a/_pkgdown.yml b/_pkgdown.yml index bdcfe90..29c43f1 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,48 +1,16 @@ +destination: pkgdown + template: bootstrap: 5 home: title: tutorizeR - description: Convert existing R Markdown and Quarto teaching materials into interactive tutorials. + description: Convert existing R Markdown and Quarto teaching material into interactive tutorial documents. navbar: structure: - left: [intro, articles, reference, jose_readiness, teaching_examples, educational_adoption] + left: [intro, articles, reference, news] right: [search, github] - components: - jose_readiness: - text: JOSE readiness - menu: - - text: JOSE submission guide - href: ../docs/jose_submission_guide.md - - text: JOSE review checklist - href: ../docs/jose_review_checklist.md - - text: JOSE audit - href: ../docs/jose_audit.md - - text: JOSE blockers report - href: ../docs/jose_blockers_report.md - teaching_examples: - text: Teaching examples - menu: - - text: Teaching workflow scenario - href: articles/teaching-workflow-scenario.html - - text: Getting started - href: articles/getting-started.html - - text: Question bank - href: articles/question-bank.html - - text: Lint and debug - href: articles/lint-and-debug.html - - text: Example course module - href: ../inst/examples/example_course_module/README.md - educational_adoption: - text: Educational adoption - menu: - - text: Educational use evidence - href: ../docs/educational_use_evidence.md - - text: Educational use cases - href: ../docs/educational_use_cases.md - - text: Large undergraduate courses - href: articles/large-undergraduate-courses.html reference: - title: Core conversion @@ -79,28 +47,30 @@ reference: - tr articles: - - title: Getting started - navbar: Getting started + - title: Start here + navbar: Start here contents: - getting-started - teaching-workflow-scenario - quarto-lesson-interactive-tutorial - reproducible-data-science-assignments - - title: Authoring and syntax + - title: Authoring and assessment navbar: Authoring contents: - - question-bank - tags-and-annotations - - conversion-rmd-vs-qmd + - question-bank - mcq-and-assessment - - lint-and-debug - - debugging-and-errors - automatic-exercise-generation-feedback - - title: Educational use - navbar: Educational use + - conversion-rmd-vs-qmd + - title: Course operations + navbar: Course operations contents: - large-undergraduate-courses - - title: Reviewer materials - navbar: JOSE + - lint-and-debug + - debugging-and-errors + - educational-use-cases + - title: Project documentation + navbar: Project documentation contents: + - documentation-website - jose-submission-readiness diff --git a/vignettes/conversion-rmd-vs-qmd.Rmd b/vignettes/conversion-rmd-vs-qmd.Rmd index b3a523f..eb14619 100644 --- a/vignettes/conversion-rmd-vs-qmd.Rmd +++ b/vignettes/conversion-rmd-vs-qmd.Rmd @@ -1,8 +1,8 @@ --- -title: "Conversion for Rmd and qmd" +title: "Conversion for R Markdown and Quarto" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Conversion for Rmd and qmd} + %\VignetteIndexEntry{Conversion for R Markdown and Quarto} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -78,4 +78,3 @@ Generated output should be reviewed in the environment where students will use i file.exists(learnr_report$output_file) file.exists(live_report$output_file) ``` - diff --git a/vignettes/documentation-website.Rmd b/vignettes/documentation-website.Rmd new file mode 100644 index 0000000..b137759 --- /dev/null +++ b/vignettes/documentation-website.Rmd @@ -0,0 +1,57 @@ +--- +title: "Documentation Website" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Documentation Website} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +## Purpose + +The repository includes a pkgdown configuration so that the README, function reference pages, and vignettes can be rendered as a documentation website. The site configuration is stored in `_pkgdown.yml`. + +The generated site is written to `pkgdown/`. This keeps generated website files separate from the repository's source documentation in `docs/`. + +## Build Locally + +```{r eval=FALSE} +library(pkgdown) + +build_site() +``` + +For a documentation-only check, build the articles and reference index locally before pushing changes. + +```{r eval=FALSE} +library(pkgdown) + +build_articles() +build_reference() +``` + +## Article Groups + +The pkgdown site organizes vignettes into four groups: + +- Start here: first conversion workflow and common teaching scenarios. +- Authoring and assessment: tags, MCQs, question banks, and output formats. +- Course operations: batch conversion, linting, debugging, and educational use cases. +- Project documentation: site maintenance and reviewer-facing readiness notes. + +## Maintenance Checklist + +Before publishing documentation changes, run: + +```bash +Rscript -e "devtools::document()" +Rscript -e "testthat::test_local('.')" +Rscript -e "lintr::lint_package()" +Rscript -e "pkgdown::build_site()" +``` + +If a user-facing function, argument, or workflow changes, update at least one vignette and the relevant reference documentation. diff --git a/vignettes/educational-use-cases.Rmd b/vignettes/educational-use-cases.Rmd new file mode 100644 index 0000000..a01f69b --- /dev/null +++ b/vignettes/educational-use-cases.Rmd @@ -0,0 +1,102 @@ +--- +title: "Educational Use Cases" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Educational Use Cases} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") +``` + +## Purpose + +`tutorizeR` is intended for instructors who maintain statistical, data science, or R programming lessons in R Markdown or Quarto. The package supports a source-first workflow: the instructor edits one source document, then generates an interactive tutorial, solution scaffolds, conceptual questions, and conversion reports from that source. + +This vignette describes plausible educational use cases. Actual classroom deployment and measured learning outcomes are not verifiable from repository contents. + +## Pre-class Tutorial + +An instructor can convert a lecture note into a pre-class activity. Students read the narrative, run short examples, answer MCQs, and complete a few code exercises before the in-person session. + +```{r eval=FALSE} +library(tutorizeR) + +report <- tutorize( + input = "lessons/week03-data-visualization.qmd", + output_dir = "tutorials/preclass", + format = "learnr", + assessment = "both", + overwrite = TRUE +) + +print(report) +``` + +## Laboratory Handout + +A laboratory handout can be maintained as a regular `.qmd` file and converted into an interactive tutorial before release. Teacher tags can mark which chunks become exercises, which chunks remain locked, and which hints should be shown to students. + +```r +# tutorizeR: hints=Start with group_by()|Then compute a summary statistic +activity |> + dplyr::group_by(program) |> + dplyr::summarise( + mean_hours = mean(study_hours), + .groups = "drop" + ) +``` + +## Reusable Concept Checks + +Question banks are useful when the same concepts appear across several modules. The instructor can store MCQs in YAML or JSON and reference them from different lessons. + +```yaml +ids: [visualization-aesthetic, grouped-summary] +strategy: ordered +shuffle_answers: false +``` + +```{r eval=FALSE} +library(tutorizeR) + +question_bank <- load_question_bank("question-bank") + +report <- tutorize( + input = "lessons/week04-summarisation.qmd", + format = "learnr", + assessment = "both", + question_bank = question_bank, + mcq_source = "mixed", + overwrite = TRUE +) +``` + +## Course Team Review + +For courses with teaching assistants or multiple instructors, conversion reports can be saved and reviewed before distributing materials. + +```{r eval=FALSE} +library(tutorizeR) + +report <- tutorize( + input = "lessons/week05-models.qmd", + output_dir = "generated", + format = "learnr", + assessment = "both", + lint_strict = TRUE, + overwrite = TRUE +) + +write_tutorize_report( + report = report, + file = "generated/week05-conversion-report.json", + format = "json" +) +``` + +## Evidence Boundary + +The repository provides source code, tests, vignettes, reviewer documentation, and an installable example module. It does not currently provide anonymized classroom analytics, controlled learning studies, or external adoption records. Any future claim about classroom deployment or learning impact should be tied to verifiable evidence. diff --git a/vignettes/large-undergraduate-courses.Rmd b/vignettes/large-undergraduate-courses.Rmd index 1f2b232..35a1806 100644 --- a/vignettes/large-undergraduate-courses.Rmd +++ b/vignettes/large-undergraduate-courses.Rmd @@ -11,7 +11,7 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -This vignette is an illustrative scenario. Actual classroom deployment is Not verifiable from repository contents. +This vignette is an illustrative scenario. Actual classroom deployment is not verifiable from repository contents. Large undergraduate courses need consistent materials, reproducible updates, and clear handoffs between instructors and teaching assistants. `tutorizeR` is designed for this kind of operational teaching workflow. diff --git a/vignettes/tags-and-annotations.Rmd b/vignettes/tags-and-annotations.Rmd index f4da785..242d63c 100644 --- a/vignettes/tags-and-annotations.Rmd +++ b/vignettes/tags-and-annotations.Rmd @@ -26,6 +26,11 @@ This vignette documents supported teacher tags. ## Example ```{r eval=FALSE} -# tutorizeR: mcq, hints=Inspect the data|Use summary() -summary(mtcars) +# tutorizeR: mcq, hints=Inspect the grouping variable|Summarise by program +activity |> + dplyr::group_by(program) |> + dplyr::summarise( + mean_hours = mean(study_hours), + .groups = "drop" + ) ``` diff --git a/vignettes/teaching-workflow-scenario.Rmd b/vignettes/teaching-workflow-scenario.Rmd index 55caeca..68a68f2 100644 --- a/vignettes/teaching-workflow-scenario.Rmd +++ b/vignettes/teaching-workflow-scenario.Rmd @@ -11,7 +11,7 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -This vignette is an illustrative scenario. Actual classroom deployment is Not verifiable from repository contents. +This vignette is an illustrative scenario. Actual classroom deployment is not verifiable from repository contents. ## Teaching problem