Metadata-Version: 2.4
Name: mkdocs-superquiz
Version: 0.6.1
Summary: MkDocs plugin to create interactive, multilingual quizzes with scoring, MathJax support and QR-code correction unlocking
Author-email: "Rod2ik, aka Rodrigo Schwencke" <rod2ik.dev@gmail.com>
License: GPL-3.0-or-later
Project-URL: Homepage, https://rod2ik.gitlab.io/mkdocs-superquiz/
Project-URL: Documentation, https://rod2ik.gitlab.io/mkdocs-superquiz/
Project-URL: Repository, https://gitlab.com/rod2ik/mkdocs-superquiz
Project-URL: Issues, https://gitlab.com/rod2ik/mkdocs-superquiz/-/issues
Keywords: mkdocs,quiz,superquiz,qcm,plugin,mc,sc,blanks,dropdown,order,columns,match,graph,flashcard,mathjax,i18n,education,interactive,markdown
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: MkDocs
Classifier: Environment :: Plugins
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Education
Classifier: Topic :: Documentation
Classifier: Topic :: Text Processing :: Markup
Classifier: Topic :: Text Processing :: Markup :: Markdown
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mkdocs<2.0,>=1.5
Requires-Dist: pymdown-extensions>=10.0
Requires-Dist: PyYAML>=6.0
Requires-Dist: python-dotenv<2.0,>=1.0
Requires-Dist: cryptography<47,>=42
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: mkdocs-material<10,>=9; extra == "dev"
Requires-Dist: Pillow; extra == "dev"
Requires-Dist: pytest<9,>=7; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: twine>=6; extra == "dev"
Dynamic: license-file

# mkdocs-superquiz

`mkdocs-superquiz` creates interactive multilingual questions for MkDocs and global evaluation sessions with one final validation and score.

## Two behaviors

### Embedded questions — default

No page mode is required. Each question is independent and gets its own Validate/Reset behavior:

```markdown
!!! mcquiz "European capitals"
    ---
    points: 2
    ---
    Select every capital.
    answers:
      - [Paris]
      - [Madrid]
      - Lyon
```

### Global evaluation

Activate one complete evaluation in page front matter:

```yaml
---
superquiz:
  mode: eval
---
```

All atomic questions belong to the same evaluation, individual Validate buttons disappear, and the page gets shared Validate, Reset, score, optional timer, randomization, and navigation.

Evaluation navigation is draggable by default. Every page-evaluation position is a focus layout. `right` replaces Material's right-hand table of contents and hides the left sidebar; `left` replaces Material's primary navigation and hides the right sidebar; `top` and `bottom` hide both desktop sidebars so the quiz content reclaims their width. As soon as Material switches its primary navigation to the hamburger drawer, all four positions converge to a dedicated nested quiz-navigation level. The numbered quiz menu therefore takes precedence at tablet and mobile widths alike, while Material's standard nested-navigation back arrow returns one level to the normal site hierarchy. For `top`, the desktop menu is anchored 2 px below the real rendered Material header and follows header/window resizing. The draggable evaluation toolbar is a separate overlay placed on the opposite side by default. Set `navigation.draggable: false` to keep the desktop menu fixed at its configured anchor.

Canonical mode and aliases:

| Canonical | Accepted aliases |
| --- | --- |
| `eval` | `evaluation`, `exam`, `examen`, `assessment`, `page.eval`, `page.evaluation`, `page.exam`, `page.examen`, `page.assessment` |


## Reveal.js integration

With `mkdocs-revealjs >= 0.10`, ordinary `mode: diapo` decks keep SuperQuiz questions embedded automatically. A `mode: diapo.eval` deck creates an independent evaluation session with global validation, timer, score and numbered navigation. Its **first click anywhere inside the visible evaluation wrapper requests deck-scoped browser fullscreen before password entry**, for both `standard` and `strict`; a Reveal password gate therefore stays in fullscreen while the learner authenticates.

No SuperQuiz mode is required for ordinary Reveal integration. The equivalent explicit two-dimensional form for a Reveal evaluation is:

```yaml
revealjs:
  mode: diapo
superquiz:
  mode: eval
```

An explicit `diapo.eval` deck is the compact form and owns the most local evaluation scope.

## Configuration priority

Question behavior resolves from least to most local:

```text
built-ins
< mkdocs.yml common
< mkdocs.yml type
< mkdocs.yml eval/embedded
< mkdocs.yml eval/embedded type
< page common/type/eval layers
< Reveal deck common/type/eval layers
< question mini-frontmatter
```

The most local explicit value wins. Evaluation sessions are scoped independently by page/deck ID.

## Installation

```bash
pip install mkdocs-superquiz
```

```yaml
plugins:
  - search
  - superquiz
```


## Secrets and evaluation access

Do not commit teacher or evaluation passwords in YAML. Point configuration to environment variables instead:

```yaml
plugins:
  - superquiz:
      security_mode: obfuscated
      teacher_code: env:SUPERQUIZ_TEACHER_CODE
      eval:
        access:
          password: env:SUPERQUIZ_EVAL_PASSWORD
```

For local development, put the real values in an ignored `.env` file. For GitLab Pages builds, define the same names under **Settings → CI/CD → Variables**. The teacher code keeps the existing SHA-256 correction-unlock behavior. Evaluation access emits only a PBKDF2-HMAC-SHA256 verifier into the generated static site; the clear-text evaluation password is not written to GitLab Pages.

Correction unlocks now use only two canonical QR scopes: `question` and `all_questions`. Set `correction_granularity: question` (the default) for one correction lock per question, or `correction_granularity: all_questions` for one page-wide unlock. Legacy unlock scopes such as `exercise`, `page`, and `eval` are intentionally unsupported. The global evaluation-toolbar action is named **Unlock All Corrections**.

A page or `diapo.eval` frontmatter can override `eval.access.password` with another `env:...` variable. Clear-text evaluation passwords in YAML are intentionally rejected.

## Question types

```text
mcquiz, scquiz, blanks, scdropdown, mcdropdown,
order, columns, sentence,
match, match.line, match.bezier,
image, path, graph,
matrix, flashcard
```

The ordering family (`order`, `columns`, `sentence`) requires an explicit `answers:` block. A bare Markdown list is not an answer definition. Localized `answers` aliases remain supported through the normal i18n vocabulary (for example `réponses:` in French).

## Development

```bash
yarn dev
yarn dev:lan
yarn build
yarn build:full
yarn bfc
yarn zip
```

`yarn dev:lan` exposes the MkDocs development server on `0.0.0.0:8000` for testing from another device on the same LAN.

`package.json` is the version source of truth.

## License

GNU GPL-3.0-or-later.

### Encrypted live QR violation snapshot

For evaluations, `eval.qr_report.enabled: true` enables the encrypted live QR snapshot inside the shared draggable evaluation toolbar. The QR is regenerated after every recorded violation and is encrypted client-side with a build-generated public ECDH P-256 key. Scanning it opens a teacher-code-protected viewer on the same static site; no backend is required. `eval.show_live_violations` is independent and defaults to `false`; when enabled, grouped counts appear at the bottom of the same toolbar. In `strict`, the QR and Reset All are visible by default while Unlock All Corrections is hidden by default through `eval.toolbar`. The toolbar is draggable by default and starts on the side opposite the numbered navigation. In strict mode the toolbar timer is enabled automatically as a 50-minute countdown (overridable, including `enabled: false`) and stops when final validation succeeds. Every recorded strict violation also emits a stacked transient notification using `--mksq-tooltip-font-size` (default `1rem`) above the UI (`z-index: 50000`).
